在目标检测领域,主流的方法一般都是基于 CNN(卷积神经网络)的,比如 Faster R-CNN、YOLO、SSD 这些大佬。但这些传统方法有个痛点:网络越深,感受野越大,但特征图越来越小,导致目标检测特别是小目标检测的效果不太行。
DetNet 论文的核心目的,就是解决深层网络导致的分辨率下降问题,让目标检测能在不牺牲高层语义信息的情况下,保留较高的分辨率,从而提升检测效果,特别是小目标的检测能力。
简单来说,DetNet 就是个 更适合目标检测的 CNN 结构,它的主要思路是:
DetNet 论文的核心贡献在于设计了一种新型的 Backbone(骨干网络)结构,让检测任务的特征图在深层网络里依然能保持较大尺寸。
传统的 CNN,比如 ResNet,层数越深,特征图缩小得越厉害。比如,一张 512x512 的图片经过 ResNet 的卷积后,到了深层可能只剩下 16x16 的特征图,这对于目标检测尤其是小目标检测是个噩梦!
DetNet 通过以下几个设计巧妙地避免了这个问题:
简单来说,DetNet 就是 ResNet 的改进版,专门为目标检测优化,让检测头能获取更多有用的信息。
在 PyTorch 代码实现之前,我们先搞清楚 DetNet 的几个核心设计点:
DetNet 里最关键的技术之一就是 扩张卷积(又叫空洞卷积),这个东西的作用是 增大感受野,同时不降低分辨率。
传统卷积 VS 扩张卷积:
这样一来,我们就可以用小小的计算量,获得更大的感受野,而不会让特征图变得太小。
在传统的 ResNet 里,到达 Stage 5(最后几个残差块)时,特征图已经变得很小(1/32 原图尺寸)。而 DetNet 直接干掉了最后的降采样,让特征图保持在 1/16 甚至 1/8 原图尺寸,这样目标检测头就能用到更清晰的特征图。
DetNet 里用了一种特殊的 残差块(Bottleneck),这个块里面的 3x3 卷积被替换成了 扩张卷积,这样可以同时 保留特征图的大小,又能获取更大感受野。
理解了 DetNet 的核心思想后,我们来用 PyTorch 实现一个 DetNet 的 Backbone(骨干网络),然后让它跑起来!
import torch
import torch.nn as nn
class DetBottleneck(nn.Module):
def __init__(self, in_channels, out_channels, dilation):
super(DetBottleneck, self).__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channels)
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3,
padding=dilation, dilation=dilation, bias=False)
self.bn2 = nn.BatchNorm2d(out_channels)
self.conv3 = nn.Conv2d(out_channels, out_channels, kernel_size=1, bias=False)
self.bn3 = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU(inplace=True)
def forward(self, x):
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.bn3(out)
return self.relu(out)
这个结构就是 DetNet 里用的特制残差块,里面的 conv2
是扩张卷积。
class DetNet(nn.Module):
def __init__(self, num_classes=20):
super(DetNet, self).__init__()
self.layer1 = DetBottleneck(64, 128, dilation=1)
self.layer2 = DetBottleneck(128, 256, dilation=2)
self.layer3 = DetBottleneck(256, 512, dilation=4)
self.classifier = nn.Conv2d(512, num_classes, kernel_size=1)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.classifier(x)
return x
这个 DetNet
类就是一个完整的骨干网络结构,最后接了个 1x1
的卷积层,用于分类。
model = DetNet(num_classes=20)
x = torch.randn(1, 64, 128, 128) # 假设输入是一张 128x128 的图片
output = model(x)
print(output.shape)
输出的 shape
应该是 (1, 20, 128, 128)
,证明 DetNet 确实保留了高分辨率的特征图!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有