GoogLeNet Incepetion V1
這是GoogLeNet的最早版本,出現在2014年的《Going deeper with convolutions》。之所以名為“GoogLeNet”而非“GoogleNet”,文章說是為了向早期的LeNet致敬。
Motivation
深度學習以及神經網絡快速發展,人們不再只關注更給力的硬件、更大的數據集、更大的模型,而是更在意新的idea、新的算法以及模型的改進。
一般來說,提升網絡性能最直接的辦法就是增加網絡深度和寬度,這也就意味着巨量的參數。但是,巨量參數容易產生過擬合也會大大增加計算量。
文章認為解決上述兩個缺點的根本方法是將全連接甚至一般的卷積都轉化為稀疏連接。一方面現實生物神經系統的連接也是稀疏的,另一方面有文獻1表明:對於大規模稀疏的神經網絡,可以通過分析激活值的統計特性和對高度相關的輸出進行聚類來逐層構建出一個最優網絡。這點表明臃腫的稀疏網絡可能被不失性能地簡化。 雖然數學證明有着嚴格的條件限制,但Hebbian准則有力地支持了這一點:fire together,wire together。
早些的時候,為了打破網絡對稱性和提高學習能力,傳統的網絡都使用了隨機稀疏連接。但是,計算機軟硬件對非均勻稀疏數據的計算效率很差,所以在AlexNet中又重新啟用了全連接層,目的是為了更好地優化並行運算。
所以,現在的問題是有沒有一種方法,既能保持網絡結構的稀疏性,又能利用密集矩陣的高計算性能。大量的文獻表明可以將稀疏矩陣聚類為較為密集的子矩陣來提高計算性能,據此論文提出了名為Inception 的結構來實現此目的。
Architectural Details
Inception 結構的主要思路是怎樣用密集成分來近似最優的局部稀疏結構。
作者首先提出下圖這樣的基本結構: 
對上圖做以下說明:
1 . 采用不同大小的卷積核意味着不同大小的感受野,最后拼接意味着不同尺度特征的融合;
2 . 之所以卷積核大小采用1、3和5,主要是為了方便對齊。設定卷積步長stride=1之后,只要分別設定pad=0、1、2,那么卷積之后便可以得到相同維度的特征,然后這些特征就可以直接拼接在一起了;
3 . 文章說很多地方都表明pooling挺有效,所以Inception里面也嵌入了。
4 . 網絡越到后面,特征越抽象,而且每個特征所涉及的感受野也更大了,因此隨着層數的增加,3x3和5x5卷積的比例也要增加。
但是,使用5x5的卷積核仍然會帶來巨大的計算量。 為此,文章借鑒NIN2,采用1x1卷積核來進行降維。
例如:上一層的輸出為100x100x128,經過具有256個輸出的5x5卷積層之后(stride=1,pad=2),輸出數據為100x100x256。其中,卷積層的參數為128x5x5x256。假如上一層輸出先經過具有32個輸出的1x1卷積層,再經過具有256個輸出的5x5卷積層,那么最終的輸出數據仍為為100x100x256,但卷積參數量已經減少為128x1x1x32 + 32x5x5x256,大約減少了4倍。
具體改進后的Inception Module如下圖: 
GoogLeNet
GoogLeNet的整體結構如下圖:

對上圖做如下說明:
1 . 顯然GoogLeNet采用了模塊化的結構,方便增添和修改;
2 . 網絡最后采用了average pooling來代替全連接層,想法來自NIN,事實證明可以將TOP1 accuracy提高0.6%。但是,實際在最后還是加了一個全連接層,主要是為了方便以后大家finetune;
3 . 雖然移除了全連接,但是網絡中依然使用了Dropout ;
4 . 為了避免梯度消失,網絡額外增加了2個輔助的softmax用於向前傳導梯度。文章中說這兩個輔助的分類器的loss應該加一個衰減系數,但看caffe中的model也沒有加任何衰減。此外,實際測試的時候,這兩個額外的softmax會被去掉。
下圖是一個比較清晰的結構圖:

Conclusion
GoogLeNet是谷歌團隊為了參加ILSVRC 2014比賽而精心准備的,為了達到最佳的性能,除了使用上述的網絡結構外,還做了大量的輔助工作:包括訓練多個model求平均、裁剪不同尺度的圖像做多次驗證等等。詳細的這些可以參看文章的實驗部分。
本文的主要想法其實是想通過構建密集的塊結構來近似最優的稀疏結構,從而達到提高性能而又不大量增加計算量的目的。GoogleNet的caffemodel大小約50M,但性能卻很優異。
GoogLeNet Inception V2
V2提出了BN,http://blog.csdn.net/app_12062011/article/details/57083447有介紹,另外, BN的反向傳導:http://www.jianshu.com/p/4270f5acc066.softmax 梯度計算:http://blog.csdn.net/u014313009/article/details/51045303
GoogLeNet Inception V3
GoogLeNet憑借其優秀的表現,得到了很多研究人員的學習和使用,因此Google團隊又對其進行了進一步發掘改進,產生了升級版本的GoogLeNet。這一節介紹的版本記為V3,文章為:《Rethinking the Inception Architecture for Computer Vision》。
Introduction
14年以來,構建更深的網絡逐漸成為主流,但是模型的變大也使計算效率越來越低。這里,文章試圖找到一種方法在擴大網絡的同時又盡可能地發揮計算性能。
首先,GoogLeNet V1出現的同期,性能與之接近的大概只有VGGNet了,並且二者在圖像分類之外的很多領域都得到了成功的應用。但是相比之下,GoogLeNet的計算效率明顯高於VGGNet,大約只有500萬參數,只相當於Alexnet的1/12(GoogLeNet的caffemodel大約50M,VGGNet的caffemodel則要超過600M)。
GoogLeNet的表現很好,但是,如果想要通過簡單地放大Inception結構來構建更大的網絡,則會立即提高計算消耗。此外,在V1版本中,文章也沒給出有關構建Inception結構注意事項的清晰描述。因此,在文章中作者首先給出了一些已經被證明有效的用於放大網絡的通用准則和優化方法。這些准則和方法適用但不局限於Inception結構。
General Design Principles
下面的准則來源於大量的實驗,因此包含一定的推測,但實際證明基本都是有效的。
1 . 避免表達瓶頸,特別是在網絡靠前的地方。 信息流前向傳播過程中顯然不能經過高度壓縮的層,即表達瓶頸。從input到output,feature map的寬和高基本都會逐漸變小,但是不能一下子就變得很小。比如你上來就來個kernel = 7, stride = 5 ,這樣顯然不合適。
另外輸出的維度channel,一般來說會逐漸增多(每層的num_output),否則網絡會很難訓練。(特征維度並不代表信息的多少,只是作為一種估計的手段)
這種情況一般發生在pooling層,字面意思是,pooling后特征圖變小了,但有用信息不能丟,不能因為網絡的漏斗形結構而產生表達瓶頸,解決辦法是作者提出了一種特征圖縮小方法,更復雜的池化。
2 . 高維特征更易處理。 高維特征更易區分,會加快訓練。
3. 可以在低維嵌入上進行空間匯聚而無需擔心丟失很多信息。 比如在進行3x3卷積之前,可以對輸入先進行降維而不會產生嚴重的后果。假設信息可以被簡單壓縮,那么訓練就會加快。
4 . 平衡網絡的寬度與深度。
上述的這些並不能直接用來提高網絡質量,而僅用來在大環境下作指導。
Factorizing Convolutions with Large Filter Size
大尺寸的卷積核可以帶來更大的感受野,但也意味着更多的參數,比如5x5卷積核參數是3x3卷積核的25/9=2.78倍。為此,作者提出可以用2個連續的3x3卷積層(stride=1)組成的小網絡來代替單個的5x5卷積層,(保持感受野范圍的同時又減少了參數量)如下圖:(這個其實在VGG里面提出過了)
然后就會有2個疑問:
1 . 這種替代會造成表達能力的下降嗎?
后面有大量實驗可以表明不會造成表達缺失;
2 . 3x3卷積之后還要再加激活嗎?
作者也做了對比試驗,表明添加非線性激活會提高性能。
從上面來看,大卷積核完全可以由一系列的3x3卷積核來替代,那能不能分解的更小一點呢。文章考慮了 nx1 卷積核。
如下圖所示的取代3x3卷積: 
於是,任意nxn的卷積都可以通過1xn卷積后接nx1卷積來替代。實際上,作者發現在網絡的前期使用這種分解效果並不好,還有在中度大小的feature map上使用效果才會更好。(對於mxm大小的feature map,建議m在12到20之間)。
總結如下圖:

(1) 圖4是GoogLeNet V1中使用的Inception結構;
(2) 圖5是用3x3卷積序列來代替大卷積核;
(3) 圖6是用nx1卷積來代替大卷積核,這里設定n=7來應對17x17大小的feature map。該結構被正式用在GoogLeNet V2中。即非對稱個卷積核,其實類似於卷積運算中,二維分解為1維計算,提高了計算速度。
優化輔助分類器
作者發現,V1中的輔助分類器有點問題:auxiliary classifiers在訓練初期的時候並不能加速收斂,只有當訓練快結束的時候它才會略微提高網絡精度。

Auxiliary Classifiers
然后Szegedy就把第一個auxiliary classifiers去掉了!還說,auxiliary classifiers能夠起到regularizer的作用。原文如下:
Instead, we argue that the auxiliary classifiers act as regularizer. This is supported by the fact that the main classifier of the network performs better if the side branch is batch-normalized or has a dropout layer. This also gives a weak supporting evidence for the conjecture that batch normalization acts as a regularizer.
優化池化
按照傳統的做法,在pooling之前,為了防止信息丟失,應當加入了expand層,如下圖右半部分。
這么做有個問題,會增加運算量,於是Szegedy就想出了下面這種pooling層。
上圖可以這么理解,Szegedy利用了兩個並行的結構完成grid size reduction,分別是conv和pool,就是上圖的右半部分。左半部分是右半部分的內部結構。
為什么這么做?我是說這種結構是怎么設計出來的?Szegedy只字不提,或許這就是深度學習的魅力所在吧。
優化標簽
Szegedy用了將近一頁的篇幅敘述label smooth,可見這個方法有多么難理解。
深度學習用的labels一般都是one hot向量,用來指示classifier的唯一結果,這樣的labels有點類似信號與系統里的脈沖函數,或者叫“Dirac delta”,即只在某一位置取1,其它位置都是0。
Labels的脈沖性質會引發兩個不良后果:一是over-fitting,另外一個是降低了網絡的適應性。這段話我實在沒看懂,附上原文:
First, it may result in over-fitting: if the model learns to assign full probability to the groundtruth label for each training example, it is not guaranteed to generalize. Second, it encourages the differences between the largest logit and all others to become large, and this, combined with the bounded gradient, reduces the ability of the model to adapt.
Szegedy在闡述完上面兩個缺點后,補充了一句話,說不良后果的產生就是因為網絡對它預測的東西太自信了。
Intuitively, this happens because the model becomes too confident about its predictions.
好了,先不管這么多,這個label smooth具體是怎么實現的?就是下式:
為了方便理解,轉換成python代碼,就是這樣的:
new_labels = (1.0 - label_smoothing) * one_hot_labels + label_smoothing / num_classes
- 1
Szegedy在網絡實現的時候,令 label_smoothing = 0.1,num_classes = 1000。Label smooth提高了網絡精度0.2%。
我對Label smooth理解是這樣的,它把原來很突兀的one_hot_labels稍微的平滑了一點,槍打了出頭鳥,削了立於雞群那只鶴的腦袋,分了點身高給雞們,避免了網絡過度學習labels而產生的弊端。
- Sanjeev Arora, Aditya Bhaskara, Rong Ge, and Tengyu Ma. Provable bounds for learning some deep representations. CoRR, abs/1310.6343, 2013.↩
- Min Lin, Qiang Chen, and Shuicheng Yan. Network in network. CoRR, abs/1312.4400, 2013.↩
V4在后面先學習完ResNet后,再補充,因為作者是結合了ResNet后,提出的V4【[v4] Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning, 3.08% test error, http://arxiv.org/abs/1602.07261】
