Backbone 之 DetNet:为检测而生(Pytorch 实现及代码解析
在组成特征金字塔时,由于特征图大小完全相同,因此可以直接从右向左传递相加,避免了上一节的上采样操作。为了进一步融合各通道的特征,需要对每一个阶段的输出进行 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 来讲,粗腰对 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 恒等变换增加额外卷积操作,此处与 ResNet 类似
identity = self.extra_conv(x)
评论