近期阅读了两篇文章, 这两篇文章刚开始的时候给我感觉十分相似。我一度认为VOLO只是将Involution的思想套在了self-attention的框架里,直到这些天看了很多的解读以及自己不断思考,才体会到VOLO相较于Involution思想的不同,以下只是自己的见解,如有错误,请批评指正!
文章列表
- Involution: Inverting the Inherence of Convolution for Visual Recognition(CVPR2021)
下载链接:https://arxiv.org/abs/2103.06255 - VOLO: Vision Outlooker for Visual Recognition
下载链接:https://arxiv.org/abs/2106.13112
Involution
Key Idea:
对于特征图中的每一点,将这一点的特征作为输入,经过两个线性层得到其周围个点的权重,最后和原feature map对应位置的值加权相加得到最终feature map的特征。整个过程依然是非常典型的Unfold—>Multiply-Add—>Fold的过程。
Pseudo code:
在具体实现过程中:
第一步:根据stride大小判断是否经过AvgPool2d,若stride>1,则需要经过下采样。
第二步:将原feature map进行Unfold操作,Unfold可以简单理解为将原feature map划分为多个patch的操作,这样feature map的维度由变成了。
第三步:将feature map按照通道进行分组,同一组的通道共享一个kernel。一共分为G组,接着经过两个线形层reduce和span得到kernel的权重。这里的reduce和span相当于先进行通道压缩再扩张的过程,有利于减小计算量。
最后是Multiply-Add的过程,将加权后的个特征相加为一个。
Involution的特点:
- spatial-specific and channel-agnostic
Convolution的特点是在空间上共享核参数,在通道上参数不同。而Involution正好相反,首先不同位置的视觉模式不同,用不同的核参数提取特征更加准确;其次,之前也有工作证明channel的冗余性,所以作者干脆反其道而行之,增加spatial上的参数减少channel层面的参数来达到更好的效果。
- self-attention为involution的一个实例
作者认为计算出来的相似矩阵其实就相当于involution中核。一方面,involution的计算机制可以看作是空间域上的一个注意聚合;另一方面,self-attention中除了需要计算的亲和矩阵,还需要加上位置编码,而involution中并不需要计算pixel之间的配对关系,并且位置信息隐含在了核的产生当中。这也引发我们思考几个问题,一个是QK相似度计算在self-attention是否必需;另一个是位置编码在self-attention中重要性。
- involution的整个过程与SENet在通道上做法相似
SENet是在通道上去做的attention,而VOLO是在spatial上做的attention。两者产生attention weight的方式相同,都是经过了两层全连接。 - 能够有效地在更广泛的空间范围内进行信息交互
得益于Involution的通道共享性,即使在空间维度上使用更大尺寸的kernel也不会引起计算量显著增长,而卷积受限于计算复杂度通常只能使用3x3或5x5的kernel。 - 通道共享性
尽管作者在具体实现的时候将通道分成了几个组,但是确实影响了组之间的信息共享,并且无法灵活地改变特征通道数。
问题:
为什么邻域的kernel值可以只通过中心点的特征值产生?
我的理解是feature map中的每个点的感受野是随着网络的加深不断增加的,本层的每个点的特征来自上一层的一个local region中点的特征的aggregate。因此中心点的特征值和周围的特征值之间并不是独立的,因此完全可以通过中心点来计算邻域的权重值,不过我认为会面临训练难收敛的问题,involution放在后面的层中应该会比前面层中效果更好。
VOLO
Key Idea:
上面一条路,对于输入,我们先经过全连接层压缩到(, H, W)。其中K表示的是Kernel的大小,你可以理解为每一个空间feature生成周边
Pseudo code:
总的来说,仍然是Unfold—>Multiply-Add—>Fold的过程。我们这里主要还是关注两点区别:(1)Unfold生成矩阵的维度为而involution中生成的矩阵维度为。(2)生成的权重矩阵是否经过了softmax层。
与Involution更加本质的区别和联系:
(1)表面上来看,都是根据某一点的特征值经过线形层生成周围邻域的点的权重。只不过VOLO生成的为注意力矩阵即相当于,所以一个为+点积操作;另一个为+矩阵相乘的操作。
(2)involution具有通道共享性,那么VOLO呢?我们不如换个角度来看这个问题:VOLO生成的attention矩阵大小为,可以看作是个矩阵,而每一个矩阵可以认为是一种组合,这样权重矩阵就有种形式。而在步骤x = mul(a,v)的过程输出的矩阵就相当于是个involution的结果,最后再进行fold操作,这样的话实际上每个通道都是个核的结果,并不是单一核的结果。因此我认为VOLO相比较于involution大致思想相似,但是VOLO在一定程度上缓解了involution的通道无异性的特点。
当然两者讲的story方向还是不同的:VOLO侧重于 encode fine-level information和减小计算量,Involution则侧重于提出了一个新的特征提取器。
最后,对之前了解的特征提取器的总结:
Deformable Conv:采样的位置不固定,共享核参数,channel-specific
Involution:采样的位置固定,不共享核参数,channel-shared
VOLO:采样的位置固定,不共享核参数,channel-moderateshared
Convolution:采样位置固定,共享核参数,channel-specific
那么问题来了,能不能做出一个更强大的特征提取器把以上这些的优点统一呢?