絡(luò)深度設(shè)計(jì):小卷積核堆疊與遷移學(xué)習(xí)價(jià)值)
前兩天有個(gè)朋友發(fā)來一段代碼說他在某個(gè)小數(shù)據(jù)集上用VGG16做遷移學(xué)習(xí)效果比一些看起來“更新”的網(wǎng)絡(luò)還好就是跑得慢。我順手把2014年那篇《Very Deep Convolutional Networks for Large-Scale Image Recognition》翻出來又讀了一遍。這篇論文對(duì)我而言確實(shí)是“常讀常新”當(dāng)年它用最笨拙的方式把卷積網(wǎng)絡(luò)從8層直接推到16層、19層靠堆疊3×3小卷積核刷新了ImageNet上的識(shí)別記錄并且之后幾年里幾乎所有檢測(cè)、分割、風(fēng)格遷移項(xiàng)目都在用它的預(yù)訓(xùn)練權(quán)重做底座。如果你正在學(xué)卷積網(wǎng)絡(luò)結(jié)構(gòu)或者要復(fù)現(xiàn)一篇舊模型并做遷移學(xué)習(xí)這篇文章基本就是繞不開的教科書。接下來我會(huì)把這篇論文的動(dòng)機(jī)、結(jié)構(gòu)設(shè)計(jì)、小卷積核的數(shù)學(xué)直覺、論文里的消融實(shí)驗(yàn)、訓(xùn)練細(xì)節(jié)和工程遺產(chǎn)完整展開順便穿插一些我復(fù)現(xiàn)和調(diào)參時(shí)的真實(shí)體會(huì)。1. VGG解決的核心問題深度到底值多少精度1.1 2014年前后卷積網(wǎng)絡(luò)的“魔法時(shí)代”2012年的AlexNet一舉把ImageNet圖像分類的錯(cuò)誤率大幅壓低卷積網(wǎng)絡(luò)從此成為視覺任務(wù)的主角。但是當(dāng)時(shí)的普遍認(rèn)知是分散且模糊的有人覺得大卷積核性能好于是用7×7甚至11×11有人覺得網(wǎng)絡(luò)不能太深因?yàn)橛?xùn)練時(shí)會(huì)遇到梯度消失、收斂特別慢。沒有一篇工作能清楚地回答“網(wǎng)絡(luò)深度到底對(duì)精度有多大的影響”。VGG這篇論文本質(zhì)上做了一件很樸素但極有意義的事把“深度”作為可控變量用幾乎一致的結(jié)構(gòu)去增加卷積層數(shù)量從11層一路加到19層然后在同樣數(shù)據(jù)集、同樣訓(xùn)練流程下看精度的變化。結(jié)果證明了深度在當(dāng)時(shí)的網(wǎng)絡(luò)結(jié)構(gòu)下是有效且必要的而且加深到16到19層時(shí)仍然能穩(wěn)定收益。這一點(diǎn)放在今天看似乎習(xí)以為常但在當(dāng)時(shí)需要很大的實(shí)驗(yàn)量來支撐。1.2 我理解的論文真實(shí)貢獻(xiàn)不只是VGG16結(jié)構(gòu)本身很多初學(xué)者會(huì)把VGG等同于“VGG16那個(gè)網(wǎng)絡(luò)結(jié)構(gòu)”這當(dāng)然沒錯(cuò)但論文更值錢的地方在三點(diǎn)系統(tǒng)驗(yàn)證了“小卷積核堆疊加深網(wǎng)絡(luò)”可以穩(wěn)定提高精度并把感受野、參數(shù)量、非線性三者之間的賬算得明明白白后來的很多網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計(jì)都從這個(gè)思想里延伸出來。給出了一組從淺到深、可復(fù)現(xiàn)的配置論文里叫A到E并且公開權(quán)重。當(dāng)時(shí)大家隨便下載一下就能用來做特征提取或遷移學(xué)習(xí)這種開源紅利對(duì)整個(gè)社區(qū)推進(jìn)作用巨大。提供了完整的訓(xùn)練和調(diào)參經(jīng)驗(yàn)比如先訓(xùn)淺層網(wǎng)絡(luò)再拿淺層權(quán)重初始化深層網(wǎng)絡(luò)這個(gè)操作后來成了很多深層網(wǎng)絡(luò)訓(xùn)練的救命稻草。1.3 這篇論文適合誰細(xì)讀如果你是剛接觸深度學(xué)習(xí)的初學(xué)者VGG是一個(gè)極好的“骨架模板”每條卷積層、每個(gè)池化層都規(guī)規(guī)矩矩通道數(shù)翻倍、尺寸減半的節(jié)奏一目了然比很多花哨的結(jié)構(gòu)容易理解得多。如果你是有幾年經(jīng)驗(yàn)的工程師重新讀一遍也會(huì)發(fā)現(xiàn)大量容易被忽略的細(xì)節(jié)比如LRN局部響應(yīng)歸一化為什么被放棄、測(cè)試時(shí)多尺度裁剪為什么有用、權(quán)重初始化對(duì)深層網(wǎng)絡(luò)有多重要。這篇文章接下來的內(nèi)容就是把這些關(guān)鍵細(xì)節(jié)一次拆開。2. 逐層拆解VGG16從224×224到分類輸出的全路徑2.1 五種配置的差異A、A-LRN、B、C、D、E論文里最讓人印象深刻的是那張配置總表。VGG團(tuán)隊(duì)用幾乎一樣的思路設(shè)計(jì)了一組網(wǎng)絡(luò)區(qū)別主要在總層數(shù)和少量結(jié)構(gòu)改動(dòng)。為了方便記憶我通常用每個(gè)卷積塊的通道數(shù)序列來區(qū)分配置代碼大概長(zhǎng)這樣cfgs { A: [64, 64, M, 128, 128, M, 256, 256, M, 512, 512, M, 512, 512, M], B: [64, 64, M, 128, 128, M, 256, 256, M, 512, 512, M, 512, 512, M], C: [64, 64, M, 128, 128, M, 256, 256, 256, M, 512, 512, 512, M, 512, 512, 512, M], D: [64, 64, M, 128, 128, M, 256, 256, 256, M, 512, 512, 512, M, 512, 512, 512, M], E: [64, 64, M, 128, 128, M, 256, 256, 256, 256, M, 512, 512, 512, 512, M, 512, 512, 512, 512, M], }其中M代表尺寸減半的max-pooling。A是基準(zhǔn)的11層網(wǎng)絡(luò)A-LRN是在A的基礎(chǔ)上加局部響應(yīng)歸一化B在A的基礎(chǔ)上把某些位置的單層卷積變成了兩層C則在B的基礎(chǔ)上又加了一些1×1卷積D把C的1×1卷積換成了3×3E在D基礎(chǔ)上繼續(xù)加深到19層。最常用的VGG16對(duì)應(yīng)D配置VGG19對(duì)應(yīng)E配置。我當(dāng)時(shí)看到這個(gè)配置表的第一反應(yīng)是原來VGG16其實(shí)就是把一堆卷積層拼成五個(gè)塊每塊第一層之后池化一次最后接三個(gè)全連接層。搞清楚這個(gè)規(guī)律之后看很多后續(xù)網(wǎng)絡(luò)就非常輕松因?yàn)楹髞淼腞esNet、DenseNet基本也是“分階段設(shè)計(jì)”的套路只是內(nèi)部變換方式不同。2.2 VGG16逐層參數(shù)與特征圖尺寸變化以224×224×3的輸入為例VGG16的完整數(shù)據(jù)流是這樣走的第一階段兩組conv3-64輸出224×224×64然后max-pool尺寸變?yōu)?12×112×64。第二階段兩組conv3-128輸出112×112×128然后max-pool尺寸變?yōu)?6×56×128。第三階段三組conv3-256輸出56×56×256然后max-pool尺寸變?yōu)?8×28×256。第四階段三組conv3-512輸出28×28×512然后max-pool尺寸變?yōu)?4×14×512。第五階段三組conv3-512輸出14×14×512然后max-pool尺寸變?yōu)?×7×512。最后將7×7×512的特征圖展開成25088維向量依次經(jīng)過4096、4096、1000三個(gè)全連接層最后通過softmax輸出分類概率。整個(gè)過程最反直覺的地方是卷積層幾乎不改變特征圖長(zhǎng)寬只增加通道數(shù)真正讓尺寸逐級(jí)減半的是那5個(gè)max-pool。一張224×224的圖片經(jīng)過5次池化之后變成7×7這里剛好是2的5次方關(guān)系224除以32等于7。所以后面換輸入大小時(shí)比如改成384×384那pool四次之后就會(huì)變成12×12結(jié)構(gòu)需要稍微調(diào)整一下。我在做目標(biāo)檢測(cè)項(xiàng)目時(shí)就經(jīng)常把VGG的輸入從224加大到384甚至512目的就是保留更多空間位置信息。2.3 參數(shù)量統(tǒng)計(jì)全連接層才是吃參數(shù)的“啞鈴”VGG16的參數(shù)量大約是1.38億這個(gè)數(shù)字驚人但更驚人的是它的分布。我把卷積層和一個(gè)全連接層的參數(shù)量拆開算過部分參數(shù)量占比全部卷積層約1472萬約10.6%fc67×7×512→4096約1.028億約74.2%fc74096→4096約1678萬約12.1%fc84096→1000約410萬約3.0%也就是說卷積層加起來只占十分之一多一點(diǎn)光一個(gè)fc6就吞掉了整個(gè)網(wǎng)絡(luò)七成以上的參數(shù)量。我第一次算完這個(gè)表之后立刻明白為什么后來全局平均池化會(huì)流行把最后的多維特征圖直接平均成一個(gè)向量既能保留語義信息又能省掉那個(gè)巨無霸的展開矩陣。VGG之所以慢和占用顯存很大一部分原因就是這三個(gè)全連接層在“拖后腿”。3. 3×3小卷積核VGG最精妙的兩筆賬3.1 等效感受野為什么兩個(gè)3×3等于一個(gè)5×5VGG全文的靈魂不是“深”而是“用什么樣的方式深”。它堅(jiān)持在整條網(wǎng)絡(luò)里只用3×3卷積核步長(zhǎng)為1padding為1。這里有一個(gè)非常關(guān)鍵的計(jì)算兩個(gè)3×3卷積堆疊之后輸出特征圖上的一個(gè)像素在原圖上覆蓋的區(qū)域等于一個(gè)5×5卷積的感受野也就是25個(gè)像素范圍三個(gè)3×3卷積堆疊則等價(jià)于一個(gè)7×7卷積的感受野覆蓋49個(gè)像素范圍。當(dāng)時(shí)我看到這個(gè)結(jié)論的第一反應(yīng)是把公式推一遍。假設(shè)輸入是一個(gè)5×5的區(qū)域經(jīng)過第一次3×3卷積之后輸出圖的每個(gè)位置對(duì)應(yīng)原圖的3×3窗口再經(jīng)過第二次3×3卷積輸出圖的每個(gè)位置對(duì)應(yīng)前一層的3×3窗口而前一層的3×3窗口又對(duì)應(yīng)原圖5×5范圍這樣兩級(jí)映射疊加起來剛好等效于一次5×5卷積。如果把中間特征圖忽略掉只看輸入輸出關(guān)系兩個(gè)小卷積核確實(shí)“拼”成了一個(gè)大卷積核。這個(gè)等效關(guān)系就是小卷積核能撐起深度的底層邏輯網(wǎng)絡(luò)并沒有因?yàn)閾Q用3×3而丟失感受野反而因?yàn)槎嗔酥虚g層獲得了更豐富的非線性表達(dá)能力。3.2 參數(shù)賬與非線性賬49對(duì)比271對(duì)比3用7×7卷積替代三個(gè)3×3卷積從參數(shù)量上算一筆賬。假設(shè)輸入輸出通道數(shù)都為C一個(gè)7×7卷積的參數(shù)是7×7×C×C49C2三個(gè)3×3卷積的參數(shù)是3×(3×3×C×C)27C2。也就是說在感受野完全等價(jià)的前提下小卷積核堆疊能節(jié)省大約45%的參數(shù)。這個(gè)比例不依賴C的具體值是一個(gè)通用的結(jié)論。如果只看參數(shù)節(jié)省可能有人覺得“少一點(diǎn)又怎樣”但VGG真正贏在非線性層數(shù)。一個(gè)大7×7卷積只有一層卷積加一層ReLU而三個(gè)3×3卷積堆疊起來是三層卷積加三層ReLU。神經(jīng)網(wǎng)絡(luò)的深度意義就在于這些非線性層的堆疊更多非線性讓網(wǎng)絡(luò)能夠擬合更復(fù)雜的函數(shù)曲面。這就好比一個(gè)三人小組各自觀察一小片信息然后層層匯總比一個(gè)人拿大掃把看一大片區(qū)域要更細(xì)致中間多出來的“討論環(huán)節(jié)”很重要。我后來在看很多輕量化網(wǎng)絡(luò)的論文時(shí)發(fā)現(xiàn)它們都在反復(fù)使用這個(gè)思想用更小的卷積核疊加替代大卷積核換取參數(shù)效率和非線性能力VGG在這方面是祖師爺級(jí)別的存在。3.3 為什么1×1卷積不夠也不直接上大卷積核論文里有一個(gè)配置C是在部分層中用1×1卷積代替3×3卷積。1×1卷積可以在不改變特征圖空間尺寸的情況下做通道混合和增加非線性參數(shù)量也更低但實(shí)驗(yàn)結(jié)果顯示C配置的精度明顯不如D配置也就是同樣深度下3×3卷積比1×1卷積更有效。我當(dāng)時(shí)反復(fù)想這段實(shí)驗(yàn)結(jié)論是1×1卷積完全不會(huì)做空間信息交互每個(gè)輸出像素只看到輸入對(duì)應(yīng)位置那個(gè)像素的通道信息等于把畫面剪成無數(shù)個(gè)點(diǎn)再逐點(diǎn)處理缺少鄰域上下文。而3×3卷積每次都整合了周圍3×3鄰域的信息雖然網(wǎng)絡(luò)設(shè)計(jì)上“每一點(diǎn)只看到一小塊”但正是這些小塊的層層傳遞才讓感受野逐步擴(kuò)大。再看“為什么不直接用7×7卷積”參數(shù)多、非線性少是一個(gè)原因另一個(gè)原因是7×7大卷積核感受野過大時(shí)提取的特征相對(duì)粗糙而三個(gè)3×3卷積相當(dāng)于在同樣的視覺范圍內(nèi)做了三次逐步精煉的特征提取精度自然更穩(wěn)。VGG的核心思路其實(shí)是把“加大感受野”的動(dòng)作拆成三次小的移動(dòng)這讓網(wǎng)絡(luò)能夠以更細(xì)膩的方式理解圖像。4. 論文里的消融實(shí)驗(yàn)與訓(xùn)練細(xì)節(jié)那些被忽略的參考值4.1 深度對(duì)精度的影響從11層到19層的臺(tái)階論文里最直接的對(duì)比就是不同深度的網(wǎng)絡(luò)在ImageNet驗(yàn)證集上的表現(xiàn)。只增加深度、保持其他結(jié)構(gòu)基本不變時(shí)性能是隨著層數(shù)增加逐步提升的。比如A配置大概在11層B和C在13到16層之間D和E在16到19層整體趨勢(shì)是越深越好直到19層時(shí)收益邊際開始變小。這條曲線給了當(dāng)時(shí)整個(gè)領(lǐng)域一個(gè)非常明確的信號(hào)網(wǎng)絡(luò)深度還有很大挖掘空間。但這里有一個(gè)容易被人忽略的背景更深的網(wǎng)絡(luò)意味著訓(xùn)練困難。論文用“先訓(xùn)練淺層網(wǎng)絡(luò)再用淺層網(wǎng)絡(luò)的權(quán)重初始化深層網(wǎng)絡(luò)”來解決這個(gè)問題這個(gè)方法在今天很多任務(wù)上仍然好用。我自己在搭大規(guī)模分類模型時(shí)如果訓(xùn)練資源不足也會(huì)先跑一個(gè)淺層模型再用它的部分權(quán)重去初始化深層模型收斂速度和最終精度都有改善。4.2 LRN被否定1×1不如3×3消融實(shí)驗(yàn)的價(jià)值VGG論文里有一組很經(jīng)典的對(duì)照實(shí)驗(yàn)A-LRN。A-LRN在A的基礎(chǔ)上增加了局部響應(yīng)歸一化LRN這在AlexNet時(shí)代被很多人視為標(biāo)配。但實(shí)驗(yàn)結(jié)果非常打臉加了LRN的A-LRN精度反而比不加LRN的A略低。既然無益且增加計(jì)算量VGG后面的配置全部取消了LRN。這件事給我的啟發(fā)比結(jié)構(gòu)本身更大不要盲從既有的“經(jīng)驗(yàn)技巧”任何設(shè)計(jì)都應(yīng)該用消融實(shí)驗(yàn)去驗(yàn)證。很多后來出現(xiàn)的模塊比如各種歸一化層、注意力模塊、激活函數(shù)變體在一個(gè)新的網(wǎng)絡(luò)里到底有沒有效果只有通過嚴(yán)格的對(duì)比才能下結(jié)論。VGG當(dāng)年就是靠這種扎實(shí)的實(shí)驗(yàn)態(tài)度把LRN從主流網(wǎng)絡(luò)里清了出去。4.3 訓(xùn)練細(xì)節(jié)清單初始化、縮放、參數(shù)配置論文在訓(xùn)練細(xì)節(jié)上的信息量很大這部分對(duì)實(shí)際復(fù)現(xiàn)非常關(guān)鍵權(quán)重初始化先訓(xùn)練配置A獲得權(quán)重再用A的淺層權(quán)重初始化B、C、D、E的對(duì)應(yīng)層。這比從頭隨機(jī)初始化深層網(wǎng)絡(luò)穩(wěn)定得多收斂也更快。輸入尺寸訓(xùn)練時(shí)把圖片短邊隨機(jī)縮放到256到512之間的某個(gè)尺度再?gòu)闹须S機(jī)裁剪224×224區(qū)域。這種多尺度訓(xùn)練相當(dāng)于免費(fèi)的數(shù)據(jù)增強(qiáng)。數(shù)據(jù)增強(qiáng)隨機(jī)水平翻轉(zhuǎn)、RGB顏色抖動(dòng)也是標(biāo)配。優(yōu)化配置SGDmini-batch為256momentum為0.9權(quán)重衰減設(shè)為5e-4前兩個(gè)全連接層使用dropout且概率為0.5。學(xué)習(xí)率策略初始學(xué)習(xí)率0.01當(dāng)驗(yàn)證集準(zhǔn)確率停止提升時(shí)將學(xué)習(xí)率除以10整個(gè)訓(xùn)練過程大約下降三次學(xué)習(xí)率。我復(fù)現(xiàn)時(shí)發(fā)現(xiàn)如果跳過淺層初始化這一步直接從深層隨機(jī)初始化開始訓(xùn)練模型其實(shí)也能收斂但需要更多的epoch和更小的學(xué)習(xí)率前期損失下降非常慢。論文里這個(gè)“從淺到深”的思路本質(zhì)上是給梯度傳播一個(gè)更平滑的起點(diǎn)。4.4 測(cè)試階段的多尺度技巧測(cè)試階段VGG團(tuán)隊(duì)也沒有只做一次中心裁剪。他們用了兩種策略疊加一個(gè)是對(duì)多尺度縮放的圖片做密集評(píng)估也就是讓卷積網(wǎng)絡(luò)在全圖上滑動(dòng)計(jì)算另一個(gè)是multi-crop從不同位置裁剪多塊區(qū)域分別預(yù)測(cè)最后平均所有結(jié)果。這些技巧疊加起來能帶來一到兩個(gè)百分點(diǎn)的提升。放在今天看這種多尺度測(cè)試思路已經(jīng)演化成了很多競(jìng)賽和工業(yè)項(xiàng)目的“測(cè)試時(shí)增強(qiáng)”。不過也要提醒一句multi-crop會(huì)成倍增加推理時(shí)間實(shí)際部署時(shí)需要在精度和速度之間做取舍。我做在線推理時(shí)基本不用多尺度但離線評(píng)測(cè)和競(jìng)賽時(shí)會(huì)開效果確實(shí)立竿見影。5. VGG的工程遺產(chǎn)與教訓(xùn)遷移價(jià)值、參數(shù)包袱與后輩改進(jìn)5.1 預(yù)訓(xùn)練模型的遷移帝國(guó)如果說VGG的論文是技術(shù)勝利那么它開源的預(yù)訓(xùn)練權(quán)重就是工程勝利。2014年之后很長(zhǎng)一段時(shí)間目標(biāo)檢測(cè)網(wǎng)絡(luò)的骨干、語義分割網(wǎng)絡(luò)的編碼器、風(fēng)格遷移的特征提取器幾乎都能看到VGG16的影子和它的預(yù)訓(xùn)練權(quán)重。我自己的感覺是當(dāng)時(shí)用VGG16做backbone比后來用很多新穎網(wǎng)絡(luò)還要省心結(jié)構(gòu)簡(jiǎn)單預(yù)訓(xùn)練模型好找上下采樣路徑清晰fine-tune時(shí)調(diào)整空間又大。就算到現(xiàn)在在某些中小規(guī)模數(shù)據(jù)集上VGG16的預(yù)訓(xùn)練特征依然非常能打。我做過一次對(duì)比把VGG16換成一個(gè)“更新”但更輕的網(wǎng)絡(luò)在小樣本遷移任務(wù)上反而是VGG16的表現(xiàn)更穩(wěn)。原因在于大參數(shù)量的模型在預(yù)訓(xùn)練階段已經(jīng)記住了大量通用視覺模式遷移到下游任務(wù)時(shí)只需要小幅度調(diào)整。5.2 VGG的不足之處顯存、參數(shù)與全連接層的“重稅”VGG的缺點(diǎn)也和它的成功一樣突出參數(shù)量大、計(jì)算量大、顯存占用高。從上面的參數(shù)分布就能看出來最后三個(gè)全連接層貢獻(xiàn)了絕大多數(shù)參數(shù)而全連接層的參數(shù)數(shù)量由輸入特征圖大小決定一旦輸入尺寸變大fc6的參數(shù)還會(huì)進(jìn)一步膨脹。這意味著VGG對(duì)輸入分辨率非常敏感想要高分辨率輸入幾乎等于把顯存花在矩陣展開上。在顯存只有幾個(gè)GB的年代訓(xùn)練VGG16的batch size不敢設(shè)太大。我的經(jīng)驗(yàn)是一張224×224的圖片在VGG16上做一次前向激活值占據(jù)的顯存比模型參數(shù)本身還大尤其最后幾個(gè)卷積層的特征圖通道數(shù)512、尺寸適中加起來非常吃內(nèi)存。后來很多網(wǎng)絡(luò)改用全局平均池化替代全連接層把參數(shù)減少到幾百萬級(jí)別正是針對(duì)這個(gè)痛點(diǎn)。殘差結(jié)構(gòu)的出現(xiàn)更是讓“更深”不再等同于“更難訓(xùn)練”。5.3 它對(duì)后續(xù)網(wǎng)絡(luò)設(shè)計(jì)留下的三條啟示讀完VGG再看后面的ResNet、DenseNet會(huì)發(fā)現(xiàn)很多思路都能溯源到這篇論文小卷積核是大勢(shì)所趨增大感受野不一定要增大卷積核用層數(shù)堆疊更劃算。網(wǎng)絡(luò)設(shè)計(jì)要有清晰的階段性通道數(shù)逐級(jí)翻倍、分辨率逐級(jí)減半這種瀑布結(jié)構(gòu)非常有利于梯度流動(dòng)和工程實(shí)現(xiàn)。每個(gè)設(shè)計(jì)選擇都必須經(jīng)過實(shí)驗(yàn)驗(yàn)證不管是LRN還是1×1卷積只有數(shù)據(jù)能說服人。VGG本身也像一個(gè)路標(biāo)它證明了深度有潛力但也暴露了單純加深網(wǎng)絡(luò)會(huì)出現(xiàn)收斂困難和高參數(shù)負(fù)擔(dān)這就直接催生了后續(xù)的殘差連接和批量歸一化??梢哉f沒有VGG踩出來的這些坑后面很多網(wǎng)絡(luò)不會(huì)走得那么順。6. 我復(fù)現(xiàn)VGG時(shí)踩過的幾個(gè)小坑6.1 顯存不夠時(shí)的處理順序我第一次在單卡上跑VGG16的時(shí)候batch size開到32直接顯存溢出。當(dāng)時(shí)急著把batch調(diào)小到8結(jié)果訓(xùn)練非常不穩(wěn)定。后來我養(yǎng)成一個(gè)習(xí)慣優(yōu)先保持batch size在16以上如果顯存不夠先把輸入圖片從224降到192或者關(guān)閉驗(yàn)證階段的數(shù)據(jù)增強(qiáng)而不是一味縮小batch。batch縮到很小會(huì)讓BatchNorm如果加了的話統(tǒng)計(jì)量不準(zhǔn)也會(huì)讓梯度的噪聲變大。VGG本身沒有BatchNorm但后來的變體加了這時(shí)候小batch問題會(huì)更明顯。6.2 遷移學(xué)習(xí)時(shí)忘了輸入歸一化VGG官方預(yù)訓(xùn)練權(quán)重在訓(xùn)練時(shí)有特定的輸入預(yù)處理方式大致是每個(gè)像素減去訓(xùn)練集的均值。很多人直接拿來fine-tune時(shí)不做這個(gè)歸一化結(jié)果準(zhǔn)確率總差一大截。我第一次犯這個(gè)錯(cuò)誤時(shí)反復(fù)調(diào)學(xué)習(xí)率都沒用最后檢查數(shù)據(jù)流才發(fā)現(xiàn)問題。如果你用任何一個(gè)現(xiàn)成模型庫(kù)加載VGG權(quán)重務(wù)必先確認(rèn)對(duì)方實(shí)現(xiàn)的預(yù)處理是否與你使用的數(shù)據(jù)加載代碼一致這一步出錯(cuò)非常隱蔽。6.3 用VGG做特征提取器時(shí)凍結(jié)層數(shù)要謹(jǐn)慎我的另一個(gè)教訓(xùn)是做小數(shù)據(jù)集的遷移學(xué)習(xí)時(shí)不要一開始就把所有層都解凍。比較穩(wěn)的做法是先把新任務(wù)的全連接層從頭訓(xùn)練卷積層暫時(shí)凍結(jié)等損失降到一個(gè)平臺(tái)之后再解凍最后一兩個(gè)卷積塊用小學(xué)習(xí)率微調(diào)。VGG的前半部分提取的是通用邊緣、紋理、形狀特征后面幾層更偏向任務(wù)相關(guān)的語義特征所以解凍順序應(yīng)該從最后往前逐漸放開。這樣訓(xùn)練速度更快也不容易把預(yù)訓(xùn)練學(xué)到的知識(shí)沖掉。6.4 關(guān)于訓(xùn)練VGG的一點(diǎn)心得體會(huì)很多人覺得VGG結(jié)構(gòu)老、參數(shù)多已經(jīng)不值得學(xué)了。我的看法恰恰相反正是因?yàn)樗慕Y(jié)構(gòu)規(guī)整、問題暴露得明顯它才是一個(gè)完美的“實(shí)驗(yàn)田”。你可以在VGG上驗(yàn)證數(shù)據(jù)增強(qiáng)的效果可以對(duì)比不同初始化的影響可以測(cè)試不同池化策略這些實(shí)驗(yàn)結(jié)論往往能推廣到更新的結(jié)構(gòu)上。如果讓我給剛?cè)腴T的人推薦第一個(gè)要反復(fù)精讀的卷積網(wǎng)絡(luò)我大概率還是會(huì)把這篇論文和VGG16的代碼一起丟過去讀懂了它再看后來的網(wǎng)絡(luò)會(huì)輕松很多。