「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。
论文名称: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
Code::github.com/d-li14/invo…
与卷积性质完全相反,广义上的自注意力:「内卷」,可以在更长距离建模,降低通道信息冗余,获得SOTA性能。
Convolution
卷积有以下性质
-
空间无关性(spatial agnostic):same kernel for different position
- 优点:参数共享,平移等变
- 缺点:不能灵活改变参数,卷积核尺寸不能过大,只能通过堆叠来扩大感受野、捕捉长距离关系
-
通道特异性(channel specific):different kernels for different channels
- 优点:充分提取不同通道上的信息
- 缺点:有冗余
Convolution kernel 尺寸为 B, , ,K,K
Involution
Involution的出发点便是实现一个与卷积性质完全相反的kernel,称为Inverted Convolution,简称为Involution
-
空间特异性:kernel privatized for different position
与卷积在空间上共享参数不同,Involution为每一个像素生成一个单独的核
-
通道不变性:kernel shared across different channels
为所有通道使用同一个核
involution kernel 的尺寸为B,G,KK,H,W.
how to generate involution kernels
kernel generated based on input featrue map(self-attention的一种体现) to ensure kernel size aligned with the input tensor size
一种简单的kernel generation function,方便起见以一个像素为例
- inputs为维度1×1×C;
- 线性变换:W_0:通道压缩,节省计算量;W_1:首先变为1×1×(K×K×G),再拆分为G组,最后变换为K×K×G;(其生成的卷积核包含了该位置所有通道上的信息,对不同通道之间的信息交换有一定的作用)
- 生成的kernel与(i,j)领域进行乘加操作,因为维度不同,需要进行广播,得到大小为k×k×C;
- 最后进行聚合(在h,w的维度进行求和),输出大小为1×1×C。
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中提取出卷积滑动的局部区域块,有点类似于im2col,较难理解,建议自行百度
# 普通的卷积操作实际上就相当于将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:增加一个维度用于广播
#这里的1体现通道不变性,kk表示在某个像素的邻域上计算
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
复制代码
Involution vs Convolution
优点:
-
参数量和计算量都很少
-
对于Convolution,其参数量为:
计算量大约为:
-
对于Involution,其参数量为:
计算量大约为:
可以看到,involution的计算量与通道数呈线性关系,并且参数量不会随着kernel_size的增大而增加太多
-
-
能有效建模长距离关系
相较于Convolution,involution kernel可以使用更大的卷积核而不过多增加其参数量,其感受野也就越大。
-
involution是动态的,其对每一个位置都生成一个核,而convolution是静态的。
缺点:
-
通道间的信息交换在一定程度上受到影响
虽然同一组内共享同一个kernel,但是不同组通道间的信息交换还是会受到影响。
-
速度相较于Convolution没有优势,involution的优化并没有convolution好,也没有相应硬件的支持,因此虽然参数量和计算量都减小了,但是实际并没有convolution快,作者建议使用CUDA编写Involution。
Relation to Self-Attention
self-attention可以看作广义involution的一种实例
可以看到与self-attention之间的相似性:
相似:
- 其中H可以类比为involution中的G,即多头类似于分组;
- self-attention中每个位置的attention map可以类比为involution中每个位置的kernel。
不同:
- 相比于self-attention,Involution潜在编码了位置信息,而self-attention需要position encoding来区分位置信息.
- 不再需要使用Q-K,仅依靠单个像素生成kernel,而非依靠像素间的关系生成attention map.
总结:self-attention是Involution的一种实例化,且Involution的表达更为宽泛和简洁。
Ablantion Analysis
可以看到:
- Involution能在不显著提升参数量和计算量的前提下,增大感受野,提升网络性能;
- 在显著降低计算量和参数量的情况下,准确度损失却不大。
思考
Involution实际上提出了一种动态核(dynamic kernel)的范式,但我对相关工作没有太多了解,就写一些我阅读论文的思考吧。
-
关于卷积的可替代性
原论文实际上没有将所有的卷积都替换为Involution,而是使用了Convolution-Involution的混合结构,我认为Involution的应用场景有两种:
- 特征在空间位置上差异明显,我们更需要注意长距离关系时,involution或许是个好的选择;
- 对于实例分割和全景分割,Involution或许会有效果,因为Convolution的一个性质是平移不变性,与语义分割不同,实例分割和全景分割不光要学习相同类别内的共性,还要学习相同类别内的差异性以区分不同的实例,卷积的性质让实例分割和全景分割难以做到全卷积(Fully Convolutional Networks for Panoptic Segmentation使用全卷积网络来进行全景分割,但是实际上其中也有动态核的身影),而Involution为每个像素都生成一个独一无二的核,我相信它能天然的区分学习到相同类别内的差异性。
-
训练与优化
不同于convolution,involution实际上是二阶优化(很多dynamic kernel都是二阶优化,如),需要优化的并不是kernel,而是kernel生成函数里的参数,这就会造成很多问题(最近的transformer优化过程也有很多问题),作者建议对于某些网络需要使用gradient clipping等方法来进行更好的优化。
-
注意力机制和动态核
作者虽然提及其与自注意力有异曲同工之妙,但是实际上Involution最多只能算是local attention,local attention也是最近研究的热点,VOLO: Vision Outlooker for Visual Recognition是一个与Involution十分相似的工作,不同于transformer,VOLO旨在进行像素邻域上的精细化建模,最佳论文的swin transformer实际上也是local attention和动态核,Demystifying Local Vision Transformer: Sparse Connectivity, Weight Sharing, and Dynamic Weight讨论了local attention,dynamic weight和weight share,证明了local attention拥有不输self attention的能力。
-
权重生成方式
本文只是提出了一种简单的生成方法,可以探索更多的权重生成方式,比如不同的稀疏连接和权重共享模式等。