深度學習第18講:CNN經典論文研讀之VGG網路及其tensorflow實現
在前兩期的論文研讀中,筆者和大家一起學習了 LeNet-5 和 AlexNet 這兩個經典的卷積神經網路結構和基本實現方式。今天我們繼續 CNN 經典論文研讀之路——VGGNet。VGGNet 是牛津大學計算機視覺組(Visual Geometry Group)和谷歌 DeepMind 一起研究出來的深度卷積神經網路,因而冠名為 VGG。在2014年的 ILSVRC 中取得了第二名的成績,可能你會問這麼厲害的網路為什麼不是第一名,因為當年實際提交 VGG 版本時作者並未作進一步的優化,而當年的第一名則是我們後面要繼續研讀的 Google Inception Net。

相較於之前的 LeNet-5 和 AlexNet,VGGNet 結構中大量使用 3x3 的卷積核和 2x2 的池化核,首次將卷積神經網路的卷積深度推向更深,最為典型的 VGGNet 是 VGG16 和 VGG19,其中的 16 的含義即網路中包含16個卷積層和全連線層, 19即即網路中包含19個卷積層和全連線層。VGGNet 的網路雖然開始加深但其結構並不複雜,但作者的實踐卻證明了卷積網路深度的重要性。深度卷積網路能夠提取影象低層次、中層次和高層次的特徵,因而網路結構需要的一定的深度來提取影象不同層次的特徵。
VGG的網路結構
在論文中,作者使用了 A-E 五個不同深度水平的卷積網路進行試驗,從A到E網路深度不斷加深:

各結構網路所含訓練引數:

其中 D 和 E 即我們常說的 VGG16 和 VGG19。可以看到 VGG16 網路需要訓練的引數數量達到了 1.38 億個,這個數量是巨大的。我們以 VGG16 為例簡單探究一下它的網路結構。
VGG16 各層的結構和引數如下:
C1-1層是個卷積層,其輸入輸出結構如下:
輸入: 224 x 224 x 3 濾波器大小: 3 x 3 x 3 濾波器個數:64
輸出: 224 x 224 x 64
C1-2層是個卷積層,其輸入輸出結構如下:
輸入: 224 x 224 x 3 濾波器大小: 3 x 3 x 3 濾波器個數:64
輸出: 224 x 224 x 64
P1層是C1-2後面的池化層,其輸入輸出結構如下:
輸入: 224 x 224 x 64 濾波器大小: 2 x 2 濾波器個數:64
輸出: 112 x 112 x 64
C2-1層是個卷積層,其輸入輸出結構如下:
輸入: 112 x 112 x 64 濾波器大小: 3 x 3 x 64 濾波器個數:128
輸出: 112 x 112 x 128
C2-2層是個卷積層,其輸入輸出結構如下:
輸入: 112 x 112 x 64 濾波器大小: 3 x 3 x 64 濾波器個數:128
輸出: 112 x 112 x 128
P2層是C2-2後面的池化層,其輸入輸出結構如下:
輸入: 112 x 112 x 128 濾波器大小: 2 x 2 濾波器個數:128
輸出: 56 x 56 x 128
C3-1層是個卷積層,其輸入輸出結構如下:
輸入: 56 x 56 x 128 濾波器大小: 3 x 3 x 128 濾波器個數:256
輸出: 56 x 56 x 256
C3-2層是個卷積層,其輸入輸出結構如下:
輸入: 56 x 56 x 256 濾波器大小: 3 x 3 x 256 濾波器個數:256
輸出: 56 x 56 x 256
C3-3層是個卷積層,其輸入輸出結構如下:
輸入: 56 x 56 x 256 濾波器大小: 3 x 3 x 256 濾波器個數:256
輸出: 56 x 56 x 256
P3層是C3-3後面的池化層,其輸入輸出結構如下:
輸入: 56 x 56 x 256 濾波器大小: 2 x 2 濾波器個數:256
輸出: 28 x 28 x 256
C4-1層是個卷積層,其輸入輸出結構如下:
輸入: 28 x 28 x 256 濾波器大小: 3 x 3 x 256 濾波器個數:512
輸出: 28 x 28 x 512
C4-2層是個卷積層,其輸入輸出結構如下:
輸入: 28 x 28 x 512 濾波器大小: 3 x 3 x 256 濾波器個數:512
輸出: 28 x 28 x 512
C4-3層是個卷積層,其輸入輸出結構如下:
輸入: 28 x 28 x 512 濾波器大小: 3 x 3 x 256 濾波器個數:512
輸出: 28 x 28 x 512
P4層是C4-3後面的池化層,其輸入輸出結構如下:
輸入: 28 x 28 x 512 濾波器大小: 2 x 2 濾波器個數:512
輸出: 14 x 14 x 512
C5-1層是個卷積層,其輸入輸出結構如下:
輸入: 14 x 14 x 512 濾波器大小: 3 x 3 x 512 濾波器個數:512
輸出: 14 x 14 x 512
C5-2層是個卷積層,其輸入輸出結構如下:
輸入: 14 x 14 x 512 濾波器大小: 3 x 3 x 512 濾波器個數:512
輸出: 14 x 14 x 512
C5-3層是個卷積層,其輸入輸出結構如下:
輸入: 14 x 14 x 512 濾波器大小: 3 x 3 x 512 濾波器個數:512
輸出: 14 x 14 x 512
P5層是C5-3後面的池化層,其輸入輸出結構如下:
輸入: 14 x 14 x 512 濾波器大小: 2 x 2 濾波器個數:512
輸出: 7 x 7 x 512
F6層是個全連線層,其輸入輸出結構如下:
輸入:4096
輸出:4096
F7層是個全連線層,其輸入輸出結構如下:
輸入:4096
輸出:4096
F8層也是個全連線層,即輸出層,其輸入輸出結構如下:
輸入:4096
輸出:1000
大致過程如 NG 老師的演示圖:

從上述的 VGG 結構分析中,我們可以看到這種網路結構非常規整,2-2-3-3-3的卷積結構也非常利於程式設計實現。卷積層的濾波器數量的變化也存在明顯的規律,由64到128再到256和512,每一次卷積都是畫素成規律的減少和通道數成規律的增加。
VGG16 的簡單實現
原本自己利用 Tensoflow 簡單寫了個 VGG16 的網路結構,但去谷歌一搜發現別人的程式碼寫的實在太好了,以至於這裡就不用自己程式碼展示 VGG16 了。編寫的思路無非就是定義卷積過程、池化過程和全連線過程,然後將其封裝到 VGG16 的模型函式中去,其中注意一些編寫細節即可。
筆者自己寫的部分程式碼截圖:

GitHub 上大佬的開源實現:
https://gist.github.com/ksimonyan/211839e770f7b538e2d8#file-readme-md