Simonyan, Karen, and Andrew Zisserman. “Very deep convolutional networks for large-scale image recognition.” arXiv preprint arXiv:1409.1556 (2014).
論文下載地址:https://arxiv.org/pdf/1409.1556.pdf
這篇文章是以比賽為目的——解決ImageNet中的1000類圖像分類和定位問題。在此過程中,作者做了六組實(shí)驗(yàn),對(duì)應(yīng)6個(gè)不同的網(wǎng)絡(luò)模型,這六個(gè)網(wǎng)絡(luò)深度逐漸遞增的同時(shí),也有各自的特點(diǎn)。實(shí)驗(yàn)表明最后兩組,即深度最深的兩組16和19層的VGGNet網(wǎng)絡(luò)模型在分類和定位任務(wù)上的效果最好。作者因此斬獲2014年分類第二(第一是GoogLeNet),定位任務(wù)第一。
其中,模型的名稱——“VGG”代表了牛津大學(xué)的Oxford Visual Geometry Group,該小組隸屬于1985年成立的Robotics Research Group,該Group研究范圍包括了機(jī)器學(xué)習(xí)到移動(dòng)機(jī)器人。下面是一段來自知乎對(duì)同年GoogLeNet和VGG的描述:
GoogLeNet和VGG的Classification模型從原理上并沒有與傳統(tǒng)的CNN模型有太大不同。大家所用的Pipeline也都是:訓(xùn)練時(shí)候:各種數(shù)據(jù)Augmentation(剪裁,不同大小,調(diào)亮度,飽和度,對(duì)比度,偏色),剪裁送入CNN模型,Softmax,Backprop。測(cè)試時(shí)候:盡量把測(cè)試數(shù)據(jù)又各種Augmenting(剪裁,不同大小),把測(cè)試數(shù)據(jù)各種Augmenting后在訓(xùn)練的不同模型上的結(jié)果再繼續(xù)Averaging出最后的結(jié)果。
需要注意的是,在VGGNet的6組實(shí)驗(yàn)中,后面的4個(gè)網(wǎng)絡(luò)均使用了pre-trained model A的某些層來做參數(shù)初始化。雖然作者沒有提該方法帶來的性能增益,但我認(rèn)為是很大的。不過既然是開篇,先來看看VGG的特點(diǎn):
- 小卷積核。作者將卷積核全部替換為3x3(極少用了1x1);
- 小池化核。相比AlexNet的3x3的池化核,VGG全部為2x2的池化核;
- 層數(shù)更深特征圖更寬。基于前兩點(diǎn)外,由于卷積核專注于擴(kuò)大通道數(shù)、池化專注于縮小寬和高,使得模型架構(gòu)上更深更寬的同時(shí),計(jì)算量的增加放緩;
- 全連接轉(zhuǎn)卷積。網(wǎng)絡(luò)測(cè)試階段將訓(xùn)練階段的三個(gè)全連接替換為三個(gè)卷積,測(cè)試重用訓(xùn)練時(shí)的參數(shù),使得測(cè)試得到的全卷積網(wǎng)絡(luò)因?yàn)闆]有全連接的限制,因而可以接收任意寬或高為的輸入。
最后我會(huì)再次引用CS231n對(duì)于VGG的中肯評(píng)價(jià)進(jìn)行總結(jié),不過還是先從當(dāng)時(shí)的任務(wù)和歷史背景開始說明。
任務(wù)背景
自從2012年AlexNet將深度學(xué)習(xí)的方法應(yīng)用到ImageNet的圖像分類比賽中并取得state of the art的驚人結(jié)果后,大家都競(jìng)相效仿并在此基礎(chǔ)上做了大量嘗試和改進(jìn),先從兩個(gè)性能提升的例子說起:
- 小卷積核。在第一個(gè)卷積層用了更小的卷積核和卷積stride(Zeiler & Fergus, 2013; Sermanet et al., 2014);
- 多尺度。訓(xùn)練和測(cè)試使用整張圖的不同尺度(Sermanet et al., 2014; Howard, 2014)。
作者也是看到這兩個(gè)沒有談到深度的工作,因而受到啟發(fā),不僅將上面的兩種方法應(yīng)用到自己的網(wǎng)絡(luò)設(shè)計(jì)和訓(xùn)練測(cè)試階段,同時(shí)想再試試深度對(duì)結(jié)果的影響。
小卷積核
說到網(wǎng)絡(luò)深度,這里就不得不提到卷積,雖然AlexNet有使用了11x11和5x5的大卷積,但大多數(shù)還是3x3卷積,對(duì)于stride=4的11x11的大卷積核,我認(rèn)為在于一開始原圖的尺寸很大因而冗余,最為原始的紋理細(xì)節(jié)的特征變化用大卷積核盡早捕捉到,后面的更深的層數(shù)害怕會(huì)丟失掉較大局部范圍內(nèi)的特征相關(guān)性,后面轉(zhuǎn)而使用更多3x3的小卷積核(和一個(gè)5x5卷積)去捕捉細(xì)節(jié)變化。
而VGGNet則清一色使用3x3卷積。因?yàn)榫矸e不僅涉及到計(jì)算量,還影響到感受野。前者關(guān)系到是否方便部署到移動(dòng)端、是否能滿足實(shí)時(shí)處理、是否易于訓(xùn)練等,后者關(guān)系到參數(shù)更新、特征圖的大小、特征是否提取的足夠多、模型的復(fù)雜度和參數(shù)量等等。
計(jì)算量
在計(jì)算量這里,為了突出小卷積核的優(yōu)勢(shì),我拿同樣conv3x3、conv5x5、conv7x7、conv9x9和conv11x11,在224x224x3的RGB圖上(設(shè)置pad=1,stride=4,output_channel=96)做卷積,卷積層的參數(shù)規(guī)模和得到的feature map的大小如下:
從上表可以看出,大卷積核帶來的特征圖和卷積核得參數(shù)量并不大,無論是單獨(dú)去看卷積核參數(shù)或者特征圖參數(shù),不同kernel大小下這二者加和的結(jié)構(gòu)都是30萬的參數(shù)量,也就是說,無論大的卷積核還是小的,對(duì)參數(shù)量來說影響不大甚至持平。
增大的反而是卷積的計(jì)算量,在表格中列出了計(jì)算量的公式,最后要乘以2,代表乘加操作。為了盡可能證一致,這里所有卷積核使用的stride均為4,可以看到,conv3x3、conv5x5、conv7x7、conv9x9、conv11x11的計(jì)算規(guī)模依次為:1600萬,4500萬,1.4億、2億,這種規(guī)模下的卷積,雖然參數(shù)量增長(zhǎng)不大,但是計(jì)算量是驚人的。
總結(jié)一下,我們可以得出兩個(gè)結(jié)論:
- 同樣stride下,不同卷積核大小的特征圖和卷積參數(shù)差別不大;
- 越大的卷積核計(jì)算量越大。
其實(shí)對(duì)比參數(shù)量,卷積核參數(shù)的量級(jí)在十萬,一般都不會(huì)超過百萬。相比全連接的參數(shù)規(guī)模是上一層的feature map和全連接的神經(jīng)元個(gè)數(shù)相乘,這個(gè)計(jì)算量也就更大了。其實(shí)一個(gè)關(guān)鍵的點(diǎn)——多個(gè)小卷積核的堆疊比單一大卷積核帶來了精度提升,這也是最重要的一點(diǎn)。
感受野
說完了計(jì)算量我們?cè)賮碚f感受野。這里給出一張VGG作者的PPT,作者在VGGNet的實(shí)驗(yàn)中只用了兩種卷積核大小:1x1和3x3。作者認(rèn)為兩個(gè)3x3的卷積堆疊獲得的感受野大小,相當(dāng)一個(gè)5x5的卷積;而3個(gè)3x3卷積的堆疊獲取到的感受野相當(dāng)于一個(gè)7x7的卷積。
見下圖,輸入的8個(gè)元素可以視為feature map的寬或者高,當(dāng)輸入為8個(gè)神經(jīng)元經(jīng)過三層conv3x3的卷積得到2個(gè)神經(jīng)元。三個(gè)網(wǎng)絡(luò)分別對(duì)應(yīng)stride=1,pad=0的conv3x3、conv5x5和conv7x7的卷積核在3層、1層、1層時(shí)的結(jié)果。因?yàn)檫@三個(gè)網(wǎng)絡(luò)的輸入都是8,也可看出2個(gè)3x3的卷積堆疊獲得的感受野大小,相當(dāng)1層5x5的卷積;而3層的3x3卷積堆疊獲取到的感受野相當(dāng)于一個(gè)7x7的卷積。
- input=8,3層conv3x3后,output=2,等同于1層conv7x7的結(jié)果;
- input=8,2層conv3x3后,output=2,等同于2層conv5x5的結(jié)果。
或者我們也可以說,三層的conv3x3的網(wǎng)絡(luò),最后兩個(gè)輸出中的一個(gè)神經(jīng)元,可以看到的感受野相當(dāng)于上一層是3,上上一層是5,上上上一層(也就是輸入)是7。
此外,倒著看網(wǎng)絡(luò),也就是backprop的過程,每個(gè)神經(jīng)元相對(duì)于前一層甚至輸入層的感受野大小也就意味著參數(shù)更新會(huì)影響到的神經(jīng)元數(shù)目。在分割問題中卷積核的大小對(duì)結(jié)果有一定的影響,在上圖三層的conv3x3中,最后一個(gè)神經(jīng)元的計(jì)算是基于第一層輸入的7個(gè)神經(jīng)元,換句話說,反向傳播時(shí),該層會(huì)影響到第一層conv3x3的前7個(gè)參數(shù)。從輸出層往回forward同樣的層數(shù)下,大卷積影響(做參數(shù)更新時(shí))到的前面的輸入神經(jīng)元越多。
優(yōu)點(diǎn)
既然說到了VGG清一色用小卷積核,結(jié)合作者和自己的觀點(diǎn),這里整理出小卷積核比用大卷積核的三點(diǎn)優(yōu)勢(shì):
更多的激活函數(shù)、更豐富的特征,更強(qiáng)的辨別能力。卷積后都伴有激活函數(shù),更多的卷積核的使用可使決策函數(shù)更加具有辨別能力,此外就卷積本身的作用而言,3x3比7x7就足以捕獲特征的變化:3x3的9個(gè)格子,最中間的格子是一個(gè)感受野中心,可以捕獲上下左右以及斜對(duì)角的特征變化。主要在于3個(gè)堆疊起來后,三個(gè)3x3近似一個(gè)7x7,網(wǎng)絡(luò)深了兩層且多出了兩個(gè)非線性ReLU函數(shù),(特征多樣性和參數(shù)參數(shù)量的增大)使得網(wǎng)絡(luò)容量更大(關(guān)于model capacity,AlexNet的作者認(rèn)為可以用模型的深度和寬度來控制capacity),對(duì)于不同類別的區(qū)分能力更強(qiáng)(此外,從模型壓縮角度也是要摒棄7x7,用更少的參數(shù)獲得更深更寬的網(wǎng)絡(luò),也一定程度代表著模型容量,后人也認(rèn)為更深更寬比矮胖的網(wǎng)絡(luò)好);
卷積層的參數(shù)減少。相比5x5、7x7和11x11的大卷積核,3x3明顯地減少了參數(shù)量,這點(diǎn)可以回過頭去看上面的表格。比方input channel數(shù)和output channel數(shù)均為C,那么3層conv3x3卷積所需要的卷積層參數(shù)是:3x(Cx3x3xC)=27C2,而一層conv7x7卷積所需要的卷積層參數(shù)是:Cx7x7xC=49C2。conv7x7的卷積核參數(shù)比conv3x3多了(49-27)/27x100% ≈ 81%;
小卷積核代替大卷積核的正則作用帶來性能提升。作者用三個(gè)conv3x3代替一個(gè)conv7x7,認(rèn)為可以進(jìn)一步分解(decomposition)原本用7x7大卷積核提到的特征,這里的分解是相對(duì)于同樣大小的感受野來說的。關(guān)于正則的理解我覺得還需要進(jìn)一步分析。
其實(shí)最重要的還是多個(gè)小卷積堆疊在分類精度上比單個(gè)大卷積要好。
小池化核
這里的“小”是相對(duì)于AlexNet的3x3的池化核來說的。不過在說池化前,先說一下CS231n的博客里的描述網(wǎng)絡(luò)結(jié)構(gòu)的layer pattern,一般常見的網(wǎng)絡(luò)都可以表示為:INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC的形式,其中,?表示pool是一個(gè)可選項(xiàng)。這樣的pattern因?yàn)榭梢詫?duì)小卷積核堆疊,很自然也更適合描述深層網(wǎng)絡(luò)的構(gòu)建,例如INPUT -> FC表示一個(gè)線性分類器。
不過從layer pattern中的[[CONV -> RELU]*N -> POOL?]*M部分,可以看出卷積層一般后面接完激活函數(shù)就緊跟池化層。對(duì)于這點(diǎn)我的理解是,池化做的事情是根據(jù)對(duì)應(yīng)的max或者average方式進(jìn)行特征篩選,還是在做特征工程上的事情。
2012年的AlexNet,其pooling的kernel size全是奇數(shù),里面所有池化采用kernel size為3x3,stride為2的max-pooling。而VGGNet所使用的max-pooling的kernel size均為2x2,stride為2的max-pooling。pooling kernel size從奇數(shù)變?yōu)榕紨?shù)。小kernel帶來的是更細(xì)節(jié)的信息捕獲,且是max-pooling更見微的同時(shí)進(jìn)一步知躇。
在當(dāng)時(shí)也有average pooling,但是在圖像任務(wù)上max-pooling的效果更勝一籌,所以圖像大多使用max-pooling。在這里我認(rèn)為max-pooling更容易捕捉圖像上的變化,梯度的變化,帶來更大的局部信息差異性,更好地描述邊緣、紋理等構(gòu)成語義的細(xì)節(jié)信息,這點(diǎn)尤其體現(xiàn)在網(wǎng)絡(luò)可視化上。
概述全連接和特征圖
全連接
VGG最后三個(gè)全連接層在形式上完全平移AlexNet的最后三層,VGGNet后面三層(三個(gè)全連接層)為:
- FC4096-ReLU6-Drop0.5,F(xiàn)C為高斯分布初始化(std=0.005),bias常數(shù)初始化(0.1)
- FC4096-ReLU7-Drop0.5,F(xiàn)C為高斯分布初始化(std=0.005),bias常數(shù)初始化(0.1)
- FC1000(最后接SoftMax1000分類),F(xiàn)C為高斯分布初始化(std=0.005),bias常數(shù)初始化(0.1)
超參數(shù)上只有最后一層fc有變化:bias的初始值,由AlexNet的0變?yōu)?.1,該層初始化高斯分布的標(biāo)準(zhǔn)差,由AlexNet的0.01變?yōu)?.005。超參數(shù)的變化,我的理解是,作者自己的感性理解指導(dǎo)認(rèn)為,我以貢獻(xiàn)bias來降低標(biāo)準(zhǔn)差,相當(dāng)于標(biāo)準(zhǔn)差和bias間trade-off,或許作者實(shí)驗(yàn)validate發(fā)現(xiàn)這個(gè)值比之前AlexNet設(shè)置的(std=0.01,bias=0)要更好。
特征圖
網(wǎng)絡(luò)在隨層數(shù)遞增的過程中,通過池化也逐漸忽略局部信息,特征圖的寬度高度隨著每個(gè)池化操作縮小50%,5個(gè)池化l操作使得寬或者高度變化過程為:224->112->56->28->14->7,但是深度depth(或說是channel數(shù)),隨著5組卷積在每次增大一倍:3->64->128->256->512->512。特征信息從一開始輸入的224x224x3被變換到7x7x512,從原本較為local的信息逐漸分?jǐn)偟讲煌琧hannel上,隨著每次的conv和pool操作打散到channel層級(jí)上。
特征圖的寬高從512后開始進(jìn)入全連接層,因?yàn)槿B接層相比卷積層更考慮全局信息,將原本有局部信息的特征圖(既有width,height還有channel)全部映射到4096維度。也就是說全連接層前是7x7x512維度的特征圖,估算大概是25000,這個(gè)全連接過程要將25000映射到4096,大概是5000,換句話說全連接要將信息壓縮到原來的五分之一。VGGNet有三個(gè)全連接,我的理解是作者認(rèn)為這個(gè)映射過程的學(xué)習(xí)要慢點(diǎn)來,太快不易于捕捉特征映射來去之間的細(xì)微變化,讓backprop學(xué)的更慢更細(xì)一些(更逐漸)。
換句話說,維度在最后一個(gè)卷積后達(dá)到7x7x512,即大概25000,緊接著壓縮到4096維,可能是作者認(rèn)為這個(gè)過程太急,又接一個(gè)fc4096作為緩沖,同時(shí)兩個(gè)fc4096后的relu又接dropout0.5去過渡這個(gè)過程,因?yàn)樽詈蠹磳⒔o1k-way softmax,所以又接了一個(gè)fc1000去降低softmax的學(xué)習(xí)壓力。
feature map維度的整體變化過程是:先將local信息壓縮,并分?jǐn)偟絚hannel層級(jí),然后無視channel和local,通過fc這個(gè)變換再進(jìn)一步壓縮為稠密的feature map,這樣對(duì)于分類器而言有好處也有壞處,好處是將local信息隱藏于/壓縮到feature map中,壞處是信息壓縮都是有損失的,相當(dāng)于local信息被破壞了(分類器沒有考慮到,其實(shí)對(duì)于圖像任務(wù)而言,單張feature map上的local信息還是有用的)。
但其實(shí)不難發(fā)現(xiàn),卷積只增加feature map的通道數(shù),而池化只減少feature map的寬高。如今也有不少做法用大stride卷積去替代池化,未來可能沒有池化。
卷積組
說到特征圖的變化,我們可以進(jìn)一步切分網(wǎng)絡(luò)觀察整體結(jié)構(gòu),再次拿出CS231n的博客里的描述網(wǎng)絡(luò)結(jié)構(gòu)的layer pattern:INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC,以pooling操作為切分點(diǎn)對(duì)整個(gè)網(wǎng)絡(luò)分組的話,我們會(huì)得到五組卷積,五組卷積中有2種卷積組的形式,切分后的VGG網(wǎng)絡(luò)可以描述成下面這樣:
- 前兩組卷積形式一樣,每組都是:conv-relu-conv-relu-pool;
- 中間三組卷積形式一樣,每組都是:conv-relu-conv-relu-conv-relu-pool;
- 最后三個(gè)組全連接fc層,前兩組fc,每組都是:fc-relu-dropout;最后一個(gè)fc僅有fc。
雖然CS231n里將這種形式稱為layer pattern,但我更喜歡把以卷積起始池化為止的最短結(jié)構(gòu)稱之為“卷積組”。
不難發(fā)現(xiàn)VGG有兩種卷積組,第二種([conv-relu]-[conv-relu]-[conv-relu]-pool)比第一種([conv-relu]-[conv-relu]-pool) 多了一個(gè)[conv-relu]。我的理解是:
- 多出的relu對(duì)網(wǎng)絡(luò)中層進(jìn)一步壓榨提煉特征。結(jié)合一開始單張feature map的local信息更多一些,還沒來得及把信息分?jǐn)偟絚hannel級(jí)別上,那么往后就慢慢以增大conv filter的形式遞增地?cái)U(kuò)大channel數(shù),等到了網(wǎng)絡(luò)的中層,channel數(shù)升得差不多了(信息分?jǐn)偟絚hannel上得差不多了),那么還想抽local的信息,就通過再加一個(gè)[conv-relu]的形式去壓榨提煉特征。有點(diǎn)類似傳統(tǒng)特征工程中,已有的特征在固定的模型下沒有性能提升了,那就用更多的非線性變換對(duì)已有的特征去做變換,產(chǎn)生更多的特征的意味;
- 多出的conv對(duì)網(wǎng)絡(luò)中層進(jìn)一步進(jìn)行學(xué)習(xí)指導(dǎo)和控制不要將特征信息漂移到channel級(jí)別上。
- 上一點(diǎn)更多的是relu的帶來的理解,那么多出的[conv-relu]中conv的意味就是模型更強(qiáng)的對(duì)數(shù)據(jù)分布學(xué)習(xí)過程的約束力/控制力,做到信息backprop可以回傳回來的學(xué)習(xí)指導(dǎo)。本身多了relu特征變換就加劇(權(quán)力釋放),那么再用一個(gè)conv去控制(權(quán)力回收),也在指導(dǎo)網(wǎng)絡(luò)中層的收斂;
- 其實(shí)conv本身關(guān)注單張feature map上的局部信息,也是在嘗試去盡量平衡已經(jīng)失衡的channel級(jí)別(depth)和local級(jí)別(width、height)之間的天平。這個(gè)conv控制著特征的信息量不要過于向著channel級(jí)別偏移。
關(guān)于Layer pattern,CS231n的博客給出如下觀點(diǎn):
- 串聯(lián)和串聯(lián)中帶有并聯(lián)的網(wǎng)絡(luò)架構(gòu)。近年來,GoogLeNet在其網(wǎng)絡(luò)結(jié)構(gòu)中引入了Inception模塊,ResNet中引入了Residual Block,這些模塊都有自己復(fù)雜的操作。換句話說,傳統(tǒng)一味地去串聯(lián)網(wǎng)絡(luò)可能并不如這樣串聯(lián)為主線,帶有一些并聯(lián)同類操作但不同參數(shù)的模塊可能在特征提取上更好。 所以我認(rèn)為這里本質(zhì)上依舊是在做特征工程,只不過把這個(gè)過程放在block或者module的小的網(wǎng)絡(luò)結(jié)構(gòu)里,畢竟kernel、stride、output的大小等等超參數(shù)都要自己設(shè)置,目的還是產(chǎn)生更多豐富多樣的特征。
- 用在ImageNet上pre-trained過的模型。設(shè)計(jì)自己模型架構(gòu)很浪費(fèi)時(shí)間,尤其是不同的模型架構(gòu)需要跑數(shù)據(jù)來驗(yàn)證性能,所以不妨使用別人在ImageNet上訓(xùn)練好的模型,然后在自己的數(shù)據(jù)和問題上在進(jìn)行參數(shù)微調(diào),收斂快精度更好。 我認(rèn)為只要性能好精度高,選擇什么樣的模型架構(gòu)都可以,但是有時(shí)候要結(jié)合應(yīng)用場(chǎng)景,對(duì)實(shí)時(shí)性能速度有要求的,可能需要多小網(wǎng)絡(luò),或者分級(jí)小網(wǎng)絡(luò),或者級(jí)聯(lián)的模型,或者做大網(wǎng)絡(luò)的知識(shí)蒸餾得到小網(wǎng)絡(luò),甚至對(duì)速度高精度不要求很高的,可以用傳統(tǒng)方法。
層維度
要說到layer pattern,不得不提到sizing pattern,其實(shí)這里相當(dāng)于前面feature map維度變化的補(bǔ)充,這也是CS231n里所講到的。對(duì)于每種層,有不同的默認(rèn)設(shè)定:
輸入層
大都是2的N次方,這和網(wǎng)絡(luò)中卷積或者池化層出現(xiàn)的stride為2的次數(shù)有關(guān),比方VGGNet中每個(gè)pattern的卷積不會(huì)對(duì)feature map的寬度和高度有改變,而每個(gè)pattern結(jié)束前總會(huì)做一個(gè)stride為2的下采樣,因?yàn)橛?組,那么做5次就是32,所以VGGNet網(wǎng)絡(luò)input大小一般都是32的倍數(shù),即,n是下采樣的次數(shù),a是最終卷積和池化得到的feature map大小,如224或者384。
卷積層
現(xiàn)在常用的是小卷積核如3x3或者1x1。卷積為了保留feature map不變,通常會(huì)采取pad為1的操作,其實(shí)具體來說應(yīng)該是:為了保證卷積后的feature map的寬度和高度不變,那么有pad=(F-1)/2,但我覺得這個(gè)有點(diǎn)問題,可以改成更一般的形式,不過首先可以看看計(jì)算下一層feature map寬高的公式:
因?yàn)橐WC和一樣,有,那么可以導(dǎo)出:
當(dāng)Stride=1時(shí),那么pad=(F-1)/2。因?yàn)楝F(xiàn)在stride=1的3x3卷積用的多,所以大家會(huì)默認(rèn)說是pad=1(關(guān)于這點(diǎn)上,也是由于實(shí)驗(yàn)發(fā)現(xiàn)這樣保留feature map的寬高情況下,性能好的緣故,我認(rèn)為填補(bǔ)主要是針對(duì)stride大于1的情況帶來的邊界問題,如果input尺寸不是事先設(shè)定的,那么就會(huì)有邊界無法卷積到的問題帶來信息丟失。不過這種填補(bǔ)我認(rèn)為也有一定問題,就是說原本conv3x3去計(jì)算對(duì)應(yīng)位置的3x3,而填補(bǔ)后為0,這樣相當(dāng)于少算了一些值,這肯定還是有影響的)。但若stride不是1,那么要保證前后feature map的寬高一樣,就要根據(jù)上面的公式計(jì)算得出。
另一個(gè)點(diǎn)是通常與Input比較接近的conv會(huì)采用大卷積核。關(guān)于接近input層使用較大的卷積核這點(diǎn),我認(rèn)為先是考慮到后面的操作,先盡可能用大的卷積核cover更多的原始信息(雖然經(jīng)過了卷積有一些變換),第二點(diǎn)在于大卷積核帶來的大感受野,后面的卷積層能的一個(gè)神經(jīng)元能看到更大的input,第三點(diǎn)是GPU的顯存受限,經(jīng)典的例子就是AlexNet使用stride=4的conv11x11,目的就是從一開始就減少顯存占用,其實(shí)這里的大stride,我覺得起到了一些正則的作用。但缺點(diǎn)也很明顯,因?yàn)榫矸e核變大,矩陣乘法實(shí)現(xiàn)卷積時(shí),若沒有大stride,那么第一個(gè)矩陣的列數(shù),也就是第二個(gè)矩陣的行數(shù),會(huì)變大,帶來大的計(jì)算量。所以在AlexNet中,大卷積核也對(duì)應(yīng)使用了大的stride值。
池化層
常見2x2的max-pooling,少見3x3或者更大的kernel。更大的kernel帶來的問題是信息丟失帶來的信息損失,此外,stride通常為2;
其實(shí)按照以上的設(shè)定看來,也是有好處的。卷積專注于保留空間信息前提下的channel變換,而池化則專注于空間信息的變換(下采樣)。
全連接轉(zhuǎn)卷積
VGG比較神奇的一個(gè)特點(diǎn)就是“全連接轉(zhuǎn)卷積”,下面是作者原文test小節(jié)中的一句:
Namely, the fully-connected layers are first converted to convolutional layers (the first FC layer to a 7 × 7 conv. layer, the last two FC layers to 1 × 1 conv. layers).
也就是說,作者在測(cè)試階段把網(wǎng)絡(luò)中原本的三個(gè)全連接層依次變?yōu)?個(gè)conv7x7,2個(gè)conv1x1,也就是三個(gè)卷積層。改變之后,整個(gè)網(wǎng)絡(luò)由于沒有了全連接層,網(wǎng)絡(luò)中間的feature map不會(huì)固定,所以網(wǎng)絡(luò)對(duì)任意大小的輸入都可以處理,因而作者在緊接著的后一句說到: The resulting fully-convolutional net is then applied to the whole (uncropped) image。
上圖是VGG網(wǎng)絡(luò)最后三層的替換過程,上半部分是訓(xùn)練階段,此時(shí)最后三層都是全連接層(輸出分別是4096、4096、1000),下半部分是測(cè)試階段(輸出分別是1x1x4096、1x1x4096、1x1x1000),最后三層都是卷積層。下面我們來看一下詳細(xì)的轉(zhuǎn)換過程(以下過程都沒有考慮bias,略了):
先看訓(xùn)練階段,有4096個(gè)輸出的全連接層FC6的輸入是一個(gè)7x7x512的feature map,因?yàn)槿B接層的緣故,不需要考慮局部性, 可以把7x7x512看成一個(gè)整體,25508(=7x7x512)個(gè)輸入的每個(gè)元素都會(huì)與輸出的每個(gè)元素(或者說是神經(jīng)元)產(chǎn)生連接,所以每個(gè)輸入都會(huì)有4096個(gè)系數(shù)對(duì)應(yīng)4096個(gè)輸出,所以網(wǎng)絡(luò)的參數(shù)(也就是兩層之間連線的個(gè)數(shù),也就是每個(gè)輸入元素的系數(shù)個(gè)數(shù))規(guī)模就是7x7x512x4096。對(duì)于FC7,輸入是4096個(gè),輸出是4096個(gè),因?yàn)槊總€(gè)輸入都會(huì)和輸出相連,即每個(gè)輸出都有4096條連線(系數(shù)),那么4096個(gè)輸入總共有4096x4096條連線(系數(shù)),最后一個(gè)FC8計(jì)算方式一樣,略。
再看測(cè)試階段,由于換成了卷積,第一個(gè)卷積后要得到4096(或者說是1x1x4096)的輸出,那么就要對(duì)輸入的7x7x512的feature map的寬高(即width、height維度)進(jìn)行降維,同時(shí)對(duì)深度(即Channel/depth維度)進(jìn)行升維。要把7x7降維到1x1,那么干脆直接一點(diǎn),就用7x7的卷積核就行,另外深度層級(jí)的升維,因?yàn)?x7的卷積把寬高降到1x1,那么剛好就升高到4096就好了,最后得到了1x1x4096的feature map。這其中卷積的參數(shù)量上,把7x7x512看做一組卷積參數(shù),因?yàn)樵搶拥妮敵鍪?096,那么相當(dāng)于要有4096組這樣7x7x512的卷積參數(shù),那么總共的卷積參數(shù)量就是:
[7x7x512]x4096,這里將7x7x512用中括號(hào)括起來,目的是把這看成是一組,就不會(huì)懵。
第二個(gè)卷積依舊得到1x1x4096的輸出,因?yàn)檩斎胍彩?x1x4096,三個(gè)維度(寬、高、深)都沒變化,可以很快計(jì)算出這層的卷積的卷積核大小也是1x1,而且,通道數(shù)也是4096,因?yàn)閷?duì)于輸入來說,1x1x4096是一組卷積參數(shù),即一個(gè)完整的filter,那么考慮所有4096個(gè)輸出的情況下,卷積參數(shù)的規(guī)模就是[1x1x4096]x4096。第三個(gè)卷積的計(jì)算一樣,略。
其實(shí)VGG的作者把訓(xùn)練階段的全連接替換為卷積是參考了OverFeat的工作,如下圖是OverFeat將全連接換成卷積后,帶來可以處理任意分辨率(在整張圖)上計(jì)算卷積,而無需對(duì)原圖resize的優(yōu)勢(shì)。
不過可以看到,訓(xùn)練階段用的是crop或者resize到14x14的輸入圖像,而測(cè)試階段可以接收任意維度,如果使用未經(jīng)crop的原圖作為輸入(假設(shè)原圖比crop或者resize到訓(xùn)練尺度的圖像要大),這會(huì)帶來一個(gè)問題:feature map變大了。比方VGG訓(xùn)練階段用224x224x3的圖作為模型輸入,經(jīng)過5組卷積和池化,最后到7x7x512維度,最后經(jīng)過無論是三個(gè)卷積或者三個(gè)全連接,維度都會(huì)到1x1x4096->1x1x4096->1x1x1000,而使用384x384x3的圖做模型輸入,到五組卷積和池化做完(即),那么feature map變?yōu)?2x12x512,經(jīng)過三個(gè)由全連接變的三個(gè)卷積,即feature map經(jīng)歷了6x6x4096->6x6x4096->6x6x1000的變化過程后,再把這個(gè)6x6x1000的feature map進(jìn)行average,最終交給SoftMax的是1x1x1000的feature map進(jìn)行分類。
以上便是將全連接轉(zhuǎn)換成卷積以及將轉(zhuǎn)換后的全卷積網(wǎng)絡(luò)應(yīng)用到測(cè)試階段的方式。其實(shí)進(jìn)一步來看卷積與全連接,二者最明顯的差異不外乎一個(gè)前者是局部連接,但其實(shí)二者都有用到全局信息,只是卷積是通過層層堆疊來利用的,而全連接就不用說了,全連接的方式直接將上一層的特征圖全部用上,稀疏性比較大,而卷積從網(wǎng)絡(luò)深度這一角度,基于輸入到當(dāng)前層這一過程逐級(jí)逐層榨取的方式利用全局信息。
1x1卷積
VGG在最后的三個(gè)階段都用到了1x1卷積核,選用1x1卷積核的最直接原因是在維度上繼承全連接,然而作者首先認(rèn)為1x1卷積可以增加決策函數(shù)(decision function,這里的決策函數(shù)我認(rèn)為就是softmax)的非線性能力,非線性是由激活函數(shù)ReLU決定的,本身1x1卷積則是線性映射,即將輸入的feature map映射到同樣維度的feature map。作者還提到“Network in Network” architecture of Lin et al. (2014).這篇文章就大量使用了1x1卷積核。
此外,查了知乎簡(jiǎn)單總結(jié)下1x1卷積的特點(diǎn)(就不說加入非線性這個(gè)conv自帶的特點(diǎn)了):
- 專注于跨通道的特征組合:conv1x1根本不考慮單通道上像素的局部信息(不考慮局部信息),專注于那一個(gè)卷積核內(nèi)部通道的信息整合。conv3x3既考慮跨通道,也考慮局部信息整合;
- 對(duì)feature map的channel級(jí)別降維或升維:例如224x224x100的圖像(或feature map)經(jīng)過20個(gè)conv1x1的卷積核,得到224x224x20的feature map。尤其當(dāng)卷積核(即filter)數(shù)量達(dá)到上百個(gè)時(shí),3x3或5x5卷積的計(jì)算會(huì)非常耗時(shí),所以1x1卷積在3x3或5x5卷積計(jì)算前先降低feature map的維度。
關(guān)于小卷積核前人就有使用,如Ciresan et al. (2011)還有Goodfellow et al. (2014),后者使用11層的網(wǎng)絡(luò)解決街道數(shù)量的識(shí)別問題(street number classification,我也沒看懂是回歸還是分類),結(jié)果顯示更深的網(wǎng)絡(luò)可以帶來更好地網(wǎng)絡(luò)性能。而作者在小卷積核的基礎(chǔ)上使用了更多層數(shù),2014年ImageNet分類比賽的第一名使用GoogLeNet,Szegedy et al., (2014)也使用了更小的卷積核、更深達(dá)到22層的網(wǎng)絡(luò),使用了5x5、3x3和1x1卷積(實(shí)際還用到了7x7的卷積,第一層卷積)。但GoogLeNet的拓?fù)浣Y(jié)構(gòu)比較復(fù)雜,上圖是Inception module的結(jié)構(gòu)圖,可以看到module內(nèi)直接使用了常見的三種卷積核進(jìn)行并聯(lián),并將最后的結(jié)果feature map直接concate到一起,而VGGNet則是使用傳統(tǒng)卷積核串聯(lián)的方式。
然而,分類性能上同樣的單模型,VGGNet比GoogLeNet在top5的錯(cuò)分率要低,雖然不確定是否是因?yàn)镚oogLeNet沒做multi-crop和dense eval.,但假設(shè)他們都做了,這樣看來似乎VGG從實(shí)驗(yàn)結(jié)果上表現(xiàn)出其結(jié)構(gòu)設(shè)計(jì)上比GoogLeNet更適合解決分類問題。
但總之,這種將全連接轉(zhuǎn)成卷積的方式還是很有意思的。但轉(zhuǎn)換后是直接拿來用先前的參數(shù)好還是否需要做參數(shù)微調(diào)轉(zhuǎn)換后的卷積層,還需要實(shí)驗(yàn)說明。
實(shí)驗(yàn)結(jié)論和評(píng)價(jià)
12年到14年的挑戰(zhàn)賽都使用的是1000個(gè)類別的ILSVRC-2012數(shù)據(jù)集(Large Scale Visual Recognition Challenge),其中:
- 訓(xùn)練集:130萬張圖片;
- 驗(yàn)證集:5萬張圖片;
- 測(cè)試集:10萬張圖片,這組數(shù)據(jù)的label沒有給出(with held-out class labels)。
兩個(gè)性能評(píng)估準(zhǔn)則:top-1和top-5 error。前一個(gè)是多類分類錯(cuò)誤率,錯(cuò)分的圖像的比率。后一個(gè)是ILSVRC中主要的評(píng)估指標(biāo),計(jì)算的是預(yù)測(cè)出來的top5的類別里沒有g(shù)round truth的比率,即top-5 error。
實(shí)驗(yàn)結(jié)論
因?yàn)樽髡咦约涸谙旅鎸?shí)驗(yàn)的緣故,當(dāng)然沒有測(cè)試集的ground truth類別,所以作者就用驗(yàn)證集當(dāng)做測(cè)試集來觀察模型性能。這里作者使用兩種方式來評(píng)估模型在測(cè)試集(實(shí)際的驗(yàn)證集)的性能表現(xiàn):single scale evaluation和multi-scale evaluation。實(shí)驗(yàn)結(jié)論:
- LRN層無性能增益(A和A-LRN)。作者通過網(wǎng)絡(luò)A和A-LRN發(fā)現(xiàn)AlexNet曾經(jīng)用到的LRN層(local response normalization,LRN是一種跨通道去normalize像素值的方法)沒有性能提升,因此在后面的4組網(wǎng)絡(luò)中均沒再出現(xiàn)LRN層。 當(dāng)然我也感覺沒啥用,想到max-pooling比average-pooling效果好,我就感覺這個(gè)LRN沒啥用,不過如果把LRN改成跨通道的max-normal,我感覺說不定會(huì)有性能提升。特征得到retain更明顯。
- 深度增加,分類性能提高(A、B、C、D、E)。從11層的A到19層的E,網(wǎng)絡(luò)深度增加對(duì)top1和top5的error下降很明顯,所以作者得出這個(gè)結(jié)論,但其實(shí)除了深度外,其他幾個(gè)網(wǎng)絡(luò)寬度等因素也在變化,depth matters的結(jié)論不夠convincing。
- conv1x1的非線性變化有作用(C和D)。C和D網(wǎng)絡(luò)層數(shù)相同,但D將C的3個(gè)conv3x3換成了conv1x1,性能提升。這點(diǎn)我理解是,跨通道的信息交換/融合,可以產(chǎn)生豐富的特征易于分類器學(xué)習(xí)。conv1x1相比conv3x3不會(huì)去學(xué)習(xí)local的局部像素信息,專注于跨通道的信息交換/融合,同時(shí)為后面全連接層(全連接層相當(dāng)于global卷積)做準(zhǔn)備,使之學(xué)習(xí)過程更自然。
- 多小卷積核比單大卷積核性能好(B)。作者做了實(shí)驗(yàn)用B和自己一個(gè)不在實(shí)驗(yàn)組里的較淺網(wǎng)絡(luò)比較,較淺網(wǎng)絡(luò)用conv5x5來代替B的兩個(gè)conv3x3。多個(gè)小卷積核比單大卷積核效果好,換句話說當(dāng)考慮卷積核大小時(shí):depths matters。
文章引用于 https://blog.csdn.net/qq_40027052/article/details/79015827
編輯 Lornatang
校準(zhǔn) Lornatang