DenseNet: Densely Connected Residual Network
解決的問題:
- 随着網絡層數加深梯度消失的問題:
As information about the input or gradient passes through many layers, it can vanish and “wash out” by the time it reaches the end (or beginning) of the network.
- 原來ResNet中有很多層的貢獻很少,在訓練的時候可以随機去掉:
Recent variations of ResNets show that many layers contribute very little and can in fact be randomly dropped during training.
新的結構:
一個L層傳統的卷積神經網絡隻有L個連接配接——每一層和它的下一層之間有一個連接配接。而這篇文章提出的Dense Convolutional Network (DenseNet) 有 L ( L − 1 ) 2 \frac{L(L-1)}{2} 2L(L−1)個連接配接。對每一層來說前面所有層的feature map都是它的輸入,而它的輸出的feature map又是後面所有層的輸入。
為什麼有很好的效果? 文章中是這樣解釋的:
Each layer has direct access to the gradients from the loss function and the original input signal, leading to an implicit deep supervision.
這句話大概就是在說每一層都能獲得來次損失函數的梯度資訊以及輸入的原始資訊,可以看成是一個隐式的監督的網絡。
優點:
- 減輕了梯度消失 (alleviate the vanishing-gradient problem)
- 增強了特征的傳遞 (strength feature propagation)
- 更有效的利用了特征資訊 (encourage feature reuse)
- 一定程度上減少了參數數量 (substantially reduce number of parameters)
DenseNet
一個L層的神經網絡,每一層都可以看做是一個非線性的映射 H l ( ⋅ ) H_{l}(\cdot) Hl(⋅), H l ( ⋅ ) H_{l}(\cdot) Hl(⋅)可以是一系列函數的組合例如BN、ReLU、Pooling、Convolution,用 X l X_l Xl表示 l t h l^{th} lth層的輸出,則可以用下面三個式子分别表示傳統的卷積神經網絡,原始的ResNet和DenseNet:
傳統的卷積神經網絡:
X l = H l ( X l − 1 ) X_\mathscr{l}=H_\mathscr{l}(X_\mathscr{l-1}) Xl=Hl(Xl−1)
ResNet:
X l = H l ( X l − 1 ) + X l − 1 X_\mathscr{l}=H_\mathscr{l}(X_\mathscr{l-1})+X_\mathscr{l-1} Xl=Hl(Xl−1)+Xl−1
DenseNet:
X l = H l ( [ X 0 , X 1 , . . . , X l − 1 ] ) X_\mathscr{l}=H_\mathscr{l}([X_\mathscr{0},X_\mathscr{1},...,X_\mathscr{l-1}]) Xl=Hl([X0,X1,...,Xl−1])
[ X 0 , X 1 , . . . , X l − 1 ] [X_\mathscr{0},X_\mathscr{1},...,X_\mathscr{l-1}] [X0,X1,...,Xl−1]表示 0 , . . . , l − 1 0,...,l-1 0,...,l−1層的拼接。從上面的式子還可以看出ResNet和DenseNet的一個差別:ResNet是将不同層的輸出加和作為下一層的輸入,而DenseNet是拼接。至于為什麼,文章中是這麼說的:
However, the identity function and output of H l H_l Hl are combined by summation, which may impede the information flow in the network.
大意是說加和會影響資訊在神經網絡的傳遞(???)。
Composite function
對于上面的複合函數 H l H_l Hl,在這篇文章中是這樣定義的: H l H_l Hl是三個連續操作的符合,這三個操作依次是BN、ReLU、3x3 convolution。
Pooling layers
神經網絡最重要的一點就是進行下采樣來改變feature-map的大小,在DenseNet并不會改變feature-map的大小。是以,為了實作下采樣作者将這個網絡分成多個不同的密集連接配接的dense block,在dense block之間添加了一個transition layer來做卷積和池化。這篇文章中作者使用的是1x1的卷積層接一個2x2的平均池化。
Growth rate
如果每個 H l H_l Hl 産生 k k k 個feature-maps,那麼第 l l l 層就會有 k 0 + k × ( l − 1 ) k_0+k\times(l-1) k0+k×(l−1) 個feature-maps作為輸入。很重要的一點是,與一般的神将網絡結構相比,DenseNet的每一層可以很窄,例如讓 k = 12 k=12 k=12。 文章将超參數 k k k 稱為 growth rate
Bottleneck layers
盡管每層隻輸出 k k k 個feature-maps,後面的層還是會有很多的輸入,有文章說到 1 × 1 c o n v o l u t i o n 1\times1\ convolution 1×1 convolution 可以被用作 b o t t l e n e c k l a y e r bottleneck\ layer bottleneck layer 來減少輸入的feature-maps的數量。是以作者設計了一種新的 H l H_l Hl: B N − R e L U − C o n v ( 1 × 1 ) − B N − R e L U − C o n v ( 3 × 3 ) BN-ReLU-Conv(1\times1)-BN-ReLU-Conv(3\times3) BN−ReLU−Conv(1×1)−BN−ReLU−Conv(3×3),将其稱為DenseNet-B。
Compression
為了進一步壓縮feature-map的數量,作者還用transition layer來減少輸入進dense block的feature-map的數量。作者設計了一個超參數 θ , 0 < θ ≤ 1 \theta,\ 0\lt\theta\le1 θ, 0<θ≤1 來控制壓縮的力度:如果一個dense block輸出了m個feature-maps,則可以通過它後面的transition layer把feature-map的數目減少到 ⌊ θ m ⌋ \lfloor\theta m\rfloor ⌊θm⌋。當同時使用了bottleneck 和 θ < 1 \theta\lt1 θ<1 的transition layer 時,作者将這樣的模型稱為 DenseNet-BC.
Experiments
下表是在三個資料集(C10,C100,SVHN)上和其他算法的對比結果。ResNet[11]就是kaiming He的論文。DenseNet-BC的網絡參數和相同深度的DenseNet相比确實減少了很多,參數減少除了可以節省記憶體,還能減少過拟合。這裡對于SVHN資料集,層數更多的DenseNet-BC的結果并沒有層數少的DenseNet (k = 24) 的效果好,作者認為原因主要是SVHN這個資料集相對簡單,更深的模型容易過拟合。在表格的倒數第二個區域的三個不同深度L和k的DenseNet的對比可以看出随着L和k的增加,模型的效果是更好的。
下圖是DenseNet-BC和ResNet在Imagenet資料集上的對比,左邊那個圖是參數複雜度和錯誤率的對比,右邊是flops和錯誤率的對比。
下圖中,左邊的圖表示不同類型DenseNet的參數數量和錯誤率的對比。中間的圖表示DenseNet-BC和ResNet在參數數量和錯誤率的對比,相同錯誤率下,DenseNet-BC的參數複雜度要小很多。右邊的圖也是表達DenseNet-BC-100隻需要很少的參數就能達到和ResNet-1001相同的結果。