论文地址:https://arxiv.org/pdf/1703.06211
相关代码(非官方):https://github.com/4uiiurz1/pytorch-deform-conv-v2/tree/529abbbe9b81e852d272220c855255fd631c43c6
1. 为什么做DCN
传统的卷积采用固定尺寸的卷积核,不能很好地适应几何形变
2. 什么是DCN
可形变卷积,卷积核的形状是可变的,也就是感受野可以变化,但注意感受野的元素是“不变”的。
3. DCN的具体实现
具体细节可以参考这个知乎:https://zhuanlan.zhihu.com/p/62661196

代码似乎也是按照这个流程写的,不过上面的输出结果不应该是(b*h*w*2c),而是(b*h*w* (2kernel_size*kernel_size)),因为只需要记录可变形卷积滤波器变形之后的位置,滤波器的原始尺寸是kernel_size*kernel_size,需记录x坐标和y坐标,故为2*kernel_size*kernel_size
代码参考这里,关键步骤及其解释如下:
![]()

这一步输入图片学习偏移量offset,输入的feature map尺寸是(64,28,28)分别表示通道数,h和w。输出之所以是18通道的,是因为kernel size是3,卷积核有3*3=9个点,每个点都有x偏移量和y偏移量(从这里看得出每个输入通道做同样的偏移处理),18通道的前九个通道表示x偏移量,后9个通道表示y偏移量。


由于offset是偏移量,需要得到偏移之后的绝对坐标p,直接把偏移量加到原始坐标就好
原始坐标一般用meshgrid函数表示

得到的偏移坐标p肯定没有对应的原始像素值,所以要做一个双线性内插,双线性内插参考https://zh.wikipedia.org/wiki/%E5%8F%8C%E7%BA%BF%E6%80%A7%E6%8F%92%E5%80%BC。双线性内插输入的四个点来自周围的四个点,四个点的面积是1,所以四个内插权重得到一定的简化:

最后,万事具备,偏移的位置都已经确定好了,用正常的卷积操作实现实现DCN:
![]()

注意执行_reshape_x_offset函数前x_offset的形状是torch.Size([32, 64, 28, 28, 9]),由于dcn的卷积核是3*3,所以感受野里总共9个元素(这也是最后一个通道是9点原因),reshape之后把9维向量的感受野展开成平面(torch.Size([32, 64, 84, 84])),而且由于self.conv的stride等于kernel size,所以卷积过程没有重叠,恰好是我们需要的卷积。
本文介绍了可形变卷积网络(DCN)的原因、概念及实现细节。传统卷积无法适应几何变形,而DCN通过允许卷积核形状变化以适应不同场景。文中提到了相关论文和非官方实现代码,并解释了DCN的关键步骤,包括学习偏移量、双线性内插以及如何应用这些偏移到正常卷积中。
3901

被折叠的 条评论
为什么被折叠?



