点击进入专栏:
《人工智能专栏》 Python与Python | 机器学习 | 深度学习 | 目标检测 | YOLOv5及其改进 | YOLOv8及其改进 | 关键知识点 | 各种工具教程
文章目录
- 1 摘要精读
- 2 SPD-Conv原理
- 2.1 Space-to-depth(SPD)
- 3 如何使用SPD-Conv
- 3.1 检测:Yolov5改进方式
- 3.2 分类:ResNet改进方式
- 4 论文实验结果
- 4.1 目标检测
- 4.2 图像分类
- 5 YOLOv5官方项目改进教程
论文地址:https://arxiv.org/pdf/2208.03641v1.pdf
代码地址:https://github.com/labsaint/spd-conv
卷积神经网络(CNN
)在图像分类、目标检测等计算机视觉任务中取得了巨大的成功。然而,在图像分辨率较低或对象较小的更困难的任务中,它们的性能会迅速下降。
这源于现有CNN
体系结构中一个有缺陷但却很常见的设计,即使用strided convolution
和/或池化层
,这导致了细粒度信息的丢失和较低效率的特征表示的学习。为此,我们提出了一种新的CNN
模块,称为SPD-Conv
,以取代每个strided convolution
和每个池化层
(从而完全消除了它们)。SPD-Conv
由 space-to-depth
(SPD)层和non-strided convolution
(Conv)层组成,可以应用于大多数CNN
架构。
我们在两个最具代表性的计算机视觉任务下解释了这种新的设计:目标检测和图像分类。然后,我们通过将SPD-Conv
应用于YOLOv5
和ResNet
来创建新的CNN
架构,实验表明我们的方法显著优于最先进的深度学习模型,特别是在处理低分辨率图像和小对象的更困难的任务时。
1 摘要精读
卷积神经网络(CNN
)在图像分类、目标检测等计算机视觉任务中取得了巨大的成功。然而,在图像分辨率较低或对象较小的更困难的任务中,它们的性能会迅速下降。
这源于现有CNN
体系结构中一个有缺陷但却很常见的设计,即使用strided convolution
和/或池化层
,这导致了细粒度信息的丢失和较低效率的特征表示的学习。为此,我们提出了一种新的CNN
模块,称为SPD-Conv
,以取代每个strided convolution
和每个池化层
(从而完全消除了它们)。SPD-Conv
由 space-to-depth
(SPD)层和non-strided convolution
(Conv)层组成,可以应用于大多数CNN
架构。
我们在两个最具代表性的计算机视觉任务下解释了这种新的设计:目标检测和图像分类。然后,我们通过将SPD-Conv
应用于YOLOv5
和ResNet
来创建新的CNN
架构,实验表明我们的方法显著优于最先进的深度学习模型,特别是在处理低分辨率图像和小对象的更困难的任务时。
2 SPD-Conv原理
2.1 Space-to-depth(SPD)
SPD-Conv
由一个SPD
层和一个non-strided convolution
层组成,SPD
组件将(原始)图像转换技术推广到对 CNN
内部和整个CNN
中的特征图进行下采样,如下所示
考虑任何大小为S × S × C1的中间特征图 X ,切出一系列子特征图为
scale = 2 时的 SPD-Conv 示意图
3 如何使用SPD-Conv
为了解释如何将提出的方法应用到重新设计CNN
架构中,使用了2个最具代表性的计算机视觉模型类别:目标检测和图像分类
3.1 检测:Yolov5改进方式
并且作者将这个模块应用到了YOLOv5中,取得了很好的效果
Fig 4 红框是发生替换的地方
YOLOv5-SPD
:将第 3 节中描述的方法应用于YOLOv5
并获得 YOLOv5-SPD
,只需用 SPD-Conv
替换YOLOv5
stride-2卷积即可。这种替换有 7 个实例,因为YOLOv5
在主干中使用 5 个 stride-2 卷积层将特征图下采样 25倍,并在颈部使用 2 个stride-2卷积层。YOLOv5
颈部的每个跨步卷积之后都有一个连接层;这不会改变本文的方法,只是将它保持在 SPD
和 Conv
之间。
与YOLOv5一样,作者也提供了多个版本适配YOLO
3.2 分类:ResNet改进方式
分类 CNN
通常从一个由 stride-2 卷积和池化层组成的stem单元开始,以将图像分辨率降低 4 4 4倍。一个流行的模型是 ResNet
,它赢得了 ILSVRC 2015 挑战。ResNet
引入了残差连接,以允许训练高达 152 层的网络。它还通过仅使用单个全连接层显着减少了参数的总数。最后使用 softmax
层对类预测进行归一化。
ResNet18-SPD 和 ResNet50-SPD 架构
ResNet-18
和ResNet-50
都使用总共4个stride-2卷积和一个stride 2的最大池化层,将每个输入图像下采样 25 25 25倍。应用我们提出的构建块,用SPD-Conv
替换了四个跨步卷积;但另一方面,我们只是删除了最大池化层,因为我们的主要目标是低分辨率图像,我们实验中使用的数据集的图像相当小(Tiny ImageNet 中为 64 × 64,CIFAR-10中为 32 × 32)因此不需要池化, 对于更大的图像,这样的最大池化层仍然可以用SPD-Conv
以相同的方式替换
4 论文实验结果
4.1 目标检测
MS-COCO 验证数据集的比较(val2017)
MS-COCO测试数据集的比较(test-dev2017)
val2017的目标检测实例。蓝色方框表示 ground truth情况。红色箭头突出了不同之处
4.2 图像分类
图像分类性能比较
绿色标签: ground truth。蓝色标签:ResNet18-SPD 预测。红色标签:ResNet-18 预测
5 YOLOv5官方项目改进教程
YOLO Magic项目同步更新
第一步:
common.py中添加如下代码
class space_to_depth(nn.Module):
# Changing the dimension of the Tensor
def __init__(self, dimension=1):
super().__init__()
self.d = dimension
def forward(self, x):
return torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1)
第二步;yolo.py中添加如下代码
elif m is space_to_depth:
c2 = 4 * ch[f]
第三步;修改配置文件(以为yolov5s为例)
其它版本依然可以通过调整宽度和深度控制
# Parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5 v6.0 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Focus, [64, 3]], # 0-P1/2
[-1, 1, Conv, [128, 3, 1]], # 1
[-1,1,space_to_depth,[1]], # 2 -P2/4
[-1, 3, C3, [128]], # 3
[-1, 1, Conv, [256, 3, 1]], # 4
[-1,1,space_to_depth,[1]], # 5 -P3/8
[-1, 6, C3, [256]], # 6
[-1, 1, Conv, [512, 3, 1]], # 7-P4/16
[-1,1,space_to_depth,[1]], # 8 -P4/16
[-1, 9, C3, [512]], # 9
[-1, 1, Conv, [1024, 3, 1]], # 10-P5/32
[-1,1,space_to_depth,[1]], # 11 -P5/32
[-1, 3, C3, [1024]], # 12
[-1, 1, SPPF, [1024, 5]], # 13
]
# YOLOv5 v6.0 head
head:
[[-1, 1, Conv, [512, 1, 1]], # 14
[-1, 1, nn.Upsample, [None, 2, 'nearest']], # 15
[[-1, 9], 1, Concat, [1]], # 16 cat backbone P4
[-1, 3, C3, [512, False]], # 17
[-1, 1, Conv, [256, 1, 1]], # 18
[-1, 1, nn.Upsample, [None, 2, 'nearest']], # 19
[[-1, 6], 1, Concat, [1]], # 20 cat backbone P3
[-1, 3, C3, [256, False]], # 21 (P3/8-small)
[-1, 1, Conv, [256, 3, 1]], # 22
[-1,1,space_to_depth,[1]], # 23 -P2/4
[[-1, 18], 1, Concat, [1]], # 24 cat head P4
[-1, 3, C3, [512, False]], # 25 (P4/16-medium)
[-1, 1, Conv, [512, 3, 1]], # 26
[-1,1,space_to_depth,[1]], # 27 -P2/4
[[-1, 14], 1, Concat, [1]], # 28 cat head P5
[-1, 3, C3, [1024, False]], # 29 (P5/32-large)
[[21, 25, 29], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
四头yaml
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# Parameters
nc: 80 # number of classes
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple
anchors:
- [7,11, 11,20, 8,31] # P2
- [18,33, 15,59, 29,54] # P3
- [25,103, 49,97, 40,174] # P4
- [64,250, 98,384, 183,475] # p5
# YOLOv5 v6.0 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Conv, [64, 3]], # 0-P1/2
[-1, 1, Conv, [128, 3, 1]], # 1
[-1,1,space_to_depth,[1]], # 2 -P2/4
[-1, 3, C3, [128]], # 3
[-1, 1, Conv, [256, 3, 1]], # 4
[-1,1,space_to_depth,[1]], # 5 -P3/8
[-1, 6, C3, [256]], # 6
[-1, 1, Conv, [512, 3, 1]], # 7
[-1,1,space_to_depth,[1]], # 8 -P4/16
[-1, 9, C3, [512]], # 9
[-1, 1, Conv, [1024, 3, 1]], # 10
[-1,1,space_to_depth,[1]], # 11 -P5/32
[-1, 3, C3, [1024]], # 12
[-1, 1, SPPF, [1024, 5]], # 13
]
# YOLOv5 v6.0 head with (P2, P3, P4, P5) outputs
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 10], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 17
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 7], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 21 (P3/8-small)
[-1, 1, Conv, [128, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P2
[-1, 1, C3, [128, False]], # 25 (P2/4-xsmall)
[-1, 1, Conv, [128, 3, 1]],
[-1, 1,space_to_depth,[1]],
[[-1, 22], 1, Concat, [1]], # cat head P3
[-1, 3, C3, [256, False]], # 29 (P3/8-small)
[-1, 1, Conv, [256, 3, 1]],
[-1, 1,space_to_depth,[1]],
[[-1, 18], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 33 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 13], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 36 (P5/32-large)
[[25, 29, 33, 36], 1, Detect, [nc, anchors]], # Detect(P2, P3, P4, P5)
]
模型 | 参数量parameters | 计算量GFLOPs |
---|---|---|
yolov5s | 7235389 | 16.5 |
yolov5s_SPD | 8771389 | 33.9 |
yolov5n_SPD | 2256157 | 8.9 |
yolov5m_SPD | 24646557 | 88.0 |
yolov5l_SPD | 52707709 | 178.6 |