这是ICCV2019的用于语义分割的论文,可以说和CVPR2019的DANet遥相呼应。关于DANet可以见我的另一篇博客
官方源码
和DANet一样,CCNet也是想建模像素之间的long range dependencies,来做更加丰富的contextual information,来补充特征图,以此来提升语义分割的性能。但是和DANet不一样,CCNet仅考虑空间分辨上的建模,不考虑建模通道之间的联系。作者提出的模块,criss-cross attention module,针对空间维度上的建模,对于空间位置的一个点u,仅考虑建模和u在同一行或者同一列的其他位置的像素之间的联系。相比DANet,能减少很多计算量,但是不足的是,对一个点的特征向量,尽管有同一行或者同一列的其他像素信息作为补充,对于语义分割任务,contextual information仍然是稀疏的(sparse),因为语义分割更在意一个像素和它周围的一些像素的关系。针对这个问题,作者提出了recurrent criss-cross attention module,来建模一个像素和全局所有像素的关系。方式是通过重复criss-cross attention module来实现的。这些module也是参数shared的。
个人看法,简单且有效的,就是极其优秀的方法,CCNet就属于这一类方法。
关于模块结构的介绍,重点应该在Affinity和Aggregation这里。H的维度是 R C × H × W R^{C\times H\times W} RC×H×W
在Q上的一点u,记作 Q u ∈ R c ′ Q_u \in R^{c'} Qu∈Rc′,绿色的位置和青色的位置,都是和u在同一行或者同一列的单元。
在K中的相同位置上,把和u在同一行或同一列的所以单元加入到集合 Ω u \Omega_u Ωu,那么集合 Ω u \Omega_u Ωu中有H+W-1个长度为C’的向量。
Affinity定义如下:
d i , u = Q u Ω i , u T d_{i,u} = Q_u \Omega_{i,u}^T di,u=QuΩi,uT
就是向量的点积运算,得到标量。i从1到H+W-1变化。则对于一个位置u,能得到H+W-1个值。则所有的一共HW个位置。就有(HW*(H+W-1))个值,形成D,将D按照channel维度进行softmax,就得到了A(attention map)。
从V中的位置u,取出 V u ∈ R c V_u \in R^c Vu∈Rc,同时得到集合 Φ u \Phi_u Φu,这个集合是包含了在V中的位置u,和u同一行或者同一列的其他单元的特征。也就是说, Φ u \Phi_u Φu中有(H+W-1)个长度为C的向量。
H u ′ = ∑ i ∈ ∣ Φ u ∣ A i , u Φ i , u + H u H'_u = \sum_{i \in |\Phi_u|} A_{i,u} \Phi_{i,u} + H_u Hu′=i∈∣Φu∣∑Ai,uΦi,u+Hu
A i , u A_{i,u} Ai,u是标量,是A中的位置u对应的特征向量中,第i个值。
Φ i , u \Phi_{i,u} Φi,u是集合 Φ u \Phi_u Φu中第i和特征向量。
这个操作可以用下图简单表示:
最后一项,对应了结构图中的最上面的线,即skip connection。
作者认为,仅考虑同一行和同一列像素关系的建模,对于语义分割仍然是sparse的。于是作者提出了用递归的方式,使用CC module,且Module之间是参数共享的。使用两个CC module,就能针对一个像素点,建模它和全部像素点的联系。
方式就是:
那为啥,递归使用两个CC module,就可以达成这样的效果呢?
假如在平面坐标系中,蓝色点要带着自己的信息去绿色点那里,且规定走的路线只能直行,即只能上下左右走。蓝色点到达目的地,最少需要几步?
答案是两步。CCNet也是利用了这个思想。
H’'虽然不能直接获得H中的全部像素点信息,但却通过间接的方式获取了。比如说,上图左下角绿色的块想获得蓝色块的信息,在第一个CC module中,蓝色块的信息被add到左上方和右下方的块中了,在第2个CC module中,左上方的块和右下方的块被add到绿色块中了。哈哈哈
觉得博主解读好的,请留个言嘛。 实验数据就不多介绍了。