0. Paper link
DenseNet
另外,關於DenseNet需要內存優化等,但我目前還看不懂。。先mark一下,之后再去學習:傳送門
1. Overview
文章開篇提到了如果在靠近輸入與輸出的層之間存在短連接(shorter connections),可以訓練更深、更准確、更有效的卷積網絡,DenseNet利用了這個性質,每層都與之前所有的層進行連接,即之前所有層的feature map都作為這一層的輸入。DenseNet有減少梯度消失,增強特征傳遞,鼓勵特征重利用同時極大的減少了參數的數量。在很多任務上達到了state-of-the-art.
另外DenseNet並不是像ResNet那樣在傳入下一層之前把特征進行相加,如同GoogLeNet一樣他把feature進行融合,因此\(l^{th}\)有\(l\)個輸入包括前面所有的卷積塊(convolutional blocks), 另外雖然叫DenseNet,但是他比傳統的卷及網絡需要更少的參數,因為他沒有必要重新學習多余的特征圖(stochastic ResNet證明ResNet其實有很多沒有用的層數),DenseNet層很窄(例如每一層有12個濾波器),僅僅增加小數量的特征圖到網絡的“集體知識”(collective knowledge),並且保持這些特征圖不變——最后的分類器基於網絡中的所有特征圖進行預測。
除了具有更好的參數利用率,DenseNets還有一個優點是它改善了網絡中信息和梯度的傳遞,這就讓網絡更容易訓練。每一層都可以直接利用損失函數的梯度以及最開始的輸入信息,相當於是一種隱形的深度監督(implicit deep supervision)。這有助於訓練更深的網絡。此外,作者還發現稠密連接有正則化的作用,在更少訓練集的任務中可以降低過擬合。
文章構建了如圖上圖的“dense block”每一個block內部feature size是相同的, 在中間的transition layer進行feature size的改變與傳遞。同時還設置了growth rate來調節網絡的size。
感覺DenseNet充分的利用了feature之間的fusing,其實在看完ResNet的時候,我就這種想法,為什么ResNet大多數shortcut只是跨過2-3層呢,作者提到實驗這些效果最好,他實驗的range是多少呢?為什么不能多跨過幾個,讓模型fuse的更多呢,當時覺得硬性規定shortcut的范圍並不是很好,感覺至少要學習一個參數去學習具體應該多少,每一層都去學習一個參數或許更好。而DenseNet則直接把所有的feature融合在一起,達到了一個所有feature作為一個“大feature”,結合GoogLeNet的一些思想,這個模型的提出並不難理解的,難得往往是第一個提出來的思想,比如AlexNet,現在也忘不了第一次見到ResNet的興奮感與新奇感,也讓我愛上了算法,找到了當初ACM的感覺(廢話說多了)。
2. DenseNet Architecture
設\(H_{l}(·)\)為一個非線性轉化(transformation),\(H_{l}(·)\)可以是BN層,ReLU,poolinghuozhe Conv的一個組合function,設一共有\(L\)層,\(l^{th}\)層的輸出為\(x_{l}\)
2.1 Analogy to ResNet
ResNet的形式如下:
很顯然他是把\(l-1\)層的輸出與殘差映射的值相加起來,作者提到這可能影響到信息在網絡中的流動。
DenseNet的形式如下:
即\(l\)層的輸入是0到\(l-1\)層的輸出串聯起來,實際操作中會把前\(l-1\)層的輸入放進一個單獨的張量中(tensor)
2.2 Composite function
在DenseNet中,定義\(H_{l}(·)\)為一個BN層后面接着ReLU層和一個3 × 3卷積的復合型函數
2.3 Dense block and Transition layer
很容易發現如果某一層的前\(l-1\)層的向量size不同,就無法拼接起來,因此受GoogLeNet的啟發,把densely connected的部分組成一個dense block,在兩個dense block中間引入transition layer,用來卷積與池化。在文章實驗中transition layer包括一個BN層和1 × 1卷積層在緊接着一個2×2 average pooling layer。
2.4 Growth rate
如果\(H_l\)產生\(k\)個feature maps, 那么\(l^{th}\)有 \(k_0 + k×(l-1)\)層input feature maps,其中\(k_0\)是輸入層的channels,DenseNet的一個很好的優點就是DenseNet可以變得很窄,比如\(k = 12\),把\(k\)作為一個超參數,叫做\(growth\ rate\),文章實驗證明了很小的\(k\)也可以獲得很多state-of-the-art的結果。
作者把這一部分進行了解析,每一層都接收之前所有層的feature,相當於獲得了“集體知識(collective knowledge)”,作者提出把feature maps看做一個網絡的總體階段(global state),每一層貢獻自己k個feature maps給這個階段,growth rate決定了每層貢獻多少新的信息給global state。
2.5 Bottleneck layers
盡管每層只產生k個feature maps,但是把之前所有層都加起來還是很多的,因此引入一個1 × 1的\(bottleneck layers\)在每個3 × 3卷積之前來減少輸入的feature maps,文章中給出了非常適合DenseNet的bottleneck layer: BN-ReLU-Conv(1 × 1)-BN-ReLU-Conv(3 × 3),把這種形式的\(H_l\)表示為DenseNet-B,在實驗中,讓每個1 × 1 卷積產生4k個feature maps。
2.6 Compression
如果一個dense block 包含m個feature maps, 讓緊接着的transition layer 產生\([\theta m]\)個 output feature-maps,其中\(0< \theta \leq 1\)代表壓縮因子(compression factor),把\(\theta < 1\)的DenseNet看作DenseNet-C,把同時帶有bottleneck layer與compression factor < 1的DenseNet稱為DenseNet-BC.
2.7 Global Network Architecture
一個整體的結構圖:
網絡參數:(注意Conv代表BN-ReLU-Conv)
3. Experiments
在某篇博客摘取了一個網絡訓練參數設置,同時這篇博客講解的也不錯
DenseNet在CIFAR與SVHN數據集上與各種主流網絡的參數與錯誤率對比:
DenseNet在ImageNet 驗證集上1-crop / 10-crop對比:
DenseNet在ImageNet 驗證集上與ResNet控制變量對比:
DenseNet在C10+ 驗證集上與ResNet控制變量對比:
4. Discussion
隱含的深度監督(implicit deep supervision)。稠密卷積網絡可以提升准確率的一個解釋是,由於更短的連接,每一層都可以從損失函數中獲得監督信息。可以將DenseNets理解為一種“深度監督”(deep supervision)。深度監督的好處已經在之前的深度監督網絡(DSN)中說明,該網絡在每一隱含層都加了分類器,迫使中間層也學習判斷特征(discriminative features)。
DensNets和深度監督網絡相似:網絡最后的分類器通過最多兩個或三個過渡層為所有層都提供監督信息。然而,DenseNets的損失函數值和梯度不是很復雜,這是因為所有層之間共享了損失函數。
遵循這個簡單的連接規則,DenseNets可以很自然的將自身映射(identity mappings)、深度監督(deep supervision)和深度多樣化(diversified depth)結合在一起。
5. Memory
DenseNet 在訓練時對內存消耗非常厲害。這個問題其實是算法實現不優帶來的。當前的深度學習框架對 DenseNet 的密集連接沒有很好的支持,我們只能借助於反復的拼接(Concatenation)操作,將之前層的輸出與當前層的輸出拼接在一起,然后傳給下一層。對於大多數框架(如 Torch 和 TensorFlow),每次拼接操作都會開辟新的內存來保存拼接后的特征。這樣就導致一個 L 層的網絡,要消耗相當於 L(L+1)/2 層網絡的內存(第 l 層的輸出在內存里被存了 (L-l+1) 份)。
解決這個問題的思路其實並不難,我們只需要預先分配一塊緩存,供網絡中所有的拼接層(Concatenation Layer)共享使用,這樣
DenseNet 對內存的消耗便從平方級別降到了線性級別。在梯度反傳過程中,我們再把相應卷積層的輸出復制到該緩存,就可以重構每一層的輸入特征,進而計算梯度。當然網絡中由於 Batch Normalization 層的存在,實現起來還有一些需要注意的細節。