大家好,我是紅色石頭!
第一個典型的CNN是LeNet5網路,而第一個大放異彩的CNN卻是AlexNet。2012年在全球知名的影像識別競賽 ILSVRC 中,AlexNet 橫空出世,直接將錯誤率降低了近 10 個百分點,這是之前所有機器學習模型無法做到的。
AlexNet的作者是多倫多大學的Alex Krizhevsky等人。Alex Krizhevsky是Hinton的學生。網上流行說 Hinton、LeCun和Bengio是神經網路領域三巨頭,LeCun就是LeNet5的作者(Yann LeCun)。
在正式介紹AlexNet之前,簡單講一下該網路是用來幹嘛的。AlexNet跟LeNet-5類似也是一個用於影像識別的卷積神經網路。AlexNet網路結構更加複雜,引數更多。在ILSVRC比賽中,AlexNet所用的資料集是ImageNet,總共識別1000個類別。
論文《ImageNet Classification with Deep Convolutional Neural Networks》
論文傳送門:
http://www.cs.toronto.edu/~fritz/absps/imagenet.pdf
1. 網路結構
AlexNet整體的網路結構包括:1個輸入層(input layer)、5個卷積層(C1、C2、C3、C4、C5)、2個全連線層(FC6、FC7)和1個輸出層(output layer)。下面對網路結構詳細介紹。
上面這張圖就是AlexNet的網路結構。初看這張圖有的讀者可能會覺得有個疑問:網路上部分是不是沒有畫完?其實不是的。鑑於當時的硬體資源限制,由於AlexNet結構複雜、引數很龐大,難以在單個GPU上進行訓練。因此AlexNet採用兩路GTX 580 3GB GPU並行訓練。也就是說把原先的卷積層平分成兩部分FeatureMap分別在兩塊GPU上進行訓練(例如卷積層55x55x96分成兩個FeatureMap:55x55x48)。上圖中上部分和下部分是對稱的,所以上半部分沒有完全畫出來。
值得一提的是,卷積層 C2、C4、C5中的卷積核只和位於同一GPU的上一層的FeatureMap相連,C3的卷積核與兩個GPU的上一層的FeautureMap都連線。
1.1 輸入層(Input layer)
原論文中,AlexNet的輸入影像尺寸是224x224x3。但是實際影像尺寸為227x227x3。據說224×224可能是寫paper時候的手誤?還是後來對網路又做了調整?世紀之謎…
1.2 卷積層(C1)
該層的處理流程是:卷積–>ReLU–>區域性響應歸一化(LRN)–>池化。
卷積:輸入是227x227x3,使用96個11x11x3的卷積核進行卷積,padding=0,stride=4,根據公式:(input_size + 2 * padding – kernel_size) / stride + 1=(227+2*0-11)/4+1=55,得到輸出是55x55x96。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函式中。
區域性響應歸一化:區域性響應歸一化層簡稱LRN,是在深度學習中提高準確度的技術方法。一般是在啟用、池化後進行。LRN對區域性神經元的活動建立競爭機制,使得其中響應比較大的值變得相對更大,並抑制其他反饋較小的神經元,增強了模型的泛化能力。
LRN的公式如下:
a為歸一化之前的神經元,b為歸一化之後的神經元;N是卷積核的個數,也就是生成的FeatureMap的個數;k,α,β,n是超引數,論文中使用的值是k=2,n=5,α=0.0001,β=0.75。
區域性響應歸一化的輸出仍然是55x55x96。將其分成兩組,每組大小是55x55x48,分別位於單個GPU上。
池化:使用3×3,stride=2的池化單元進行最大池化操作(max pooling)。注意這裡使用的是重疊池化,即stride小於池化單元的邊長。根據公式:(55+2*0-3)/2+1=27,每組得到的輸出為27x27x48。
1.3 卷積層(C2)
該層的處理流程是:卷積–>ReLU–>區域性響應歸一化(LRN)–>池化。
卷積:兩組輸入均是27x27x48,各組分別使用128個5x5x48的卷積核進行卷積,padding=2,stride=1,根據公式:(input_size + 2 * padding – kernel_size) / stride + 1=(27+2*2-5)/1+1=27,得到每組輸出是27x27x128。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函式中。
區域性響應歸一化:使用引數k=2,n=5,α=0.0001,β=0.75進行歸一化。每組輸出仍然是27x27x128。
池化:使用3×3,stride=2的池化單元進行最大池化操作(max pooling)。注意這裡使用的是重疊池化,即stride小於池化單元的邊長。根據公式:(27+2*0-3)/2+1=13,每組得到的輸出為13x13x128。
1.4 卷積層(C3)
該層的處理流程是: 卷積–>ReLU
卷積:輸入是13x13x256,使用384個3x3x256的卷積核進行卷積,padding=1,stride=1,根據公式:(input_size + 2 * padding – kernel_size) / stride + 1=(13+2*1-3)/1+1=13,得到輸出是13x13x384。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函式中。將輸出其分成兩組,每組FeatureMap大小是13x13x192,分別位於單個GPU上。
1.5 卷積層(C4)
該層的處理流程是:卷積–>ReLU
卷積:兩組輸入均是13x13x192,各組分別使用192個3x3x192的卷積核進行卷積,padding=1,stride=1,根據公式:(input_size + 2 * padding – kernel_size) / stride + 1=(13+2*1-3)/1+1=13,得到每組FeatureMap輸出是13x13x192。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函式中。
1.6 卷積層(C5)
該層的處理流程是:卷積–>ReLU–>池化
卷積:兩組輸入均是13x13x192,各組分別使用128個3x3x192的卷積核進行卷積,padding=1,stride=1,根據公式:(input_size + 2 * padding – kernel_size) / stride + 1=(13+2*1-3)/1+1=13,得到每組FeatureMap輸出是13x13x128。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函式中。
池化:使用3×3,stride=2的池化單元進行最大池化操作(max pooling)。注意這裡使用的是重疊池化,即stride小於池化單元的邊長。根據公式:(13+2*0-3)/2+1=6,每組得到的輸出為6x6x128。
1.7 全連線層(FC6)
該層的流程為:(卷積)全連線 –>ReLU –>Dropout (卷積)
全連線:輸入為6×6×256,使用4096個6×6×256的卷積核進行卷積,由於卷積核尺寸與輸入的尺寸完全相同,即卷積核中的每個係數只與輸入尺寸的一個畫素值相乘一一對應,根據公式:(input_size + 2 * padding – kernel_size) / stride + 1=(6+2*0-6)/1+1=1,得到輸出是1x1x4096。既有4096個神經元,該層被稱為全連線層。
ReLU:這4096個神經元的運算結果通過ReLU啟用函式中。
Dropout:隨機的斷開全連線層某些神經元的連線,通過不啟用某些神經元的方式防止過擬合。4096個神經元也被均分到兩塊GPU上進行運算。
1.8 全連線層(FC7)
該層的流程為:(卷積)全連線 –>ReLU –>Dropout
全連線:輸入為4096個神經元,輸出也是4096個神經元(作者設定的)。
ReLU:這4096個神經元的運算結果通過ReLU啟用函式中。
Dropout:隨機的斷開全連線層某些神經元的連線,通過不啟用某些神經元的方式防止過擬合。
4096個神經元也被均分到兩塊GPU上進行運算。
1.9 輸出層(Output layer)
該層的流程為:(卷積)全連線 –>Softmax
全連線:輸入為4096個神經元,輸出是1000個神經元。這1000個神經元即對應1000個檢測類別。
Softmax:這1000個神經元的運算結果通過Softmax函式中,輸出1000個類別對應的預測概率值。
2. 網路引數
2.1 AlexNet神經元數量
整個AlexNet網路包含的神經元個數為:
290400 + 186624 + 64896 + 64896 + 43264 + 4096 + 4096 + 1000 = 659272
大約65萬個神經元。
2.2 AlexNet引數數量
整個AlexNet網路包含的引數數量為:
34944 + 307456 + 885120 + 663936 + 442624 + 37752832 + 16781312 + 4096000 = 60964224
大約6千萬個引數。
設定每個引數是32位浮點數,每個浮點數4個位元組。這樣引數佔用的空間為:
60964224 x 4 = 243856896(Byte) = 238141.5(Kb) = 232.56(Mb)
引數共佔用了大約232Mb的空間。
2.3 FLOPs
FLOPS(即“每秒浮點運算次數”,“每秒峰值速度”),是“每秒所執行的浮點運算次數”(floating-point operations per second)的縮寫。它常被用來估算電腦的執行效能,尤其是在使用到大量浮點運算的科學計算領域中。正因為FLOPS字尾的那個S,代表秒,而不是複數,所以不能省略掉。
一個MFLOPS(megaFLOPS)等於每秒一佰萬(=10^6)次的浮點運算,
一個GFLOPS(gigaFLOPS)等於每秒十億(=10^9)次的浮點運算,
一個TFLOPS(teraFLOPS)等於每秒一萬億(=10^12)次的浮點運算,(1太拉)
一個PFLOPS(petaFLOPS)等於每秒一千萬億(=10^15)次的浮點運算,
一個EFLOPS(exaFLOPS)等於每秒一佰京(=10^18)次的浮點運算。
在AlexNet網路中,對於卷積層,FLOPS=num_params∗(H∗W)。其中num_params為引數數量,H*W為卷積層的高和寬。對於全連線層,FLOPS=num_params。
AlexNet整體的網路結構,包含各層引數個數、FLOPS如下圖所示:
3. AlexNet創新之處
3.1 Data Augmentation
在本文中,作者採用了兩種資料增強(data augmentation)方法,分別是:
- 映象反射和隨機剪裁
-
改變訓練樣本RGB通道的強度值
映象反射和隨機剪裁的做法是,先對影像做映象反射:
然後在原圖和映象反射的圖(256×256)中隨機裁剪227×227的區域:
測試的時候,對左上、右上、左下、右下、中間分別做了5次裁剪,然後翻轉,共10個裁剪,之後對結果求平均。
改變訓練樣本RGB通道的強度值,做法是對RGB空間做PCA(主成分分析),然後對主成分做一個(0, 0.1)的高斯擾動,也就是對顏色、光照作變換,結果使錯誤率又下降了1%。
3.2 啟用函式ReLU
在當時,標準的神經元啟用函式是tanh()函式,這種飽和的非線性函式在梯度下降的時候要比非飽和的非線性函式慢得多,因此,在AlexNet中使用ReLU函式作為啟用函式。
ReLU函式是一個分段線性函式,小於等於0則輸出0;大於0的則恆等輸出。反向傳播中,ReLU有輸出的部分,導數始終為1。而且ReLU會使一部分神經元的輸出為0,這樣就造成了網路的稀疏性,並且減少了引數的相互依存關係,緩解了過擬合問題的發生。
下圖展示了在一個4層的卷積網路中使用ReLU函式在CIFAR-10資料集上達到25%的訓練錯誤率要比在相同網路相同條件下使用tanh函式快6倍。(黑實線是使用ReLU啟用函式,黑虛線是使用tanh啟用函式)
3.3 區域性響應歸一化
區域性響應歸一化(LRN)對區域性神經元的活動建立競爭機制,使得其中響應比較大的值變得相對更大,並抑制其他反饋較小的神經元,增強了模型的泛化能力。
3.4 Dropout Dropout
是神經網路中比較常用的抑制過擬合的方法。在神經網路中Dropout通過修改神經網路本身結構來實現,對於某一層的神經元,通過定義的概率將神經元置為0,這個神經元就不參與前向和後向傳播,就如同在網路中被刪除了一樣,同時保持輸入層與輸出層神經元的個數不變,然後按照神經網路的學習方法進行引數更新。在下一次迭代中,又重新隨機刪除一些神經元(置為0),直至訓練結束。
在AlexNet網路中,全連線層FC6、FC7就使用了Dropout方法。
Dropout應該算是AlexNet中一個很大的創新,現在神經網路中的必備結構之一。Dropout也可以看成是一種模型組合,每次生成的網路結構都不一樣,通過組合多個模型的方式能夠有效地減少過擬合,Dropout只需要兩倍的訓練時間即可實現模型組合(類似取平均)的效果,非常高效。
3.5 重疊池化
在以前的CNN中普遍使用平均池化層(average pooling),AlexNet全部使用最大池化層 max pooling。避免了平均池化層的模糊化的效果,並且步長比池化的核的尺寸小,這樣池化層的輸出之間有重疊,提升了特徵的豐富性。重疊池化可以避免過擬合,這個策略貢獻了0.3%的Top-5錯誤率。
3.6 雙GPU訓練
受當時硬體水平限制,AlexNet訓練作者使用了雙GPU,這是工程上的一種創新做法。雙GPU網路的訓練時間比單GPU網路更少,分別將top-1和top-5錯誤率分別降低了1.7%和1.2%。
3.7 端到端訓練
AlexNet網路,CNN的輸入直接是一張圖片,而當時比較多的做法是先使用特徵提取演算法對RGB圖片進行特徵提取。AlexNet使用了端對端網路,除了將每個畫素中減去訓練集的畫素均值之外,沒有以任何其他方式對影像進行預處理,直接使用畫素的RGB值訓練網路。
手撕 CNN 系列:
手撕 CNN 經典網路之 LeNet-5(MNIST 實戰篇)
手撕 CNN 經典網路之 LeNet-5(CIFAR10 實戰篇)