Squeeze-and-Excitation Networks
簡介
SENet提出了一種更好的特征表示結構,通過支路結構學習作用到input上更好的表示feature。結構上是使用一個支路去學習如何評估通道間的關聯,然后作用到原feature map上去,實現對輸入的校准。支路的幫助學習到的是神經網絡更加適合的表示。為了使網絡通過全局信息來衡量通道關聯,結構上使用了global pooling捕獲全局信息,然后連接兩個全連接層,作用到輸入上去,即完成了對輸入的重校准,可以使網絡學習到更好的表示。
SQUEEZE-AND-EXCITATION BLOCKS
一個block的結構大致如下:
上圖中Fsq是Squeeze過程,Fex是Excitation過程,然后通過Fscale將學習到的權重作用在輸入上。
Squeeze: Global Information Embedding
作者將Squeeze過程稱為global information embedding的過程,因為squeeze的過程實際上是對feature map利用global pooling來整合全局特征。
Excitation: Adaptive Recalibration
作者將Excitation過程稱為重校准過程,因為此過程通過支路學習到的權重,作用到原輸入上去,要實現對每個通道進行打分,即網絡學習到通道score,則必須要學習到非線性結果,所以作者采用fc-relu-fc-sigmoid的excitation結構來實現score映射。
根據作者論文中的舉例,可以清楚看到以Inception為例的Squeeze和Excitation過程:
而Fscale過程就是對應相乘,把每個通道的權重對應乘上input的對應通道feature。
這個論文比較好理解。
簡單寫了一個block:
import torch
import torch.nn as nn
class SEModule(nn.Module):
def __init__(self,r = 3):
super(SEModule,self).__init__()
self.global_pooling = nn.MaxPool2d(128)
self.fc1 = nn.Linear(64,64//r)
self.relu1 = nn.ReLU(64//r)
self.fc2 = nn.Linear(64//r,64)
self.sigmoid = nn.Sigmoid()
def forward(self,x):
se_x = self.global_pooling(x)
se_x = self.fc1(se_x.view(-1,64))
se_x = self.relu1(se_x)
se_x = self.fc2(se_x)
se_x = self.sigmoid(se_x).view(-1,64,1,1)
return x * se_x
if __name__ =="__main__":
from torchsummary import summary
model = SEModule()
summary(model,(64,128,128),device = "cpu")
'''
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
MaxPool2d-1 [-1, 64, 1, 1] 0
Linear-2 [-1, 21] 1,365
ReLU-3 [-1, 21] 0
Linear-4 [-1, 64] 1,408
Sigmoid-5 [-1, 64] 0
================================================================
Total params: 2,773
Trainable params: 2,773
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 4.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.01
Estimated Total Size (MB): 4.01
----------------------------------------------------------------
'''