1. 程式人生 > >CNN: 1x1卷積層的精妙之處

CNN: 1x1卷積層的精妙之處

現在各種神經網路都會用到1x1 conv,它到底起到什麼作用呢?要回答這個問題,先從最經典的Inception模型說起,Figure 1是Inception-ResNet-v2的block架構圖。

Figure 1: https://arxiv.org/pdf/1602.07261.pdf

作用一:改變矩陣維度

block中每個sublayer的第一層都1x1 conv,它在這裡的作用之一是降維,減少運算量–feature map channel數越少,卷積操作需要的計算量越小。但就像影象壓縮一樣,壓縮率越大丟幀越多,1x1 conv是如果做到在質量與速度的平衡的呢?

Figure 2

Figure 2中間圖形就是1x1卷積核,左邊的矩陣是input,而右邊的正方形代表feature map中的一個grid,或一個pixel,它是1x1卷積核其中一個channel:(1x1x1),與input矩陣對應pixel位置的pixel-wise向量:(1x1x32)的點積的結果。當input矩陣與1x1卷積核完成所有pixel位置(4x4)的點積計算後,會得到一個4x4x1 shape的feature map,grid size不變,整個過程相當於把一個3D矩陣壓縮為一個2D矩陣。feature map經過非線性(啟用函式)計算後,每個pixel位置就相當於input矩陣對應pixel位置的pixel-wise向量的均值。這就是為什麼神經網路會用1x1 conv來改變矩陣維度的原因,無論是降維還是升維,矩陣的性質不變,所以可以構造出各種結構的神經網路

要特別注意的是,這裡的一個Conv層並不是只有一個conv(),而是conv()、droupout()、BN()和ReLu()等組合。Conv層是CNN的底層模組,每個神經網路都有自己的定義,例如:

def Conv(nin, nf, stride=1):
  return nn.Sequential(
      nn.Conv2d(nin, nf, 3, stride, 1, bias=False),
      nn.BatchNorm2d(nf),
      nn.ReLU(inplace=True)
  )

作用二:增加非線性

Figure 3: https://arxiv.org/pdf/1512.03385.pdf

Figure 3是Resnet-18/34/50/101/152

的block架構圖,圖中黃色框位置是Resnet-50的一個block,它由三個Conv層組成,開頭和結尾都是1x1 conv,三個block組成一個conv2_x層。把這三個block展開你會發現一個很有趣的結構,即block中的第二層、第三層,以及下一個block的第一層組成了一個如Figure 4,稱為“bottleneck”的從低緯到高維又到低維的網路,bottleneck是瓶頸的意思,它是從一個空間到另一個大(或小)空間的過度地帶,“小->大->小”或“大->小->大”都是bottleneck network。

Figure 4

前文已經分析了1x1 conv不會對矩陣的性質產生大影響,Resnet-50為什麼要引入bottleneck,而不是像隔壁Resnet-34那樣每個block的卷積核維數都是相同的呢?原因有兩個:

  • 如上前文所述,矩陣降維可以減小所需運算量。深層神經網路的計算量可能會隨層數增加呈指數增長,所以,Resnet-50/101/152都引入了1x1conv,1x1卷積核相比3x3卷積核所需計算量更少。
  • 增加神經網路非線性程度。增加非線性可以增加神經網路的複雜度,複雜的神經網路才可以更精確地逼近任意函式(或數學模型),而1x1 conv可以用較低運算成本通過改變channel維度為網路增加複雜度。如果對非線性與神經網路的關係有疑問,可以閱讀我另一篇博文你真的明白神經網路是什麼?

總結

1x1卷積層可以在不改變矩陣性質的情況下,可以靈活地變化矩陣channel的維度,不僅可以給矩陣降維減輕運算量,還可以構建bottleneck來增加網路複雜度使其可以逼近更精確的目標數學模型。

Refences