卷积神经网络发展(网络骨架:Backbone)
CNN網絡架構演進:從LeNet到DetNet
卷積神經網絡可謂是現在深度學習領域中大紅大紫的網絡框架,尤其在計算機視覺領域更是一枝獨秀。CNN從90年代的LeNet開始,21世紀初沉寂了10年,直到12年AlexNet開始又再煥發第二春,從ZF Net到VGG,GoogLeNet再到ResNet和最近的DenseNet,網絡越來越深,架構越來越復雜,解決反向傳播時梯度消失的方法也越來越巧妙。
在圖像的眾多任務中,第一步通常是利用卷積神經網絡處理輸入圖像,生成深層的特征圖,然后再利用各種算法完成區域生成與損失計算,這部分卷積神經網絡是整個檢測算法的“骨架”,也被稱為Backbone。
本文將會談到以下經典的卷積神經網絡:
1、LeNet:開山之作
2、AlexNet:王者歸來
3、ZF:穩步前行
4、VGG:走向深度
5、GoogLeNet(Inception):縱橫交錯
6、ResNet:里程碑的殘差結構
7、DenseNet:繼往開來,多重殘差
8、FPN:特征金字塔
9、DetNet:為檢測而生
1 開山之作:LeNet
LeNet-5出自論文Gradient-Based Learning Applied to Document Recognition,是一種用于手寫體字符識別的非常高效的卷積神經網絡。
閃光點:定義了CNN的基本組件,是CNN的鼻祖。
LeNet是卷積神經網絡的祖師爺LeCun在1998年提出,用于解決手寫數字識別的視覺任務。自那時起,CNN的最基本的架構就定下來了:卷積層、池化層、全連接層。如今各大深度學習框架中所使用的LeNet都是簡化改進過的LeNet-5(-5表示具有5個層),和原始的LeNet有些許不同,比如把激活函數改為了現在很常用的ReLu。
LeNet-5跟現有的conv->pool->ReLU的套路不同,它使用的方式是conv1->pool->conv2->pool2再接全連接層,但是不變的是,卷積層后緊接池化層的模式依舊不變。
以上圖為例,對經典的LeNet-5做深入分析:
-
1首先輸入圖像是單通道的28* 28大小的圖像,用矩陣表示就是[1,28,28]
-
2 第一個卷積層conv1所用的卷積核尺寸為5* 5,滑動步長為1,卷積核數目為20,那么經過該層后圖像尺寸變為24,28-5+1=24,輸出矩陣為[20,24,24]。
-
3 第一個池化層pool核尺寸為2* 2,步長2,這是沒有重疊的max pooling,池化操作后,圖像尺寸減半,變為12×12,輸出矩陣為[20,12,12]。
-
4 第二個卷積層conv2的卷積核尺寸為5* 5,步長1,卷積核數目為50,卷積后圖像尺寸變為8,這是因為12-5+1=8,輸出矩陣為[50,8,8].
-
5 第二個池化層pool2核尺寸為2* 2,步長2,這是沒有重疊的max pooling,池化操作后,圖像尺寸減半,變為4×4,輸出矩陣為[50,4,4]。
-
6 pool2后面接全連接層fc1,神經元數目為500,再接relu激活函數。
-
7 再接fc2,神經元個數為10,得到10維的特征向量,用于10個數字的分類訓練,送入softmaxt分類,得到分類結果的概率output。
LeNet的Keras實現:
def LeNet():
model = Sequential()
model.add(Conv2D(32,(5,5),strides=(1,1),input_shape=(28,28,1),padding=‘valid’,activation=‘relu’,kernel_initializer=‘uniform’))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64,(5,5),strides=(1,1),padding=‘valid’,activation=‘relu’,kernel_initializer=‘uniform’))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(100,activation=‘relu’))
model.add(Dense(10,activation=‘softmax’))
return model
Lenet更為詳細介紹,詳見網絡解析(一):LeNet-5詳解
2 王者歸來:AlexNet
AlexNet在2012年ImageNet競賽中以超過第二名10.9個百分點的絕對優勢一舉奪冠,從此深度學習和卷積神經網絡名聲鵲起,深度學習的研究如雨后春筍般出現,AlexNet的出現可謂是卷積神經網絡的王者歸來。
2.1 特點
AlexNet是在LeNet的基礎上加深了網絡的結構,學習更豐富更高維的圖像特征。AlexNet的特點:
- 更深的網絡結構
- 使用層疊的卷積層,即卷積層+卷積層+池化層來提取圖像的特征
- 使用Dropout抑制過擬合
- 使用數據增強Data Augmentation抑制過擬合
- 使用Relu替換之前的sigmoid的作為激活函數
- LRN
- 多GPU訓練
2.1.1 ReLu作為激活函數
相比于sigmoid,ReLU有以下有點:
- 計算開銷小。
sigmoid的正向傳播有指數運算,倒數運算,而ReLu是線性輸出;反向傳播中,sigmoid有指數運算,而ReLU有輸出的部分,導數始終為1. - 梯度飽和問題
- 稀疏性。Relu會使一部分神經元的輸出為0,這樣就造成了網絡的稀疏性,并且減少了參數的相互依存關系,緩解了過擬合問題的發生。
2.1.2 數據增強
神經網絡由于訓練的參數多,表能能力強,所以需要比較多的數據量,不然很容易過擬合。當訓練數據有限時,可以通過一些變換從已有的訓練數據集中生成一些新的數據,以快速地擴充訓練數據。對于圖像數據集來說,可以對圖像進行一些形變操作:
- 翻轉
- 隨機裁剪
- 平移,顏色光照的變換
…
AlexNet中對數據做了以下操作:
1、隨機裁剪,對256×256的圖片進行隨機裁剪到224×224,然后進行水平翻轉。
2、測試的時候,對左上、右上、左下、右下、中間分別做了5次裁剪,然后翻轉,共10個裁剪,之后對結果求平均。
3、對RGB空間做PCA(主成分分析),然后對主成分做一個(0, 0.1)的高斯擾動,也就是對顏色、光照作變換,結果使錯誤率又下降了1%。
2.1.3 層疊池化
在LeNet中池化是不重疊的,即池化的窗口的大小和步長是相等的,如下
一般的池化層因為沒有重疊,所以pool_size 和 stride一般是相等的,例如8×8的一個圖像,如果池化層的尺寸是2×2,那么經過池化后的操作得到的圖像是 4×4大小,這種設置叫做不覆蓋的池化操作,如果 stride < pool_size, 那么就會產生覆蓋的池化操作,這種有點類似于convolutional化的操作,這樣可以得到更準確的結果。在AlexNet中使用的池化(Pooling)卻是可重疊的,AlexNet池化的大小為3×3的正方形,每次池化移動步長為2,這樣就會出現重疊。在top-1,和top-5中使用覆蓋的池化操作分別將error rate降低了0.4%和0.3%。論文中說,在訓練模型過程中,覆蓋的池化層更不容易過擬合。
2.1.4 Local Responce Normalization局部相應歸一化
局部響應歸一層的基本思路是,假如這是網絡的一塊,比如是 13×13×256, LRN 要做的就是選取一個位置,比如說這樣一個位置,從這個位置穿過整個通道,能得到 256 個數字,并進行歸一化。進行局部響應歸一化的動機是,對于這張 13×13 的圖像中的每個位置來說,我們可能并不需要太多的高激活神經元。但是后來,很多研究者發現 LRN 起不到太大作用,因為并不重要,而且我們現在并不用 LRN 來訓練網絡。
2.1.5 Dropout
這個是比較常用的抑制過擬合的方法了。
引入Dropout主要是為了防止過擬合。在神經網絡中Dropout通過修改神經網絡本身結構來實現,對于某一層的神經元,通過定義的概率將神經元置為0,這個神經元就不參與前向和后向傳播,就如同在網絡中被刪除了一樣,同時保持輸入層與輸出層神經元的個數不變,然后按照神經網絡的學習方法進行參數更新。在下一次迭代中,又重新隨機刪除一些神經元(置為0),直至訓練結束。
Dropout應該算是AlexNet中一個很大的創新,現在神經網絡中的必備結構之一。Dropout也可以看成是一種模型組合,每次生成的網絡結構都不一樣,通過組合多個模型的方式能夠有效地減少過擬合,Dropout只需要兩倍的訓練時間即可實現模型組合(類似取平均)的效果,非常高效。
2.2 Alex網絡結構
首先這幅圖分為上下兩個部分的網絡,論文中提到這兩部分網絡是分別對應兩個GPU,只有到了特定的網絡層后才需要兩塊GPU進行交互,這種設置完全是利用兩塊GPU來提高運算的效率,其實在網絡結構上差異不是很大。因此,只需拿出其中一個講解即可:
AlexNet針對的是1000類的分類問題,輸入圖片規定是256×256的三通道彩色圖片,為了增強模型的泛化能力,避免過擬合,作者使用了隨機裁剪的思路對原來256×256的圖像進行隨機裁剪,得到尺寸為3×224×224的圖像,輸入到網絡訓練。
網絡包含8個帶權重的層;前5層是卷積層,剩下的3層是全連接層。最后一層全連接層的輸出是1000維softmax的輸入,softmax會產生1000類標簽的分布網絡包含8個帶權重的層;前5層是卷積層,剩下的3層是全連接層。最后一層全連接層的輸出是1000維softmax的輸入,softmax會產生1000類標簽的分布。
- 卷積層C1
- 該層的處理流程是: 卷積–>ReLU–>池化–>歸一化。
- 卷積,輸入是224×224×3,使用96個11×11×3的卷積核,滑動步長為4,得到的FeatureMap為55×55×96。(這里的55是個難以理解的數字,作者也沒有對此說明,如果按照正常計算的話(224-11)/4+1 != 55的,所以這里是做了padding再做卷積的,即先padiing圖像至227×227,再做卷積(227-11)/4+1 = 55。)
- ReLU,將卷積層輸出的FeatureMap輸入到ReLU函數中。
- 池化,使用3×3步長為2的池化單元(重疊池化,步長小于池化單元的寬度),輸出為27×27×96((55?3)/2+1=27)
- 局部響應歸一化,使用k=2,n=5,α=10?4,β=0.75進行局部歸一化,輸出的仍然為27×27×96,輸出分為兩組,每組的大小為27×27×48
- 卷積層C2
- 該層的處理流程是:卷積–>ReLU–>池化–>歸一化
- 卷積,輸入是2組27×27×48。使用2組,每組128個尺寸為5×5×48的卷積核,并作了邊緣填充padding=2,卷積的步長為1. 則輸出的FeatureMap為2組,每組的大小為27×27 times128. ((27+2?2?5)/1+1=27)
- ReLU,將卷積層輸出的FeatureMap輸入到ReLU函數中
- 池化運算的尺寸為3×3,步長為2,池化后圖像的尺寸為(27?3)/2+1=13,輸出為13×13×256
- 局部響應歸一化,使用k=2,n=5,α=10?4,β=0.75進行局部歸一化,輸出的仍然為13×13×256,輸出分為2組,每組的大小13×13×128
- 卷積層C3
- 該層的處理流程是: 卷積–>ReLU
- 卷積,輸入是13×13×256,使用2組共384個尺寸為3×3×256的卷積核,做了邊緣填充padding=1,卷積的步長為1.則輸出的FeatureMap為13×13 times384
- ReLU,將卷積層輸出的FeatureMap輸入到ReLU函數中
- 卷積層C4
- 該層的處理流程是: 卷積–>ReLU(該層和C3類似。)
- 卷積,輸入是13×13×384,分為兩組,每組為13×13×192.使用2組,每組192個尺寸為3×3×192的卷積核,做了邊緣填充padding=1,卷積的步長為1.則輸出的FeatureMap為13×13 times384,分為兩組,每組為13×13×192
- ReLU,將卷積層輸出的FeatureMap輸入到ReLU函數中
- 卷積層C5
- 該層處理流程為:卷積–>ReLU–>池化
- 卷積,輸入為13×13×384,分為兩組,每組為13×13×192。使用2組,每組為128尺寸為3×3×192的卷積核,做了邊緣填充padding=1,卷積的步長為1.則輸出的FeatureMap為13×13×256
- ReLU,將卷積層輸出的FeatureMap輸入到ReLU函數中
- 池化,池化運算的尺寸為3×3,步長為2,池化后圖像的尺寸為 (13?3)/2+1=6,即池化后的輸出是6×6×256
- 全連接層FC6
- 該層的流程為:(卷積)全連接 -->ReLU -->Dropout
- 卷積->全連接: 輸入為6×6×256,該層有4096個卷積核,每個卷積核的大小為6×6×256。由于卷積核的尺寸剛好與待處理特征圖(輸入)的尺寸相同,即卷積核中的每個系數只與特征圖(輸入)尺寸的一個像素值相乘,一一對應,因此,該層被稱為全連接層。由于卷積核與特征圖的尺寸相同,卷積運算后只有一個值,因此,卷積后的像素層尺寸為4096×1×1,即有4096個神經元。
- ReLU,這4096個運算結果通過ReLU激活函數生成4096個值
- Dropout,抑制過擬合,隨機的斷開某些神經元的連接或者是不激活某些神經元
- 全連接層FC7
- 流程為:全連接–>ReLU–>Dropout
- 全連接,輸入為4096的向量
- ReLU,這4096個運算結果通過ReLU激活函數生成4096個值
- Dropout,抑制過擬合,隨機的斷開某些神經元的連接或者是不激活某些神經元
- 輸出層
- 第七層輸出的4096個數據與第八層的1000個神經元進行全連接,經過訓練后輸出1000個float型的值,這就是預測結果的值
2.3 AlexNet參數數量
卷積層的參數 = 卷積核的數量 * 卷積核 + 偏置
- C1: 96個11×11×3的卷積核,96×11×11×3+96=34848
- C2: 2組,每組128個5×5×48的卷積核,(128×5×5×48+128)×2=307456
- C3: 384個3×3×256的卷積核,3×3×256×384+384=885120
- C4: 2組,每組192個3×3×192的卷積核,(3×3×192×192+192)×2=663936
- C5: 2組,每組128個3×3×192的卷積核,(3×3×192×128+128)×2=442624
- FC6: 4096個6×6×256的卷積核,6×6×256×4096+4096=37752832
- FC7: 4096?4096+4096=16781312
- output: 4096?1000=4096000
卷積層 C2,C4,C5中的卷積核只和位于同一GPU的上一層的FeatureMap相連。從上面可以看出,參數大多數集中在全連接層,在卷積層由于權值共享,權值參數較少。
AlexNet的Keras實現:
def AlexNet():
3 穩步前行:ZF-Net
ZFNet是2013ImageNet分類任務的冠軍,其網絡結構沒什么改進,只是調了調參,性能較Alex提升了不少。ZF-Net只是將AlexNet第一層卷積核由11變成7,步長由4變為2,第3,4,5卷積層轉變為384,384,256。這一年的ImageNet還是比較平靜的一屆,其冠軍ZF-Net的名堂也沒其他屆的經典網絡架構響亮。
ZF-Net的Keras實現:
def ZF_Net():
model = Sequential() model.add(Conv2D(96,(7,7),strides=(2,2),input_shape=(224,224,3),padding='valid',activation='relu',kernel_initializer='uniform')) model.add(MaxPooling2D(pool_size=(3,3),strides=(2,2))) model.add(Conv2D(256,(5,5),strides=(2,2),padding='same',activation='relu',kernel_initializer='uniform')) model.add(MaxPooling2D(pool_size=(3,3),strides=(2,2))) model.add(Conv2D(384,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform')) model.add(Conv2D(384,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform')) model.add(Conv2D(256,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform')) model.add(MaxPooling2D(pool_size=(3,3),strides=(2,2))) model.add(Flatten()) model.add(Dense(4096,activation='relu')) model.add(Dropout(0.5)) model.add(Dense(4096,activation='relu')) model.add(Dropout(0.5)) model.add(Dense(1000,activation='softmax')) return model4 越走越深:VGG-Nets
VGG-Nets是由牛津大學VGG(Visual Geometry Group)提出,是2014年ImageNet競賽定位任務的第一名和分類任務的第二名的中的基礎網絡。VGG可以看成是加深版本的AlexNet. 都是conv layer + FC layer,在當時看來這是一個非常深的網絡了,因為層數高達十多層,我們從其論文名字就知道了(《Very Deep Convolutional Networks for Large-Scale Visual Recognition》),當然以現在的目光看來VGG真的稱不上是一個very deep的網絡。
上面一個表格是描述的是VGG-Net的網絡結構以及誕生過程。為了解決初始化(權重初始化)等問題,VGG采用的是一種Pre-training的方式,這種方式在經典的神經網絡中經常見得到,就是先訓練一部分小網絡,然后再確保這部分網絡穩定之后,再在這基礎上逐漸加深。表1從左到右體現的就是這個過程,并且當網絡處于D階段的時候,效果是最優的,因此D階段的網絡也就是VGG-16了!E階段得到的網絡就是VGG-19了!VGG-16的16指的是conv+fc的總層數是16,是不包括max pool的層數!
從圖中可以看出,VGGNet采用了五組卷積與三個
全連接層,最后使用Softmax做分類。
下面這個圖就是VGG-16的網絡結構。
由上圖看出,VGG-16的結構非常整潔,深度較AlexNet深得多,里面包含多個conv->conv->max_pool這類的結構,VGG的卷積層都是same的卷積,即卷積過后的輸出圖像的尺寸與輸入是一致的,它的下采樣完全是由max pooling來實現。
VGG網絡后接3個全連接層,filter的個數(卷積后的輸出通道數)從64開始,然后沒接一個pooling后其成倍的增加,128、512,VGG的注意貢獻是使用小尺寸的filter,及有規則的卷積-池化操作。
閃光點:卷積層使用更小的filter尺寸和間隔
與AlexNet相比,可以看出VGG-Nets的卷積核尺寸還是很小的,比如AlexNet第一層的卷積層用到的卷積核尺寸就是11* 11,這是一個很大卷積核了。而反觀VGG-Nets,用到的卷積核的尺寸無非都是1×1和3×3的小卷積核,可以替代大的filter尺寸。
3×3卷積核的優點:
- 多個3×3的卷基層比一個大尺寸filter卷基層有更多的非線性,使得判決函數更加具有判決性
- 多個3×3的卷積層比一個大尺寸的filter有更少的參數,假設卷基層的輸入和輸出的特征圖大小相同為C,那么三個3×3的卷積層參數個數3×(3×3×C×C)=27CC;一個7×7的卷積層參數為49CC;所以可以把三個3×3的filter看成是一個7×7filter的分解(中間層有非線性的分解)
1×1卷積核的優點:
作用是在不影響輸入輸出維數的情況下,對輸入進行線性形變,然后通過Relu進行非線性處理,增加網絡的非線性表達能力。
5 縱橫交錯Inception(GoogLeNet)
一般來說,增加網絡的深度與寬度可以提升網絡的性能,但是這樣做也會帶來參數量的大幅度增加,同時較深的網絡需要較多的數據,否則容易產生過擬合現象。除此之外,增加神經網絡的深度容易帶來梯度消失的現象。
Inception v1(又名GoogLeNet)在2014的ImageNet分類任務上擊敗了VGG-Nets奪得冠軍,其實力肯定是非常深厚的,GoogLeNet跟AlexNet,VGG-Nets這種單純依靠加深網絡結構進而改進網絡性能的思路不一樣,它另辟幽徑,在加深網絡的同時(22層),也在網絡結構上做了創新,引入Inception結構代替了單純的卷積+激活的傳統操作(這思路最早由Network in Network提出)。GoogLeNet進一步把對卷積神經網絡的研究推上新的高度。
Inception歷經了V1、V2、V3、V4等多個版本的發展,不斷趨于完善,下面一一進行介紹
5.1 Inception V1
Inception v1網絡是一個精心設計的22層卷積網絡,并提出了具有良好局部特征結構的Inception模塊,即對特征并行地執行多個大小不同的卷積運算與池化,最后再拼接到一起。由于1×1、3×3和5×5的卷積運算對應不同的特征圖區域,因此這樣做的好處是可以得到更好的圖像表征信息。
通過設計一個稀疏網絡結構,但是能夠產生稠密的數據,既能增加神經網絡表現,又能保證計算資源的使用效率。谷歌提出了最原始Inception的基本結構:
該結構將CNN中常用的卷積(1x1,3x3,5x5)、池化操作(3x3)堆疊在一起(卷積、池化后的尺寸相同,將通道相加),一方面增加了網絡的寬度,另一方面也增加了網絡對尺度的適應性。
網絡卷積層中的網絡能夠提取輸入的每一個細節信息,同時5x5的濾波器也能夠覆蓋大部分接受層的的輸入。還可以進行一個池化操作,以減少空間大小,降低過度擬合。在這些層之上,在每一個卷積層后都要做一個ReLU操作,以增加網絡的非線性特征。
然而這個Inception原始版本,所有的卷積核都在上一層的所有輸出上來做,而那個5x5的卷積核所需的計算量就太大了,造成了特征圖的厚度很大,為了避免這種情況,在3x3前、5x5前、max pooling后分別加上了1x1的卷積核,以起到了降低特征圖厚度的作用,這也就形成了Inception v1的網絡結構,如下圖所示:
1x1的卷積核有什么用呢?
1x1卷積的主要目的是為了減少維度,還用于修正線性激活(ReLU)。比如,上一輸出為100x100x128,經過具有256個通道的5x5卷積層之后(stride=1,pad=2),輸出數據為100x100x256,其中,卷積層的參數為128x5x5x256= 819200。而假如上一層輸出先經過具有32個通道的1x1卷積層,再經過具有256個輸出的5x5卷積層,那么輸出數據仍為為100x100x256,但卷積參數量已經減少為128x1x1x32 + 32x5x5x256= 204800,大約減少了4倍。
基于Inception構建了GoogLeNet的網絡結構如下(共22層)。Inception v1網絡一共有9個上述堆疊的模塊,共有22層,在最后的Inception模塊處使用了全局平均池化。為了避免深層網絡訓練時帶來的梯度消失問題,作者還引入了兩個輔助的分類器,在第3個與第6個Inception模塊輸出后執行Softmax并計算損失,在訓練時和最后的損失一并回傳。
對上圖說明如下:
(1)GoogLeNet采用了模塊化的結構(Inception結構),方便增添和修改;
(2)網絡最后采用了average pooling(平均池化)來代替全連接層,該想法來自NIN(Network in Network),事實證明這樣可以將準確率提高0.6%。但是,實際在最后還是加了一個全連接層,主要是為了方便對輸出進行靈活調整;
(3)雖然移除了全連接,但是網絡中依然使用了Dropout ;
(4)為了避免梯度消失,網絡額外增加了2個輔助的softmax用于向前傳導梯度(輔助分類器)。輔助分類器是將中間某一層的輸出用作分類,并按一個較小的權重(0.3)加到最終分類結果中,這樣相當于做了模型融合,同時給網絡增加了反向傳播的梯度信號,也提供了額外的正則化,對于整個網絡的訓練很有裨益。而在實際測試的時候,這兩個額外的softmax會被去掉。
GoogLeNet的網絡結構圖細節如下:
注:上表中的“#3x3 reduce”,“#5x5 reduce”表示在3x3,5x5卷積操作之前使用了1x1卷積的數量。
LOSS單元
GoogLeNet網絡結構中有3個LOSS單元,這樣的網絡設計是為了幫助網絡的收斂。在中間層加入輔助計算的LOSS單元,目的是計算損失時讓低層的特征也有很好的區分能力,從而讓網絡更好地被訓練。在論文中,這兩個輔助LOSS單元的計算被乘以0.3,然后和最后的LOSS相加作為最終的損失函數來訓練網絡。
全連接層全部替換為簡單的全局平均pooling
GoogLeNet還有一個閃光點值得一提,那就是將后面的全連接層全部替換為簡單的全局平均pooling,在最后參數會變的更少。而在AlexNet中最后3層的全連接層參數差不多占總參數的90%,使用大網絡在寬度和深度允許GoogleNet移除全連接層,但并不會影響到結果的精度,在ImageNet中實現93.3%的精度,而且要比VGG還要快。
5.2 Inception V2
GoogLeNet憑借其優秀的表現,得到了很多研究人員的學習和使用,因此GoogLeNet團隊又對其進行了進一步地發掘改進,產生了升級版本的GoogLeNet。
GoogLeNet設計的初衷就是要又準又快,而如果只是單純的堆疊網絡雖然可以提高準確率,但是會導致計算效率有明顯的下降,所以如何在不增加過多計算量的同時提高網絡的表達能力就成為了一個問題。
Inception V2版本的解決方案就是修改Inception的內部計算邏輯,提出了比較特殊的“卷積”計算結構。
1、卷積分解(Factorizing Convolutions)
大尺寸的卷積核可以帶來更大的感受野,但也意味著會產生更多的參數,比如5x5卷積核的參數有25個,3x3卷積核的參數有9個,前者是后者的25/9=2.78倍。因此,GoogLeNet團隊提出可以用2個連續的3x3卷積層組成的小網絡來代替單個的5x5卷積層,即在保持感受野范圍的同時又減少了參數量,如下圖:
那么這種替代方案會造成表達能力的下降嗎?通過大量實驗表明,并不會造成表達缺失。
可以看出,大卷積核完全可以由一系列的3x3卷積核來替代,那能不能再分解得更小一點呢?GoogLeNet團隊考慮了nx1的卷積核,如下圖所示,用3個3x1取代3x3卷積:
因此,任意nxn的卷積都可以通過1xn卷積后接nx1卷積來替代。GoogLeNet團隊發現在網絡的前期使用這種分解效果并不好,在中度大小的特征圖(feature map)上使用效果才會更好(特征圖大小建議在12到20之間)。
2、降低特征圖大小
一般情況下,如果想讓圖像縮小,可以有如下兩種方式:
先池化再作Inception卷積,或者先作Inception卷積再作池化。但是方法一(左圖)先作pooling(池化)會導致特征表示遇到瓶頸(特征缺失),方法二(右圖)是正常的縮小,但計算量很大。為了同時保持特征表示且降低計算量,將網絡結構改為下圖,使用兩個并行化的模塊來降低計算量(卷積、池化并行執行,再進行合并)
5.3 Inception V3
Inception-v2 和 Inception-v3 出現在同一篇paper中(在此之前的Batch Nomalization的文章中,也用到了Inception網絡;Inception-v2 和 Inception-v3開始使用Batch Normalization)。
Inception-v3比Inception-v2增加了幾種處理:(1)RMSProp優化器;(2)使用了LabelSmoothing;(3)7×7卷積變成了1×7和7×1的卷積核疊加;(4)輔助分類器使用了 BatchNorm。 同時輸入圖像大小變成299×299。
5.4 Inception V4
Inception V4研究了Inception模塊與殘差連接的結合。ResNet結構大大地加深了網絡深度,還極大地提升了訓練速度,同時性能也有提升。
Inception V4主要利用殘差連接(Residual Connection)來改進V3結構,得到Inception-ResNet-v1,Inception-ResNet-v2,Inception-v4網絡。
ResNet的殘差結構如下:
將該結構與Inception相結合,變成下圖:
通過20個類似的模塊組合,Inception-ResNet構建如下:
6 里程碑式創新:ResNet
2015年何愷明推出的ResNet在ISLVRC和COCO上橫掃所有選手,獲得冠軍。ResNet在網絡結構上做了大創新,而不再是簡單的堆積層數,ResNet在卷積神經網絡的新思路,絕對是深度學習發展歷程上里程碑式的事件。
閃光點:
- 層數非常深,已經超過百層
- 引入殘差單元來解決退化問題
從前面可以看到,隨著網絡深度增加,網絡的準確度應該同步增加,當然要注意過擬合問題。但是網絡深度增加的一個問題在于這些增加的層是參數更新的信號,因為梯度是從后向前傳播的,增加網絡深度后,比較靠前的層梯度會很小。這意味著這些層基本上學習停滯了,這就是梯度消失問題。深度網絡的第二個問題在于訓練,當網絡更深時意味著參數空間更大,優化問題變得更難,因此簡單地去增加網絡深度反而出現更高的訓練誤差,深層網絡雖然收斂了,但網絡卻開始退化了,即增加網絡層數卻導致更大的誤差,比如下圖,一個56層的網絡的性能卻不如20層的性能好,這不是因為過擬合(訓練集訓練誤差依然很高),這就是煩人的退化問題。殘差網絡ResNet設計一種殘差模塊讓我們可以訓練更深的網絡。
這里詳細分析一下殘差單元來理解ResNet的精髓。
從下圖可以看出,數據經過了兩條路線,一條是常規路線,另一條則是捷徑(shortcut),直接實現單位映射的直接連接的路線,這有點類似與電路中的“短路”。通過實驗,這種帶有shortcut的結構確實可以很好地應對退化問題。我們把網絡中的一個模塊的輸入和輸出關系看作是y=H(x),那么直接通過梯度方法求H(x)就會遇到上面提到的退化問題,如果使用了這種帶shortcut的結構,那么可變參數部分的優化目標就不再是H(x),若用F(x)來代表需要優化的部分的話,則H(x)=F(x)+x,也就是F(x)=H(x)-x。因為在單位映射的假設中y=x就相當于觀測值,所以F(x)就對應著殘差,因而叫殘差網絡。為啥要這樣做,因為作者認為學習殘差F(X)比直接學習H(X)簡單!設想下,現在根據我們只需要去學習輸入和輸出的差值就可以了,絕對量變為相對量(H(x)-x 就是輸出相對于輸入變化了多少),優化起來簡單很多。
考慮到x的維度與F(X)維度可能不匹配情況,需進行維度匹配。這里論文中采用兩種方法解決這一問題(其實是三種,但通過實驗發現第三種方法會使performance急劇下降,故不采用):
- zero_padding:對恒等層進行0填充的方式將維度補充完整。這種方法不會增加額外的參數
- projection:在恒等層采用1x1的卷積核來增加維度。這種方法會增加額外的參數
下圖展示了兩種形態的殘差模塊,左圖是常規殘差模塊,有兩個3×3卷積核卷積核組成,但是隨著網絡進一步加深,這種殘差結構在實踐中并不是十分有效。針對這問題,右圖的“瓶頸殘差模塊”(bottleneck residual block)可以有更好的效果,它依次由1×1、3×3、1×1這三個卷積層堆積而成,這里的1×1的卷積能夠起降維或升維的作用,從而令3×3的卷積可以在相對較低維度的輸入上進行,以達到提高計算效率的目的。
那么從另一個角度看,在反向傳播中,residual模塊會起到什么樣的作用呢?
-
residual模塊將輸出分成F(x)+x兩部分,其中F依然是x的函數,也就是說F實際上是對于x的補充,是對于x的fun-tuning,這樣就把任務從根據x映射成一個新的y轉為了根據x求x和y之間的差距,這明顯是一個相對更加簡單的任務,論文是這么寫的,到底怎么簡單的,我們來分析一下。
-
其次,因為前向過程中有恒等映射的支路存在,因此在反向傳播過程中梯度的傳導也多了更簡便的路徑,僅僅經過一個relu就可以把梯度傳達給上一個模塊。
-
所謂反向傳播就是網絡輸出一個值,然后與真實值做比較的到一個誤差損失,同時將這個損失做差改變參數,返回的損失大小取決于原來的損失和梯度,既然目的是為了改變參數,而問題是改變參數的力度過小,則可以減小參數的值,使損失對參數改變的力度相對更大。
-
因此殘差模塊最重要的作用就是改變了前向和后向信息傳遞的方式從而很大程度上促進了網絡的優化。
————————————————
在ResNet中,上述的一個殘差模塊稱為Bottleneck。ResNet有不同網絡層數的版本,如18層、34層、50層、101層和152層,這里以常用的50層來講解。ResNet-50的網絡架構如圖3.18所示,最主要的部分在于中間經歷了4個大的卷積組,而這4個卷積組分別包含了3、4、6這3個Bottleneck模塊。最后經過一個全局平均池化使得特征圖大小變為1×1,然后進行1000維的全連接,最后經過Softmax輸出分類得分。
由于F(x)+x是逐通道進行相加,因此根據兩者是否通道數相同,存在兩種Bottleneck結構。對于通道數不同的情況,比如每個卷積組的第一個Bottleneck,需要利用1×1卷積對x進行Downsample操作,將通道數變為相同,再進行加操作。對于相同的情況下,兩者可以直接進行相加。
7 繼往開來:DenseNet
自Resnet提出以后,ResNet的變種網絡層出不窮,都各有其特點,網絡性能也有一定的提升。DenseNet是CVPR 2017最佳論文,論文中提出的DenseNet(Dense Convolutional Network)主要還是和ResNet及Inception網絡做對比,思想上有借鑒,但卻是全新的結構,網絡結構并不復雜,卻非常有效,在CIFAR指標上全面超越ResNet。可以說DenseNet吸收了ResNet最精華的部分,并在此上做了更加創新的工作,使得網絡性能進一步提升。
閃光點:
密集連接:緩解梯度消失問題,加強特征傳播,鼓勵特征復用,極大的減少了參數量
DenseNet 是一種具有密集連接的卷積神經網絡。在該網絡中,任何兩層之間都有直接的連接,也就是說,網絡每一層的輸入都是前面所有層輸出的并集,而該層所學習的特征圖也會被直接傳給其后面所有層作為輸入。下圖是 DenseNet 的一個dense block示意圖,一個block里面的結構如下,與ResNet中的BottleNeck基本一致:BN-ReLU-Conv(1×1)-BN-ReLU-Conv(3×3) ,而一個DenseNet則由多個這種block組成。每個DenseBlock的之間層稱為transition layers,由BN?>Conv(1×1)?>averagePooling(2×2)組成
密集連接不會帶來冗余嗎?不會!密集連接這個詞給人的第一感覺就是極大的增加了網絡的參數量和計算量。但實際上 DenseNet 比其他網絡效率更高,其關鍵就在于網絡每層計算量的減少以及特征的重復利用。DenseNet則是讓l層的輸入直接影響到之后的所有層,它的輸出為:xl=Hl([X0,X1,…,xl?1]),其中[x0,x1,…,xl?1]就是將之前的feature map以通道的維度進行合并。并且由于每一層都包含之前所有層的輸出信息,因此其只需要很少的特征圖就夠了,這也是為什么DneseNet的參數量較其他模型大大減少的原因。這種dense connection相當于每一層都直接連接input和loss,因此就可以減輕梯度消失現象,這樣更深網絡不是問題
需要明確一點,dense connectivity 僅僅是在一個dense block里的,不同dense block 之間是沒有dense connectivity的,比如下圖所示。
在上圖中,Dense Block中的黑點代表一個卷積層,其中的多條黑線代表數據的流動,每一層的輸入由前面的所有卷積層的輸出組成。注意這里使用了通道拼接(Concatnate)操作,而非ResNet的逐元素相加操作。
DenseNet的結構有如下兩個特性:
- 神經網絡一般需要使用池化等操作縮小特征圖尺寸來提取語義特征,而Dense Block需要保持每一個Block內的特征圖尺寸一致來直接進行Concatnate操作,因此DenseNet被分成了多個Block。Block的數量一般為4。
- 兩個相鄰的Dense Block之間的部分被稱為Transition層,具體包括BN、ReLU、1×1卷積、2×2平均池化操作。1×1卷積的作用是降維,起到壓縮模型的作用,而平均池化則是降低特征圖的尺寸,
具體的Block實現細節如圖3.20所示,每一個Block由若干個Bottleneck的卷積層組成,對應圖3.19中的黑點。Bottleneck由BN、ReLU、1×1卷積、BN、ReLU、3×3卷積的順序構成。
關于Block,有以下4個細節需要注意:
- 每一個Bottleneck輸出的特征通道數是相同的,例如這里的32。同時可以看到,經過Concatnate操作后的通道數是按32的增長量增加的,因此這個32也被稱為GrowthRate。
- 這里1×1卷積的作用是固定輸出通道數,達到降維的作用。當幾十個Bottleneck相連接時,Concatnate后的通道數會增加到上千,如果不增加1×1的卷積來降維,后續3×3卷積所需的參數量會急劇增加。1×1卷積的通道數通常是GrowthRate的4倍。
- 圖3.20中的特征傳遞方式是直接將前面所有層的特征Concatnate后傳到下一層,這種方式與具體代碼實現的方式是一致的,而不像圖3.19中,前面層都要有一個箭頭指向后面的所有層。
- Block采用了激活函數在前、卷積層在后的順序,這與一般的網絡上是不同的。
DenseNet網絡的優勢主要體現在以下兩個方面:
- 密集連接的特殊網絡,使得每一層都會接受其后所有層的梯度,而不是像普通卷積鏈式的反傳,因此一定程度上解決了梯度消失的問題。
- 通過Concatnate操作使得大量的特征被復用,每個層獨有的特征圖的通道是較少的,因此相比ResNet,DenseNet參數更少且計算更高效。
DenseNet的不足在于由于需要進行多次Concatnate操作,數據需要被復制多次,顯存容易增加得很快,需要一定的顯存優化技術。另外,DenseNet是一種更為特殊的網絡,ResNet則相對一般化一些,因此ResNet的應用范圍更廣泛。
8、特征金字塔:FPN
為了增強語義性,傳統的物體檢測模型通常只在深度卷積網絡的最后一個特征圖上進行后續操作,而這一層對應的下采樣率(圖像縮小的倍數)通常又比較大,如16、32,造成小物體在特征圖上的有效信息較少,小物體的檢測性能會急劇下降,這個問題也被稱為多尺度問題。
解決多尺度問題的關鍵在于如何提取多尺度的特征。傳統的方法有圖像金字塔(Image Pyramid),主要思路是將輸入圖片做成多個尺度,不同尺度的圖像生成不同尺度的特征,這種方法簡單而有效,大量使用在了COCO等競賽上,但缺點是非常耗時,計算量也很大。
從前面幾節內容可以知道,卷積神經網絡不同層的大小與語義信息不同,本身就類似一個金字塔結構。2017年的FPN(Feature PyramidNetwork)方法融合了不同層的特征,較好地改善了多尺度檢測問題。
FPN的總體架構如圖3.21所示,主要包含自下而上網絡、自上而下網絡、橫向連接與卷積融合4個部分。
- 自下而上:最左側為普通的卷積網絡,默認使用ResNet結構,用作提取語義信息。C1代表了ResNet的前幾個卷積與池化層,而C2至C5分別為不同的ResNet卷積組,這些卷積組包含了多個Bottleneck結構,組內的特征圖大小相同,組間大小遞減。
- 自上而下:首先對C5進行1×1卷積降低通道數得到P5,然后依次進行上采樣得到P4、P3和P2,目的是得到與C4、C3與C2長寬相同的特征,以方便下一步進行逐元素相加。這里采用2倍最鄰近上采樣,即直接對臨近元素進行復制,而非線性插值。
- 橫向連接(Lateral Connection):目的是為了將上采樣后的高語義特征與淺層的定位細節特征進行融合。高語義特征經過上采樣后,其長寬與對應的淺層特征相同,而通道數固定為256,因此需要對底層特征C2至C4進行11卷積使得其通道數變為256,然后兩者進行逐元素相加得到P4、P3與P2。由于C1的特征圖尺寸較大且語義信息不足,因此沒有把C1放到橫向連接中。
- 卷積融合:在得到相加后的特征后,利用3×3卷積對生成的P2至P4再進行融合,目的是消除上采樣過程帶來的重疊效應,以生成最終的特征圖。
FPN將深層的語義信息傳到底層,來補充淺層的語義信息,從而獲得了高分辨率、強語義的特征,在小物體檢測、實例分割等領域有著非常不俗的表現。
9、為檢測而生:DetNet
前面幾節的網絡骨架,如VGGNet和ResNet等,雖從各個角度出發提升了物體檢測性能,但究其根本是為ImageNet的圖像分類任務而設計的。而圖像分類與物體檢測兩個任務天然存在著落差,分類任務側重于全圖的特征提取,深層的特征圖分辨率很低;而物體檢測需要定位出物體位置,特征圖分辨率不宜過小,因此造成了以下兩種缺陷:
- 大物體難以定位:對于FPN等網絡,大物體對應在較深的特征圖上檢測,由于網絡較深時下采樣率較大,物體的邊緣難以精確預測,增加了回歸邊界的難度。
- 小物體難以檢測:對于傳統網絡,由于下采樣率大造成小物體在較深的特征圖上幾乎不可見;FPN雖從較淺的特征圖來檢測小物體,但淺層的語義信息較弱,且融合深層特征時使用的上采樣操作也會增加物體檢測的難度。
針對以上問題,曠視科技提出了專為物體檢測設計的DetNet結構,引入了空洞卷積,使得模型兼具較大感受野與較高分辨率,同時避免了FPN的多次上采樣,實現了較好的檢測效果。
DetNet的網絡結構如圖3.22所示,仍然選擇性能優越的ResNet-50作為基礎結構,并保持前4個stage與ResNet-50相同,具體的結構細節有以下3點:
- 引入了一個新的Stage 6,用于物體檢測。Stage 5與Stage 6使用了DetNet提出的Bottleneck結構,最大的特點是利用空洞數為2的3×3卷積取代了步長為2的3×3卷積。
- Stage 5與Stage 6的每一個Bottleneck輸出的特征圖尺寸都為原圖的通道數都為256,而傳統的Backbone通常是特征圖尺寸遞減,通道數遞增。
- 在組成特征金字塔時,由于特征圖大小完全相同,因此可以直接從右向左傳遞相加,避免了上一節的上采樣操作。為了進一步融合各通道的特征,需要對每一個階段的輸出進行1×1卷積后再與后一Stage傳回的特征相加。
DetNet這種精心設計的結構,在增加感受野的同時,獲得了較大的特征圖尺寸,有利于物體的定位。與此同時,由于各Stage的特征圖尺寸相同,避免了上一節的上采樣,既一定程度上降低了計算量,又有利于小物體的檢測。
DetNet中Bottleneck的細節如圖3.23所示,左側的兩個Bottleneck A與Bottleneck B分別對應圖3.22的A與B,右側的為原始的ResNet殘差結構。DetNet與ResNet兩者的基本思想都是卷積堆疊層與恒等映射的相加,區別在于DetNet使用了空洞數為2的3×3卷積,這樣使得特征圖尺寸保持不變,而ResNet是使用了步長為2的3×3卷積。B相比于A,在恒等映射部分增加了一個1×1卷積,這樣做可以區分開不同的Stage,并且實驗發現這種做法對于特征金字塔式的檢測非常重要。
總結
以上是生活随笔為你收集整理的卷积神经网络发展(网络骨架:Backbone)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NEON介绍
- 下一篇: oracle trim函数用法详解