论文介绍
题目:Deformable ConvNets v2: More Deformable, Better Results
论文地址:https://openaccess.thecvf.com/content_CVPR_2019/papers/Zhu_Deformable_ConvNets_V2_More_Deformable_Better_Results_CVPR_2019_paper.pdf
QQ深度学习交流群:994264161
扫描下方二维码,加入深度学习论文指南星球!
加入即可获得,模块缝合、制作、写作技巧,学会“结构”创新、“创新点”创新,从三区到顶会,小论文大论文,毕业一站式服务
创新点
增强的可变形建模能力:
引入了更多的可变形卷积层(deformable convolution layers),并将这些层应用于网络的多个阶段(conv3、conv4 和 conv5)。这种设计提升了网络适应几何变形的能力。
提出了调制机制(modulation mechanism),使得网络可以不仅调整采样位置的偏移量,还可以调制采样点的特征幅度。这样,网络可以动态调整空间支持范围,从而更专注于重要的图像区域。
引入 R-CNN 特征模仿(feature mimicking):
为了解决冗余上下文对检测精度的负面影响,论文提出通过一个 R-CNN 分支指导网络学习更专注于感兴趣区域(RoI)的特征表示。这种特征模仿损失通过将 Faster R-CNN 的特征与 R-CNN 的特征对齐,帮助网络更好地聚焦于目标区域。
保持模块轻量化并兼容现有架构:
可变形模块经过设计后可以无缝地集成到现有的检测系统(如 Faster R-CNN 和 Mask R-CNN)中,并在添加较少参数和计算成本的情况下显著提高性能。
显著的性能提升:
在 COCO 数据集上的实验表明,这种改进的可变形网络在目标检测和实例分割任务中均显著优于原始版本(DCNv1),并在多个基准测试上取得了领先结果。
方法
整体架构
这篇论文的模型基于 Faster R-CNN 和 Mask R-CNN 框架,通过在主干网络中加入可变形卷积层和可变形 RoIPooling 增强了对几何变形的建模能力,同时引入特征模仿机制,使网络能够更专注于目标区域的特征学习。模型结构包括骨干网络、区域建议网络、可变形 RoIPooling、分类和回归分支,以及辅助的特征模仿分支,整体设计兼顾了性能提升和计算效率。
骨干网络(Backbone Network):
使用 ResNet 或 ResNeXt 作为主干网络提取初始特征。
区域建议网络(Region Proposal Network, RPN):
可变形 RoIPooling:
将区域建议框(RoI)通过可变形 RoIPooling 映射到固定大小的特征图上。这一步不仅动态调整采样位置,还通过调制机制调整采样点的特征权重,以聚焦于与目标相关的区域。
特征提取与分类回归:
特征模仿损失:
最终输出:
在网络的多个阶段(conv3、conv4 和 conv5)替换常规卷积层为可变形卷积层(Deformable Convolution),以增强对几何变形的建模能力。
从特征图中生成候选的区域建议框(Region Proposals),这些框是目标检测的候选区域。
使用全连接层(fc layers)将特征映射到目标分类和边界框回归分支中。为了更好地提取特征,论文引入了一个辅助的 R-CNN 分支,用于特征模仿(Feature Mimicking),从而使网络在训练时更专注于感兴趣区域的特征学习。
通过一个 R-CNN 分支对候选区域进行裁剪和重新编码,计算辅助损失(Feature Mimic Loss),指导主网络(Faster R-CNN 或 Mask R-CNN)的特征学习。
在推理阶段,使用增强的 Faster R-CNN 或 Mask R-CNN 网络进行目标检测(包括类别预测和边界框预测)以及实例分割(针对 Mask R-CNN)。
即插即用模块作用
DCNv2 作为一个即插即用模块:
目标检测(Object Detection):
DCNv2 可以集成到目标检测框架(如 Faster R-CNN 和 YOLO)中,提升模型对几何变形目标的适应能力。
适用于复杂场景下的多目标检测,特别是当目标的大小、形状、角度等几何特性存在显著变化时。
实例分割(Instance Segmentation):
在 Mask R-CNN 等分割任务中,DCNv2 模块可以更好地捕捉目标的边界和形状细节。
有助于提升对复杂背景中多个目标的分割精度。
语义分割(Semantic Segmentation):
在场景分割任务中,DCNv2 的可变形卷积能够动态调整采样位置,从而更精准地分割区域。
视频理解和动作检测:
多模态融合任务(Multi-modal Fusion):
DCNv2 通过动态调整空间采样位置,可以在多模态数据(如图像和点云数据)的配准和融合中发挥作用。
适用于视频目标检测和动作识别等任务,能够处理随时间发生几何变化的目标。
消融实验结果
说明了可变形卷积层数量的增加(从 conv5 扩展到 conv3-conv5)以及调制机制的引入对性能的提升作用。
实验表明,在 Faster R-CNN 和 Mask R-CNN 框架中,增加可变形卷积层和使用调制机制可以显著提升目标检测(APbbox)和实例分割(APmask)的准确率,同时保持计算成本的相对轻量化。
评估了 R-CNN 特征模仿机制的不同设置(如对正样本、负样本或两者同时进行模仿)的效果。
结果表明,仅对正样本的特征进行模仿能够显著提升模型性能,而对负样本或所有样本的模仿效果不明显。这表明特征模仿机制主要通过优化正样本特征来提高目标检测的准确率。
展示了特征模仿机制如何影响网络的空间支持范围。
结果显示,启用特征模仿后,网络的空间支持更集中于目标区域,尤其是正样本区域,从而减少了冗余背景信息的干扰。
即插即用模块
import torch
import torch.nn as nn
import math
from torchvision.ops import deform_conv2d
# 论文地址:https://openaccess.thecvf.com/content_CVPR_2019/papers/Zhu_Deformable_ConvNets_V2_More_Deformable_Better_Results_CVPR_2019_paper.pdf
# 论文:Deformable ConvNets v2: More Deformable, Better Results
# 自动填充padding的函数
def autopad(kernel_size, padding):
# 默认返回的padding让卷积层输入输出大小相同(保持原大小)
return padding if padding is not None else kernel_size // 2
class DCNv2(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1,
padding=1, groups=1, act=True, dilation=1, deformable_groups=1):
super(DCNv2, self).__init__()
self.in_channels = in_channels
self.out_channels = out_channels
self.kernel_size = (kernel_size, kernel_size)
self.stride = (stride, stride)
self.padding = (autopad(kernel_size, padding), autopad(kernel_size, padding))
self.dilation = (dilation, dilation)
self.groups = groups
self.deformable_groups = deformable_groups
self.weight = nn.Parameter(
torch.empty(out_channels, in_channels, *self.kernel_size)
)
self.bias = nn.Parameter(torch.empty(out_channels))
out_channels_offset_mask = (self.deformable_groups * 3 *
self.kernel_size[0] * self.kernel_size[1])
self.conv_offset_mask = nn.Conv2d(
self.in_channels,
out_channels_offset_mask,
kernel_size=self.kernel_size,
stride=self.stride,
padding=self.padding,
bias=True,
)
self.bn = nn.BatchNorm2d(out_channels)
self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())
self.reset_parameters()
def forward(self, x):
offset_mask = self.conv_offset_mask(x)
o1, o2, mask = torch.chunk(offset_mask, 3, dim=1)
offset = torch.cat((o1, o2), dim=1)
mask = torch.sigmoid(mask)
x = torch.ops.torchvision.deform_conv2d(
x,
self.weight,
offset,
mask,
self.bias,
self.stride[0], self.stride[1],
self.padding[0], self.padding[1],
self.dilation[0], self.dilation[1],
self.groups,
self.deformable_groups,
True
)
x = self.bn(x)
x = self.act(x)
return x
def reset_parameters(self):
n = self.in_channels
for k in self.kernel_size:
n *= k
std = 1. / math.sqrt(n)
self.weight.data.uniform_(-std, std)
self.bias.data.zero_()
self.conv_offset_mask.weight.data.zero_()
self.conv_offset_mask.bias.data.zero_()
def main():
input_tensor = torch.randn(4, 3, 64, 64)
block = DCNv2(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)
output_tensor = block(input_tensor)
print(output_tensor.size())
if __name__ == "__main__": main()
便捷下载方式
浏览打开网址:https://github.com/ai-dawang/PlugNPlay-Modules
更多分析可见原文