点击上方“3D视觉车间,选择星标
第一时间送达干货
作者丨南山
来源丨AI约读社
YOLOv以其性能和速度行的单阶段目标检测,的单阶段目标检测,其结构清晰灵活。 yolov5是一种强大的工具,但它被设计成一种通用的目标检测器,因此对较小的目标检测没有很好的优化。。主要有以下方法:
1.增加小目标检测层
2、Transformer PredictionHeads (TPH)集成到YOLOv5
3、将CBAM集成到YOLOv5
4、用Bi-FPN替换PAN-Net
YOLOv小目标检测效果差的原因之一是小目标样本尺寸小,yolov5的下采样倍数相对较大,较深的特征图很难学习小目标的特征信息。因此,建议增加小目标检测层,在拼接浅特征图和深特征图后进行检测。
这种方法的实现非常简单有效,只需要修改yolov5的模型文件yaml小目标检测层可以增加,但增加检测层后,问题是计算量增加,导致推理检测速度降低。然而,小目标确实有了很好的改进。
修改Anchor:增加一组较小的anchor
#anchors anchors: - [5,6, 8,14, 15,11] #4 - [10,13, 16,30, 33,23] # P3/8 - [30,61, 62,45, 59,119] # P4/16 - [116,90, 156,198, 373,326] # P5/32
修改Head部分:
第17层后,继续采样特征图,使特征图继续扩大。同时,在第20层,获得的尺寸为160X骨干网络160特征图和第二层特征图concat为了获得更大的特征图进行小目标检测
#YOLOv5head [-1, 1, Conv, [256, 1, 1]], #18 80*80 [-1, 1, nn.Upsample, [None, 2, 'nearest']], #19 160*160 [[-1, 2], 1, Concat, [1]], #20 cat backbone p2 160*160 [-1, 3, BottleneckCSP, [256, False]], #21 160*160 #部分代码在空间限制中间省略,原代码关注公众后台回复:YOLO小目标 [[21, 24, 27, 30], 1, Detect, [nc, anchors]], # Detect(p2, P3, P4, P5) ]
论文题目:TPH-YOLOv5: Improved YOLOv5 Based on Transformer Prediction Head for Object Detection on Drone-Captured Scenarios
TPH-YOLOv网络结构如下:
TPH-YOLOv5用Transformer encoder块替换了YOLOv5中的一些卷积块和CSP bottleneck blocks,每个结构如下图所示:Transformer encoder block包括两个子层。第1子层为multi-head attention layer,第2子层(MLP)全连接层。残差连接用于每个子层之间。Transformer encoder block提高了捕获不同局部信息的能力。它还可以利用自注机制来挖掘特征来表示潜力。
class C3TR(C3): # C3 module with TransformerBlock() def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): super().__init__(c1, c2, n, shortcut, g, e) c_ = int(c2 * e) self.m = TransformerBlock(c_, c_, 4, n) class TransformerBlock(nn.Module): # Vision Transformer https://arxiv.org/abs/2010.11929 def __init__(self, c1, c2, num_heads, num_layers): super().__init__() self.conv = None if c1 != c2: self.conv = Conv(c1, c2) self.linear = nn.Linear(c2, c2) # learnable position embedding self.tr = nn.Sequential(*(TransformerLayer(c2, num_heads) for _ in range(num_layers))) self.c2 = c2 def forward(self, x): if self.conv is not None: x = self.conv(x) b, _, w, h = x.shape p = x.flatten(2).unsqueeze(0).transpose(0, 3).squeeze(3) return self.tr(p self.linear(p)).unsqueeze(3).transpose(0, 3).reshape(b, self.c2, w, h)
与CSPDarknet53中的bottleneck blocks相比,Transformer encoder block可捕获全局信息和丰富的上下文信息。
在YOLOV5中插入CBAM,CBAM它可以无缝地集成到任何东西中CNN在架构上,成本不会很大,可以和基本一起使用CNN网络一起进行端到端训练。假设我们有中间特征F(H×W×C)作为卷积层的输出。根据层的深度,每个特征层都会捕获有用的信息,如简单的边缘和形状,以获得更复杂的输入语义表示。我们希望网络能更多地关注这些特征图的重要组成部分(即关注)。
class CBAM(nn.Module): def __init__(self, c1,c2): super(CBAM, self).__init__() self.channel_attention = ChannelAttentionModule(c1) self.spatial_attention = SpatialAttentionModule() def forward(self, x): out = self.channel_attention(x) * x out = self.spatial_attention(out) * out return out classChannelAttentionModule(nn.Module): def __init__(self, c1, reduction=16): super(ChannelAttentionModule, self).__init__() mid_channel = c1 // reduction self.avg_pool = nn.AdaptiveAvgPool2d(1) self.max_pool = nn.AdaptiveMaxPool2d(1) self.shared_MLP = nn.Sequential( nn.Linear(in_features=c1, out_features=mid_channel), nn.ReLU(), nn.Linear(in_features=mid_channel, out_features=c1) ) self.sigmoid = nn.Sigmoid() #self.act=SiLU() defforward(self,x): avgout = self.shared_MLP(self.avg_pool(x).view(x.size(0),-1)).unsqueeze(2).unsqueeze(3)
maxout = self.shared_MLP(self.max_pool(x).view(x.size(0),-1)).unsqueeze(2).unsqueeze(3)
return self.sigmoid(avgout + maxout)
class SpatialAttentionModule(nn.Module):
def __init__(self):
super(SpatialAttentionModule, self).__init__()
self.conv2d = nn.Conv2d(in_channels=2, out_channels=1, kernel_size=7, stride=1, padding=3)
#self.act=SiLU()
self.sigmoid = nn.Sigmoid()
def forward(self, x):
avgout = torch.mean(x, dim=1, keepdim=True)
maxout, _ = torch.max(x, dim=1, keepdim=True)
out = torch.cat([avgout, maxout], dim=1)
out = self.sigmoid(self.conv2d(out))
return out
使用CBAM可以提取注意区域,以帮助YOLOv5抵制令人困惑的信息,并关注有用的目标对象。
将位于Head和Backbone之间的结构称为“Neck”,其目标是在将Backbone提取的信息反馈到Head之前尽可能多地聚合这些信息。该结构通过防止小目标信息丢失,在传递小目标信息方面发挥了重要作用。它通过再次提高特征图的分辨率来做到这一点,这样来自Backbone的不同层的特征就可以被聚合,以提升整体的检测性能。
neck部分模型结构文件yaml代码
# YOLOv5 v6.0 head
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)
[ -1, 1, Conv, [ 128, 1, 1 ] ],
[ -1, 1, nn.Upsample, [ None, 2, 'nearest' ] ],
[ [ -1, 2 ], 1, Concat, [ 1 ] ], # cat backbone P2
[-1, 1, SPP, [128, [5, 9, 13]]],
[ -1, 3, C3, [ 128, False ] ], # (P2/4-xsmall)
[-1, 1, CBAM, [128]], # 23
这篇文章介绍了四种基于YOLOV5小目标检测的网络结构优化方法,主要是通过Transformer encoder块替换了YOLOv5中的一些卷积块,以及增加小目标检测层,集成CBAM空间通道注意力模块和使用Bi-FPN替换PAN-FPN,还有一些针对小目标检测技巧的改进,后续有时间我们在做总结。
[1] Zhu X, Lyu S, Wang X, et al. TPH-YOLOv5: Improved YOLOv5 Based on Transformer Prediction Head for Object Detection on Drone-captured Scenarios[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision. 2021: 2778-2788.
[2] Benjumea A, Teeti I, Cuzzolin F, et al. YOLO-Z: Improving small object detection in YOLOv5 for autonomous vehicles[J]. arXiv preprint arXiv:2112.11798, 2021.
[3] 集智书童@公众号 详细解读TPH-YOLOv5 | 让目标检测任务中的小目标无处遁形
https://mp.weixin.qq.com/s/QPwvZSjHRQsnME8CjUg6UA
[4] 集智书童@公众号 记录修改YOLOv5以适应小目标检测的实验过程https://cloud.tencent.com/developer/article/1925516
[5] Tz..@CSDN FPN以及其他结构FPN——Bi-FPN重点(仅供自己学习使用)https://blog.csdn.net/qq_41456654/article/details/115558583
[6] 小俊俊的博客 @CSDN yolov5增加小目标检测层
https://blog.csdn.net/weixin_41868104/article/details/111596851?spm=1001.2014.3001.5501
本文仅做学术分享,如有侵权,请联系删文。
1.面向自动驾驶领域的多传感器数据融合技术
2.面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)3.彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进4.国内首个面向工业级实战的点云处理课程5.激光-视觉-IMU-GPS融合SLAM算法梳理和代码讲解6.彻底搞懂视觉-惯性SLAM:基于VINS-Fusion正式开课啦7.彻底搞懂基于LOAM框架的3D激光SLAM: 源码剖析到算法优化8.彻底剖析室内、室外激光SLAM关键算法原理、代码和实战(cartographer+LOAM +LIO-SAM)
9.从零搭建一套结构光3D重建系统[理论+源码+实践]
10.单目深度估计方法:算法梳理与代码实现
11.自动驾驶中的深度学习模型部署实战
12.相机模型与标定(单目+双目+鱼眼)
13.重磅!四旋翼飞行器:算法与实战
扫码添加小助手微信,可
一定要备注:
▲长按加微信群或投稿
▲长按关注公众号
学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
圈里有高质量教程资料、答疑解惑、助你高效解决问题