備案時(shí)候網(wǎng)站不能打開嗎it教育培訓(xùn)機(jī)構(gòu)排名
論文《GCNet: Non-local Networks Meet Squeeze-Excitation Networks and Beyond》
1、作用
GCNet通過(guò)聚合每個(gè)查詢位置的全局上下文信息來(lái)捕獲長(zhǎng)距離依賴關(guān)系,從而改善了圖像/視頻分類、對(duì)象檢測(cè)和分割等一系列識(shí)別任務(wù)的性能。非局部網(wǎng)絡(luò)(NLNet)首次提出了通過(guò)聚合查詢特定的全局上下文到每個(gè)查詢位置來(lái)捕獲長(zhǎng)距離依賴的方法。GCNet在此基礎(chǔ)上進(jìn)行了改進(jìn)和簡(jiǎn)化,旨在以更少的計(jì)算量保持NLNet的準(zhǔn)確性。
2、機(jī)制
GCNet通過(guò)以下三個(gè)步驟來(lái)建模全局上下文:
1、上下文建模:
通過(guò)加權(quán)平均所有位置的特征來(lái)形成全局上下文特征
2、特征轉(zhuǎn)換:
捕捉通道間的依賴關(guān)系。
3、融合:
將全局上下文特征合并到每個(gè)位置的特征中。GCNet發(fā)現(xiàn)NLNet中的全局上下文對(duì)于圖像內(nèi)的不同查詢位置幾乎是相同的,基于這一發(fā)現(xiàn),GCNet采用了查詢獨(dú)立的注意力圖來(lái)簡(jiǎn)化計(jì)算過(guò)程。
3、獨(dú)特優(yōu)勢(shì)
1、計(jì)算效率:GCNet通過(guò)使用查詢獨(dú)立的注意力圖顯著減少了計(jì)算量,與NLNet相比,保持了準(zhǔn)確性的同時(shí)大幅減少了計(jì)算需求。
2、輕量級(jí):GCNet的設(shè)計(jì)允許它被應(yīng)用于背骨網(wǎng)絡(luò)的多個(gè)層次,與SENet相似,它通過(guò)特征重標(biāo)定和全局上下文建模來(lái)提高性能,但引入的計(jì)算和參數(shù)增量非常小。
3、通用性和魯棒性:在多個(gè)基準(zhǔn)數(shù)據(jù)集和不同的視覺識(shí)別任務(wù)(如對(duì)象檢測(cè)/分割、圖像分類和動(dòng)作識(shí)別)上,GCNet普遍優(yōu)于簡(jiǎn)化的NLNet和SENet,展示了其優(yōu)越的性能和廣泛的適用性。
4、代碼
import torch
import torch.nn as nn# 定義全局上下文塊類
class GlobalContextBlock(nn.Module):def __init__(self, inplanes, ratio, pooling_type="att", fusion_types=('channel_mul')) -> None:super().__init__()# 定義有效的融合類型valid_fusion_types = ['channel_add', 'channel_mul']# 斷言池化類型為'avg'或'att'assert pooling_type in ['avg', 'att']# 斷言至少使用一種融合方式assert len(fusion_types) > 0, 'at least one fusion should be used'# 初始化基本參數(shù)self.inplanes = inplanesself.ratio = ratioself.planes = int(inplanes * ratio)self.pooling_type = pooling_typeself.fusion_type = fusion_typesif pooling_type == 'att':self.conv_mask = nn.Conv2d(inplanes, 1, kernel_size=1)self.softmax = nn.Softmax(dim=2)else:# 否則,使用自適應(yīng)平均池化self.avg_pool = nn.AdaptiveAvgPool2d(1)# 如果池化類型為'att',使用1x1卷積作為掩碼,并使用Softmax進(jìn)行歸一化if 'channel_add' in fusion_types:self.channel_add_conv = nn.Sequential(nn.Conv2d(self.inplanes, self.planes, kernel_size=1),nn.LayerNorm([self.planes, 1, 1]),nn.ReLU(inplace=True),nn.Conv2d(self.planes, self.inplanes, kernel_size=1))else:self.channel_add_conv = None# 如果融合類型包含'channel_mul',定義通道相乘卷積if 'channel_mul' in fusion_types:self.channel_mul_conv = nn.Sequential(nn.Conv2d(self.inplanes, self.planes, kernel_size=1),nn.LayerNorm([self.planes, 1, 1]),nn.ReLU(inplace=True),nn.Conv2d(self.planes, self.inplanes, kernel_size=1))else:self.channel_mul_conv = None# 定義空間池化函數(shù)def spatial_pool(self, x):batch, channel, height, width = x.size()if self.pooling_type == 'att':input_x = xinput_x = input_x.view(batch, channel, height * width) # 使用1x1卷積生成掩碼input_x = input_x.unsqueeze(1)context_mask = self.conv_mask(x) # 使用1x1卷積生成掩碼context_mask = context_mask.view(batch, 1, height * width)context_mask = self.softmax(context_mask)# 應(yīng)用Softmax進(jìn)行歸一化context_mask = context_mask.unsqueeze(-1)context = torch.matmul(input_x, context_mask) # 計(jì)算上下文context = context.view(batch, channel, 1, 1)else:context = self.avg_pool(x) # 執(zhí)行自適應(yīng)平均池化return context# 定義前向傳播函數(shù)def forward(self, x):context = self.spatial_pool(x)out = xif self.channel_mul_conv is not None:channel_mul_term = torch.sigmoid(self.channel_mul_conv(context)) # 將權(quán)重進(jìn)行放大縮小out = out * channel_mul_term # 與x進(jìn)行相乘if self.channel_add_conv is not None:channel_add_term = self.channel_add_conv(context)out = out + channel_add_termreturn outif __name__ == "__main__":input = torch.randn(16, 64, 32, 32) #生成隨機(jī)數(shù)net = GlobalContextBlock(64, ratio=1 / 16) #還是實(shí)例化哈out = net(input)print(out.shape)