全局響應(yīng)歸一化(Global Response Normalization,GRN)是ConvNeXtV2中提出的一種歸一化方法,其實(shí)也就是一種注意力機(jī)制,跟視覺(jué)中常用的SE、ECA、CBAM的作用一樣,就是對(duì)特征進(jìn)行重標(biāo)定。
GRN的pytorch代碼如下:
import torch
from torch import nn as nn
class GlobalResponseNorm(nn.Module):
""" Global Response Normalization layer
"""
def __init__(self, dim, eps=1e-6, channels_last=True):
super().__init__()
self.eps = eps
if channels_last:
self.spatial_dim = (1, 2)
self.channel_dim = -1
self.wb_shape = (1, 1, 1, -1)
else:
self.spatial_dim = (2, 3)
self.channel_dim = 1
self.wb_shape = (1, -1, 1, 1)
self.weight = nn.Parameter(torch.zeros(dim))
self.bias = nn.Parameter(torch.zeros(dim))
def forward(self, x):
x_g = x.norm(p=2, dim=self.spatial_dim, keepdim=True)
x_n = x_g / (x_g.mean(dim=self.channel_dim, keepdim=True) + self.eps)
out=x + torch.addcmul(self.bias.view(self.wb_shape), self.weight.view(self.wb_shape), x * x_n)
return out
if __name__ == "__main__":
net = GlobalResponseNorm(dim=96,channels_last=False)
x = torch.randn(5, 96, 112, 112)
out = net(x)
GRN主要由全局特征聚合、特征歸一化和特征校準(zhǔn)三部分組成。
其中全局特征聚合的代碼是:
x_g = x.norm(p=2, dim=self.spatial_dim, keepdim=True)
通過(guò)在H和W維度上使用L2范數(shù),把空間特征聚合成為一個(gè)向量,其實(shí)也可以使用類似SE里的全局平均池化層,主要用于獲取全局性的通道信息。
特征歸一化的代碼是:
x_n = x_g / (x_g.mean(dim=self.channel_dim, keepdim=True) + self.eps)
用于計(jì)算當(dāng)前通道相對(duì)于其他通道的相對(duì)重要性,其值在0~1之間,該方法類似于SE里的sigmoid輸出。
特征校準(zhǔn)的代碼是:
out=x + torch.addcmul(self.bias.view(self.wb_shape), self.weight.view(self.wb_shape), x * x_n)
這就是一個(gè)特征重標(biāo)定的過(guò)程,特征歸一化輸出的其實(shí)是一個(gè)權(quán)重值,這個(gè)值載荷輸入x相乘就能獲得每個(gè)通道的重要程度,GRN中還加入了兩個(gè)可學(xué)習(xí)參數(shù)weight和bias用于優(yōu)化。
同時(shí)GRN里還使用了跳躍連接,論文說(shuō)是為了更好的地用于訓(xùn)練優(yōu)化。