卷積神經網絡 CNN 經典模型 — GoogleLeNet、ResNet、DenseNet with Pytorch code

李謦伊
謦伊的閱讀筆記
11 min readOct 8, 2020

--

上篇文介紹了CNN 的經典模型 LeNet、AlexNet、VGG、NiN,本篇將要來講 GoogleLeNet、ResNet、DenseNet,一樣是使用 Kaggle 的貓狗圖像作為訓練集

所有的 code 都放在我的 Github 裡

GoogLeNet (Inception-V1,2014)

論文連接: https://wmathor.com/usr/uploads/2020/01/3184187721.pdf

GoogLeNet 是由 Google 開發的,比 AlexNet 參數量少,但網路更深、準確率更高,在 2014 年 ImageNet LSVRC 分類競賽中獲得了冠軍

GoogLeNet 受到 NiN 的啟發,透過多個小基礎模組串聯成大網路,這個小網路模組稱之為 Inception module

  • Inception module

Inception module 一開始採用下圖 (a),透過三種不同大小的卷積以及 3x3 Maxpooling 萃取出不同的特徵,再將這四個結果以通道軸串接在一起。這樣增加網路寬度的方式,能夠擷取更多圖片的特徵與細節

但若是這四個結果的尺寸不同,則卷積層與池化層皆使用 padding=”same”、stride=1,以確保輸入特徵圖的尺寸

後來為了降低訓練參數量,Inception module 在原先的架構中加入一些 1x1 卷積層 (圖b)。改良後的 Inception module 會先透過 1x1 卷積層降低輸出通道數後,再接上原本的卷積層。此外,由於池化層沒辦法降低通道為數,因此輸入特徵圖在通過 3x3 Maxpooling 後,會再使用 1x1 卷積層來降低輸出通道數

將四個結果以通道軸串接在一起 (source)

❓ 1x1 卷積層如何降低輸出通道數及參數量?

先看接了一層 3x3 卷積層的參數量,由下圖所示,參數量為 [3x3x192 + 1] x 128 = 106112

接著來看先接 1x1 卷積層,再接 3x3 卷積層的參數量為 [1x1x192 + 1] x 64 + [3x3x64 + 1] x 128 = 86208

從原先的參數量 106112 降至 86208個,因此之後的 Inception module 都是使用改良過的版本

介紹完 Inception module 後,接著要來講 GoogLeNet 的模型架構。下圖為 GoogLeNet 的模型架構,由下至上為輸入到輸出。橘色的框框為 Inception module,而粉色的框框為分類輔助器 (auxiliary classifiers)

GoogLeNet 是深層的神經網路,因此會遇到梯度消失的問題。分類輔助器就是為了避免這個問題,並提高其穩定性和收斂速度,下圖為分類輔助器的架構。方法是會在兩個不同層的 Inception module 輸出結果並計算 loss,最後在將這兩個 loss 跟真實 loss 加權總和,計算出總 loss,其中 Inception module 的 loss 權重值為 0.3

total_loss = real_loss + 0.3 * aux_loss_1 + 0.3 * aux_loss_2

auxiliary classifiers

接下來看 Inception-V1 code~ 分別定義了 InceptionV1 block、auxiliary classifiers,再將這兩個模組組合成 InceptionV1,其中輔助分類器只在訓練時使用

ResNet (2015)

論文連接: https://arxiv.org/pdf/1512.03385.pdf

ResNet 在 2015 年由微軟的何愷明博士提出,並於同年 ImageNet LSVRC 分類競賽中獲得了冠軍,同時也在ImageNet detection、ImageNet localization、COCO detection和COCO segmentation等任務中均獲得了第一名,此外還獲得了 CVPR2016 最佳論文獎

在競賽中 ResNet 一共使用了 152 層網路,其深度比 GoogLeNet 高了七倍多 (20層),並且錯誤率為 3.6%,而人類在 ImageNet 的錯誤率為 5.1%,已經達到小於人類的錯誤率的程度

ResNet 為何能夠如此厲害!! 原因是因為在 ResNet 問世之前,神經網路一直無法做更深層的訓練,而 ResNet 提出的 Residual Learning 能夠讓深層網路更容易訓練,開啟了超深網路的時代

至於神經網路無法做更深層的訓練是什麼意思? 隨著網路層數的增加到達一定的程度時,反而會降低訓練準確率。由下圖就可以看出 56 層的網路表現比 20 層還差,但這並不是因為過擬合的問題,而是深層網路的退化問題 (degradation)

Degradation 就是指當網路層數越來越高時,梯度在做反向傳播法的過程中消失,導致梯度無法傳遞對參數進行更新,以至於越深的網路訓練效果越差

ResNet 的特色在於使用了 Shortcut Connection 的結構,一共有兩個分支:一個是將輸入的 x 跨層傳遞,而另一個就是 F(x)。將這兩個分支相加再送到激活函數中,這樣的方式稱做 Residual Learning,可以解決模型退化的問題 (degradation)

❓ Residual Learning 是怎麼解決模型退化的問題?

由 Residual Learning 我們可以知道輸出為 F(x) + x,首先令這個式子等於 H(x),也就是輸出值為 H(x) = F(x) + x

當網路訓練達到飽和的時候,F(x) 容易被優化成 0,這時只剩下 x,此時 H(x) = x,這樣的情況就是 Identify mapping (恆等映射)

先來看一下 Identify mapping 的定義

設 M為一集合,於 M上的恆等函數 f被定義於一具有定義域和對應域 M的函數,其對任一 M內的元素x,會有 f(x)=x 的關係

這段話的意思其實就是指輸入函數的值會等於輸出函數的值,因此越深的網路,也能確保準確率不會下降

  • Residual Block

Residual 一樣採用模組化的方式,針對不同深度的 ResNet,作者提出了兩種Residual Block

下圖 (a) 為基本的 Residual Block,使用連續的兩個 3x3 卷積層,並每兩個卷積層進行一次 Shortcut Connection,用於 ResNet-34

下圖 (b) 則是針對較深的網路所做的改進,稱為 bottleneck。因為層數越高,導致訓練成本變高,因此為了要降低維度,再送入 3x3 卷積層之前,會先通過 1x1 卷積層降低維度,最後再通過 1x1 卷積層恢復原本的維度。用於 ResNet-50、ResNet-101、ResNet-152

  • ResNet 架構

下圖為 ResNet 不同層數的網路架構,可以看到第一層為 7x7 的卷積層,接上 3x3 Maxpooling,接著再使用大量的 Residual Block,最後使用全域平均池化 (Global Average Pooling) 並傳入全連接層進行分類

下圖為 ResNet-34 的網路模型圖,虛線部分就是指在做 Shortcut Connection 時,輸入的 x 與權重輸出的 F(x) 通道 (channel) 數目不同,因此需要使用1x1 卷積層調整通道維度,使其可以做相加的運算

看完了 ResNet 架構就來看一下 code 吧!剛剛有講到 ResNet 針對不同深度提出了兩種 Residual Block,所以 code 裡分別有定義 basic_block 及 bottleneck_block 兩種模組

DenseNet (2017)

論文連接: https://arxiv.org/pdf/1608.06993.pdf

DenseNet 有別於以往的神經網絡,不從網路深度與寬度著手,而是由特徵的角度去考慮,通過特徵重用的方式,加強了特徵的利用、減輕梯度消失的問題、大幅地減少了參數計算量,並達到更好的準確率,因而獲得了 CVPR 2017 最佳論文

那 DenseNet 是怎麼由特徵的角度去考慮的呢? 其作法就是將前面所有層的 feature map 作為輸入,然後將其 concate 起來聚合信息,如此一來可以保留前面的特徵,稱為特徵重用 (feature reuse),讓結構更加密集,提高了網絡的信息和梯度流動,使得網絡更加容易訓練

而這個特徵重用的想法是來自於 ResNet 的 Shortcut Connection 思想,但不同的是 ResNet 是將 feature map 做跨通道的相加,而 DenseNet 則是以通道軸做串接的動作

source

DenseNet 由 Dense block 與 Transition layer (過渡層) 所組成,Dense block 就是剛剛說到的特徵重用的部分,而 Transition layer 就是將兩個相鄰的 Dense block 做連接

下圖是 DenseNet 的網路架構,總共有三個 Dense block,並且兩個 block 之間的卷積層與池化層為 transition layer,全域平均池化 (Global Average Pooling) 以及全連接層

source
  • Dense block

Dense block 採用 Batch Normalization、ReLU、3x3 卷積層的結構,與 ResNet block 不同的是 Dense block 有個超參數 k 稱為 growth rate,是指每層輸出的 channel 數目為 k 個 (輸出通道數會隨著層數而增加)。為了不使網路變寬,通常使用較小的 k

source
  • Bottleneck Layer

因為特徵重用的因素,輸出通道數會隨著層數而增加,因此 Dense block 可以採用 Bottleneck 來降低通道維度、減少參數計算量

Bottleneck 的結構為 Batch Normalization、ReLU、1x1 卷積層、Batch Normalization、ReLU、3x3 卷積層,稱為 DenseNet-B

source
  • Transition Layer

Transition layer 目的是為了要壓縮模型,使模型不會過於複雜,主要是將兩個 Dense block 去做連接。由於 Dense block 的輸出通道數目很多,會有通道數過長的問題,因此需要使用 1x1 卷積層來降維,並且使用平均池化來縮小特徵圖的尺寸

  • DenseNet 架構

下圖為 DenseNet 不同層數的網路架構,可以看到第一層為 7x7 的卷積層,接上 3x3 Maxpooling,接著再使用大量的 Dense Block、Transition Layer,最後使用全域平均池化 (Global Average Pooling) 並傳入全連接層進行分類

然後來看 code 吧! 前面有說到一開始的 Dense block 是採用 Batch Normalization、ReLU、3x3 卷積層的結構,但後來為了要降低通道維度就改採用 Bottleneck。在 code 裡還是都有定義,只是 DenseNet 的結構是使用 Bottleneck~

那本文的 CNN 經典模型就介紹到這邊啦~

--

--