1. 程式人生 > >我讀DenseNet

我讀DenseNet

背景

之前聽說過DenseNet,再次被提起是因為七月初上交大主辦的SSIST 2017,Yann Lecun的一頁PPT,將其地位放置到如此之高,查了一下是CVPR 2017的一篇Oral,於是下定決心好好拜讀一下。1
這裡寫圖片描述
文章地址:https://arxiv.org/abs/1608.06993
程式碼地址:Torch版本TensorFlow版本MxNet版本Caffe版本

方法

我們回顧一下ResNet,大意就是本層的啟用值與本層的輸入,作為本層的輸出。換一種方式理解,第l層的啟用值不僅僅影響l+1層,而且還影響l+2層。那麼由此及廣,我們可不可以讓第l層的啟用值一直影響到第l+k

層呢?這樣就有了本文的基本思想,稠密就是從這裡產生。好處如下:
這裡寫圖片描述

  • 與傳統的卷積網路相比,需要更少的引數就能得到相同的效果。這裡指出一點,引數少並不意味計算量降低,實驗前向速度並未比ResNet降低。作者給出的原因是每層的輸入包括之前的所有層,所以可以避免傳統網路中冗餘的層;
  • Densenet改變了傳統網路反向傳遞時,梯度(資訊)傳播方式,由線性變成樹狀反向,這樣的好處就在於減少了梯度消失的可能,並且加速訓練,有利於更深層網路的訓練;
  • 作者發現稠密的網路結構有類似正則功能,在小資料集合上更好的避免過擬合。

實現

對於輸入影象x0定義一個L層的網路,他的第l層是一個非線性變換(如BN,ReLU,Conv等),設為H

l(·),輸出為xl,那麼我們一般有

xl=Hl(xl1),在ResNet中我們有xl=Hl(xl1)+xl1。作者指出由於單純使用求和操作可能會干擾網路訊號的傳遞。於是提出不是簡單求和,而是將前面的結果放入新的channel通道,然後進行非線性操作,於是我們有xl=Hl([x0,x1,...,xl1])。同ResNet一樣,這裡的Hl(·)是BN+ReLU+Conv的組合。但是我們可以看到在上面的[x0,x1,...,xl1]如果維度的尺寸不同的話,無法進行操作的,於是作者使用了模組的方式,模組內部沒有Pooling操作,這樣避免了形狀不同。模組之間有Pooling操作。如下圖
這裡寫圖片描述
作者又嘗試了H
l
(·)
輸出channels個數(記為k)對消耗和結果的影響,channels個數越多網路引數越多,計算量更大。
  • Hl(·)是BN+ReLU+Conv(1x1)+BN+ReLU+Conv(3x3)的組合,這種網路記為Densenet-B
  • 假設Dense模組之間的卷積輸出channels個數是模組輸出層數的θ倍,如果θ<1網路記為Densenet-C,一般我們設θ=0.5
  • 同時上面兩種情況記為網路Densenet-BC

網路引數不放了,直接結果:
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述