【轻量化网络】实战:更改SqueezeNet网络&MobileNet网络& ShuffleNet网络输出替换yolo的backbone部分

565 阅读3分钟

关键词:轻量化、低功耗、深度可分离卷积、通道重排、1×1卷积核

前言

  因此我们可以在“写(水)”论文的时候更换yolo的主干网络进行实验获取实验参数。在本文中将介绍ShuffleNetV2网络以及MobilenetV2网络更改的主干网络。

  轻量化网络相比于 YOLO 系列网络的主干网络,具有以下优势:

  1. 更快的推理速度:轻量化网络通常具有更少的参数和计算量,因此在推理时可以更快地处理输入数据。
  2. 更小的模型尺寸:轻量化网络通常具有更小的模型尺寸,这使得它们更容易部署到嵌入式设备或移动设备上。
  3. 更低的计算资源需求:轻量化网络需要更少的计算资源来运行,这使得它们更适合于在资源受限的环境中使用。
  4. 更好的泛化能力:轻量化网络通常具有更好的泛化能力,可以在小数据集上训练,并且可以更好地应对数据集的变化。
  5. 更容易优化:由于轻量化网络具有更少的参数,因此可以更容易地进行优化和调整,以在特定的任务上实现更好的性能

轻量化移植

   本文以yolov5作为例子向大家介绍如何进行轻量化替代迁移。这里我们主要是替代“三张图”

yolo5主干

  YOLOv5的主干网络采用的是CSPNet(Cross Stage Partial Network)结构,它是一种轻量级的卷积神经网络,可以有效地减少参数数量和计算量,提高模型的速度和精度。CSPNet结构的具体实现包括以下几个部分:

  1. CSPDarknet:包括多个卷积层和残差块,用于从图像中提取特征;
  2. SPP(Spatial Pyramid Pooling)模块:用于在不同尺度下对特征图进行池化操作,以提取更全局和丰富的特征信息;
  3. CSP Bottleneck Block:包括多个卷积层和残差块,用于进一步加深网络结构和提取更复杂的特征;
  4. PAN(Path Aggregation Network)模块:用于将不同层级的特征图进行融合,以提高检测精度;
  5. Detection Head:包括多个卷积层和全连接层,用于对特征图进行分类和回归,以得到目标的位置和类别。

MobilenetV2&ShuffleNetV2迁移

移植步骤:

  1. 使用torchvision.models中自带的MobilenetV2的网络当作模板进行使用;
  2. 修改YOLOv5的代码:需要将MobilenetV2的卷积层、批归一化层、激活函数等等替换为原来的CSPDarknet中的对应层次。同时,你还需要调整一些超参数,例如输入图像的大小、通道数、卷积核大小等等,以适应MobilenetV2网络的结构和特点;
  3. 加载MobilenetV2的预训练权重文件;
  4. 对新的模型进行微调.

代码示例

import torch
import torchvision
from torch import nn

class MobilenetV2(nn.Module):
    def __init__(self, pretrained=False):
        super(MobilenetV2, self).__init__()
        self.model = torchvision.models.mobilenet_v2(pretrained=pretrained)

    def forward(self, x):
        out3 = self.model.features[:7](x)
        out4 = self.model.features[7:14](out3)
        out5 = self.model.features[14:18](out4)
        return out3, out4, out5

class Shufflenetv2_x0_5(nn.Module):
    def __init__(self, pretrained=False):
        super(Shufflenetv2_x0_5, self).__init__()
        self.model = torchvision.models.shufflenet_v2_x0_5(pretrained=pretrained)

    def forward(self, x):
        x1 = self.model.conv1(x)
        x2 = self.model.maxpool(x1)
        out3 = self.model.stage2(x2)
        out4 = self.model.stage3(out3)
        out5 = self.model.stage4(out4)
        return out3, out4, out5


if __name__ == "__main__":

    x = torch.zeros([1, 3, 640, 640])
    model = Shufflenetv2_x0_5()
    out3, out4, out5 = model(x)
    print(out3.shape)
    print(out4.shape)
    print(out5.shape)