深度學習案例研究
第一課:為什麼要進行案例研究?
上週我們學習了一些基本結構模組,例如卷積層,池化層和全連線層。事實證明,過去幾年的計算機視覺研究已經著手於如何將這些基礎結構模組組合起來以形成高效的神經網路,讓你自己受到啟發的最好方法就是去研究案例。
一個更好的方法學會如何構建卷積網路的機制就是去看別人的高效的卷積網路的例子。事實證明,一個神經網路結構如果在一個計算機視覺問題中表現良好,通常也會在其他問題中表現良好。
一些計算機領域的研究論文,我希望你也會覺得它們有用。
總覽幾個經典的神經網路(有些觀點已經成為了現代計算機視覺的基石):

開錘!
第二課:經典神經網路
在這節課,你會學到一些經典的神經網路結構,如LeNet 5,AlexNet和VGGNet,讓我們看一下:
LeNet 5在灰度圖上進行訓練,所以圖層通道數目為1。
識別數字7,32 * 32 * 1的原始影象,5 * 5過濾器,步長為1,得到28 * 28 * 6的輸出。
然後進行池化,在發表這篇文章時,人們更常用均值池化,雖然現在一般選擇最大池化,f = 2,s = 2的濾波器進行均值池化,進行降維,得到14 * 14 * 6的體積結果。
接著進行另一層卷積。16個濾波器尺寸為5 * 5,得到10 * 10 * 16的結果。
這篇文章完成於1998年,那時人們不怎麼用填充,或總用有效卷積進行計算,這就是為什麼每次使用卷積時,結果的尺寸都會縮小。
接著進行進一步池化,得到5 * 5 * 16的結果。
然後接下來一層是進行全連線層,其本身120個神經元每個都連線這400個節點,因此叫做全連線層。
接著是另一個全連線層,得到84維特徵。
最後一步是將這84維特徵生成一個最終結果來預測y帽,y帽包括10個預測值。
作為該網路結構的現代版,我們用softmax層來生成10個分類結果,儘管LeNet 5原先是用別的分類器做輸出層,而那個分類器現在已經不用了。
這是一個小型的神經網路,大概有60000個引數,而如今你經常可以見到包含千萬到億量級引數的神經網路,這些字面上比LeNet 5大千倍的神經網路。
但是當你深入研究網路,值得注意的一個模式是從左到右,高度和寬度往往會下降,通道數是增加的,另一個神經網路至今仍然使用的模式是你會用一層或多層卷積,隨後是池化層,然後再是一層或多層卷積層,然後是池化層,隨後是幾層全連線層,然後輸出,這種層次排列很常見。

最後對於想讀這篇文獻的人,新增一些腳註:
人們用sigmoid函式和tanh非線性函式而不用ReLu非線性函式,且還有一些有趣的方式,即以現代標準來看這個網路聯級的方式很有趣,例如你會發現如果有一個nh * nw * nc的網路結構,然後用f * f * nc維的濾波器,其中每個濾波器都處理了每一維通道,但那時計算機比較慢,所以為了節省計算量和引數數量,原始LeNet 5有種比較瘋狂的計算方法,其中不同的濾波器會處理輸入塊的不同通道,而現在先進的應用則不會用這種複雜的方法。另外一個變化就是LeNet 5在池化後有非典型處理,應該是在池化後使用sigmoid非線性函式,可以重點看這篇文章的二三兩章。
第二個經典卷積神經網路演算法是AlexNet:
227 * 227 * 3原始影象,用96個11 * 11,步長為4的過濾器,得到55 * 55 * 96的輸出,之後用3 * 3步長為2的濾波器進行最大池化,體積降到27 * 27 * 96,然後用5 * 5進行卷積,相同填充,得到27 * 27 * 256,再次最大池化,得到13 * 13 * 256,然後相同的卷積,相同填充,得到13 * 13 * 384然,然後再次3 * 3相同卷積,最後最大池化,得到6 * 6 * 256的輸出。
6 * 6 * 256 = 9216。因此我們把它展開為9216個節點,然後有幾層全連線層,然後用softmax輸出結果,即目標可能是1000類中的哪一類。
這個網路結構實際上很像LeNet,但更大。LeNet 5有60000個引數,AlexNet大概有6千萬個引數,而且AlexNet採用非常相似的構造板塊,擁有更多的隱藏神經元,在更多的資料上訓練,AlexNet在ImageNet資料庫上進行訓練,大資料庫使它有更好的效能。使AlexNet比LeNet更好的一個因素是:
ReLu函式的使用。
腳註:當時GPU還比較慢,因此該文章有在兩塊GPU上訓練的複雜方法,基本思想是網路中很多層被分割到兩塊不同的GPU上,兩塊GPU可以互相通訊,而且原始的AlexNet結構還有另一種層,叫做區域性響應歸一層(LRN),這種層實際上用的很少。但區域性響應歸一層的基本思想是:當你看一個塊體,你看一個位置高和寬,然後看跨越通道的位置,跨越了256個通道然後歸一化,這個區域性響應操作是針對處理該13 * 13影象的每一個位置但是不想要太多高啟用率的神經元。

鑑於AlexNet有很多複雜的結構和超引數,在哪放置這些超引數,是AlexNet演算法必須考慮的問題。
第三個VGG/VGG-16演算法:

VGG-16非常值得注意的一點是:
與大量超引數不同,VGG-16結構更簡單,更能關注卷積層,即3 * 3,s=1,same填充的卷積濾波器,所有最大池化都採用2 * 2,s=2。
VGG-16有一個優點:
真正簡化了神經網路結構。
原始影象224 * 224 * 3,卷積池化卷積池化...最後得到7 * 7 * 512的結果輸入全連線層,通過兩層4096個神經元的全連線層,然後是softmax函式輸出1000類結果。
VGG-16中的16表示該網路有16層帶權重的層,這是個相當大的網路,該網路總共有1億3千八百萬個引數,即使以現在的標準衡量也是很大了。但VGG-16結構的簡潔性非常吸引人,看得出這個結構相當統一,有幾組卷積,然後是池化層,以降低高和寬,另一方面,如果你看卷積層的濾波器數量,你有64個濾波器,然後兩倍到128到256到512,這種在每步粗略的雙倍增加,或在每組卷積層雙倍增加的方式,是設計這個網路時用的另一個簡單原則。
所以我認為這種相對統一性對研究者來說很有趣,而該結構的主要缺點是:以訓練引數的數量來看是個非常大的網路。
VGG-19是比VGG-16更大的版本,但是VGG-19和VGG-16效能差不多,很多人用VGG-16。我最喜歡的是這種高和寬隨著網路深入而減少的模式,尺寸每次會因為池化層按因子2減少,與此同時,通道數量增加。每次用一組卷積層時,通道數會按照因子2增加。
這種按照比率減少或增加是非常有條理性的。
以上就是三種經典神經網路結構。
更先進更強大的神經網路?
第三課:ResNets(殘差網路)
太深的神經網路訓練起來很難,因為有梯度消失和爆炸這類問題。
本節講述跳躍連線,它能讓你從一層中得到啟用,並突然把它傳遞給下一層,甚至更深的神經網路層,利用它,你就可以訓練網路層很深很深的殘差網路(ResNets),有時能超過100層。
殘差網路是使用了殘差結構的網路。這裡有兩層神經網路,a[l]代表第l層中的啟用函式,然後到了第a[l+1],兩層之後是a[l+2],在這個計算步驟中,你先有一個a[l],之後你做的第一件事就是將這個線性運算應用到它上面,即用a[l]計算z[l+1],通過乘以一個加權矩陣,並加上一個偏置向量,之後你通過非線性ReLu函式來得到a[l+1],然後在下一層,再次應用這個線性步驟,最後再執行ReLu函式,得到a[l+2]。
換言之,從a[l]到a[l+2]的資訊,它需要經過這些步驟,我們把這個步驟稱為這組層的主路徑。
在殘差網路中,我們要做一點改變。
我們把a[l],把它往前提,然後複製,提到神經網路非常靠後的位置,最後應用一些非線性處理,比如線性整流函式ReLu,我將這個稱為快捷路徑。
所以無需遵循主路徑,a[l]中的資訊現在可以遵循快捷路徑進入到更深層的神經網路中,這意味著最後一個等式:

消失了,我們有了:

使這成為了一個殘差塊。實際上快捷路徑是加在ReLu非線性函式之前的,所以在第二個神經網路層中每個節點都應用一個線性方程和ReLu函式。
有時這個術語不叫快捷路徑,叫做跳躍連線,是指a[l]跳過一層或者跳過幾乎兩層把資訊傳遞到更深的神經網路中去。

作者發現使用殘差塊,讓你可以訓練更深層的神經網路,而你建立一個ResNets的方法就是通過大量的這些殘差塊,然後把它們堆疊起來,形成一個深層網路。
看一下plain網路:
要把一個plain網路變成ResNets,你需要做的就是新增所有這些跳躍連線(或稱為快捷路徑連線),所以每兩層結束於額外的改變,將這個10層的神經網路結構變為5個殘差塊堆積在一起,這就是一個殘差網路。

事實證明:
如果你使用標準的優化演算法,如梯度下降法或者高階優化演算法來訓練plain網路,沒有額外的快捷路徑或者跳躍連線。從經驗上來說,隨著你層數的增加,訓練誤差會在下降一段時間後,又回升上去。從理論上說,當你使神經網路更深,它在訓練資料上的效能應該會更好,但是在實踐中或者現實中,沒有ResNets,一個plain網路如果很深意味著你的優化演算法訓練起來很困難。
所以在現實中,如果你選擇的網路太深,則訓練誤差會更糟糕。但是有了ResNets的情況是,即使層數越來越深,你仍然可以讓誤差繼續下降,即使我們訓練超過100層的網路。
使用ResNets確實對解決梯度消失和爆炸問題非常有幫助。這使得我們可以訓練深得多的神經元網路而不會看到效能倒退的現象,儘管在某一層可能會達到平原現象,但是ResNets對訓練很深的演算法確實有幫助。
為什麼ResNets有效?
第四課:為什麼ResNets有效?
看一個例子:
你可以通過使用ResNets來訓練非常深的神經網路,讓它們越來越深而又沒有真正的損害讓它們在訓練集上好好工作的能力,在訓練集上表現出色通常是你出色地控制你在訓練集上的深度的前提條件,所以使用ResNets是對付你訓練集的第一步。
對於一個普通的神經網路,我們在後面新增幾層,使神經網路的層數更深一點。

通過以上公式推導可以得出:
殘差塊比較容易學習恆等函式,由於跳躍連線也可以得到a[l+2] = a[l]。這意味著將這兩層加入到你的神經網路與上面沒有這兩層的神經網路相比,並不會影響神經網路的能力,因為對它來說學習恆等函式非常容易,只需要複製a[l]到a[l+2],即便它中間有額外的兩層,所以這就是為什麼要新增這額外的兩層,這個殘差塊到大型神經網路,中間或者尾部並不會影響神經網路的表現。
當然我們目標並不是維持現有的表現,而是獲得更好的表現,你可以想象成我們額外新增的兩層,應該學習到有意義的東西,可能要比學習恆等函式更好。
有極多層的神經網路裡比較深層的網路在沒有殘差塊跳躍連線的情況下,容易出錯的地方是:當你的神經網路越深層,它就很難選擇引數來學習,即便是恆等引數也很難,這就是為什麼有很多層數卻會使你的結果更糟而不是更好。
我認為殘差塊網路有效的主要原因是:
這些額外層學習恆等函式非常簡單,你幾乎總能保證它不會影響總體的表現,甚至有些時候幸運的話,可以提升網路的表現。至少不會影響效果,然後梯度下降在這裡開始可以改善最終的結果。
殘差網路另一個值得討論的細節是:
我們假定a[l+2]和a[l]是同一維度的,所以你將看到在ResNet中許多相同卷積的應用,輸出層的維度相同,所以我們可以做一個快捷連線,因為相同的卷積會保留維度,也使你運算這個快捷連線更加方便,因為運算的是兩個相同維度的向量的和。
如果不是相同維度怎麼辦?
你需要做的是增加一個額外的矩陣,稱它為ws。那麼這個ws可以更改a[l]的維度和z[l]相同。
ws矩陣也可以做一些其他的事:比如它可以是一個包含已學習到引數的矩陣,也可以是一個固定的矩陣,其中包含很多0項。
最後我們來看一下ResNet在影象上的應用:

你輸入一張影象,然後經過一系列卷積層,直到最終你輸出一個softmax分類,要把這個變為ResNet,你需要新增那些額外的跳躍連線。
細節:這裡有很多3 * 3卷積,其中大部分都是相同的3 * 3卷積,這也是為什麼你需要做相同維度向量的相加。所以與其說是相互充分連線的層,還不如說這些是卷積層,但由於它們是相同的卷積層,這裡的維度相同,因此z[l+2]+a[l]的算數得以成立。
和你之前見過的ResNet相同的是:
你有一堆卷積層,然後偶爾有池化層或者類似於池化的層,你可以利用我們提到的方法調整維度,你可以用矩陣ws人,然後在這些網路中比較常見的是,你有個池,最後連線一個softmax作出預測。
接下來,1 * 1過濾,1 * 1卷積的神經網路,如何使用它?
第五課:網中網,網路中的1x1卷積
在設計卷積網路的架構時,一種很有用的方法是用1 * 1的卷積,1 * 1的卷積能做什麼?

如果你有一個6 * 6 * 1的影象,那麼經過1 * 1卷積就是進行畫素乘法,但是當你的影象有兩個維度的時候,和一個1 * 1的過濾器做卷積很有意義:
比如6 * 6 * 32,這個1 * 1的卷積會逐一掃過這裡的36個不同的位置,然後進行對應元素之間的乘法,將左邊的32個數和過濾器中的32個數相乘(做內積),然後將一個非線性對映ReLu(線性整流函式)作用於它。
事實上,你可以這樣理解:這個 * 1 * 32過濾器中的32個數,它類似於你有一個神經元,接收一個32個數的輸入向量,將這一條位於相同位置,即相同高度和寬度,但位於32個不同通道的數和32個權重相乘,然後將線性整流函式(ReLu函式)作用於它,再把對應的結果輸出到這裡。
更通常地,有多個過濾器,那麼這類似於,你有不止一個單元,而有多個單元,接收用一面中的所有數作為輸入,然後將它們生成一個6 * 6濾波器數的輸出量。。。
所以對1 * 1卷積的一種理解就是:
它本質上是一個完全連線的神經網路,逐一作用於這36個不同的位置上,這個完全連線的神經網路所做的是:
它接收32個數的輸入,然後輸出過濾器數個輸出值,即nc[l+1],然後對這36個位置中的每一個都進行相同的操作,最終得到輸出為6 * 6 * 過濾器數。
這對你的輸入量所進行的是一個非常不平凡的計算,這個想法被稱為1 * 1卷積。但有時也被稱為網中網。
舉一個1 * 1卷積有應用價值的例子:

28 * 28 * 192,通道數太多,想要縮小通道數到28 * 28 * 32,你可以使用32個1 * 1的過濾器,從技術上說,每一個過濾器都會是1 * 1 * 19大小的,因為過濾器的通道數需要和輸入量的通道數保持一致。
由於你使用了32個過濾器,所以這個過程的輸出將會是28 * 28 * 32大小的立方體。
這是一種讓你縮小nc的方式。
而池化層我只可以用它來縮小nh和nw,即這個立方體的高度和寬度。
之後我們會分析為什麼1 * 1卷積會縮小通道數,從而達到在某些網路中減少計算量的目的。當然,如果你想保持192個通道數,這也是可行的。
採用192個1 * 1的過濾器,這時1 * 1卷積的效果是增加非線性,它通過新增一層輸入28 * 28 * 192再輸出28 * 28 * 192的操作,使得你的網路可以學習到更復雜的函式形式。
綜上就是1 * 1卷積,可以做一些不平凡的操作,以及在神經網路中增加非線性,以及允許你減少或不改變增加輸入的通道數。接下來你會看到這種思想在構建inception network中是十分有用的。
第六課:Inception Network
為卷積網路設計某一層時,你可能需要選擇一個1 * 3的濾波器或者3 * 3或則5 * 5等,或者你需要一個池化層,Inception Network是:為什麼不全用呢?
這使得網路結構更加複雜,但它的效果也會越好,比如:

Inception Network是指:與其在卷積神經網路中選擇一個你想使用的卷積核尺寸,乃至選擇你是否需要一個卷積層還是一個池化層,讓我們全部都做了吧。
你要做的是,對於不同的過濾器,將第二個量並列的堆疊在第一個量旁邊,並且保證維度是匹配的,所以要使用same填充,保證輸出與輸入的維度相同。
為了保證維度的匹配,事實上你需要為最大池化操作使用填充,所以這是一種不一般的池化。
對於像這樣的一個Inception Network,你可以輸入一些量並且獲得一個輸出,如果你把所有過濾器得到的維度加起來,得到256。
即你將有一個Inception Network,輸入28 * 28 * 192,輸出為28 * 28 * 256。
這就是Inception Network的核心。
這個網路基礎的一個特點就是:你不用去只挑選一個卷積核的大小或者是池化,你可以都做,然後把所有的結果結合起來,讓神經網路去學習它想要的引數以及他想要用到的卷積核大小。
但是這裡會出現一個Inception Network的問題:
計算成本問題。
對於5 * 5過濾器進行分析:看一下獲得28 * 28 * 32的輸出的計算成本是多少?

你有32個卷積核,因為你有32個通道,然後每一個卷積核大小應該是5x5x192,那麼輸出張量的大小將是:28x28x32,所以你需要計算28x28x32,每一個都需要做那麼多乘法,對應你做乘法的總數為:5x5x192x28x28x32 = 1.2億。
但是通過1 * 1卷積可以將這個運算降低到其1/10。
另一種計算方法:

你用1 * 1的卷積運算將通道的個數從192減小到16,然後我們用這個相對較小的量去做5x5卷積並最終得到結果,兩者的輸入和輸出維度相同,但是這種計算方法,我們先把這較大的輸入減小為一個較小的中間值,也就是隻有16個通道而不是192個通道,我們把中間層稱為瓶頸層。這個方法的計算成本是:
第一個卷積層的計算成本:28x28x16x192 = 240萬
28x28x32x5x5x16 = 1000萬
1240萬次乘法
第二種方法中,你想加的次數和相乘的次數差不多。
總結一下:如果你在建立一個卷積網路層,並且你不想去決定到底使用1x1, 3x3,5x5的卷積核或者是否使用池化,那麼就用這個Inception Network,它會做所有的工作,並將結果都連線起來,通過別計較計算成本,可以看到1 * 1卷積計算可以生成一個瓶頸層,並且顯著降低計算成本。
如此劇烈的縮小特徵表示的大小會不會影響神經網路的效能?
只要你合理的去實現這個瓶頸層,你既可以縮小輸入張量的維度,又不會影響到整體的效能,還能給你節省計算成本。
完整的Inception Network是什麼樣的?
第七課:Inception Network
你已經學到了所有構建Inception Network的基本模組,讓我們把這些模組連線起來從而建立自己的Inception Network。
Inception Network模組的輸入值一般是啟用值或者來自上層的輸出。
這裡:
當我們為了保持輸出的維度,而對池化使用填充操作的時候,這裡的輸出和輸入相同都是28x28x192,它的通道的個數以及深度和我們給的輸入是一樣的,這個看上去好像有很多通道,因此我們要做的是加上一個1x1的卷積層,來增強通道的個數。
這樣的話,我們避免了在最後的輸出中把所有的通道加到池化層。
最後,所有的模組都用來做渠道連線,得到28x28x256的輸出

這就是一個Inception模組Inception Network所做的事,差不多把這些模組放到一起。
圖中的每一個模組就是一個Inception模組,還有另一個池化層來改變高和寬的維度。

最後一個細節就是:加入了你讀的論文。
加入旁支的作用就是:它把隱藏層作為輸入,來做預測,在中間就得到softmax輸出。它的作用就是保證所計算的特徵值,即使它們在最頭部的單元裡,或者在中間層裡,它們對於預測結果不算太差。
這就是Inception Network的正則化,用來防止這個網路過度學習。
GoogleNet

最後。。。名字的來源:

總結:
如果你理解了Inception模組的話,你就能理解Inception Network,Inception Network就是重複的多次使用Inception模組的網路結構,自從Inception模組開發以來,有些新的Inception Network在不同的論文中被提出,但是所有的新版本都是建立在這個基礎上的。
你已經學習了一定數量的神經網路,使用的技巧?
如何構建自己的計算機視覺系統?