[PaperRead]Involution: Inverting the Inherence of Convolution for Visual Recogni

「这是我参与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

卷积有以下性质

  1. 空间无关性(spatial agnostic):same kernel for different position

    • 优点:参数共享,平移等变
    • 缺点:不能灵活改变参数,卷积核尺寸不能过大,只能通过堆叠来扩大感受野、捕捉长距离关系
  2. 通道特异性(channel specific):different kernels for different channels

    • 优点:充分提取不同通道上的信息
    • 缺点:有冗余

Convolution kernel 尺寸为 B, C o u t C_{out} , C i n C_{in} ,K,K

Involution

Involution的出发点便是实现一个与卷积性质完全相反的kernel,称为Inverted Convolution,简称为Involution

  1. 空间特异性:kernel privatized for different position

    与卷积在空间上共享参数不同,Involution为每一个像素生成一个单独的核

  2. 通道不变性: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,方便起见以一个像素为例

image-20210426192156487

  1. inputs为维度1×1×C;
  2. 线性变换:W_0:通道压缩,节省计算量;W_1:首先变为1×1×(K×K×G),再拆分为G组,最后变换为K×K×G;(其生成的卷积核包含了该位置所有通道上的信息,对不同通道之间的信息交换有一定的作用)
  3. 生成的kernel与(i,j)领域进行乘加操作,因为维度不同,需要进行广播,得到大小为k×k×C;
  4. 最后进行聚合(在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

优点:

  1. 参数量和计算量都很少

    • 对于Convolution,其参数量为:

      K 2 C i n C o u t K^2C_{in}C_{out}

      计算量大约为:

      H W K 2 C i n C o u t HWK^2C_{in}C_{out}
    • 对于Involution,其参数量为:

      C 2 + C G K 2 r \frac{C^2+CGK^2}{r}

      计算量大约为:

      H W K 2 C HWK^2C

    可以看到,involution的计算量与通道数呈线性关系,并且参数量不会随着kernel_size的增大而增加太多

  2. 能有效建模长距离关系

    相较于Convolution,involution kernel可以使用更大的卷积核而不过多增加其参数量,其感受野也就越大。

  3. involution是动态的,其对每一个位置都生成一个核,而convolution是静态的。

缺点:

  1. 通道间的信息交换在一定程度上受到影响

    虽然同一组内共享同一个kernel,但是不同组通道间的信息交换还是会受到影响。

  2. 速度相较于Convolution没有优势,involution的优化并没有convolution好,也没有相应硬件的支持,因此虽然参数量和计算量都减小了,但是实际并没有convolution快,作者建议使用CUDA编写Involution。

Relation to Self-Attention

self-attention可以看作广义involution的一种实例

可以看到与self-attention之间的相似性:

image-20210427212347084

相似:

  1. 其中H可以类比为involution中的G,即多头类似于分组;
  2. self-attention中每个位置的attention map可以类比为involution中每个位置的kernel。

不同:

  1. 相比于self-attention,Involution潜在编码了位置信息,而self-attention需要position encoding来区分位置信息.
  2. 不再需要使用Q-K,仅依靠单个像素生成kernel,而非依靠像素间的关系生成attention map.

总结:self-attention是Involution的一种实例化,且Involution的表达更为宽泛和简洁。

Ablantion Analysis

image-20210427213135224

可以看到:

  • Involution能在不显著提升参数量和计算量的前提下,增大感受野,提升网络性能;
  • 在显著降低计算量和参数量的情况下,准确度损失却不大。

思考

Involution实际上提出了一种动态核(dynamic kernel)的范式,但我对相关工作没有太多了解,就写一些我阅读论文的思考吧。

  1. 关于卷积的可替代性

    原论文实际上没有将所有的卷积都替换为Involution,而是使用了Convolution-Involution的混合结构,我认为Involution的应用场景有两种:

    1. 特征在空间位置上差异明显,我们更需要注意长距离关系时,involution或许是个好的选择;
    2. 对于实例分割全景分割,Involution或许会有效果,因为Convolution的一个性质是平移不变性,与语义分割不同,实例分割和全景分割不光要学习相同类别内的共性,还要学习相同类别内的差异性以区分不同的实例,卷积的性质让实例分割和全景分割难以做到全卷积(Fully Convolutional Networks for Panoptic Segmentation使用全卷积网络来进行全景分割,但是实际上其中也有动态核的身影),而Involution为每个像素都生成一个独一无二的核,我相信它能天然的区分学习到相同类别内的差异性。
  2. 训练与优化

    不同于convolution,involution实际上是二阶优化(很多dynamic kernel都是二阶优化,如),需要优化的并不是kernel,而是kernel生成函数里的参数,这就会造成很多问题(最近的transformer优化过程也有很多问题),作者建议对于某些网络需要使用gradient clipping等方法来进行更好的优化。

  3. 注意力机制和动态核

    作者虽然提及其与自注意力有异曲同工之妙,但是实际上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的能力。

  4. 权重生成方式

    本文只是提出了一种简单的生成方法,可以探索更多的权重生成方式,比如不同的稀疏连接和权重共享模式等。

猜你喜欢

转载自juejin.im/post/7054801383253344293