用于低分辨率图像和小物体的新 CNN 模块SPD-Conv

简介: 用于低分辨率图像和小物体的新 CNN 模块SPD-Conv


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 × C 1 S × S × C1S×S×C1的中间特征图 X XX,切出一系列子特征图为

image.png

一般来说,给定任何(原始)特征图 X XX,子图 f x , y f_{x,y}f

x,y

由 i + x i+xi+x 和 i + y i+yi+y 可按比例整除的所有条目X ( i + y ) X(i+y)X(i+y) 形成。因此,每个子图按比例因子对X XX进行下采样。下图给出了s c a l e = 2 scale=2scale=2时的例子,得到4个子图f 0 , 0 f_{0,0}f

0,0  ,f 1 , 0 f_{1,0}f 1,0 ,f 0 , 1 f_{0,1}f 0,1  , f 1 , 1 f_{1,1}f 1,1  每个都具有形状( S / 2 , S / 2 , C 1 ) (S/2,S/2,C_1)(S/2,S/2,C 1 )并将X XX下采样 2 22 倍。

image.png


接下来,沿着通道维度连接这些子特征图,从而获得一个特征图X ′ X'X ′ ,它的空间维度减少了一个比例因子,通道维度增加了一个比例因子2 22。换句话说,SPD将特征图X ( S , S , C 1 ) X(S,S,C_1)X(S,S,C 1 ) 转换为中间特征图X ′ ( S / s a c l e , S / s a c l e , s c a l e 2 C 1 ) X'(S/sacle,S/sacle,scale^2C_1)X ′ (S/sacle,S/sacle,scale 2 C 1 )

2.2 Non-strided Convolution


在SPD特征变换层之后,添加了一个带有C 2 C_2C 2

滤波器的非跨步(即 stride=1)卷积层,其中C 2 < s c a l e 2 C 1 C_2<scale^2C_1C 2 <scale 2 C 1 ,并进一步变换 X ′ ( S / s a c l e , S / s a c l e , s c a l e 2 C 1 → X ′ ′ ( S / s a c l e , S / s a c l e ,C2)X'(S/sacle,S/sacle,scale^2C_1→X''(S/sacle,S/sacle,C_2)X ′ (S/sacle,S/sacle,scale 2 C 1 →X ′′ (S/sacle,S/sacle,C 2 ) 。


使用非跨步卷积的原因是尽可能地保留所有的判别特征信息。否则,例如,使用 s t r i d e = 3 stride=3stride=3 的 3 × 3 3×33×3 卷积,特征图将“缩小”,但每个像素只采样一次;如果 s t r i d e = 2 stride=2stride=2,将发生不对称采样,其中偶数和奇数行/列的采样时间不同。一般来说,步长大于 1 11 会导致信息的非歧视性丢失,尽管在表面上,它似乎转换了特征图 X ( S , S , C 1 ) → X ′ ′ ( S / s a c l e , S / s a c l e , C 2 ) X(S,S,C_1)→X''(S/sacle,S/sacle,C_2)X(S,S,C 1 )→X ′′ (S/sacle,S/sacle,C 2 )(但没有X ′ X'X ′)

3 如何使用SPD-Conv


为了解释如何将提出的方法应用到重新设计CNN架构中,使用了2个最具代表性的计算机视觉模型类别:目标检测和图像分类

3.1 检测:Yolov5改进方式


并且作者将这个模块应用到了YOLOv5中,取得了很好的效果a9deab4323c24acdaef38a488da30a9d.png

Fig 4 红框是发生替换的地方

YOLOv5-SPD:将第 3 节中描述的方法应用于YOLOv5并获得 YOLOv5-SPD,只需用 SPD-Conv 替换YOLOv5 s t r i d e − 2 stride-2stride−2 卷积即可。这种替换有 7 77 个实例,因为 YOLOv5 在主干中使用5 55个s t r i d e − 2 stride-2stride−2 卷积层将特征图下采样 25 2525 倍,并在颈部使用2 22个 s t r i d e − 2 stride-2stride−2 卷积层。YOLOv5颈部的每个跨步卷积之后都有一个连接层;这不会改变本文的方法,只是将它保持在 SPD 和 Conv 之间。


与YOLOv5一样,作者也提供了多个版本适配YOLO

image.png可扩展性:YOLOv5-SPD 可以通过与 YOLOv5 相同的方式轻松扩展和缩减来适应不同的应用程序或硬件需求

具体来说,可以简单地调整(1)每个非跨步卷积层中的过滤器数量和/或(2)C3模块的重复次数(如图4所示),以获得不同版本的YOLOv5-SPD


第1个称为宽度缩放:它将原始宽度n w nwnw(通道数)更改为 n w × w i d t h f a c t o r e nw × width_f actorenw×width f actore(四舍五入到最接近的 8 倍数)


第2个称为深度缩放:它将原始深度 n d ndnd(重复 C3 模块的次数;例如,图 4 中的 9 × C 3 9 × C39×C3 中的 9)更改为 n d × d e p t hfactornd×depth_factornd×depth factor这样,通过选择不同的宽度/深度因子,我们得到了YOLOv5-SPD的nano、small、medium和large版本,如表2所示,其中因子值选择与YOLOv5相同,以便在后面的实验中进行比较 .

3.2 分类:ResNet改进方式


分类 CNN通常从一个由 s t r i d e − 2 stride-2stride−2 卷积和池化层组成的stem单元开始,以将图像分辨率降低4 44倍。一个流行的模型是 ResNet,它赢得了 ILSVRC 2015 挑战。ResNet引入了残差连接,以允许训练高达152 152152 层的网络。它还通过仅使用单个全连接层显着减少了参数的总数。最后使用 softmax层对类预测进行归一化。


ResNet18-SPD 和 ResNet50-SPD 架构

image.png

ResNet-18和ResNet-50都使用总共4 44个s t r i d e − 2 stride-2stride−2卷积和一个s t r i d e 2 stride 2stride2的最大池化层,将每个输入图像下采样25 2525倍。应用我们提出的构建块,用SPD-Conv替换了四个跨步卷积;但另一方面,我们只是删除了最大池化层,因为我们的主要目标是低分辨率图像,我们实验中使用的数据集的图像相当小(Tiny ImageNet 中为64 × 64 64 × 6464×64,CIFAR-10中为32 × 32 32 × 3232×32)因此不需要池化, 对于更大的图像,这样的最大池化层仍然可以用SPD-Conv以相同的方式替换

4 论文实验结果


4.1 目标检测


MS-COCO 验证数据集的比较(val2017)

image.png

MS-COCO测试数据集的比较(test-dev2017)

image.png

image.png

val2017的目标检测实例。蓝色方框表示 ground truth情况。红色箭头突出了不同之处

4.2 图像分类


图像分类性能比较

image.png

绿色标签: 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中添加如下代码

image.png

        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)
  ]
模型 参数量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

有问题欢迎大家指正,如果感觉有帮助的话请点赞支持下👍📖🌟

相关文章
|
4月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
PYTHON TENSORFLOW 2二维卷积神经网络CNN对图像物体识别混淆矩阵评估|数据分享
PYTHON TENSORFLOW 2二维卷积神经网络CNN对图像物体识别混淆矩阵评估|数据分享
|
11月前
|
机器学习/深度学习 运维 算法
基于卷积神经网络和手工特征注入的皮肤损伤图像异常检测:一种绕过皮肤镜图像预处理的方法
基于卷积神经网络和手工特征注入的皮肤损伤图像异常检测:一种绕过皮肤镜图像预处理的方法
96 1
|
4月前
|
机器学习/深度学习 数据可视化 数据挖掘
R语言深度学习卷积神经网络 (CNN)对 CIFAR 图像进行分类:训练与结果评估可视化
R语言深度学习卷积神经网络 (CNN)对 CIFAR 图像进行分类:训练与结果评估可视化
|
4月前
|
机器学习/深度学习 算法 TensorFlow
【视频】神经网络正则化方法防过拟合和R语言CNN分类手写数字图像数据MNIST|数据分享
【视频】神经网络正则化方法防过拟合和R语言CNN分类手写数字图像数据MNIST|数据分享
|
4月前
|
机器学习/深度学习 数据采集 TensorFlow
R语言KERAS深度学习CNN卷积神经网络分类识别手写数字图像数据(MNIST)
R语言KERAS深度学习CNN卷积神经网络分类识别手写数字图像数据(MNIST)
|
机器学习/深度学习 算法 PyTorch
手把手教你使用LabVIEW实现Mask R-CNN图像实例分割(含源码)
前面给大家介绍了使用LabVIEW工具包实现图像分类,目标检测,今天我们来看一下如何使用LabVIEW实现Mask R-CNN图像实例分割。
226 0
|
机器学习/深度学习 人工智能 算法
CVPR 2022 | CNN自监督预训练新SOTA:上交、Mila、字节联合提出具有层级结构的图像表征自学习新框架
CVPR 2022 | CNN自监督预训练新SOTA:上交、Mila、字节联合提出具有层级结构的图像表征自学习新框架
241 0
|
机器学习/深度学习 数据采集 数据可视化
PyTorch深度学习实战 | 搭建卷积神经网络进行图像分类与图像风格迁移
PyTorch是当前主流深度学习框架之一,其设计追求最少的封装、最直观的设计,其简洁优美的特性使得PyTorch代码更易理解,对新手非常友好。 本文为实战篇,介绍搭建卷积神经网络进行图像分类与图像风格迁移。
461 0
PyTorch深度学习实战 | 搭建卷积神经网络进行图像分类与图像风格迁移
|
机器学习/深度学习 存储 编解码
高效神经网络架构的正确打开方式 | EMO:结合 CNN 和 Transformer 的现代倒残差移动模块设计
高效神经网络架构的正确打开方式 | EMO:结合 CNN 和 Transformer 的现代倒残差移动模块设计
284 0
|
机器学习/深度学习 传感器 算法
【图像检测】基于CNN深度学习实现图像视网膜病变检测附matlab代码
【图像检测】基于CNN深度学习实现图像视网膜病变检测附matlab代码

热门文章

最新文章

相关实验场景

更多