手撕 CNN 经典网络之 AlexNet(理论篇)
大家好,我是紅色石頭!
第一個典型的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。據說224x224可能是寫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上。
池化:使用3x3,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。?
池化:使用3x3,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函數中。?
池化:使用3x3,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神經元數量
層數 | 定義 | 數量 |
C1 | C1層的FeatureMap的神經元個數 | 55x55x48x2=290400 |
C2 | C2層的FeatureMap的神經元個數 | 27x27x128x2=186624 |
C3 | C3層的FeatureMap的神經元個數 | 13x13x192x2=64896 |
C4 | C4層的FeatureMap的神經元個數 | 13x13x192x2=64896 |
C5 | C5層的FeatureMap的神經元個數 | 13x13x128x2=43264 |
FC6 | FC6全連接層神經元個數 | 4096 |
FC7 | FC7全連接層神經元個數 | 4096 |
Output layer | 輸出層神經元個數 | 1000 |
整個AlexNet網絡包含的神經元個數為:?
290400 + 186624 + 64896 + 64896 + 43264 + 4096 + 4096 + 1000 = 659272?
大約65萬個神經元。
2.2 AlexNet參數數量
層數 | 定義 | 數量 |
C1 | 卷積核11x11x3,96個卷積核,偏置參數 | (11x11x3+1)x96=34944 |
C2 | 卷積核5x5x48,128個卷積核,2組,偏置參數 | (5x5x48+1)x128x2=307456 |
C3 | 卷積核3x3x256,384個卷積核,偏置參數 | (3x3x256+1)x384=885120 |
C4 | 卷積核3x3x192,192個卷積核,2組,偏置參數 | (3x3x192+1)x192x2=663936 |
C5 | 卷積核3x3x192,128個卷積核,2組,偏置參數 | (3x3x192+1)x128x2=442624 |
FC6 | 卷積核6x6x256,4096個神經元,偏置參數 | (6x6x256+1)x4096=37752832 |
FC7 | 全連接層,4096個神經元,偏置參數 | (4096+1)x4096=16781312 |
Output layer | 全連接層,1000個神經元 | 1000x4096=4096000 |
整個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。
層數 | 定義 | 數量 |
C1 | num_params?(H?W) | 34944x55x55=105705600 |
C2 | num_params?(H?W) | 307456x27x27=224135424 |
C3 | num_params?(H?W) | 885120x13x13=149585280 |
C4 | num_params?(H?W) | 663936x13x13=112205184 |
C5 | num_params?(H?W) | 442624x13x13=74803456 |
FC6 | num_params | 37752832 |
FC7 | num_params | 16781312 |
Output layer | num_params | 4096000 |
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(理論篇)
手撕 CNN 經典網絡之 LeNet-5(MNIST 實戰篇)
手撕 CNN 經典網絡之 LeNet-5(CIFAR10 實戰篇)
手撕 CNN 經典網絡之 LeNet-5(自定義實戰篇)
如果覺得這篇文章有用的話,麻煩點個在看或轉發朋友圈!
推薦閱讀
(點擊標題可跳轉閱讀)
干貨 | 公眾號歷史文章精選
我的深度學習入門路線
我的機器學習入門路線圖
重磅!
AI有道年度技術文章電子版PDF來啦!
掃描下方二維碼,添加?AI有道小助手微信,可申請入群,并獲得2020完整技術文章合集PDF(一定要備注:入群?+ 地點 + 學校/公司。例如:入群+上海+復旦。?
長按掃碼,申請入群
(添加人數較多,請耐心等待)
感謝你的分享,點贊,在看三連??
總結
以上是生活随笔為你收集整理的手撕 CNN 经典网络之 AlexNet(理论篇)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如果你还在徘徊在程序员的门口,那就赶紧来
- 下一篇: 如何移动当前正在使用的文件