论文名称:Involution: Inverting the Inherence of Convolution for Visual Recognition
作者:Duo Li, Jie Hu, Changhu Wang, Xiangtai Li, Qi She, Lei Zhu, Tong Zhang, Qifeng Chen, The Hong Kong University of Science and Technology, ByteDance AI Lab, Peking University, Beijing University of Posts and Telecommunications
Convolution kernel 尺寸为 B,C_out,C_in,K,K
与convolution不同,involution拥有完全相反的性质:
involution kernel 的尺寸为B,G,KK,H,W.
kernel generated based on input featrue map(self-attention的一种体现?) to ensure kernel size aligned with the input tensor size
一种简单的kernel generation function,方便起见以一个像素为例
class Involution(nn.Module):
def __init__(self, channel, group, kernel, s):
super(Involution, self).__init__()
self.channel = channel
self.group = group
self.kernel_size = kernel
ratio=4
self.o = nn.AvgPool2d(s, s) if s > 1 else nn.Identity()
self.reduce = nn.Sequential(
nn.Conv2d(channel, channel//ratio, 1),
nn.BatchNorm2d(channel//ratio),
nn.ReLU(inplace=True)
)
self.span = nn.Conv2d(channel//ratio, kernel**2*group, 1)
# 从一个Batch中提取出卷积滑动的局部区域块,较难理解,建议自行百度
# 普通的卷积操作实际上就相当于将feature map unfold与conv kernel乘加之后再fold
self.unfold = nn.Unfold(
kernel_size=kernel, padding=(kernel-1)//2, stride=s)
def forward(self, x):
kernel = self.span(self.reduce(self.o(x))) # B,KKG,H,W
B, _, H, W = kernel.shape
kernel = kernel.view(B, self.group, self.kernel_size **
2, H, W).unsqueeze(2) # B,G,1,kk,H,W,unsqueeze:增加一个维度用于广播
x_unfolded = self.unfold(x) # B,CKK,HW
x_unfolded = x_unfolded.view(
B, self.group, self.channel//self.group, self.kernel_size**2, H, W)# B,G,C/G,KK,H,W
out = (kernel*x_unfolded).sum(dim=3) # B,G,C/G,H,W
out = out.view(B, self.channel, H, W) # B,C,H,w
return out
更多:
优点:
参数量和计算量都很少
对于Convolution,其参数量为:
K 2 C i n C o u t K^2C_{in}C_{out} K2CinCout
计算量大约为:
H W K 2 C i n C o u t HWK^2C_{in}C_{out} HWK2CinCout
对于Involution,其参数量为:
C 2 + C G K 2 r \frac{C^2+CGK^2}{r} rC2+CGK2
计算量大约为:
H W K 2 C HWK^2C HWK2C
可以看到,involution的计算量与通道数呈线性关系。
能有效建模长距离关系
相较于Convolution,involution kernel可以使用更大的卷积核而不过多增加其参数量,其感受野也就越大。
involution是动态的,而convolution是静态的。
缺点:
通道间的信息交换在一定程度上受到影响
虽然同一组内共享同一个kernel,但是不同组通道间的信息交换还是会受到影响。
速度相较于Convolution没有优势
self-attention可以看作广义involution的一种实例
可以看到与self-attention之间的相似性:
相似:
不同:
总结:self-attention是Involution的一种实例化,且Involution的表达更为宽泛和简洁。
可以看到:
关于卷积的可替代性
特征在空间位置上差异明显,我们更需要注意长距离关系时,involution或许是个好的选择。
训练与优化
不同于convolution,involution实际上是二阶优化,需要优化的并不是kernel,而是kernel生成函数里的参数,这就会造成很多问题(最近的transformer优化过程也有很多问题),作者建议对于某些网络需要使用gradient clipping等方法来进行更好的优化。
硬件支持
involution的优化并没有convolution好,也没有相应硬件的支持,因此虽然参数量和计算量都减小了,但是实际并没有convolution快,作者建议使用CUDA编写Involution。