卷積神經網絡 CNN 經典模型 — LeNet、AlexNet、VGG、NiN with Pytorch code
卷積神經網絡 (Convolutional Neural Network) 在電腦視覺中佔有非常重要的地位,在影像辨識上的精準度可以達到超過人類的水準,是目前深度學習發展的一大主力
本文要來介紹 CNN 的經典模型 LeNet、AlexNet、VGG、NiN,並使用 Pytorch 實現。其中 LeNet 使用 MNIST 手寫數字圖像作為訓練集,而其餘的模型則是使用 Kaggle 的貓狗圖像
所有的 code 都放在我的 Github 裡
LeNet (1998)
論文連接: http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf
官網: http://yann.lecun.com/exdb/lenet/
Github: https://github.com/feiyuhug/lenet-5
LeNet 是由 Yann LeCun 團隊提出的網路架構,是卷積神經網路的始祖。其架構由兩個卷積層、池化層、全連接層以及最後一層 Gaussian 連接層所組成,早期用來辨識手寫數字圖像
由下圖可以看到 LeNet 的網路架構共有七層:卷積層 (Convolutions, C1)、池化層 (Subsampling, S2)、卷積層 (C3)、池化層 (S4)、全連接卷積層 (C5)、全連接層 (F6)、Gaussian 連接層 (output)
輸入層是一個 28x28 的一維影像,而 Filter size 皆為 5x5,第一個 Filter 與第二個 Filter 的輸出通道分別為 6、16,並且皆使用 Sigmoid 作為激活函數。
池化層的窗口為 2x2,stride 為 2,使用平均池化進行採樣。最後的全連接層的神經元數量分別是 120、84 個。
最後一層輸出層是 Gaussian連接層,採用 RBF 函數 (徑向歐式距離函數),計算輸入向量和參數向量之間的歐式距離。因為 LeNet 應用於辨識手寫圖像,數字為0~9,所以輸出層為 10 個神經元
接著來看一下 LeNet code 吧~
AlexNet (2012)
Alex Krizhevsky 於 2012 年提出卷積神經網路 AlexNet,並在同年的 ImageNet LSVRC 競賽中奪得了冠軍 (Top-5 錯誤率為 15.3%),並且準確率遠超過第二名 (Top-5 錯誤率為 26.2%),造成了很大的轟動,至此 CNN 開始廣泛被研究
在 AlexNet 出現之前,深度學習沉寂了一段時間。這是因為 LeNet 在早期的小數據集上可以取得好的成績,但在更大的數據集的表現卻不如人意,因此許多人改鑽研其他的機器學習方法。而 AlexNet 的出現,可以說是時代的分水嶺,正式開啟了 CNN 的時代
AlexNet 的架構有八層,共使用五個卷積層、三個全連接層,相較於 LeNet 模型更深,下圖是 AlexNet 的網路架構
AlexNet 為何如此成功? 以下來介紹 AlexNet的特點
1. 模型架構:第一層到第五層是卷積層,其中第一、第二和第五個卷積層後使用池化層,並且採用大小為 3x3、stride 為2 的 Maxpooling。比 LeNet 使用的平均池化,更能保留重要的特徵,並且因為 stride < size (2<3),因此pooling 可以重疊 (overlap),能重複檢視特徵,避免重要的特徵被捨棄掉,同時避免過擬合的問題。第六到第八層則是全連接層
2. 輸入層尺寸:將輸入層變大,可以輸入224x224 尺寸的彩色圖片
3. 卷積核尺寸 (kernel size):由於輸入層變大,所以將第一層的kernel 設定為 11x11、stride 為4,擴大感受野,並且也使用較大的步長 (stride) 萃取特徵;第二層的 kernel 則使用 5x5,然後之後的 kernel 皆使用 3x3,stride 都設定為1
4. 激活函數:將 LeNet 使用的 Sigmoid 改為 ReLU,可以避免因為神經網路層數過深或是梯度過小,而導致梯度消失 (Vanishing gradient) 的問題
並且相較於早期使用的 Sigmoid/Tanh,ReLU 收斂速度較快。下圖是論文比較 ReLU 和 Tanh 的收斂速度
5. 降低 overfitting 的方法:採用了 Dropout 以及資料擴增 (Data augmentation)
📚 Dropout
Dropout 是指在每一次訓練時,隨機選取神經元使其不參與訓練,如此一來可以讓模型不過度依賴某些特徵,進而增強模型的泛化能力 (generalization)
AlexNet 在第六、第七層全連接層中加入了 Dropout ,設定為 0.5
📚 Data augmentation
為了提升演算法的準確率,增加訓練資料集是一個很有效的方式。資料擴增就是從既有的訓練資料集中利用一些變換去生成一些新的資料,以快速地擴充訓練資料
AlexNet 的處理方式有兩種:
🔹 隨機裁減 將 256x256 的圖片進行隨機裁減至 224x224,然後進行水平翻轉,這樣的做法可以增加 2*[ (256–224)**2] = 2048 倍
🔹 對 RGB 通道做主成分分析 (PCA),接著使用高斯擾動,對顏色、光照做變換
6. 使用 GPU
AlexNet 使用了兩塊 GTX580 GPU 做訓練,由於單個 GTX580 GPU 只有 3 GB 的記憶體,無法負荷如此大量的運算,因此將神經網路分布於兩塊 GPU 上平行運算,大幅的加快了訓練速度
哈哈說了這麼多,接下來就來看一下 AlexNet code 吧!
VGG (2014)
論文連接: https://arxiv.org/pdf/1409.1556.pdf
VGGNet 在 2014 年由牛津大學 Visual Geometry Group 提出,並在 ImageNet LSVRC 的分類競賽中獲得了第二名 (第一名是 GooLeNet)
VGGNet 比起 AlexNet 採用更深層的網路,特點是重複採用同一組基礎模組,並改用小卷積核替代 AlexNet 裡的中大型卷積核,其架構由 n 個 VGG Block 與3個全連接層所組成
- VGG Block
VGG Block 的構造就是由不同數量 (數量為超參數) 的 3x3 卷積層 (kernel size=3x3, stride=1, padding=”same”),以及 2x2 的 Maxpooling 組成 (pool size=2, stride=2)
🔹 padding=”same” 會保持 feature map 的尺寸跟原輸入一樣
- 採用小卷積核代替大卷積核
VGG 使用多個小卷積核 3x3 來代替 AlexNet 的中大型卷積核 (5x5),這樣的作法可以達到相同的感受野,同時減少參數量
由下圖可以看出使用兩個 3x3 卷積層可以達到與 5x5 的卷積層相同的感受野,5x5 的卷積層的訓練參數量為 5x5=25,而 3x3 的卷積層所需要的參數量更少,只需要 3x3x2=18 個參數量 (不考慮 bias)
VGGNet 有許多不同的結構,例如 VGG11, VGG13, VGG16, VGG19,其差異在於網路的層數 (卷積層數量與全連接層數量)。常見的 VGGNet 指的是 VGG16,其架構使用了五個卷積層與三個全連接層,其中前兩個卷積層內含 2 個基礎模組、後三個卷積層內含 3 個基礎模組,總共為 2x2 + 3x3 + 3 = 16 層網路層數
在這邊就先示範 VGG16 code
Network in Network (2014)
論文連接: https://arxiv.org/pdf/1312.4400.pdf
NiN 是2014 年提出的,比起 AlexNet 使用更少的參數量,卻達到更高的準確率。作者認為一般要提取的特徵是高度非線性的,因此在每個局部感受野中加入更複雜的神經網路來運算,提出了 MLP 卷積層 (Mlpconv)
- MLP 卷積層 (Mlpconv)
Mlpconv 就是指將 CNN 縮小成一個小型網路包含於每個卷積的局部感受野中,這也呼應了網路本身的名字 Network in Network (網路中的網路)!
由下圖可以看到線性卷積層跟 Mlpconv 的差別
那 Mlpconv 是由什麼組成的呢?
其公式如下,第一層為一般的卷積運算,接下來就是由前一層的參數去混合加權運算,等同於一個 1x1 的卷積運算,而該篇論文是首次提出 1x1 卷積層的論文
因此 Mlpconv 的架構就是一個卷積層後接兩個 1x1 的卷積層
而這些層各別的作用是什麼?
第一層的卷積層是用來進行空間特徵的萃取,其卷積核大小類似 AlexNet,第一個 Mlpconv 使用 11x11,第二個 Mlpconv 使用 5x5,第三個 Mlpconv 使用 3x3 (NiN 使用了三個 Mlpconv)
第二、第三層的 1x1 卷積層是用來實現跨通道的特徵訊息整合,同時降低訓練參數量
📚 1x1 卷積層除了將不同通道同一位置的資訊進行整合外,還可以實現通道的降維或升維。由下圖可以看出原本的輸入通道為 192,經過 1x1 卷積層後,輸出通道變為 1
NiN 是由三個 Mlpconv 與一個全局平均池化層 (Global Average Pooling) 組成,其中每個 Mlpconv 後會接一個 Maxpooling。下圖為其網路架構
- Global Average Pooling
NiN 使用 GAP 代替全連接層,能夠大幅降低參數量,也能避免過擬和的問題
下圖為使用全連接層跟 GAP 的比較圖,兩者的輸出會是一樣的
最後來看 NiN code 吧! param 是指各個 Mlpconv 的參數 in_channels, out_channels, kernel_size, padding, stride
本文的 CNN 經典模型就介紹到這邊,下篇文會再介紹其他的 CNN 經典模型 GoogleLeNet、ResNet、DenseNet