手撕 CNN 经典网络之 VGGNet(理论篇)
2014年,牛津大學(xué)計(jì)算機(jī)視覺(jué)組(Visual Geometry Group)和Google DeepMind公司一起研發(fā)了新的卷積神經(jīng)網(wǎng)絡(luò),并命名為VGGNet。VGGNet是比AlexNet更深的深度卷積神經(jīng)網(wǎng)絡(luò),該模型獲得了2014年ILSVRC競(jìng)賽的第二名,第一名是GoogLeNet(我們之后會(huì)介紹)。
論文《Very Deep Convolutional Networks for Large-Scale Image Recognition》
論文傳送門:https://arxiv.org/abs/1409.1556
1. 網(wǎng)絡(luò)結(jié)構(gòu)
VGG 的結(jié)構(gòu)與 AlexNet 類似,區(qū)別是深度更深,但形式上更加簡(jiǎn)單。VGG由5層卷積層、3層全連接層、1層softmax輸出層構(gòu)成,層與層之間使用maxpool(最大化池)分開,所有隱藏層的激活單元都采用ReLU函數(shù)。作者在原論文中,根據(jù)卷積層不同的子層數(shù)量,設(shè)計(jì)了A、A-LRN、B、C、D、E這6種網(wǎng)絡(luò)結(jié)構(gòu)。
這6種網(wǎng)絡(luò)結(jié)構(gòu)相似,都是由5層卷積層、3層全連接層組成,區(qū)別在于每個(gè)卷積層的子層數(shù)量不同,從A至E依次增加,總的網(wǎng)絡(luò)深度從11層到19層。表格中的卷積層參數(shù)表示為“conv(感受野大小)-通道數(shù)”,例如con3-64,表示使用3x3的卷積核,通道數(shù)為64;最大池化表示為maxpool,層與層之間使用maxpool分開;全連接層表示為“FC-神經(jīng)元個(gè)數(shù)”,例如FC-4096表示包含4096個(gè)神經(jīng)元的全連接層;最后是softmax層。
其中,D表示著名的VGG16,E表示著名的VGG19。下面以VGG16為例,來(lái)詳細(xì)剖析一下VGG的網(wǎng)絡(luò)結(jié)構(gòu)。VGG16的結(jié)構(gòu)如下圖所示:
VGG16總共包含16個(gè)子層,第1層卷積層由2個(gè)conv3-64組成,第2層卷積層由2個(gè)conv3-128組成,第3層卷積層由3個(gè)conv3-256組成,第4層卷積層由3個(gè)conv3-512組成,第5層卷積層由3個(gè)conv3-512組成,然后是2個(gè)FC4096,1個(gè)FC1000。總共16層,這也就是VGG16名字的由來(lái)。
1.1 輸入層
VGG輸入圖片的尺寸是224x224x3。
1.2 第1層卷積層
第1層卷積層由2個(gè)conv3-64組成。
該層的處理流程是:卷積-->ReLU--> 卷積-->ReLU-->池化。
卷積:輸入是224x224x3,使用64個(gè)3x3x3的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(224+2*1-3)/1+1=224
得到輸出是224x224x64。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
卷積:輸入是224x224x64,使用64個(gè)3x3x64的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(224+2*1-3)/1+1=224
得到輸出是224x224x64。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
池化:使用2x2,stride=2的池化單元進(jìn)行最大池化操作(max pooling)。根據(jù)公式:
(224+2*0-2)/2+1=112
每組得到的輸出為112x112x64。
1.3 第2層卷積層
第2層卷積層由2個(gè)conv3-128組成。
該層的處理流程是:卷積-->ReLU--> 卷積-->ReLU-->池化。
卷積:輸入是112x112x64,使用128個(gè)3x3x64的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(112+2*1-3)/1+1=112
得到輸出是112x112x128。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
卷積:輸入是112x112x128,使用128個(gè)3x3x128的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(112+2*1-3)/1+1=112
得到輸出是112x112x128。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
池化:使用2x2,stride=2的池化單元進(jìn)行最大池化操作(max pooling)。根據(jù)公式:
(112+2*0-2)/2+1=56
每組得到的輸出為56x56x128。
1.4 第3層卷積層
第3層卷積層由3個(gè)conv3-256組成。
該層的處理流程是:卷積-->ReLU--> 卷積-->ReLU-->池化。
卷積:輸入是56x56x128,使用256個(gè)3x3x128的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(56+2*1-3)/1+1=56
得到輸出是56x56x256。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
卷積:輸入是56x56x256,使用256個(gè)3x3x256的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(56+2*1-3)/1+1=56
得到輸出是56x56x256。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
池化:使用2x2,stride=2的池化單元進(jìn)行最大池化操作(max pooling)。根據(jù)公式:
(56+2*0-2)/2+1=28
每組得到的輸出為28x28x256。
1.5 第4層卷積層
第4層卷積層由3個(gè)conv3-512組成。
該層的處理流程是:卷積-->ReLU--> 卷積-->ReLU-->池化。
卷積:輸入是28x28x256,使用512個(gè)3x3x256的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(28+2*1-3)/1+1=28
得到輸出是28x28x512。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
卷積:輸入是28x28x512,使用512個(gè)3x3x512的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(28+2*1-3)/1+1=28
得到輸出是28x28x512。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
池化:使用2x2,stride=2的池化單元進(jìn)行最大池化操作(max pooling)。根據(jù)公式:
(28+2*0-2)/2+1=14
每組得到的輸出為14x14x512。
1.6 第5層卷積層
第5層卷積層由3個(gè)conv3-512組成。
該層的處理流程是:卷積-->ReLU--> 卷積-->ReLU-->池化。
卷積:輸入是14x14x512,使用512個(gè)3x3x512的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(14+2*1-3)/1+1=14
得到輸出是14x14x512。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
卷積:輸入是14x14x512,使用512個(gè)3x3x512的卷積核進(jìn)行卷積,padding=1,stride=1,根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(14+2*1-3)/1+1=14
得到輸出是14x14x512。
ReLU:將卷積層輸出的FeatureMap輸入到ReLU函數(shù)中。
池化:使用2x2,stride=2的池化單元進(jìn)行最大池化操作(max pooling)。根據(jù)公式:
(14+2*0-2)/2+1=7
每組得到的輸出為7x7x512。
1.7 第1層全連接層
第1層全連接層FC4096由4096個(gè)神經(jīng)元組成。
該層的處理流程是:FC-->ReLU-->Dropout。
FC:輸入是7x7x512的FeatureMap,展開為7*7*512的一維向量,即7*7*512個(gè)神經(jīng)元,輸出為4096個(gè)神經(jīng)元。
ReLU:這4096個(gè)神經(jīng)元的運(yùn)算結(jié)果通過(guò)ReLU激活函數(shù)中。
Dropout:隨機(jī)的斷開全連接層某些神經(jīng)元的連接,通過(guò)不激活某些神經(jīng)元的方式防止過(guò)擬合。
1.8 第2層全連接層
第2層全連接層FC4096由4096個(gè)神經(jīng)元組成。
該層的處理流程是:FC-->ReLU-->Dropout。
FC:輸入是4096個(gè)神經(jīng)元,輸出為4096個(gè)神經(jīng)元。
ReLU:這4096個(gè)神經(jīng)元的運(yùn)算結(jié)果通過(guò)ReLU激活函數(shù)中。
Dropout:隨機(jī)的斷開全連接層某些神經(jīng)元的連接,通過(guò)不激活某些神經(jīng)元的方式防止過(guò)擬合。
1.9 第3層全連接層
第3層全連接層FC1000由1000個(gè)神經(jīng)元組成,對(duì)應(yīng)ImageNet數(shù)據(jù)集的1000個(gè)類別。
該層的處理流程是:FC。
FC:輸入是4096個(gè)神經(jīng)元,輸出為1000個(gè)神經(jīng)元。
1.10 softmax層
該層的流程為:Softmax
Softmax:這1000個(gè)神經(jīng)元的運(yùn)算結(jié)果通過(guò)Softmax函數(shù)中,輸出1000個(gè)類別對(duì)應(yīng)的預(yù)測(cè)概率值。
2. 全卷積網(wǎng)絡(luò)
接著對(duì)1.7、1.8、1.9節(jié)的內(nèi)容進(jìn)行介紹。這三節(jié)講的是全連接網(wǎng)絡(luò),VGG16在訓(xùn)練的時(shí)候使用的是全連接網(wǎng)絡(luò)。然而在測(cè)試驗(yàn)證階段,網(wǎng)絡(luò)結(jié)構(gòu)稍有不同,作者將全連接全部替換為卷積網(wǎng)絡(luò)。
先介紹做法!
2.1 第1層全連接層
輸入為7x7x512的FeatureMap,使用4096個(gè)7x7x512的卷積核進(jìn)行卷積,由于卷積核尺寸與輸入的尺寸完全相同,即卷積核中的每個(gè)系數(shù)只與輸入尺寸的一個(gè)像素值相乘一一對(duì)應(yīng),根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(7+2*0-7)/1+1=1
得到輸出是1x1x4096。相當(dāng)于4096個(gè)神經(jīng)元,但屬于卷積層。
2.2 第2層全連接層
輸入為1x1x4096的FeatureMap,使用4096個(gè)1x1x4096的卷積核進(jìn)行卷積,由于卷積核尺寸與輸入的尺寸完全相同,即卷積核中的每個(gè)系數(shù)只與輸入尺寸的一個(gè)像素值相乘一一對(duì)應(yīng),根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(1+2*0-1)/1+1=1
得到輸出是1x1x4096。相當(dāng)于4096個(gè)神經(jīng)元,屬于卷積層。
2.3 第2層全連接層
輸入為1x1x4096的FeatureMap,使用1000個(gè)1x1x4096的卷積核進(jìn)行卷積,由于卷積核尺寸與輸入的尺寸完全相同,即卷積核中的每個(gè)系數(shù)只與輸入尺寸的一個(gè)像素值相乘一一對(duì)應(yīng),根據(jù)公式:
(input_size + 2 * padding - kernel_size) / stride + 1=(1+2*0-1)/1+1=1
得到輸出是1x1x1000。相當(dāng)于1000個(gè)神經(jīng)元,屬于卷積層。
得到1x1x1000的輸出之后,最后經(jīng)過(guò)softmax層進(jìn)行預(yù)測(cè)類別。
2.4 為什么要將全連接層轉(zhuǎn)變?yōu)槿矸e層?
作者將三個(gè)全連接層轉(zhuǎn)成了1個(gè)7×7,和 2 個(gè) 1×1 的卷積層。從下圖可以看到,以第一個(gè)全連接層為例,要轉(zhuǎn)卷積層,FC6的輸入是 7×7×512,輸出是4096(也可以看做 1×1×4096),那么就要對(duì)輸入在尺寸上(寬高)降維(從7×7 降到 1×1)和深度(channel 或者 depth)升維(從512 升到4096)。把7×7降到1×1,使用大小為 7×7的卷積核就好了,卷積核個(gè)數(shù)設(shè)置為4096,即卷積核為7×7×4096(下圖中的[7×7×512]×4096 表示有 4096 個(gè) [7×7×512] 這樣的卷積核,7×7×4096 是簡(jiǎn)寫形式忽略了輸入的深度),經(jīng)過(guò)對(duì)輸入卷積就得到了最終的 1×1×4096 大小的 feature map。
為什么要在模型測(cè)試的時(shí)候?qū)⑷B接層轉(zhuǎn)變?yōu)槿矸e層呢?最直接的原因是讓網(wǎng)絡(luò)模型可以接受任意大小的尺寸。
我們?cè)谇懊娼榻B的時(shí)候限定了網(wǎng)絡(luò)輸入圖片的尺寸是224x224x3。如果后面三個(gè)層都是全連接,遇到寬高大于224的圖片就需要進(jìn)行圖片的剪裁、縮放或其它處理,使圖片尺寸統(tǒng)一到224x224x3,才能符合后面全連接層的輸入要求。但是,我們并不能保證每次裁剪都能將圖片中的關(guān)鍵目標(biāo)保留下來(lái),可能裁剪去的部分恰好包含了目標(biāo),造成裁減丟失關(guān)鍵目標(biāo)信息,影響模型的測(cè)試精度。
(輸出是一個(gè)分類得分圖,通道的數(shù)量和類別的數(shù)量相同,空間分辨率依賴于輸入圖像尺寸。最終為了得到固定尺寸的分類得分向量,將分類得分圖進(jìn)行空間平均化(求和——池化)。我們同樣使用水平翻轉(zhuǎn)來(lái)對(duì)測(cè)試集進(jìn)行數(shù)據(jù)增強(qiáng);在原始圖像和翻轉(zhuǎn)圖像上的soft-max分類概率的平均值作為這幅圖像的最終得分。)
使用全卷積層,即使圖片尺寸大于224x224x3,最終經(jīng)過(guò)softmax層得到的得分圖就不是1x1x1000,例如是2x2x1000,這里的通道1000與類別的數(shù)量相同,空間分辨率2x2依賴于輸入圖像尺寸。然后將得分圖進(jìn)行空間平均化(求和池化),得到的還是1x1x1000。最后對(duì)1000個(gè)通道的得分進(jìn)行比較,取較大值作為預(yù)測(cè)類別。
這樣做的好處就是大大減少特征位置對(duì)分類帶來(lái)的影響。
舉個(gè)簡(jiǎn)單的例子:
從上圖我們可以看出,貓?jiān)谠瓐D片中不同的位置,如果使用全連接層很容易使得剪裁之后的圖片丟失關(guān)鍵目標(biāo)。然而使用全卷積層,對(duì)原圖片直接進(jìn)行卷積,最終得分圖經(jīng)過(guò)求和池化后得到的得分都是1,即不管貓?jiān)趫D片的什么位置,都能判定這張圖片中有貓,保證分類正確。保留原圖,使用全卷積層,相當(dāng)于貓?jiān)谀奈也还?#xff0c;我只要貓,于是我讓模型去把這個(gè)貓找到,實(shí)際就是把feature map整合成一個(gè)值,這個(gè)值大,就有貓,這個(gè)值小,那就可能沒(méi)貓!和這個(gè)貓?jiān)趫D片哪里關(guān)系不大了,魯棒性大大增強(qiáng)。
3. VGG網(wǎng)絡(luò)特點(diǎn)
3.1 結(jié)構(gòu)簡(jiǎn)潔
雖然VGG層數(shù)較多,總的網(wǎng)絡(luò)深度從11層到19層,但是它的整體結(jié)構(gòu)還是相對(duì)簡(jiǎn)單。概括來(lái)說(shuō),VGG由5層卷積層(每個(gè)卷積層的子層數(shù)量不同)、3層全連接層、softmax輸出層構(gòu)成,層與層之間使用maxpooling(最大化池)分開,所有隱層的激活單元都采用ReLU函數(shù)。
3.2 小卷積核
小卷積核是VGG的一個(gè)重要特點(diǎn),VGG沒(méi)有采用AlexNet中比較大的卷積核尺寸(如7x7),而是通過(guò)降低卷積核的大小(3x3),增加卷積子層數(shù)來(lái)達(dá)到同樣的性能(VGG:從1到4卷積子層,AlexNet:1子層)。
VGG使用多個(gè)較小卷積核(3x3)的卷積層代替一個(gè)卷積核較大的卷積層,VGG作者認(rèn)為兩個(gè)3x3的卷積堆疊獲得的感受野大小,相當(dāng)一個(gè)5x5的卷積;而3個(gè)3x3卷積的堆疊獲取到的感受野相當(dāng)于一個(gè)7x7的卷積。示意圖如下所示:
使用3x3小卷積核的好處有兩個(gè)方面:
一是大幅度減少模型參數(shù)數(shù)量。例如使用2個(gè)3x3的卷積核代替1個(gè)5x5的卷積核,通道數(shù)為C,1個(gè)5x5的卷積核參數(shù)量為5*5*C,2個(gè)3x3的卷積核參數(shù)量為2*3*3*C,參數(shù)兩減小了28%。另外,小卷積核選取小的 stride可以防止較大的stride導(dǎo)致細(xì)節(jié)信息的丟失。
二是多層卷積層(每個(gè)卷積層后都有非線性激活函數(shù)),增加非線性,提升模型性能。
此外,我們注意到在VGG網(wǎng)絡(luò)結(jié)構(gòu)D中,還使用了1x1卷積核,1x1卷積核可以在不改變感受野的情況下,增加模型的非線性(后面的非線性激活函數(shù))。同時(shí),還可以用它來(lái)整合各通道的信息,并輸出指定通道數(shù)。通道數(shù)減小即降維,通道數(shù)增加即升維。
3.3 小池化核
相比AlexNet的3x3的池化核,VGG全部采用2x2的池化核。
3.4 通道數(shù)更多,特征度更寬
每個(gè)通道代表著一個(gè)FeatureMap,更多的通道數(shù)表示更豐富的圖像特征。VGG網(wǎng)絡(luò)第一層的通道數(shù)為64,后面每層都進(jìn)行了翻倍,最多到512個(gè)通道,通道數(shù)的增加,使得更多的信息可以被提取出來(lái)。
3.5 層數(shù)更深
使用連續(xù)的3x3小卷積核代替大的卷積核,網(wǎng)絡(luò)的深度更深,并且對(duì)邊緣進(jìn)行填充,卷積的過(guò)程并不會(huì)減小圖像尺寸。僅使用小的2x2池化單元,減小圖像的尺寸。
3.6 全連接轉(zhuǎn)卷積
這部分內(nèi)容在全卷積網(wǎng)絡(luò)已經(jīng)介紹過(guò)了。
3.7 模型參數(shù)
A、A-LRN、B、C、D、E這6種網(wǎng)絡(luò)結(jié)構(gòu)的深度雖然從11層增加至19層,但參數(shù)量變化不大,這是由于基本上都是采用了小卷積核,參數(shù)主要集中在全連接層。
3.8 其他
A-LRN網(wǎng)絡(luò)結(jié)構(gòu)使用了LRN層(local response normalization,局部響應(yīng)歸一化),這在AlexNet網(wǎng)絡(luò)中也使用過(guò)。但是作者實(shí)驗(yàn)發(fā)現(xiàn)使用LRN并沒(méi)有帶來(lái)性能的提升,因此在其它組的網(wǎng)絡(luò)中均沒(méi)再出現(xiàn)LRN層。
從11層的A到19層的E,網(wǎng)絡(luò)深度增加對(duì)top1和top5的錯(cuò)誤率下降很明顯。
VGG作者用B網(wǎng)絡(luò)和一個(gè)較淺網(wǎng)絡(luò)比較,較淺網(wǎng)絡(luò)用1個(gè)5x5卷積核來(lái)代替B的2個(gè)3x3卷積核,結(jié)果顯示多個(gè)小卷積核比單個(gè)大卷積核效果要好。
關(guān)于VGG的更多細(xì)節(jié)和實(shí)驗(yàn)對(duì)比結(jié)果,建議大家直接看原論文!
手撕 CNN 系列:
手撕 CNN 經(jīng)典網(wǎng)絡(luò)之 LeNet-5(理論篇)
手撕 CNN 經(jīng)典網(wǎng)絡(luò)之 LeNet-5(MNIST 實(shí)戰(zhàn)篇)
手撕 CNN 經(jīng)典網(wǎng)絡(luò)之 LeNet-5(CIFAR10 實(shí)戰(zhàn)篇)
手撕 CNN 經(jīng)典網(wǎng)絡(luò)之 LeNet-5(自定義實(shí)戰(zhàn)篇)
手撕 CNN 經(jīng)典網(wǎng)絡(luò)之 AlexNet(理論篇)
手撕 CNN 經(jīng)典網(wǎng)絡(luò)之 AlexNet(PyTorch 實(shí)戰(zhàn)篇)
如果覺(jué)得這篇文章有用的話,麻煩點(diǎn)個(gè)在看或轉(zhuǎn)發(fā)朋友圈!
推薦閱讀
(點(diǎn)擊標(biāo)題可跳轉(zhuǎn)閱讀)
干貨 | 公眾號(hào)歷史文章精選
我的深度學(xué)習(xí)入門路線
我的機(jī)器學(xué)習(xí)入門路線圖
重磅!
AI有道年度技術(shù)文章電子版PDF來(lái)啦!
掃描下方二維碼,添加?AI有道小助手微信,可申請(qǐng)入群,并獲得2020完整技術(shù)文章合集PDF(一定要備注:入群?+ 地點(diǎn) + 學(xué)校/公司。例如:入群+上海+復(fù)旦。?
長(zhǎng)按掃碼,申請(qǐng)入群
(添加人數(shù)較多,請(qǐng)耐心等待)
感謝你的分享,點(diǎn)贊,在看三連??
總結(jié)
以上是生活随笔為你收集整理的手撕 CNN 经典网络之 VGGNet(理论篇)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何零基础开始自学Python编程,值得
- 下一篇: 手撕 CNN 经典网络之 VGGNet(