1. 程式人生 > >Deep Learning-TensorFlow (13) CNN卷積神經網路_ GoogLeNet 之 Inception(V1-V4)

Deep Learning-TensorFlow (13) CNN卷積神經網路_ GoogLeNet 之 Inception(V1-V4)

環境:Win8.1 TensorFlow1.0.1

軟體:Anaconda3 (整合Python3及開發環境)

TensorFlow安裝:pip install tensorflow (CPU版) pip install tensorflow-gpu (GPU版)

TFLearn安裝:pip install tflearn

參考:

1. 前言

上篇介紹的 NIN 在改造傳統 CNN 結構上作出了矚目貢獻,通過 Mlpconv Layer 和 Global Average Pooling 建立的網路模型在多個數據集上取得了不錯的結果,同時將訓練引數控制在 AlexNet

引數量的 1/12

本文將要介紹的是在 ILSVRC 2014 取得了最好的成績的 GoogLeNet,及其核心結構—— Inception。早期的V1 結構借鑑了 NIN 的設計思路,對網路中的傳統卷積層進行了修改,針對限制深度神經網路效能的主要問題,一直不斷改進延伸到 V4

  • 引數空間大,容易過擬合,且訓練資料集有限;
  • 網路結構複雜,計算資源不足,導致難以應用;
  • 深層次網路結構容易出現梯度彌散,模型效能下降。

2. Inception

GoogLeNet 對網路中的傳統卷積層進行了修改,提出了被稱為 Inception 的結構,用於增加網路深度和寬度,提高深度神經網路效能。

其各個版本的設計思路:

2.1 Inception V1


Naive Inception

Inception module 的提出主要考慮多個不同 size 的卷積核能夠增強網路的適應力,paper 中分別使用1*1、3*3、5*5卷積核,同時加入3*3 max pooling。

 
隨後文章指出這種 naive 結構存在著問題:每一層 Inception module 的 filters 引數量為所有分支上的總數和,多層 Inception 最終將導致 model 的引數數量龐大,對計算資源有更大的依賴。

在 NIN 模型中與1*1卷積層等效的 MLPConv 既能跨通道組織資訊,提高網路的表達能力,同時可以對輸出有效進行降維

,因此文章提出了Inception module with dimension reduction,在不損失模型特徵表示能力的前提下,儘量減少 filters 的數量,達到降低模型複雜度的目的:


Inception Module

Inception Module 的4個分支在最後通過一個聚合操作合併(在輸出通道數這個維度上聚合,在 TensorFlow 中使用 tf.concat(3, [], []) 函式可以實現合併)。

完整的 GoogLeNet 結構在傳統的卷積層和池化層後面引入了 Inception 結構,對比 AlexNet 雖然網路層數增加,但是引數數量減少的原因是絕大部分的引數集中在全連線層,最終取得了 ImageNet 上 6.67% 的成績。

2.2 Inception V2

Inception V2 學習了 VGG 用兩個3´3的卷積代替5´5的大卷積,在降低引數的同時建立了更多的非線性變換,使得 CNN 對特徵的學習能力更強:


兩個3´3的卷積層功能類似於一個5´5的卷積層

另外提出了著名的 Batch Normalization(以下簡稱BN)方法。BN 是一個非常有效的正則化方法,可以讓大型卷積網路的訓練速度加快很多倍,同時收斂後的分類準確率也可以得到大幅提高。BN 在用於神經網路某層時,會對每一個 mini-batch 資料的內部進行標準化(normalization)處理,使輸出規範化到 N(0,1) 的正態分佈,減少了 Internal Covariate Shift(內部神經元分佈的改變)。


補充:在 TensorFlow 1.0.0 中採用 tf.image.per_image_standardization() 對影象進行標準化,舊版為 tf.image.per_image_whitening。

BN 的論文指出,傳統的深度神經網路在訓練時,每一層的輸入的分佈都在變化,導致訓練變得困難,我們只能使用一個很小的學習速率解決這個問題。而對每一層使用 BN 之後,我們就可以有效地解決這個問題,學習速率可以增大很多倍,達到之前的準確率所需要的迭代次數只有1/14,訓練時間大大縮短。而達到之前的準確率後,可以繼續訓練,並最終取得遠超於 Inception V1 模型的效能—— top-5 錯誤率 4.8%,已經優於人眼水平。因為 BN 某種意義上還起到了正則化的作用,所以可以減少或者取消 DropoutLRN,簡化網路結構。

2.3 Inception V3

                     

將一個3´3卷積拆成1´3卷積和3´1卷積

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

另一方面,Inception V3 優化了 Inception Module 的結構,現在 Inception Module 有35´35、17´17和8´8三種不同結構。這些 Inception Module 只在網路的後部出現,前部還是普通的卷積層。並且 Inception V3 除了在 Inception Module 中使用分支,還在分支中使用了分支(8´8的結構中),可以說是Network In Network In Network。最終取得 top-5 錯誤率 3.5%

2.4 Inception V4

Inception V4 相比 V3 主要是結合了微軟的 ResNet,將錯誤率進一步減少到 3.08%


3. GoogLeNet V1


例如,在 tflearn googlenet.py 中,定義 Inception(3a) 中的分支結構,用 merge 函式合併 feature map:

network = input_data(shape=[None, 227, 227, 3])
conv1_7_7 = conv_2d(network, 64, 7, strides=2, activation='relu', name = 'conv1_7_7_s2')
pool1_3_3 = max_pool_2d(conv1_7_7, 3,strides=2)
pool1_3_3 = local_response_normalization(pool1_3_3)
conv2_3_3_reduce = conv_2d(pool1_3_3, 64,1, activation='relu',name = 'conv2_3_3_reduce')
conv2_3_3 = conv_2d(conv2_3_3_reduce, 192,3, activation='relu', name='conv2_3_3')
conv2_3_3 = local_response_normalization(conv2_3_3)
pool2_3_3 = max_pool_2d(conv2_3_3, kernel_size=3, strides=2, name='pool2_3_3_s2')
inception_3a_1_1 = conv_2d(pool2_3_3, 64, 1, activation='relu', name='inception_3a_1_1')
inception_3a_3_3_reduce = conv_2d(pool2_3_3, 96,1, activation='relu', name='inception_3a_3_3_reduce')
inception_3a_3_3 = conv_2d(inception_3a_3_3_reduce, 128,filter_size=3,  activation='relu', name = 'inception_3a_3_3')
inception_3a_5_5_reduce = conv_2d(pool2_3_3,16, filter_size=1,activation='relu', name ='inception_3a_5_5_reduce' )
inception_3a_5_5 = conv_2d(inception_3a_5_5_reduce, 32, filter_size=5, activation='relu', name= 'inception_3a_5_5')
inception_3a_pool = max_pool_2d(pool2_3_3, kernel_size=3, strides=1, )
inception_3a_pool_1_1 = conv_2d(inception_3a_pool, 32, filter_size=1, activation='relu', name='inception_3a_pool_1_1')

# merge the inception_3a__
inception_3a_output = merge([inception_3a_1_1, inception_3a_3_3, inception_3a_5_5, inception_3a_pool_1_1], mode='concat', axis=3)

最後對於 Inception(5b) 的7*7*1024的輸出採用7*7的 avg pooling,40%的 Dropout 和 softmax:

pool5_7_7 = avg_pool_2d(inception_5b_output, kernel_size=7, strides=1)
pool5_7_7 = dropout(pool5_7_7, 0.4)
loss = fully_connected(pool5_7_7, 17,activation='softmax')

由於解決 Oxford 17 類鮮花 資料集分類任務,最後的輸出通道設為17。

4. 總結

Inception V1——構建了1x1、3x3、5x5的 conv 和3x3的 pooling 的分支網路,同時使用 MLPConv 全域性平均池化,擴寬卷積層網路寬度,增加了網路對尺度的適應性;

Inception V2——提出了 Batch Normalization,代替 Dropout 和 LRN,其正則化的效果讓大型卷積網路的訓練速度加快很多倍,同時收斂後的分類準確率也可以得到大幅提高,同時學習 VGG 使用兩個3´3的卷積核代替5´5的卷積核,在降低引數量同時提高網路學習能力;

Inception V3——引入了 Factorization,將一個較大的二維卷積拆成兩個較小的一維卷積,比如將3´3卷積拆成1´3卷積和3´1卷積,一方面節約了大量引數,加速運算並減輕了過擬合,同時增加了一層非線性擴充套件模型表達能力,除了在 Inception Module 中使用分支,還在分支中使用了分支(Network In Network In Network);

Inception V4——研究了 Inception Module 結合 Residual Connection,結合 ResNet 可以極大地加速訓練,同時極大提升效能,在構建 Inception-ResNet 網路同時,還設計了一個更深更優化的 Inception v4 模型,能達到相媲美的效能。