第六週:論文泛讀(一)
1、《Selective Kernel Networks》
論文原址:https://arxiv.org/pdf/1903.06586.pdf
開源參考地址:github: https://github.com/implus/SKNet
SKNet核心思想是用多尺度的特徵獲得通道級別的權重,使用5×5的Kernel提升精度,採用普遍的Attention操作。為降低引數量,使用GroupConvolution做trade off
簡單來說,SKNet將原始的feature map經過不同大小的kernel得到多個特徵圖,特徵圖相加得到U,用全域性平均池化沿著H*W維度進行平均,獲得關於channel的C×1×1的一維向量,通過線性變換將C維對映到Z維,再使用線性變換(個數與kernel的個數一致)從Z維對映到C維,獲得channel維度的資訊提取,再使用softmax進行歸一化,代表channel的重要程度(相當於mask)。這三個mask與多個特徵圖相乘得到三個模組,相加後得到最終模組A。(先分支-再合併
程式碼:
1 import torch.nn as nn 2 import torch 3 class SKConv(nn.Module): 4 def __init__(self, features, WH, M, G, r, stride=1, L=32): 5 super(SKConv, self).__init__() 6 d = max(int(features / r), L) 7 self.M = M 8 self.features = features 9 self.convs = nn.ModuleList([])10 for i in range(M): 11 # 使用不同kernel size的卷積 12 self.convs.append( 13 nn.Sequential( 14 nn.Conv2d(features, 15 features, 16 kernel_size=3 + i * 2, 17 stride=stride,18 padding=1 + i, 19 groups=G), nn.BatchNorm2d(features), 20 nn.ReLU(inplace=False))) 21 22 self.fc = nn.Linear(features, d) 23 self.fcs = nn.ModuleList([]) 24 for i in range(M): 25 self.fcs.append(nn.Linear(d, features)) 26 self.softmax = nn.Softmax(dim=1) 27 def forward(self, x): 28 for i, conv in enumerate(self.convs): 29 fea = conv(x).unsqueeze_(dim=1) 30 if i == 0: 31 feas = fea 32 else: 33 feas = torch.cat([feas, fea], dim=1) 34 fea_U = torch.sum(feas, dim=1) 35 fea_s = fea_U.mean(-1).mean(-1) 36 fea_z = self.fc(fea_s) 37 for i, fc in enumerate(self.fcs): 38 print(i, fea_z.shape) 39 vector = fc(fea_z).unsqueeze_(dim=1) 40 print(i, vector.shape) 41 if i == 0: 42 attention_vectors = vector 43 else: 44 attention_vectors = torch.cat([attention_vectors, vector], 45 dim=1) 46 attention_vectors = self.softmax(attention_vectors) 47 attention_vectors = attention_vectors.unsqueeze(-1).unsqueeze(-1) 48 fea_v = (feas * attention_vectors).sum(dim=1) 49 return fea_v 50 if __name__ == "__main__": 51 t = torch.ones((32, 256, 24,24)) 52 sk = SKConv(256,WH=1,M=2,G=1,r=2) 53 out = sk(t) 54 print(out.shape)
2、《Strip Pooling: Rethinking Spatial Pooling for Scene Parsing》
程式碼地址:https://github.com/Andrew-Qibin/SPNet
作者提出長條性的Kernel應用於特定場景,使用了兩個模組:SPM(在橫向與縱向backbone的feature map上進行global pooling操作,增大網路感受野,用於優化特徵圖)、MPM(對backbone部分和backbone上模組進行優化)
(1)Strip Pooling Module
分別在垂直方向和水平方向做池化操作,再應用卷積核為3的一維卷積進行調和,再expand到原先的特徵圖大小,再將兩個特徵圖進行融合,添加了1×1的卷積用於改變channel個數。經過sigmoid啟用函式後獲得權重矩陣再與原特徵圖進行點乘得到最後的結果,這就類似於attention機制。
(2)Mixed Pooling Module金字塔模型
MPM由兩個子模組(長依賴和短依賴)構成。上圖(a)是針對短依賴,類似金字塔模型,使用輕量化的PPM模組進行設計,解決區域性依賴問題。上圖(b)是針對長依賴,使用strip pooling操作替換原有的全域性平均池化操作。
1 ### 通過AdaptiveAvgPool2d實現strip pooling 2 self.pool1 = nn.AdaptiveAvgPool2d(pool_size[0]) 3 self.pool2 = nn.AdaptiveAvgPool2d(pool_size[1]) 4 self.pool3 = nn.AdaptiveAvgPool2d((1, None)) 5 self.pool4 = nn.AdaptiveAvgPool2d((None, 1)) 6 7 ## SPM模組 8 def forward(self, x): 9 _, _, h, w = x.size() 10 x1 = self.conv1_1(x) 11 x2 = self.conv1_2(x) 12 x2_1 = self.conv2_0(x1) 13 x2_2 = F.interpolate(self.conv2_1(self.pool1(x1)), (h, w), **self._up_kwargs) 14 x2_3 = F.interpolate(self.conv2_2(self.pool2(x1)), (h, w), **self._up_kwargs) 15 x2_4 = F.interpolate(self.conv2_3(self.pool3(x2)), (h, w), **self._up_kwargs) 16 x2_5 = F.interpolate(self.conv2_4(self.pool4(x2)), (h, w), **self._up_kwargs) 17 x1 = self.conv2_5(F.relu_(x2_1 + x2_2 + x2_3)) 18 x2 = self.conv2_6(F.relu_(x2_5 + x2_4)) 19 out = self.conv3(torch.cat([x1, x2], dim=1)) 20 return F.relu_(x + out)
3、《HRNet:Deep High-Resolution Representation Learning for Human Pose Estimation》
論文地址:https://arxiv.org/pdf/1902.09212.pdf
github:https://github.com/leoxiaobin/deep-high-resolution-net.pytorch
動機:
- 分類網路並不適合區域層次和畫素層次的問題,因為學到的表徵本質上具有低解析度的特點,在解析度上的巨大損失使得其在對空間精度敏感的任務上很難取得準確的預測結果;
- 作者認為不應該侷限於從分類卷積神經網路生成的低解析度表徵來恢復高解析度表徵這一路線,而應該為高解析度表徵學習建立新的網路結構。
方法:
由傳統的序列連線高低解析度卷積,改成並行連線高低解析度卷積,始終保持高解析度特徵,並且多次進行高低解析度的資訊交換,學習到較為豐富的特徵表示。
橫向為depth變化,縱向為scale變化。第一行為主幹網路,特徵圖保持高解析度水平,作為第一階段。後面逐漸並行加入解析度子網路建立更多的階段。各個並行網路之間相互交換資訊,實現多尺度的特徵融合和特徵提取。最終預測圖所估計的關鍵點是在高解析度主幹網路進行輸出。但是訓練量大,不是輕量級的網路結構。