可变形卷积 DeformConv2d

本文介绍了可变形卷积(DConv)的概念、其与普通卷积的区别,以及为什么在处理位置敏感任务时更有效。重点讲解了在PyTorch中的实现过程,包括标准卷积的计算机制和DConv的变形采样策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

可变形卷积即DCN(缩写取自Deformable ConvNets)提出于ICCV 2017的paper:
Deformable Convolutional Networks
论文paper地址:https://openaccess.thecvf.com/content_ICCV_2017/papers/Dai_Deformable_Convolutional_Networks_ICCV_2017_paper.pdf

codebase地址:(很多框架中都已实现,这里选择以pytorch的为例)https://github.com/4uiiurz1/pytorch-deform-conv-v2/blob/master/deform_conv_v2.py


在这里插入图片描述
3×3标准和可变形卷积的采样位置图示。(a) 标准卷积的规则采样网格(绿点)。(b) 可变形卷积中带有增强偏移量(浅蓝色箭头)的变形采样位置(深蓝色点)。(c)(d)是(b)的特例,表明可变形卷积概括了尺度、(各向异性)长宽比和旋转的各种变换。


为什么要用DConv

卷积单元(卷积核)对输入的特征图在固定的位置进行采样;池化层不断减小着特征图的尺寸;RoI池化层产生空间位置受限的RoI。然而,这样做会产生一些问题,比如,卷积核权重的固定导致同一CNN在处理一张图的不同位置区域的时候感受野尺寸都相同,这对于编码位置信息的深层卷积神经网络是不合理的。因为不同的位置可能对应有不同尺度或者不同形变的物体,这些层需要能够自动调整尺度或者感受野的方法。再比如,目标检测的效果很大程度上依赖于基于特征提取的边界框,这并不是最优的方法,尤其是对于非网格状的物体而言。


普通卷积和与可变形卷积计算过程

普通卷积计算过程

在这里插入图片描述

在这里插入图片描述
这里dilation:controls the spacing between the kernel points;
stride相似,实际含义为:每个点之间有空隙的过滤器,即为dilation。例如,在一个维度上,一个大小为 3 3 3的过滤器 w w w会对输入的x进行如下计算: w [ 0 ] ∗ x [ 0 ] + w [ 1 ] ∗ x [ 1 ] + w [ 2 ] ∗ x [ 2 ] w[0] * x[0] + w[1] * x[1] + w[2] * x[2] w[0]x[0]+w[1]x[1]+w[2]x[2] 。若 d i l a t i o n = 1 dilation = 1 dilation=1,过滤器会计算: w [ 0 ] ∗ x [ 0 ] + w [ 1 ] ∗ x [ 2 ] + w [ 2 ] ∗ x [ 4 ] w[0] * x[0] + w[1] * x[2] + w[2] * x[4] w[0]x[0]+w[1]x[2]+w[2]x[4];换句话说,在不同点之间有一个1的差距。(Pytoch中 d i l a t i o n dilation dilation默认等于 1 1 1,但是实际为不膨胀,也就是说设置 d i l a t i o n = 2 dilation = 2 dilation=2时才会真正进行膨胀操作)
下面动画的 d i l a t i o n = 2 dilation = 2 dilation=2 的卷积操作
在这里插入图片描述

Pytorch官方API

torch.nn.Conv2d(in_channels, 
                out_channels, 
                kernel_size, 
                stride=1, 
                padding=0, 
                dilation=1, 
                groups=1, 
                bias=True, 
                padding_mode='zeros')
  • in_channels参数代表输入特征矩阵的深度即channel,比如输入一张RGB彩色图像,那in_channels = 3;
  • out_channels参数代表卷积核的个数,使用n个卷积核输出的特征矩阵深度即channel就是n;
  • kernel_size参数代表卷积核的尺寸,输入可以是int类型如3 代表卷积核的height = width = 3,也可以是tuple类型如(3, 5)代表卷积核的height = 3,width = 5;
  • stride参数代表卷积核的步距默认为1,和kernel_size一样输入可以是int类型,也可以是tuple类型,这里注意,若为tuple类型即第一个int用于高度尺寸,第二个int用于宽度尺寸;
  • padding参数代表在输入特征矩阵四周补零的情况默认为0,同样输入可以为int型如1代表上下方向各补一行0元素,左右方向各补一列0像素(即补一圈0),如果输入为tuple型如(2, 1) 代表在上方补两行下方补两行,左边补一列,右边补一列。可见下图,padding[0]是在H高度方向两侧填充的,padding[1]是在W宽度方向两侧填充的;
    在这里插入图片描述
    使用方法可见官方文档:https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#

可变形卷积计算过程

在这里插入图片描述
在这里插入图片描述
∇ P n \nabla P_n Pn是由普通卷积计算得到的,这里的 o u t _ c h a n n e l = 2 ∗ k e r n e l _ s i z e 2 out\_channel =2*kernel\_size^2 out_channel=2kernel_size2,变换生成kernel_size*kernel_size 大小的 ∇ R \nabla R R表。
在这里插入图片描述
使用双向线性插值方法确定最后的位置,后计算value。
在这里插入图片描述
在这里插入图片描述
可变卷积形pytorch API 地址
https://pytorch.org/vision/main/generated/torchvision.ops.deform_conv2d.html#torchvision.ops.deform_conv2d

参考资源

1.https://blog.csdn.net/jiangqixing0728/article/details/126269423
2.https://www.bilibili.com/video/BV1Sh4y1y75i/?spm_id_from=333.337.search-card.all.click&vd_source=17d3748d0773a2015a74ab52544dd499

### 使用DeformConv2d类 为了在Python中使用`deform_conv`库中的`DeformConv2d`类,需先安装必要的依赖项并导入所需的模块。通常情况下,在基于PyTorch的环境中操作变形卷积(Deformable Convolution),会涉及到CUDA扩展来加速计算过程。 #### 安装依赖包 确保环境已经配置好PyTorch以及对应的CUDA版本之后,可以通过pip或其他方式安装特定于变形卷积的支持库: ```bash pip install git+https://github.com/4uiiurz1/pytorch-deform-conv-v2.git@master ``` 这段命令将会克隆指定仓库到本地,并按照README指示完成编译和安装[^2]。 #### 导入与初始化 成功安装后,可以在脚本里通过如下语句引入`DeformConv2d`: ```python from torchvision.ops import DeformConv2d import torch.nn as nn ``` 创建一个自定义层实例时,可以像下面这样设置输入通道数、输出通道数以及其他超参数: ```python dcn_layer = DeformConv2d(in_channels=3, out_channels=64, kernel_size=(3, 3), stride=1, padding=1) ``` 值得注意的是,默认情况下某些属性可能不符合具体应用场景的需求;因此建议查阅官方文档确认最合适的配置选项[^4]。 #### 构建模型结构 当构建神经网络架构时,可将上述定制化的DCN层与其他标准组件组合起来形成完整的前馈路径。例如: ```python class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() # 假设这里的in_channels等于上一层输出特征图的数量 self.deform_conv = DeformConv2d(in_channels=64, out_channels=128, kernel_size=(3, 3)) def forward(self, x): offset = ... # 计算偏移量的方法取决于具体的实现细节 output = self.deform_conv(x, offset) return output ``` 在这个例子中,除了常规的权重矩阵外还需要额外提供给定位置处的感受野中心相对于原始网格坐标的位移向量作为offset参数传递进去[^3]。 #### 处理可能出现的问题 如果遇到类似于“cannot import name 'deform_conv_cuda' from 'assets.ops.dcn'”这样的错误提示,则可能是由于缺少相应的CUDA扩展文件或者是路径配置不正确所引起的。此时应该检查是否正确设置了PYTHONPATH变量指向包含`.so`动态链接库的位置,并且确认源码目录下存在有效的C++实现部分用于编译生成这些二进制资源[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值