轻量级网络结构mobilenetv1、v2、v3学习笔记

本文详细介绍了Mobilenet系列模型,包括V1、V2和V3的主要特点。 MobilenetV1引入了深度可分离卷积以减少参数量,V2则在此基础上采用了残差结构并优化了通道维度的调整,而V3进一步引入了通道注意力机制和不同的激活函数。这些改进使得Mobilenet系列在保持高效的同时,提升了计算机视觉任务的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天是自己做一下mobilenet的简单笔记,怕自己后面忘记了mobilenet的相关内容,首先我们要知道mobilenet是为了能够在嵌入式设备上使用的一种模型框架,因此它最大的优点就是参数量少,并且还是要保证对于计算机视觉相关任务的精确度不能降得太低。下面就是mobilenet的各版本情况 。

mobilenetv1网络结构图

那么对于mobilenetv1来说,最大的优点或者说是改进就是选择了深度可分离卷积块来减少一般卷积的参数量,我们可以通过下面的图可以看出。(图片来源水印的地方,大家可以去看该大佬的bilibili视频,非常棒!)

 对于传统的卷积机制:假设输入的是3x3xc维度的特征图,通过3x3xd的卷积块进行卷积,得到的是1x1xd的特诊图,那么计算量为3x3xcxdx3x3=81cd.

对于深度可分离卷积来说,假设输入的是3x3xc维度的特征图,首先通过3x3xc的进行深度可分离卷积,就是对每个通道进行卷积,得到的是1x1xc的特征图,计算量为1x1x3x3xc,在经过1x1xd的卷积块进行卷积得到的结果是1x1xd,计算量为1x1xdx1x1xc,那么总的计算量1x1x3x3xc+1x1xdx1x1xc=9c+cd

通过上下进行对比,能够很明显看出差距。

下面就是mobilenetv1的整体架构图,其实原论文还提出了两个超参数,一个是α一个是β。α参数是一个倍率因子,用来调整卷积核的个数,这个卷积核个数是每个深度可分离卷积结束后通过1x1xd的卷积块的通道数改变,希望大家能够明白,β是控制输入网络的图像尺寸参数,但是深度可分离卷积也有下面图中所显示的缺点就是容易使卷积核参数变成0.至此才会出现mobilenetv2模型。

mobilenetv2网络结构图

 下面是mobilenetv2的block,可以从中大致看出就像一个残差块一样,没错就是那么简单,他就是继承了mobilenetv1的深度可分离卷积,然后由进行了一个创新,就是先升通道数再降通道数,为什么这么做呢,因为论文中说,激活函数relu对低维度的特征会造成更多的信息丢失,对于高维度的特征的丢失会少一些,所以就有了这个创新。整体步骤就是,先通过一般卷积进行升维,再通过深度可分离卷积操作,再通过一般卷积进行降维,最后再进行残差相加(特征图大小必须是一样的,相信大家这是知道的),具体看代码所示.而对于一般的残差块是1x1卷积降维->3x3卷积->1x1卷积升维。这就是两者的区别。

       mobilenetv2的block

class InvertedResidual(nn.Module):
    def __init__(self, inp, oup, stride, expand_ratio):
        super(InvertedResidual, self).__init__()
        self.stride = stride
        assert stride in [1, 2]#stride=2就是进行了下采样操作。

        hidden_dim = int(round(inp * expand_ratio))
        self.use_res_connect = self.stride == 1 and inp == oup,判断输出的通道数和输出的是否一样。如果不进行想加,那么就是进行了下采样操作。

        layers = []
        if expand_ratio != 1:
            layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1))
        layers.extend([
            ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim),
            nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
            nn.BatchNorm2d(oup),
        ])
        self.conv = nn.Sequential(*layers)

    def forward(self, x):
        if self.use_res_connect:
            return x + self.conv(x)#这是相加,并不是通道数拼接,要看懂
        else:
            return self.conv(x)

 下面就是mobilenetv2的整体结构图。这个结构图的解读是这样的:

Input 代表输入的特征图大小 从第二个开始也代表是上一个卷积块的输出结果(这个相信大家能看懂)

Operator 代表的是执行代码块,除了第一个和后三个,都是组成mobilenetv2最终要的卷积块,也就是上面代码所示的那样。

t 代表的是扩展因子,也就是在每个block中,升维的通道数是输入通道数的t倍。

n 代表的是block需要执行多少次

s代表的是步长   但是这里需要注意的是,这里的步长只要是大于1的都是对于第一个block来说的,举个例子,在n=2时,s=2,那么只有第一个block的stride是2,另一个block的s还是1.

mobilenetv3网络结构图

 对于mobilenetv3来说,又有一个大的改进就是应用通道注意力机制。就是将输入的特征图在进行池化操作,变成1x1xc的大小,然后再进行展平----->全连接------->全连接------->sigmoid()------->得到的是1x1xc的大小,然后再与输入的特征图在通道上进行相乘,从而达到通道注意力机制的作用。具体看下面的代码。

 mobilenetv3的block

class InvertedResidual(nn.Module):
    def __init__(self, inp, hidden_dim, oup, kernel_size, stride, use_se, use_hs):
        super(InvertedResidual, self).__init__()
        assert stride in [1, 2]

        self.identity = stride == 1 and inp == oup

        if inp == hidden_dim:
            self.conv = nn.Sequential(
                # dw
                nn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups=hidden_dim, bias=False),
                nn.BatchNorm2d(hidden_dim),
                h_swish() if use_hs else nn.ReLU(inplace=True),
                # Squeeze-and-Excite
                SELayer(hidden_dim) if use_se else nn.Identity(),
                # pw-linear
                nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
                nn.BatchNorm2d(oup),
            )
        else:
            self.conv = nn.Sequential(
                # pw
                nn.Conv2d(inp, hidden_dim, 1, 1, 0, bias=False),
                nn.BatchNorm2d(hidden_dim),
                h_swish() if use_hs else nn.ReLU(inplace=True),
                # dw
                nn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, (kernel_size - 1) // 2, groups=hidden_dim, bias=False),
                nn.BatchNorm2d(hidden_dim),
                # Squeeze-and-Excite
                SELayer(hidden_dim) if use_se else nn.Identity(),
                h_swish() if use_hs else nn.ReLU(inplace=True),
                # pw-linear
                nn.Conv2d(hidden_dim, oup, 1, 1, 0, bias=False),
                nn.BatchNorm2d(oup),
            )

    def forward(self, x):
        if self.identity:
            return x + self.conv(x)
        else:
            return self.conv(x)

通道注意力机制代码如下图所示:

# class SqueezeExcitation(nn.Module):#注意力机制
#     def __init__(self, input_c: int, squeeze_factor: int = 4):
#         super(SqueezeExcitation, self).__init__()
#         squeeze_c = _make_divisible(input_c // squeeze_factor, 8)#这个作用是为了将输入的通道数变成离8最近的8的倍数。这是一个自己弄的函数。
#         self.fc1 = nn.Conv2d(input_c, squeeze_c, 1)
#         self.fc2 = nn.Conv2d(squeeze_c, input_c, 1)
#
#     def forward(self, x):
#         scale = F.adaptive_avg_pool2d(x, output_size=(1, 1))
#         scale = self.fc1(scale)
#         scale = F.relu(scale, inplace=True)
#         scale = self.fc2(scale)
#         scale = F.hardsigmoid(scale, inplace=True)
#         return scale * x

 下面是mobilenetv3的模型架构图,和v2的差不多,就是多了SE(是否使用注意力机制模块)和NL(三种激活函数的使用),exp_size也是扩展因子,但是这是扩展后的结果,并不是倍数。

 最后说明一下,本博客的代码来自:

原文链接:睿智的目标检测49——Pytorch 利用mobilenet系列(v1,v2,v3)搭建yolov4目标检测平台_Bubbliiiing的学习小课堂-CSDN博客

### MobileNetV2 图像分类完整流程 #### 准备工作环境 为了使用MobileNetV2进行图像分类,首先需要准备合适的工作环境。创建专门的项目目录来组织所有的文件和依赖项[^4]。 ```bash mkdir mobilenet_v2 && cd mobilenet_v2 ``` 接着复制必要的模型文件到指定位置: ```bash cp ${MOBILE_DIR}/mobilenet_v2_deploy.prototxt . cp ${MOBILE_DIR}/mobilenet_v2.caffemodel . ``` 同时也要准备好测试所需的图片集合以及存储中间结果的空间: ```bash cp -rf ${TPUMLIR_DIR}/regression/dataset/ILSVRC2012/. . cp -rf ${TPUMLIR_DIR}/regression/image/. . mkdir workspace && cd workspace ``` #### 数据预处理 对于输入的数据集,通常会经过一系列标准化操作以适应神经网络的要求。这些步骤可能包括但不限于调整大小、裁剪、颜色空间转换等。具体实现取决于所选用框架的支持库函数[^1]。 #### 构建模型架构 MobileNetV2采用了特殊的层设计——瓶颈模块(bottleneck block)。这种结构能够有效减少计算成本的同时保持较高的表达能力。整个网络由多个这样的单元堆叠而成,并辅以外围的标准卷积层完成最终特征提取任务。 #### 训练过程概述 一旦完成了上述准备工作,则可以着手于实际训练环节。这涉及设置优化器参数、损失函数形式等方面的选择。值得注意的是,在某些情况下还可以引入迁移学习策略加速收敛速度或提高泛化性能[^3]。 #### 测试与评估 当训练完成后,应当利用独立验证集对得到的结果进行全面检验。此时不仅关注准确率指标,还需考察其他方面如召回率、F1分数等综合考量模型质量[^2]。 #### 部署应用 最后一步便是将训练好的权重导出成适合目标硬件运行的形式。例如通过量化技术降低内存占用从而更好地适配移动设备端部署需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值