Backbone 之 DetNet:为检测而生(Pytorch实现及代码解析)
Posted 心之所向521
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Backbone 之 DetNet:为检测而生(Pytorch实现及代码解析)相关的知识,希望对你有一定的参考价值。
背景:
前面几节的网络骨架,如VGGNet和ResNet等,虽从各个角度出发提升了物体检测性能,但究其根本是为ImageNet的图像分类任务而设计的。而图像分类与物体检测两个任务天然存在着落差,分类任务侧重于全图的特征提取,深层的特征图分辨率很低;而物体检测需要定位出物体位置,特征图分辨率不宜过小,因此造成了以下两种缺陷:
-
大物体难以定位:对于FPN等网络,大物体对应在较深的特征图上检测,由于网络较深时下采样率较大,物体的边缘难以精确预测,增加了回归边界的难度。
-
小物体难以检测:对于传统网络,由于下采样率大造成小物体在较深的特征图上几乎不可见;FPN虽从较浅的特征图来检测小物体,但浅层的语义信息较弱,且融合深层特征时使用的上采样操作也会增加物体检测的难度。
DetNet应运而生:
针对以上问题,旷视科技提出了专为物体检测设计的DetNet结构,引入了空洞卷积,使得模型兼具较大感受野与较高分辨率,同时避免了3.6节中FPN的多次上采样,实现了较好的检测效果。
了解网络结构之前有必要了解以下空洞卷积:
DetNet的网络结构:
如图所示,仍然选择性能优越的ResNet-50作为基础结构,并保持前4个stage与ResNet-50相同,具体的结构细节有以下3点:
-
引入了一个新的Stage 6,用于物体检测。Stage 5与Stage 6使用了DetNet提出的Bottleneck结构,最大的特点是利用空洞数为2的3×3卷积取代了步长为2的3×3卷积。(具体什么是空洞卷积见上)
-
Stage 5与Stage 6的每一个Bottleneck输出的特征图尺寸都为原图的,通道数都为256,而传统的Backbone通常是特征图尺寸递减,通道数递增。
-
在组成特征金字塔时,由于特征图大小完全相同,因此可以直接从右向左传递相加,避免了上一节的上采样操作。为了进一步融合各通道的特征,需要对每一个阶段的输出进行1×1卷积后再与后一Stage传回的特征相加。
DetNet这种精心设计的结构作用:
-
在增加感受野的同时,获得了较大的特征图尺寸,有利于物体的定位。
-
与此同时,由于各Stage的特征图尺寸相同,避免了上一节的上采样,既一定程度上降低了计算量,又有利于小物体的检测。
DetNet网络结构与残差ResNet网络结果对比:
这样设计的区别及作用:本图中左侧的两个Bottleneck A与Bottleneck B分别对应DetNet网络结构图中的A与B,右侧的为原始的ResNet残差结构。DetNet与ResNet两者的基本思想都是卷积堆叠层与恒等映射的相加,区别在于DetNet使用了空洞数为2的3×3卷积,这样使得特征图尺寸保持不变,而ResNet是使用了步长为2的3×3卷积。B相比于A,在恒等映射部分增加了一个1×1卷积,这样做可以区分开不同的Stage,并且实验发现这种做法对于特征金字塔式的检测非常重要。
具体代码如下:
from torch import nn
###这个类只是表示的DetNet的小砖块的定义
class DetBottleneck(nn.Module):
###初始化参数extra为False时,代表BottleneckA,反之代表BottleneckB
def __init__(self, inplanes, planes, stride=1, extra=False):
super(DetBottleneck, self).__init__()
###构造连续3*3个卷积层的Bottleneck
self.bottleneck = nn.Sequential(
nn.Conv2d(inplanes, planes, 1, bias=False),
nn.BatchNorm2d(planes),
nn.ReLU(inplace=True),
##表示空洞数为2的空洞卷积,dilation表示空洞数
nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=2,
dilation=2, bias=False),
nn.BatchNorm2d(planes),
nn.ReLU(inplace=True),
nn.Conv2d(planes, planes, 1, bias=False),
nn.BatchNorm2d(planes),
)
self.relu = nn.ReLU(inplace=True)
self.extra = extra
if self.extra:
###表示Bottleneck B的1*1卷积
self.extra_conv = nn.Sequential(
nn.Conv2d(inplanes, planes, 1, bias=False),
nn.BatchNorm2d(planes)
)
def forward(self, x):
if self.extra:
###对于Bottleneck B来讲,粗腰对恒等变换增加额外卷积操作,此处与ResNet类似
identity = self.extra_conv(x)
else:
identity = x
out = self.bottleneck(x)
out += identity
out = self.relu(out)
return out
点个赞再走呗!!
以上是关于Backbone 之 DetNet:为检测而生(Pytorch实现及代码解析)的主要内容,如果未能解决你的问题,请参考以下文章