1. 程式人生 > >深度學習,影象分類,從vgg到inception,到resnet

深度學習,影象分類,從vgg到inception,到resnet

最近工作在做一件事情,就是把遊戲影象進行場景分類,相比於自然影象來說,遊戲影象種類較少,因此分類任務比較簡單,但是由於追求工程上的高精度和高效率,所以閱讀了vgg,inception,resnet等相關論文,並且都試了一下效果,算是對深度學習影象分類有了一個系統的瞭解,在這裡總結一下。

VGG

vgg

vgg的最主要的思想就是增加網路深度減小卷積核尺寸(3*3)。減少卷積核的好處就是可以減少引數和計算量,比如,論文中舉了一個例子,把一個7*7的卷積層替換成3個3*3的卷積層,引數上可以減少81%,因為3*3*3 = 27, 7*7 = 49.

文中還提到了1*1的卷積層,比如說下圖的configC的conv1層,這樣做的目的主要是增加捲積層的非線性表達,同時影響卷積層的感受野,這個思想在google的inception系列網路中有了很好的應用,具體可以參考Network in Network這篇論文。

這裡寫圖片描述

vgg的引數還是很多的,可以看出vgg-16有138million個引數。

inception系列

參考論文:
[v1] Going Deeper with Convolutions, 6.67% test error
http://arxiv.org/abs/1409.4842
[v2] Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift, 4.8% test error
http://arxiv.org/abs/1502.03167
[v3] Rethinking the Inception Architecture for Computer Vision, 3.5% test error

http://arxiv.org/abs/1512.00567
[v4] Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning, 3.08% test error
http://arxiv.org/abs/1602.07261

inception-v1

這個就是GoogLeNet了,讀谷歌的論文,一股工程的氣息撲面而來,作者摘要中就說,本文的主要工作,就是研究怎麼設計一種網路,更加有效地利用計算資源。

inception

一般來說,提升網路效能最直接的辦法就是增加網路深度和寬度,這也就意味著巨量的引數。但是,巨量引數容易產生過擬合也會大大增加計算量。

文章認為解決上述兩個缺點的根本方法是將全連線甚至一般的卷積都轉化為稀疏連線。一方面現實生物神經系統的連線也是稀疏的,另一方面有文獻表明:對於大規模稀疏的神經網路,可以通過分析啟用值的統計特性和對高度相關的輸出進行聚類來逐層構建出一個最優網路。這點表明臃腫的稀疏網路可能被不失效能地簡化。 雖然數學證明有著嚴格的條件限制,但Hebbian準則有力地支援了這一點:fire together,wire together。

早些的時候,為了打破網路對稱性和提高學習能力,傳統的網路都使用了隨機稀疏連線。但是,計算機軟硬體對非均勻稀疏資料的計算效率很差,所以在AlexNet中又重新啟用了全連線層,目的是為了更好地優化並行運算。

所以,現在的問題是有沒有一種方法,既能保持網路結構的稀疏性,又能利用密集矩陣的高計算效能。大量的文獻表明可以將稀疏矩陣聚類為較為密集的子矩陣來提高計算效能,據此論文提出了名為Inception 的結構來實現此目的。

inception module 主要就是把稀疏結構近似成幾個密集的子矩陣,從而在減少引數的同時,更加有效地利用計算資源。

這裡寫圖片描述

  1. 採用不同大小的卷積核意味著不同大小的感受野,最後拼接意味著不同尺度特徵的融合;
  2. 之所以卷積核大小採用1、3和5,主要是為了方便對齊。設定卷積步長stride=1之後,只要分別設定pad=0、1、2,那麼卷積之後便可以得到相同維度的特徵,然後這些特徵就可以直接拼接在一起了;
  3. 文章說很多地方都表明pooling挺有效,所以Inception裡面也嵌入了。
  4. 網路越到後面,特徵越抽象,而且每個特徵所涉及的感受野也更大了,因此隨著層數的增加,3x3和5x5卷積的比例也要增加。

但是,這種naive的inception 並不實用,因為不同的feature map拼到一起之後傳遞到下一層inception 的5*5卷積層,計算量是非常巨大的,所以需要有一個降維的操作,這個降維就是依靠1*1的卷積層來實現,下面是改進之後的inception。

這裡寫圖片描述

Network in Network

GoogLeNet提出之時,說到其實idea是來自NIN,NIN就是Network in Network了。

NIN有兩個特性,是它對CNN的貢獻:

  1. MLP代替GLM
  2. Global Average Pooling

mlpconv

這裡寫圖片描述

普通的卷積可以看做輸入feature map 和kernel 矩陣相乘的過程,是一個線性變換。MLP是指多層感知機,由於是多層的,f(x) = w*g(x)+b, g(x) = w*x +b,輸出f和輸入x自然是非線性關係,mlpconv的意思就是用mlp代替普通卷積,可以增加網路的抽象表達能力。

所以,基於如上,可以認為,在抽特徵的時候直接做了非線性變換,可以有效的對影象特徵進行更好的抽象。

從而,Linear convolution layer就變成了Mlpconv layer。

值得一提的是,Mlpconv相當於在啟用函式後面,再新增一個1×1的卷積層。
當然,1*1卷積層在本文中的最重要的作用還是進行降維。

Global Average Pooling

Global Average Pooling的做法是將全連線層去掉。

全連線層的存在有兩個缺點:

全連線層是傳統的神經網路形式,使用了全連線層以為著卷積層只是作為特徵提取器來提取影象的特徵,而全連線層是不可解釋的,從而CNN也不可解釋了
全連線層中的引數往往佔據CNN整個網路引數的一大部分,從而使用全連線層容易導致過擬合。
而Global Average Pooling則是在最後一層,將卷積層設為與類別數目一致,然後全域性pooling,從而輸出類別個數個結果。

但是本文中,在average pooling 後面還跟了一個linear layer,加這個層主要是為了方便起見,能夠更容易擴充套件到其他的資料集上。

結構

最後的結構如下圖所示:

這裡寫圖片描述

網路在訓練的時候還加了兩個額外的分類器,目的是為了防止梯度消失,最後測試的時候可以把這兩個分類器去掉。
最後的引數相比於alexnet少了12倍,相比於vgg-16來說少了3倍。

inception-v2

最主要的貢獻就是提出了batch normalization,目的主要在於加快訓練速度

關於BN層,這一篇部落格講得很好,http://blog.csdn.net/app_12062011/article/details/57083447
我在這裡轉一下。
作者認為:網路訓練過程中引數不斷改變導致後續每一層輸入的分佈也發生變化,而學習的過程又要使每一層適應輸入的分佈,因此我們不得不降低學習率、小心地初始化。作者將分佈發生變化稱之為internal covariate shift。
大家應該都知道,我們一般在訓練網路的時會將輸入減去均值,還有些人甚至會對輸入做白化等操作,目的是為了加快訓練。為什麼減均值、白化可以加快訓練呢,這裡做一個簡單地說明:
首先,影象資料是高度相關的,假設其分佈如下圖a所示(簡化為2維)。由於初始化的時候,我們的引數一般都是0均值的,因此開始的擬合y=Wx+b,基本過原點附近,如圖b紅色虛線。因此,網路需要經過多次學習才能逐步達到如紫色實線的擬合,即收斂的比較慢。如果我們對輸入資料先作減均值操作,如圖c,顯然可以加快學習。更進一步的,我們對資料再進行去相關操作,使得資料更加容易區分,這樣又會加快訓練,如圖d。

這裡寫圖片描述

白化的方式有好幾種,常用的有PCA白化:即對資料進行PCA操作之後,在進行方差歸一化。這樣資料基本滿足0均值、單位方差、弱相關性。作者首先考慮,對每一層資料都使用白化操作,但分析認為這是不可取的。因為白化需要計算協方差矩陣、求逆等操作,計算量很大,此外,反向傳播時,白化操作不一定可導。於是,作者採用下面的Normalization方法。

資料歸一化方法很簡單,就是要讓資料具有0均值和單位方差
這裡寫圖片描述

但是作者又說如果簡單的這麼幹,會降低層的表達能力。比如下圖,在使用sigmoid啟用函式的時候,如果把資料限制到0均值單位方差,那麼相當於只使用了啟用函式中近似線性的部分,這顯然會降低模型表達能力。

這裡寫圖片描述

為此,作者又為BN增加了2個引數,用來保持模型的表達能力:

這裡寫圖片描述

整個BN的演算法如下:

這裡寫圖片描述

測試的時候:

我們依然會應用下面的式子:

這裡寫圖片描述

特別注意: 這裡的均值和方差已經不是針對某一個Batch了,而是針對整個資料集而言。因此,在訓練過程中除了正常的前向傳播和反向求導之外,我們還要記錄每一個Batch的均值和方差,以便訓練完成之後按照下式計算整體的均值和方差:

這裡寫圖片描述

在測試的時候,計算公式為:

這裡寫圖片描述

作者在文章中說應該把BN放在啟用函式之前,這是因為Wx+b具有更加一致和非稀疏的分佈。

inception-v3

本文的主要目的是研究如何在增加網路規模的同時,能夠保證計算的高效率。

Rethinking這篇論文中提出了一些CNN調參的經驗型規則,暫列如下:

  1. 避免特徵表徵的瓶頸。特徵表徵就是指影象在CNN某層的啟用值,特徵表徵的大小在CNN中應該是緩慢的減小的。
  2. 高維的特徵更容易處理,在高維特徵上訓練更快,更容易收斂
  3. 低維嵌入空間上進行空間匯聚,損失並不是很大。這個的解釋是相鄰的神經單元之間具有很強的相關性,資訊具有冗餘。
  4. 平衡的網路的深度和寬度。寬度和深度適宜的話可以讓網路應用到分散式上時具有比較平衡的computational budget。

更小的卷積核

這裡寫圖片描述

簡而言之,就是將尺寸比較大的卷積,變成一系列3×3的卷積的疊加,這樣既具有相同的視野,還具有更少的引數。
實驗表明,這樣做不會導致效能的損失。

Grid Size Reduction

Grid就是影象在某一層的啟用值,即feature_map,一般情況下,如果想讓影象縮小,可以有如下兩種方式:

這裡寫圖片描述

右圖是正常的縮小,但計算量很大。左圖先pooling會導致特徵表徵遇到瓶頸,違反上面所說的第一個規則,為了同時達到不違反規則且降低計算量的作用,將網路改為下圖:

這裡寫圖片描述

結構如左圖表示,左邊兩個代表的是右圖中的左邊分支。

label smoothing

除了上述的模型結構的改進以外,Rethinking那篇論文還改進了目標函式。

原來的目標函式,在單類情況下,如果某一類概率接近1,其他的概率接近0,那麼會導致交叉熵取log後變得很大很大。從而導致兩個問題:

過擬合
導致樣本屬於某個類別的概率非常的大,模型太過於自信自己的判斷。
所以,使用了一種平滑方法,可以使得類別概率之間的差別沒有那麼大.

resnet

這裡寫圖片描述

深度學習網路的深度對最後的分類和識別的效果有著很大的影響,所以正常想法就是能把網路設計的越深越好,但是事實上卻不是這樣,常規的網路的堆疊(plain network)在網路很深的時候,效果卻越來越差了。

這裡其中的原因之一即是網路越深,梯度消失的現象就越來越明顯,網路的訓練效果也不會很好。
但是現在淺層的網路(shallower network)又無法明顯提升網路的識別效果了,所以現在要解決的問題就是怎樣在加深網路的情況下又解決梯度消失的問題。

殘差網路

作者提出了一個Residual的結構:

這裡寫圖片描述

即增加一個identity mapping(恆等對映),將原始所需要學的函式H(x)轉換成F(x)+x,而作者認為這兩種表達的效果相同,但是優化的難度卻並不相同,作者假設F(x)的優化 會比H(x)簡單的多。這一想法也是源於影象處理中的殘差向量編碼,通過一個reformulation,將一個問題分解成多個尺度直接的殘差問題,能夠很好的起到優化訓練的效果。
這個Residual block通過shortcut connection實現,通過shortcut將這個block的輸入和輸出進行一個element-wise的加疊,這個簡單的加法並不會給網路增加額外的引數和計算量,同時卻可以大大增加模型的訓練速度、提高訓練效果,並且當模型的層數加深時,這個簡單的結構能夠很好的解決退化問題。

接下來,作者就設計實驗來證明自己的觀點。
首先構建了一個18層和一個34層的plain網路,即將所有層進行簡單的鋪疊,然後構建了一個18層和一個34層的residual網路,僅僅是在plain上插入了shortcut,而且這兩個網路的引數量、計算量相同,並且和之前有很好效果的VGG-19相比,計算量要小很多。(36億FLOPs VS 196億FLOPs,FLOPs即每秒浮點運算次數。)這也是作者反覆強調的地方,也是這個模型最大的優勢所在。

這裡寫圖片描述

模型構建好後進行實驗,在plain上觀測到明顯的退化現象,而且ResNet上不僅沒有退化,34層網路的效果反而比18層的更好,而且不僅如此,ResNet的收斂速度比plain的要快得多。

對於shortcut的方式,作者提出了三個選項:
A. 使用恆等對映,如果residual block的輸入輸出維度不一致,對增加的維度用0來填充;
B. 在block輸入輸出維度一致時使用恆等對映,不一致時使用線性投影以保證維度一致;
C. 對於所有的block均使用線性投影。
對這三個選項都進行了實驗,發現雖然C的效果好於B的效果好於A的效果,但是差距很小,因此線性投影並不是必需的,而使用0填充時,可以保證模型的複雜度最低,這對於更深的網路是更加有利的。另外,shortcut過程中,stride是2可以保證feature map的大小一致。
進一步實驗,作者又提出了deeper的residual block:

這裡寫圖片描述

這相當於對於相同數量的層又減少了引數量,因此可以拓展成更深的模型。於是作者提出了50、101、152層的ResNet,而且不僅沒有出現退化問題,錯誤率也大大降低,同時計算複雜度也保持在很低的程度。
這個時候ResNet的錯誤率已經把其他網路落下幾條街了,但是似乎還並不滿足,於是又搭建了更加變態的1202層的網路,對於這麼深的網路,優化依然並不困難,但是出現了過擬合的問題,這是很正常的,作者也說了以後會對這個1202層的模型進行進一步的改進。

Inception-ResNet-v2

這篇論文裡,作者借鑑了resnet的殘差網路的思想,將其應用到了inception-v3當中,結構如下:

這裡寫圖片描述

inception-v4

inception-v4 是通過提出了更多新的inception module擴充套件網路結構,能夠達到和inception-resnet-v2相媲美的效果,這個有時間再研究一下。