YOLOv8 的改进:渐进特征金字塔网络 (AFPN)| 实现小目标检测
????????????本文改进:渐近特征金字塔网络(AFPN),解决多尺度削弱了非相邻 Level 的融合效果。
AFPN | 亲测在多个数据集能够实现涨点,尤其在小目标数据集。
1.AFPN介绍
论文: 2306.15988.pdf (arxiv.org)
摘要:多尺度特征在目标检测任务中对具有尺度方差的目标进行编码时具有重要意义。多尺度特征提取的一种常见策略是采用经典的自上而下和自下而上的特征金字塔网络。然而,这些方法遭受特征信息的丢失或退化,削弱了非相邻 Level 的融合效果。本文提出了一种渐近特征金字塔网络(AFPN)来支持非相邻层的直接交互。AFPN是通过融合两个相邻的Low-Level特征来启动的,并渐进地将High-Level特征纳入融合过程。通过这种方式,可以避免非相邻 Level 之间的较大语义差距。考虑到在每个空间位置的特征融合过程中可能出现多目标信息冲突,进一步利用自适应空间融合操作来缓解这些不一致。本文将所提出的AFPN纳入两阶段和一阶段目标检测框架,并使用MS-COCO 2017验证和测试数据集进行评估。实验评估表明,与其他最先进的特征金字塔网络相比,作者的方法获得了更具竞争力的结果。
在Backbone网络自下而上的特征提取过程中,AFPN渐进地集成了Low-Level、High-Level和*特征。具体来说,AFPN最初融合了Low-Level特征,然后融合了深层特征,最后融合了最High-Level的特征,即最抽象的特征。非相邻层次特征之间的语义差距大于相邻层次特征间的语义差距,尤其是底部和顶部特征。这直接导致了非相邻层次特征的融合效果较差。因此,直接使用C2、C3、C4和C5进行特征融合是不合理的。由于AFPN的架构是渐进的,这将使不同 Level 特征的语义信息在渐进融合过程中更加接近,从而缓解上述问题。例如,C2和C3之间的特征融合减少了它们的语义差距。由于C3和C4是相邻的层次特征,因此减少了C2和C4之间的语义差距。
在多级特征融合过程中,作者利用ASFF为不同 Level 的特征分配不同的空间权重,增强了关键 Level 的重要性,并减轻了来自不同目标的矛盾信息的影响。
将提出的AFPN方法应用于两阶段和一阶段目标检测框架,并在MS-COCO 2017验证和测试数据集上进行评估。实验结果表明,所提出方法比其他最先进的特征金字塔网络取得了更具竞争力的结果
2.AFPN引入yolov8
2.1新建ultralytics/nn/head/AFPN.py
核心代码:
class ASFF3(nn.Module):
"""ASFF3 module for YOLO AFPN head https://arxiv.org/abs/2306.15988"""
def __init__(self, c1, c2, level=0):
super().__init__()
c1_l, c1_m, c1_h = c1[0], c1[1], c1[2]
self.level = level
self.dim = c1_l, c1_m, c1_h
self.inter_dim = self.dim[self.level]
compress_c = 8
if level == 0:
self.stride_level_1 = Upsample(c1_m, self.inter_dim)
self.stride_level_2 = Upsample(c1_h, self.inter_dim, scale_factor=4)
if level == 1:
self.stride_level_0 = Conv(c1_l, self.inter_dim, 2, 2, 0) # downsample 2x
self.stride_level_2 = Upsample(c1_h, self.inter_dim)
if level == 2:
self.stride_level_0 = Conv(c1_l, self.inter_dim, 4, 4, 0) # downsample 4x
self.stride_level_1 = Conv(c1_m, self.inter_dim, 2, 2, 0) # downsample 2x
self.weight_level_0 = Conv(self.inter_dim, compress_c, 1, 1)
self.weight_level_1 = Conv(self.inter_dim, compress_c, 1, 1)
self.weight_level_2 = Conv(self.inter_dim, compress_c, 1, 1)
self.weights_levels = nn.Conv2d(compress_c * 3, 3, kernel_size=1, stride=1, padding=0)
self.conv = Conv(self.inter_dim, self.inter_dim, 3, 1)
def forward(self, x):
x_level_0, x_level_1, x_level_2 = x[0], x[1], x[2]
if self.level == 0:
level_0_resized = x_level_0
level_1_resized = self.stride_level_1(x_level_1)
level_2_resized = self.stride_level_2(x_level_2)
elif self.level == 1:
level_0_resized = self.stride_level_0(x_level_0)
level_1_resized = x_level_1
level_2_resized = self.stride_level_2(x_level_2)
elif self.level == 2:
level_0_resized = self.stride_level_0(x_level_0)
level_1_resized = self.stride_level_1(x_level_1)
level_2_resized = x_level_2
level_0_weight_v = self.weight_level_0(level_0_resized)
level_1_weight_v = self.weight_level_1(level_1_resized)
level_2_weight_v = self.weight_level_2(level_2_resized)
levels_weight_v = torch.cat((level_0_weight_v, level_1_weight_v, level_2_weight_v), 1)
w = self.weights_levels(levels_weight_v)
w = F.softmax(w, dim=1)
fused_out_reduced = level_0_resized * w[:, :1] + level_1_resized * w[:, 1:2] + level_2_resized * w[:, 2:]
return self.conv(fused_out_reduced)
详见:
https://cv2023.blog.****.net/article/details/132229675
上一篇: 这就是图佩罗数字孪生污水处理厂的模样。
下一篇: 如果忘记在图片上添加标尺,该怎么办?
推荐阅读
-
CVPR 2021 | pixelNeRF:基于 NeRF 的多视角 3D 重建网络
-
清华大学提出了一种新的三维重建方法:O²-Recon,用二维扩散模型补充残缺的三维物体
-
基于图像的三维物体重建:深度学习时代的最新技术和训练趋势概览
-
基于图像的 3D 物体深度学习时代的性能比较和未来研究方向:最新技术与趋势概览
-
基于深度学习的 3D 重建算法综述
-
探索基于 NeRF 的 3D 现实重建技术
-
什么是 3D 重构?三维重建有什么用?-以下为部分截图,点击文末名片关注我的公众号AI科技星球发码321即可获得(必发码321)
-
A100 实现了无需三维卷积的三维重建方法,每帧重建时间仅为 70 毫秒
-
GPS 的全称是什么?
-
上塘提出手机实时单目三维重建系统,实现逼真的 AR 效果和交互