1. 程式人生 > >經典神經網路學習(二)——Google net系列

經典神經網路學習(二)——Google net系列

Googe Inception Net首次出現在ILSVRC2014的比賽中(和VGGNet同年),以較大的優勢獲得冠軍。那一屆的GoogleNet通常被稱為Inception V1,Inception V1的特點控制了計算量的引數量的同時,獲得了非常好的效能-top5錯誤率6.67%, 這主要歸功於GoogleNet中引入一個新的網路結構Inception模組,所以GoogleNet又被稱為Inception V1(後面還有改進版V2、V3、V4)架構中有22層深,V1比VGGNet和AlexNet都深,但是它只有500萬的引數量,計算量也只有15億次浮點運算,在引數量和計算量下降的同時保證了準確率,可以說是非常優秀並且實用的模型。

GoogLeNet系列解讀

Inception V1:

        Inception V1中精心設計的Inception Module提高了引數的利用率;在先前的網路中,全連線層佔據了網路的大部分引數,很容易產生過擬合現象;Inception V1去除了模型最後的全連線層,用全域性平均池化層代替(將圖片尺寸變為1x1)。

這樣的結構主要有以下改進:
1. 一層 block 就包含 1x1 卷積,3x3 卷積,5x5 卷積,3x3 池化(使用這樣的尺寸不是
必需的,可以根據需要進行調整)。這樣,網路中每一層都能學習到“稀疏”(3x3、5x5)或“不
稀疏”(1x1)的特徵,既增加了網路的寬度,也增加了網路對尺度的適應性;
2. 通過 deep concat 在每個 block 後合成特徵,獲得非線性屬性。雖然這樣提高了效能,但是網路的計算量實在是太大了,因此 GoogLeNet 借鑑了Network-in-Network 的思想,使用 1x1 的卷積核實現降維操作,以此來減小網路的引數量(這裡就不對兩種結構的引數量進行定量比較了),如上圖所示

googleNet V1具體結構的個層計算:

如表所示,實現的網路仍有一層全連線層,該層的設定是為了遷移學習的實現(下同)。在之前的網路中,最後都有全連線層,經實驗證明,全連線層並不是很必要的,因為可能會帶來以下三點不便:
 網路的輸入需要固定
 引數量多
 易發生過擬合
實驗證明,將其替換為平均池化層(或者 1x1 卷積層)不僅不影響精度,還可以減少。

Inception V2:

Inception V2學習了VGGNet,用兩個3*3的卷積代替5*5的大卷積核(降低引數量的同時減輕了過擬合),同時還提出了著名的Batch Normalization(簡稱BN)方法。BN是一個非常有效的正則化方法

,可以讓大型卷積網路的訓練速度加快很多倍,同時收斂後的分類準確率可以的到大幅度提高。

BN在用於神經網路某層時,會對每一個mini-batch資料的內部進行標準化處理,使輸出規範化到(0,1)的正態分佈,減少了Internal Covariate Shift(內部神經元分佈的改變)。BN論文指出,傳統的深度神經網路在訓練時,每一層的輸入的分佈都在變化,導致訓練變得困難,我們只能使用一個很小的學習速率解決這個問題。而對每一層使用BN之後,我們可以有效的解決這個問題,學習速率可以增大很多倍,達到之間的準確率需要的迭代次數有需要1/14,訓練時間大大縮短,並且在達到之間準確率後,可以繼續訓練。以為BN某種意義上還起到了正則化的作用,所有可以減少或取消Dropout,簡化網路結構。

    當然,在使用BN時,需要一些調整:

  • 增大學習率並加快學習衰減速度以適應BN規範化後的資料
  • 去除Dropout並減輕L2正則(BN已起到正則化的作用)
  • 去除LRN
  • 更徹底地對訓練樣本進行shuffle
  • 減少資料增強過程中對資料的光學畸變(BN訓練更快,每個樣本被訓練的次數更少,因此真實的樣本對訓練更有幫助)

Inception V3:

  • 引入了Factorization into small convolutions的思想,將一個較大的二維卷積拆成兩個較小的一維卷積,比如將7*7卷積拆成1*7卷積和7*1卷積(下圖是3*3拆分為1*3和3*1的示意圖)。 一方面節約了大量引數,加速運算並減去過擬合,同時增加了一層非線性擴充套件模型表達能力。論文中指出,這樣非對稱的卷積結構拆分,結果比對稱地拆分為幾個相同的小卷積核效果更明顯,可以處理更多、更豐富的空間特徵、增加特徵多樣性。

  • 另一方面,Inception V3優化了Inception Module的結構,現在Inception Module有35*35、17*17和8*8三種不同的結構。這些Inception Module只在網路的後部出現,前部還是普通的卷積層。並且還在Inception Module的分支中還使用了分支。

GoogLeNet思想帶來的一點思考:

一般來說,提升網路效能最直接的方式就是增加網路的大小:
            1.增加網路的深度 
            2.增加網路的寬度 

    這樣簡單的解決辦法有兩個主要的缺點: 
        1.網路引數的增多,網路容易陷入過擬閤中,這需要大量的訓練資料,而在解決高粒度分類的問題上,高質量的訓練資料成本太高; 
        2.簡單的增加網路的大小,會讓網路計算量增大,而增大計算量得不到充分的利用,從而造成計算資源的浪費  一般來說,提升網路效能最直接的辦法就是增加網路深度和寬度,這也就意味著巨量的引數。但是,巨量引數容易產生過擬合也會大大增加計算量。

googlenet的主要思想就是圍繞這兩個思路去做的:

1.深度,層數更深,文章採用了22層,為了避免上述提到的梯度消失問題,googlenet巧妙的在不同深度處增加了兩個loss來保證梯度回傳消失的現象。

2.寬度,增加了多種核 1x1,3x3,5x5,還有直接max pooling的,但是如果簡單的將這些應用到feature map上的話,concat起來的feature map厚度將會很大,所以在googlenet中為了避免這一現象提出的inception具有如下結構,在3x3前,5x5前,max pooling後分別加上了1x1的卷積核起到了降低feature map厚度的作用。

綜上googlent有兩個最重要的創新點分別是為了解決深度和寬度受限來設計的,由於googlenet的兩個輔助loss的限制,很多文章拿base model的時候比較偏向與vgg

優點:

把整個Inception的網路架構畫出來,更直觀感受網路結構

1.寬度。總共是9個Inception的模組,每個模組除了num_output的個數不一樣之外,其他的都是相同的。每一個卷積後都要做relu操作。

2.深度。除了在最後的全連線計算了loss和top_1,top_5的準確率之外,還在inception_4a/output和inception_4d/output之後進行池化卷積全連線,最後計算loss和top_1,top_5。

個人感覺這種方式,一方面可以比較不同深度下的loss和準確率,同時,這些中間層的backward computation會對整個起到調整梯度的作用,這樣防止當層次過深時的梯度消失的問題。