前言
本文主要介紹2012-2015年的一些經典CNN結構,從AlexNet,ZFNet,OverFeat到VGG,GoogleNetv1-v4,ResNetv1-v2。
在論文筆記:CNN經典結構2中我介紹了2016-2017年的幾個經典CNN結構,WideResNet,FractalNet,DenseNet,ResNeXt,DPN,SENet。另外,在ImageNet歷年冠軍和相關CNN模型中,我簡單介紹了ImageNet和歷年冠軍。html
AlexNet
- 貢獻:ILSVRC2012冠軍,展示出了深度CNN在圖像任務上的驚人表現,掀起CNN研究的熱潮,是現在深度學習和AI迅猛發展的重要緣由。ImageNet比賽爲一直研究神經網絡的Hinton提供了施展平臺,AlexNet就是由hinton和他的兩位學生髮表的,在AlexNet以前,深度學習已經沉寂了好久。
- 網絡結構:以下圖所示,8層網絡,參數大約有60 million,使用了relu函數,頭兩個全鏈接層使用了0.5的dropout。使用了LRN和重疊的池化,如今LRN都不用了,通常用BN做Normalization。當時使用了多GPU訓練。
- 預處理:先down-sample成最短邊爲256的圖像,而後剪出中間的256x256圖像,再減均值作歸一化(over training set)。 訓練時,作數據加強,對每張圖像,隨機提取出227x227以及水平鏡像版本的圖像。除了數據加強,還使用了PCA對RGB像素降維的方式來緩和過擬合問題。
- 預測:對每張圖像提取出5張(四個角落以及中間)以及水平鏡像版本,總共10張,平均10個預測做爲最終預測。
- 超參數:SGD,學習率0.01,batch size是128,momentum爲0.9,weight decay爲0.0005(論文有個權重更新公式),每當validation error再也不降低時,學習率除以10。權重初始化用(0,0.01)的高斯分佈,二四五卷積層和全鏈接層的bias初始化爲1(給relu提供正值利於加速前期訓練),其他bias初始化爲0。
![](http://static.javashuo.com/static/loading.gif)
ZFNet
- 貢獻:ILSVRC2013分類任務的冠軍,使用反捲積對CNN的中間特徵圖進行可視化分析,經過分析特徵行爲找到提高模型的辦法,微調Alexnet提高了表現。ZFNet的Z和F指的是Zeiler和Fergus,曾是hinton的學生,後在紐約大學讀博的Zeiler,聯手紐約大學研究神經網絡的Fergus提出了ZFNet。
- 冠軍?:嚴格意義上來講當時分類冠軍是Clarifai,可是咱們一般討論的ILSVRC2013冠軍(winner)指的是ZFNet。ZF中的Zeiler是Clarifai的建立者和CEO。
- 網絡結構:以下圖所示,和AlexNet同樣,頭兩個全鏈接層後面加0.5的dropout。相比於AlexNet,主要區別是使用了更小的卷積核和步長,11x11的卷積核變成7x7的卷積核,stride從4變成了2。另外,經過可視化發現第一層的卷積核影響大,因而對第一層的卷積核作了規範化,若是RMS(Root Mean Square)超過0.1,就把卷積核的均方根normalize爲固定0.1。
- 其它數據集:ZFNet還在Caltech-101,Caltech-256,Pascal AOC-2012上作了遷移學習的實驗。
- 預處理和超參數:和AlexNet基本一致。權重初始化不一樣,權重初始化爲0.01,bias初始化爲0。
- 更多:具體內容我在另外一篇論文筆記:可視化CNN中有所說起。
![](http://static.javashuo.com/static/loading.gif)
OverFeat
- 貢獻:ILSVRC2013定位任務的冠軍,用一個CNN集成了分類,定位和檢測三個任務,提出了多尺度的方法。OverFeat是由Yann Lecun團隊提出,Lecun提出的LeNet能夠說是CNN的開端,提出來並無火起來,由於當時機器性能不高並且SVM也能達到相似的效果甚至超過。
- 網絡結構:相比於AlexNet,再也不使用LRN;使用非重疊的池化;使用更小的步長,大的步長能夠提升速度可是損害了精度。和AlexNet同樣,頭兩個全鏈接層後面加0.5的dropout。
- 預處理和超參數:和AlexNet基本一致。權重初始化不一樣,所有用(0,0.01)的高斯分佈初始化。momentum爲0.6,學習率爲0.005。在(30,50,60,70,80)epoch學習率減半(decreased a factor by 0.5)。
- 預測:在測試階段,再也不使用AlexNet的10 views法(4 corners and center, with horizontal flip),探索了多尺度來進行平均預測的方法,直接從原圖rescale成多個尺度的圖像輸入網絡進行多尺度預測。
- 多尺度(和全卷積):以下圖所示,把全鏈接層改爲全卷積(5x5卷積),在網絡最後配合全局最大池化,能夠輸入多尺度的圖像,舉例來講,輸入14x14的圖像,最後獲得的是1x1個分類特徵,輸入16x16的圖像最後會獲得2x2個分類特徵,可是經過全局最大池化就能夠轉爲1x1個分類特徵,對於多尺度輸入,輸出是一致的。並且從下圖中的藍色色塊能夠看出,在16x16上卷積能夠看做用14x14的窗口在上面滑動2步的4次卷積結果。
- 更多:具體內容我在另外一篇論文筆記:OverFeat中有所說起。
![](http://static.javashuo.com/static/loading.gif)
VGG
- 貢獻:ILSVRC2014定位任務的冠軍(Winner),分類任務的亞軍(runner-up)。該網絡的特色在於結構規整,經過反覆堆疊3x3的卷積,卷積核數量逐漸加倍來加深網絡,後續的不少CNN結構都採用了這種3x3卷積思想,這是一個很大的影響。ZFNet和OverFeat都使用了更小的卷積核,更小的步長來提高AlexNet的表現,相比之下,VGG則是探索CNN的深度,經過固定其它參數,而後穩定地疊加深度。
- 網絡結構
以下圖所示,VGG-16,16層,參數大約有138 million。實驗發現LRN的加入沒有提高反而更差,捨棄使用。實驗發現1x1效果更差,因而沒有使用,1x1卷積在Network in Network(顏水成)中提出推廣,是很重要的思想,在GoogleNet和ResNet都有用到。
使用小卷積核3x3能夠捕捉左右上下的信息,並且利於堆疊深度(保證參數不要過大)。步長爲1。same卷積。
兩個3x3卷積能夠和5x5卷積達到同樣的感覺野。三個3x3卷積能夠和7x7卷積達到同樣的感覺野。使用三個3x3的好處在於使用了3個非線性變換,同時後減少了參數,假設輸入輸出通道數同樣,那麼有
\[ 3(3^2C^2)=27C^2 < 7^2C^2 = 49C^2 \]
和AlexNet同樣,頭兩個全鏈接層後面加0.5的dropout。
- 超參數:和AlexNet基本一致。batch size是256。初始化也是用(0,0.01)的高斯分佈,只不過VGG先訓練一個淺層的網絡,而後把淺層網絡的部分參數來初始化深層網絡部分參數,其它參數仍是用高斯分佈。值得注意的是論文提交後VGG發現使用glorot的初始化方法能夠不用預訓練。
- 預處理:和AlexNet不一樣,在下采樣的時候不是變成256,變成一個S,S有兩種方法來設定。第一個方法是固定的S(single-scale),固定爲256或384。爲了加速384的網絡,用256預訓練的模型進行權重初始化。另外學習率調小爲0.001。第二個方法從[256, 512]中隨機採樣S(multi-scale,注意這裏的是multi-scale training,和overfeat中的multi-scale test含義不同),這能夠當作用尺寸抖動(scale jittering)對訓練集進行加強。爲了加速,使用384預訓練的模型進行權重初始化。
- 預測:採用了AlexNet的10 views法(VGG論文中把它稱做multi-crop評估)和overfeat的多尺度預測方法(VGG論文中把它稱做dense評估)相結合。在OverFeat已經提到了multi-crop是有缺點的,存在冗餘的卷積計算,因此使用了dense評估,可是Inceptionv1的論文中提到multi-crop使用大量crops能提升準確率由於它的採樣更精細。而VGG認爲實做上準確率的提高不足以彌補速度,可是爲了參考起見,仍是跑了multi-scrop的方法。在實驗中,二者結合優於multi-crop優於dense,好那麼一點點,差異不大。
- 集成:實驗的最後融合了多個模型(集成),最好的模型是融合了VGG-16和VGG-19,訓練使用multi-scale training,測試使用multi-crop和dense評估相結合。在AlexNet,ZFNet和OverFeat最後的實驗都會使用集成,最好的模型通常都是集成的結果。
- 定位:VGG的定位任務的模型是在OverFeat的基礎上作了一些修改。對於bounding box的預測有兩種,SCR(single-class regression)是全部類共享一個框,這時最後輸出是4維向量。PCR(per-class regression)是每一個類一個框,這樣最後輸出就是4x1000,其中1000表示1000類。
- 泛化:和ZFNet同樣,VGG也作了遷移學習,用ILSVRC的數據預訓練,而後遷移到其它數據集VOC-2007,VOC-2012,Caltech-101,Caltech-256。
![](http://static.javashuo.com/static/loading.gif)
GoogleNet(Inceptionv1)
- 貢獻:ILSVRC2014分類任務的冠軍。該網絡設計了Inception塊代替人工來選擇卷積類型,而後堆疊Inception塊(增長深度)造成Inception網絡。去除了全鏈接層(佔據了網絡的大部分參數),使用了全局均值池化(思想來自Network in Network),大大減少了參數量。這兩個思想在GoogleNet後面的一些論文中都有體現,一個是Inception塊的自動選擇網絡結構(Google後面發表了一些自動選擇網絡超參,網絡優化器,網絡激活函數的論文),另外一個是減少模型參數和計算資源(Google的mobileNet,相似工做還有face++的shuffleNet)。
- 網絡結構:以下圖所示爲Inception塊。網絡總共有22層,圖太大,這裏就給個表格。能夠看到雖然把全鏈接替換成了全局均值池化(這後面仍是使用了0.4的dropout),可是網絡圖中最後仍是有一個全鏈接層,這是爲了便於把網絡fine tune到其它數據集。
- 參數:爲了提高模型表現,典型的辦法是增大模型(增長深度或寬度),可是這樣會帶來過大的參數,而後致使計算資源增大並且須要的數據更多(而高質量數據每每是昂貴的),因此要考慮下降參數。Inceptionv1雖然有22層的參數卻只有5 million,是同期VGG16(138 million)的1/27,是AlexNet(60 million)的1/12而準確率卻遠勝AlexNet。
- 1x1卷積好處:減少了參數,容許增長深度; 能夠降維,構建瓶頸層來減少計算成本,Inception塊中就是經過在3x3和5x5後面加入1x1來減少計算;加強了網絡的表達能力(能夠根據本身的意願,或壓縮或增長或保持通道數)。還有配合全局均值池化來代替全鏈接層,這個就是爲了能大大減少模型的參數。1x1的思想也來自Network in Network。
- 超參數和預處理:由於比賽的過程作了不少變更,包括採樣方法和各類超參,因此很難定義一個有效的指導去訓練這個網絡。只給出了幾個超參數,固定學習率,每8epoch降低4%,momentum是0.9。
- 預測:先降低樣出256,288,320和352大小,分別從左中右三個方位裁(若是是人畫像則從上中下三個方位裁),而後從4 corners和center剪出224x224再加上把正方形縮放到224,以及它們的水平鏡像。這樣就能夠獲得4x3x6x2也就是144個crops,最後對crops取平均。
- 集成:和以前的網絡同樣,最後也使用了集成,訓練了7個版本的網絡進行集成,使用Polyak averaging進行平均,7個網絡使用同樣的初始化和學習率設置,不一樣之處在於數據採樣的方法和順序。
- 目標檢測:Inceptionv1的目標檢測使用了相似R-CNN的方法來完成。
- 輔助輸出:Inceptionv1中有兩個輔助輸出,說是由於太深的網絡的梯度回傳能力有限(梯度消失),因而在中間層接另兩條分支來利用中間層的特徵,能夠增長梯度回傳,還有附加的正則化做用。而後在v3的論文中又提到說利用中間層特徵的想法多是錯的,由於去掉低層的輔助(第一個輔助輸出)對最終結果並無什麼影響,可是仍是強調了輔助輸出的正則化效果,由於在輔助輸出中加入BN和dropout能夠提高主輸出表現。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
GoogleNet(Inceptionv2)
- 貢獻:學習VGG,使用兩個3x3卷積代替5x5的大卷積(保持感覺野的同時又能夠減少參數量),還使用了衆所周知的BN。值得注意的是Inception-BN在v4的論文中把這個網絡被稱爲v2,而在v3的論文中有另一個v2(v3的一個低配版)。這兩篇論文中提到的v2不是同一個v2,一般說的v2指的是這個Inception-BN。
- 網絡結構:以下圖所示,主要改變有,用兩個3x3代替5x5,28x28的Inception塊從2個變成了3個,pooling時有些是avg有些是max,在Incetpion塊之間再也不有額外的max-pool而是直接把卷積和池化的stride設置爲2。BN被用在每個輸入層後面(先BN再激活)。batch size爲32。網絡使用DistBelief(Tensorflow前身)訓練
- 其它變更: 增大學習率並加快學習率衰減(適用BN後的數據),移除dropout並減少L2權重衰減(BN有必定的正則效果),去除LRN(發現用了BN後不須要LRN了),更完全對訓練樣本進行shuffle,減少數據加強時對數據的光學畸變(由於BN訓練更快,每一個樣本被訓練次數變少,模型須要注重更真實的樣本)。
- 集成:最好的結果固然仍是要集成了(以前的BN筆記中沒有說起)。集成了6個網絡,都是基於BNx30,6個版本分別在卷積層增長初始化權重;使用dropout 5%;使用dropout 10%;在Inceptionv1適用dropout 40%;不使用卷積;先激活再BN。集成方式還有multi-crop的使用和Inceptionv1同樣。
- 更多:關於BN(包括我在上一條提到的BNx30)我在另外一篇論文論文筆記:BN中有所說起,這篇論文也是講述Inception-BN的論文
![](http://static.javashuo.com/static/loading.gif)
GoogleNet(Inceptionv3)
- 貢獻:經過一系列的卷積分解和正則化手段來提高模型。這篇論文稱爲v3論文,裏面有一個低配版v3稱爲v2,這裏的v2只是v3這篇論文的v2,這一節提到的v2都是指這個v2。日常說的v2指的是BN那篇論文的v2。
- 訓練配置:使用tensorflow訓練,學習率爲0.045,以0.94的指數率每兩輪衰減一次。梯度裁剪閾值爲2。
- v2網絡結構:共42層,網絡圖就不放了,主要改動有以下。圖有點多,這裏就不放圖了,各個改動模塊圖能夠參考後面v4的結構圖。
- 修改部分Inception塊,使5x5分解成2個3x3卷積(可參考下面v4的InceptionA)。
- 修改部分Inception塊,分解成非對稱卷積(把nxn分解成1xn和nx1卷積,這裏n=7。注意原始結構並無7x7卷積)(可參考下面v4的InceptionB)。
- 修改部分Inception塊,擴大卷積核數量(匯聚的分支數量)(可參考下面v4的InceptionC)
- 修改部分Inception塊,減少特徵圖大小(使用並行的stride爲2的卷積和池化)(可參考下面v4的Reduction)
- v3網絡結構:在以上基礎上,加入以下改動
- 用RMSProp訓練,decay爲0.9,\(\epsilon\)爲1.0
- 使用Label smoothing進行模型正則
- 開頭第一層7x7分解成3個3x3卷積
- 加入帶BN的輔助分類器
GoogleNet(Inceptionv4,Inception-ResNet)
- 貢獻:基於v3的基礎,引入殘差結構,提出了Inception-ResNet-v1和Inception-ResNet-v2。同時修改了Inception提出了Inceptionv4,發現Inceptionv4能達到Incetpion-ResNet-v2相似的結果,認爲殘差結構對於訓練深度網絡不是必須的(以前看過一篇分形網絡的論文也提出了」殘差塊並非訓練深度網絡的必要組件」的觀點,我在論文筆記:分形網絡有所說起)。
- v4網絡結構:以下第一個圖是v4。
- Inception-ResNet:探索了多種Inception-ResNet,論文只闡述了兩個。其中Inceptin-ResNet-v1和Inceptinv3計算代價差很少,Inceptin-ResNet-v2和Inceptionv4計算代價差很少,然而實做上Inceptionv4慢不少多是由於層數太多。在帶有ResNet的Inception中,還有一個和純Inception的不一樣點是隻在傳統層上使用BN,不在BN層上使用,這樣能夠減少計算從而堆疊更多Inceptin塊。
- Inception-ResNet-v2結構:以下第二個圖是Inception-ResNet-v2(輸出的shape是Inception-ResNet-v1的)。
- 訓練配置:tensorflow,RMSProp,decay爲0.9,\(\epsilon\)爲1.0,學習率爲0.045,以0.94的指數率每兩輪衰減一次。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
ResNet
- 貢獻:ILSVRC2015冠軍(分類,檢測,定位),由MSRA的何鎧明等人提出,經過使用殘差塊訓練了152層的網絡,下降了錯誤率。解決了退化問題(plain網絡隨着網絡加深,錯誤率升高),而使用殘差後,隨着網絡加深,錯誤率仍是能降低。
- 網絡加深:對於網絡加深,會出現梯度消失或梯度爆炸,這個問題能夠經過正則初始化(何凱明初始化等等)和BN來解決。
- 退化問題:然而深層網絡到了必定深度,準確率趨近飽和,並且繼續加深的話會下降準確率,這稱爲退化問題(degradation),並且這個問題並非過擬合致使的(過擬合在訓練集應該更好),也不是梯度消失形成的(論文檢查了梯度)。
- 殘差塊:爲了解決退化問題,提出了殘差學習,以下圖所示爲殘差塊,假設原本是要學習H(x),加了一條恆等映射以後咱們要學習的就是F(x) = H(x) - x,(假設)學習F(x)會比學習H(x)更容易,最極端的狀況就是假設咱們要學習的映射是x,那麼讓F(x)爲0,比學習到H(x)爲恆等映射要容易。這種作法的motivation是,若是增長的層能被構建成恆等映射層,那麼一個更深的網絡的準確率至少不會低於淺層網絡。
- 殘差塊的相加:當殘差塊的輸入和輸出不是相同維度時(由於部分殘差塊會使用stride爲2的卷積來降採樣),有兩種方法來保證維度一致,一個是補0,另外一個是乘以W矩陣作映射(使用1x1卷積)。
- 訓練配置:預處理時像VGG同樣隨機採樣[256, 480]的scale,而後像AlexNet同樣crop出224x224的圖像以及水平翻轉,而後作mean substracted。預測時候使用AlexNet的10-crop測試法,最好的結果是跟從VGG中的全卷積後的multi-scale評估,scale爲{224, 256, 384, 480, 640}。在每一個卷積的激活前使用BN,不使用dropout。何凱明初始化。SGD,batch size爲256,學習率從0.1開始每次錯誤率平緩時就除以10,模型訓練了60萬個iteration,權重衰減爲0.0001,momentum爲0.9。
- Identity和projection:對於殘差塊的相加,有三種配置,A配置是捷徑用identity,須要增長維度時的捷徑補0。B配置是捷徑通常都用identity,可是增長維度時使用映射。C配置是全部捷徑都使用映射(1x1卷積)。表現是C>B>A,可是三者差別不大,實做上不會使用C,由於C增長了參數和計算。
- 網絡結構:論文闡述了ResNet-18-34-50-101-152。其中ResNet-18/34使用配置A,ResNet-50/101/152使用配置B,此外使用了bottleneck結構,以下第一個圖的右圖所示。
- 其它實驗:除了在ImageNet上,還在CIFAR-10上作了實驗。還在Pascal和MS COCO上作了目標檢測的實驗。檢測使用的是Faster R-CNN的算法,我在另外一篇論文筆記:經典目標檢測算法(R-CNN,Fast R-CNN,Faster R-CNN,YOLOv1-v3)中介紹了相關的幾個經典檢測算法。
![](http://static.javashuo.com/static/loading.gif)
ResNetv2
- 貢獻:在v1的基礎上作了修改,提高了表現。
- 分析:ResNetv1的公式以下,論文分析了h函數和f函數的選取,即shortcut路徑的函數選取,以及addition後的操做選取。在ResNetv1中,h函數爲恆等映射,f函數爲relu函數,以下圖(a)所示。
\[y_l = h(x_l) + F(x_l, W_l), \\ x_{l+1} = f(y_l) \]
- h函數的選取:論文分析了h函數選取爲恆等映射,作常數scale,異或,1x1卷積,dropout時的表現,發現恆等映射的表現最好,主要是經過實驗來分析。
- f函數的選取:因爲h函數使用恆等映射表現最好,下圖的分析中h函數都使用的恆等映射。下圖(a)表示f函數爲Relu,這是ResNetv1的作法。下圖(b)表示f函數爲BN+Relu。下圖(c)表示f函數爲恆等映射(Relu放到addition前)。下圖d表示f函數爲恆等映射,可是把最後一個Relu放在下一個殘差塊的F-path中。下圖e和圖d相似,只不過把BN也放在addition後的下一個殘差塊的F-path,ResNetv2使用的就是圖e的結構,經過實驗發現這個結構表現最好。
- f和h函數都爲恆等映射:ResNetv2採起圖e的結構,此時f和h函數都爲恆等映射,那麼上式能夠寫成下式,能夠看到這樣的式子有幾個特色,首先,無論L和l差多少層,\(x_L\)和\(x_l\)老是相差一個殘差函數;其次,普通網絡輸入和輸出的關係是不少個Wx相乘(忽略激活和BN的話),而這裏是各個殘差函數相加;另外,從求導式看,1+後面那一項不會老是爲-1(對一個mini-batch的樣原本說),因此梯度很難爲0。
\[ x_{l+1} = x_l + F(x_l, W_l), \\ x_L = x_l + \sum_{i=l}^{L-1}{F(x_i, W_i)}, \\ \frac{\partial \varepsilon }{\partial x_l} = \frac{\partial \varepsilon }{\partial x_L}\frac{\partial x_L }{\partial x_l}=\frac{\partial \varepsilon }{\partial x_L}(1+\frac{\partial x_L }{\partial x_l}\sum_{i=l}^{L-1}{F(x_i, W_i)})\]
訓練配置:和ResNetv1基本一致。對於CIFAR的實驗前400個iteration用0.01(warming up),以後恢復0.1,儘管觀察到這對於殘差塊沒有必要。對於ImageNet實驗,學習率爲0.1(no warming up),在30輪和60輪除以10。在ResNet的開頭第一個殘差塊和最後一個殘差塊是特殊case,第一個殘差塊的激活會放在後面的「單獨卷積」以後和分紅兩路以前,最後一個殘差塊的激活放在它的addition以後。
![](http://static.javashuo.com/static/loading.gif)
參考文獻
- AlexNet(2012 NIPS):ImageNet Classification with Deep Convolutional Neural Networks(模型源碼-cuda實現)
- ZFNet(2014 ECCV):Visualizing and Understanding Convolutional Networks
- OverFeat(2014 ICLR):OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks(模型源碼-C++實現)
- VGG(2015 ICLR):Very Deep Convolutional Networks for Large-Scale Image Recognition(模型源碼-caffe實現)
- Inception-V1(2015 CVPR):Going Deeper with Convolutions(v1到v4的模型源碼-tf實現)
- Inception-V2(2015 ICML):Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
- Inception-V3(2016 CVPR):Rethinking the Inception Architecture for Computer Vision
- Inception-V4(2016 ICLR):Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning
- ResNetv1(2016 CVPR):Deep Residual Learning for Image Recognition(模型源碼-torch實現)
- ResNetv2(2016 ECCV):Identity Mappings in Deep Residual Networks(模型源碼-torch實現)