densenet 論文解讀
工作中遇到了densenet,需要參考其中的denseblock,打算將這個結構加入到unet中,試試看效果,先來從幾個方面解讀一下這片文章吧。
優點
從feature入手,通過對feature的極致利用達到更好的效果和更少的參數。
先列下DenseNet的幾個優點: 1、減輕了vanishing-gradient(梯度消失)
dense connection相當於每一層都直接連接input和loss,因此就可以減輕梯度消失現象
2、加強了feature的傳遞 3、更有效地利用了feature 4、一定程度上較少了參數數量
DenseNet網路更窄,參數更少,很大一部分原因得益於這種dense block的設計,後面有提到在dense block中每個卷積層的輸出feature map的數量都很小(小於100),而不是像其他網路一樣動不動就幾百上千的寬度。同時這種連接方式使得特徵和梯度的傳遞更加有效,網路也就更加容易訓練。
5、減輕過擬合
dense connection有正則化的效果,因此對於過擬合有一定的抑制作用,因為參數減少了,所以過擬合現象減輕。神經網路每一層提取的特徵都相當於對輸入數據的一個非線性變換,而隨著深度的增加,變換的複雜度也逐漸增加(更多非線性函數的複合)。相比於一般神經網路的分類器直接依賴於網路最後一層(複雜度最高)的特徵,DenseNet 可以綜合利用淺層複雜度低的特徵,因而更容易得到一個光滑的具有更好泛化性能的決策函數。
結構
Dense block
dense block的結構圖如下。在傳統的卷積神經網路中,如果你有L層,那麼就會有L個連接,但是在DenseNet中,會有L(L+1)/2個連接。簡單講,就是每一層的輸入來自前面所有層的輸出。如下圖:x0是input,H1的輸入是x0(input),H2的輸入是x0和x1(x1是H1的輸出)
和resnet區別
文章中只有兩個公式,是用來闡述DenseNet和ResNet的關係。
第一個公式是ResNet的。這裡的l表示層,xl表示l層的輸出,Hl表示一個非線性變換。所以對於ResNet而言,l層的輸出是l-1層的輸出加上對l-1層輸出的非線性變換。
第二個公式是DenseNet的。[x0,x1,…,xl-1]表示將0到l-1層的輸出feature map做concatenation。concatenation是做通道的合併,就像Inception那樣。而前面resnet是做值的相加,通道數是不變的。Hl包括BN,ReLU和3*3的卷積。
所以從這兩個公式就能看出DenseNet和ResNet在本質上的區別。
Densenet
DenseNet的結構圖中包含了3個dense block。作者將DenseNet分成多個dense block,原因是希望各個dense
block內的feature map的size統一,這樣在做concatenation就不會有size的問題。
表是整個網路的結構圖。表中的k=32,k=48中的k是growth rate,表示每個dense block中每層輸出的feature
map個數。為了避免網路變得很寬,作者都是採用較小的k,比如32這樣,作者的實驗也表明小的k可以有更好的效果。根據dense
block的設計,後面幾層可以得到前面所有層的輸入,因此concat後的輸入channel還是比較大的。另外這裡每個dense block的3*3卷積前面都包含了一個1*1的卷積操作,就是所謂的bottleneck layer,目的是減少輸入的feature map數量,既能降維減少計算量,又能融合各個通道的特徵。另外作者為了進一步壓縮參數,在每兩個dense block之間又增加了1*1的卷積操作。因此在後面的實驗對比中,如果你看到DenseNet-C這個網路,表示增加了這個Translation layer,該層的1*1卷積的輸出channel默認是輸入channel到一半。如果你看到DenseNet-BC這個網路,表示既有bottleneck layer,又有Translation layer。思考
密集連接不會帶來冗餘嗎?
這麼多的密集連接,是不是全部都是必要的,有沒有可能去掉一些也不會影響網路的性能?論文裡面有一個熱力圖(heatmap),直觀上刻畫了各個連接的強度。從圖中可以觀察到網路中比較靠後的層確實也會用到非常淺層的特徵。
DenseNet 特別耗費顯存?
DenseNet 在訓練時對內存消耗非常厲害。這個問題其實是演算法實現不優帶來的。當前的深度學習框架對 DenseNet 的密集連接沒有很好的支持,我們只能藉助於反覆的拼接(Concatenation)操作,將之前層的輸出與當前層的輸出拼接在一起,然後傳給下一層。對於大多數框架(如 Torch 和 TensorFlow),每次拼接操作都會開闢新的內存來保存拼接後的特徵。這樣就導致一個 L 層的網路,要消耗相當於 L(L+1)/2 層網路的內存(第 l 層的輸出在內存里被存了 (L-l+1) 份)。
解決這個問題的思路其實並不難,我們只需要預先分配一塊緩存,供網路中所有的拼接層(Concatenation Layer)共享使用,這樣
DenseNet 對內存的消耗便從平方級別降到了線性級別。在梯度反傳過程中,我們再把相應卷積層的輸出複製到該緩存,就可以重構每一層的輸入特徵,進而計算梯度。當然網路中由於 Batch Normalization 層的存在,實現起來還有一些需要注意的細節。總結
利用bottleneck layer,Translation layer以及較小的growth rate使得網路變窄,參數減少,有效抑制了過擬合,同時計算量也減少了。
推薦閱讀:
※ICLR 2018最佳論文重磅出爐!Adam新演算法、球形CNN等受關注
※【AAAI Oral】利用DeepMind的DQN解數學應用題,準確率提升15%
※小技巧之如何降低論文查重抄襲率
※如何在Econometrica上發表論文
※AAAI 2018最佳論文出爐,中國留學生再下一城
TAG:論文 |