最后一屆ImageNet冠軍模型:SENet

作者:小小將
編輯:黃俊嘉
01
主體思路
對(duì)于CNN網(wǎng)絡(luò)來說,其核心計(jì)算是卷積算子,其通過卷積核從輸入特征圖學(xué)習(xí)到新特征圖。從本質(zhì)上講,卷積是對(duì)一個(gè)局部區(qū)域進(jìn)行特征融合,這包括空間上(H和W維度)以及通道間(C維度)的特征融合。

圖1 CNN中的卷積操作
對(duì)于卷積操作,很大一部分工作是提高感受,即空間上融合更多特征融合,或者是提取多尺度空間信息,如Inception網(wǎng)絡(luò)的多分支結(jié)構(gòu)。對(duì)于channel維度的特征融合,卷積操作基本上默認(rèn)對(duì)輸入特征圖的所有channel進(jìn)行融合。而MobileNet網(wǎng)絡(luò)中的組卷積(Group Convolution)和深度可分離卷積(Depthwise Separable Convolution)對(duì)channel進(jìn)行分組也主要是為了使模型更加輕量級(jí),減少計(jì)算量。而SENet網(wǎng)絡(luò)的創(chuàng)新點(diǎn)在于關(guān)注channel之間的關(guān)系,希望模型可以自動(dòng)學(xué)習(xí)到不同channel特征的重要程度。為此,SENet提出了Squeeze-and-Excitation (SE)模塊,如下圖所示:

圖2 Squeeze-and-Excitation (SE)模塊
SE模塊首先對(duì)卷積得到的特征圖進(jìn)行Squeeze操作,得到channel級(jí)的全局特征,然后對(duì)全局特征進(jìn)行Excitation操作,學(xué)習(xí)各個(gè)channel間的關(guān)系,也得到不同channel的權(quán)重,最后乘以原來的特征圖得到最終特征。本質(zhì)上,SE模塊是在channel維度上做attention或者gating操作,這種注意力機(jī)制讓模型可以更加關(guān)注信息量最大的channel特征,而抑制那些不重要的channel特征。另外一點(diǎn)是SE模塊是通用的,這意味著其可以嵌入到現(xiàn)有的網(wǎng)絡(luò)架構(gòu)中。
02
Squeeze-and-Excitation (SE) 模塊
SE模塊主要包括Squeeze和Excitation兩個(gè)操作,可以適用于任何映射
,
,
,以卷積為例,卷積核為
,其中
表示第c個(gè)卷積核。那么輸出
:

其中*代表卷積操作,而
代表一個(gè)3D卷積核,其輸入一個(gè)channel上的空間特征,它學(xué)習(xí)特征空間關(guān)系,但是由于對(duì)各個(gè)channel的卷積結(jié)果做了sum,所以channel特征關(guān)系與卷積核學(xué)習(xí)到的空間關(guān)系混合在一起。而SE模塊就是為了抽離這種混雜,使得模型直接學(xué)習(xí)到channel特征關(guān)系。
Squeeze操作
由于卷積只是在一個(gè)局部空間內(nèi)進(jìn)行操作,
很難獲得足夠的信息來提取channel之間的關(guān)系,對(duì)于網(wǎng)絡(luò)中前面的層這更嚴(yán)重,因?yàn)楦惺芤氨容^小。為了,SENet提出Squeeze操作,將一個(gè)channel上整個(gè)空間特征編碼為一個(gè)全局特征,采用global average pooling來實(shí)現(xiàn)(原則上也可以采用更復(fù)雜的聚合策略):

Excitation操作
Sequeeze操作得到了全局描述特征,我們接下來需要另外一種運(yùn)算來抓取channel之間的關(guān)系。這個(gè)操作需要滿足兩個(gè)準(zhǔn)則:首先要靈活,它要可以學(xué)習(xí)到各個(gè)channel之間的非線性關(guān)系;第二點(diǎn)是學(xué)習(xí)的關(guān)系不是互斥的,因?yàn)檫@里允許多channel特征,而不是one-hot形式。基于此,這里采用sigmoid形式的gating機(jī)制:

其中
,
。為了降低模型復(fù)雜度以及提升泛化能力,這里采用包含兩個(gè)全連接層的bottleneck結(jié)構(gòu),其中第一個(gè)FC層起到降維的作用,降維系數(shù)為r是個(gè)超參數(shù),然后采用ReLU激活。最后的FC層恢復(fù)原始的維度。
最后將學(xué)習(xí)到的各個(gè)channel的激活值(sigmoid激活,值0~1)乘以U上的原始特征:

其實(shí)整個(gè)操作可以看成學(xué)習(xí)到了各個(gè)channel的權(quán)重系數(shù),從而使得模型對(duì)各個(gè)channel的特征更有辨別能力,這應(yīng)該也算一種attention機(jī)制。
03
SE模塊在Inception和ResNet上的應(yīng)用
SE模塊的靈活性在于它可以直接應(yīng)用現(xiàn)有的網(wǎng)絡(luò)結(jié)構(gòu)中。這里以Inception和ResNet為例。對(duì)于Inception網(wǎng)絡(luò),沒有殘差結(jié)構(gòu),這里對(duì)整個(gè)Inception模塊應(yīng)用SE模塊。對(duì)于ResNet,SE模塊嵌入到殘差結(jié)構(gòu)中的殘差學(xué)習(xí)分支中。具體如下圖所示:

圖3 加入SE模塊的Inception和ResNet網(wǎng)絡(luò)
同樣地,SE模塊也可以應(yīng)用在其它網(wǎng)絡(luò)結(jié)構(gòu),如ResNetXt,Inception-ResNet,MobileNet和ShuffleNet中。這里給出SE-ResNet-50和SE-ResNetXt-50的具體結(jié)構(gòu),如下表所示:

增加了SE模塊后,模型參數(shù)以及計(jì)算量都會(huì)增加,這里以SE-ResNet-50為例,對(duì)于模型參數(shù)增加量為:

其中r為降維系數(shù),S表示stage數(shù)量,
為第s個(gè)stage的通道數(shù),
為第s個(gè)stage的重復(fù)block量。當(dāng)r=16時(shí),SE-ResNet-50只增加了約10%的參數(shù)量。但計(jì)算量(GFLOPS)卻增加不到1%。
04
模型效果
SE模塊很容易嵌入到其它網(wǎng)絡(luò)中,作者為了驗(yàn)證SE模塊的作用,在其它流行網(wǎng)絡(luò)如ResNet和VGG中引入SE模塊,測(cè)試其在ImageNet上的效果,如下表所示:

可以看到所有網(wǎng)絡(luò)在加入SE模塊后分類準(zhǔn)確度均有一定的提升。此外,作者還測(cè)試了SE模塊在輕量級(jí)網(wǎng)絡(luò)MobileNet和ShuffleNet上的效果,如下表所示,可以看到也是有效果提升的。

最終作者采用了一系列的SENet進(jìn)行集成,在ImageNet測(cè)試集上的top-5 error為2.251%,贏得了2017年競(jìng)賽的冠軍。其中最關(guān)鍵的模型是SENet-154,其建立在ResNeXt模型基礎(chǔ)上,效果如下表所示:

05
SE模塊的實(shí)現(xiàn)
SE模塊是非常簡(jiǎn)單的,實(shí)現(xiàn)起來也比較容易,這里給出PyTorch版本的實(shí)現(xiàn)(參考(https://github.com/moskomule/senet.pytorch)):
class?SELayer(nn.Module):
????def?__init__(self,?channel,?reduction=16):
????????super(SELayer,?self).__init__()
????????self.avg_pool?=?nn.AdaptiveAvgPool2d(1)
????????self.fc?=?nn.Sequential(
????????????nn.Linear(channel,?channel?//?reduction,?bias=False),
????????????nn.ReLU(inplace=True),
????????????nn.Linear(channel?//?reduction,?channel,?bias=False),
????????????nn.Sigmoid()
????????)
????def?forward(self,?x):
????????b,?c,?_,?_?=?x.size()
????????y?=?self.avg_pool(x).view(b,?c)
????????y?=?self.fc(y).view(b,?c,?1,?1)
????????return?x?*?y.expand_as(x)對(duì)于SE-ResNet模型,只需要將SE模塊加入到殘差單元(應(yīng)用在殘差學(xué)習(xí)那一部分)就可以:
????class?SEBottleneck(nn.Module):
????????expansion?=?4
????????def?__init__(self,?inplanes,?planes,?stride=1,?downsample=None,?reduction=16):
????????????super(SEBottleneck,?self).__init__()
????????????self.conv1?=?nn.Conv2d(inplanes,?planes,?kernel_size=1,?bias=False)
????????????self.bn1?=?nn.BatchNorm2d(planes)
????????????self.conv2?=?nn.Conv2d(planes,?planes,?kernel_size=3,?stride=stride,
???????????????????????????????????padding=1,?bias=False)
????????????self.bn2?=?nn.BatchNorm2d(planes)
????????????self.conv3?=?nn.Conv2d(planes,?planes?*?4,?kernel_size=1,?bias=False)
????????????self.bn3?=?nn.BatchNorm2d(planes?*?4)
????????????self.relu?=?nn.ReLU(inplace=True)
????????????self.se?=?SELayer(planes?*?4,?reduction)
????????????self.downsample?=?downsample
????????????self.stride?=?stride
????????def?forward(self,?x):
????????????residual?=?x
????????????out?=?self.conv1(x)
????????????out?=?self.bn1(out)
????????????out?=?self.relu(out)
????????????out?=?self.conv2(out)
????????????out?=?self.bn2(out)
????????????out?=?self.relu(out)
????????????out?=?self.conv3(out)
????????????out?=?self.bn3(out)
????????????out?=?self.se(out)
????????????if?self.downsample?is?not?None:
????????????????residual?=?self.downsample(x)
????????????out?+=?residual
????????????out?=?self.relu(out)
????????????return?out
06
小 結(jié)
SE模塊主要為了提升模型對(duì)channel特征的敏感性,這個(gè)模塊是輕量級(jí)的,而且可以應(yīng)用在現(xiàn)有的網(wǎng)絡(luò)結(jié)構(gòu)中,只需要增加較少的計(jì)算量就可以帶來性能的提升。另外最新的CVPR 2019有篇與SENet非常相似的網(wǎng)絡(luò)SKNet([Selective Kernel Networks](https://arxiv.org/abs/1903.06586)),SKNet主要是提升模型對(duì)感受野的自適應(yīng)能力,感興趣可以深入看一下。
參考文獻(xiàn)
1.[Squeeze-and-Excitation Networks](https://arxiv.org/abs/1709.01507)
2.[CVPR2017 WorkShop](http://image-net.org/challenges/talks_2017/SENet.pdf)
?
END
往期回顧之作者小小將
【2】深入理解one-stage目標(biāo)檢測(cè)算法(上篇)?
【3】深入理解one-stage目標(biāo)檢測(cè)算法(下篇)?
【5】輕量級(jí)CNN網(wǎng)絡(luò)之MobileNetv2
【6】ShuffleNetV2:輕量級(jí)CNN網(wǎng)絡(luò)中的桂冠
【7】深入理解TensorFlow中的tf.metrics算子
【9】目標(biāo)檢測(cè)|YOLOv2原理與實(shí)現(xiàn)(附Y(jié)OLOv3)
機(jī)器學(xué)習(xí)算法工程師
? ? ? ? ? ? ? ? ? ? ? ? ? ? 一個(gè)用心的公眾號(hào)
進(jìn)群,學(xué)習(xí),得幫助
你的關(guān)注,我們的熱度,
我們一定給你學(xué)習(xí)最大的幫助
