轻量级网络——MobileNetV1

简介: 轻量级网络——MobileNetV1

1.MobileNetV1的介绍


传统卷积神经网络, 内存需求大、 运算量大导致无法在移动设备以及嵌入式设备上运行.VGG16的权重大小有450M,而ResNet中152层的模型,其权重模型644M,这么大的内存需求是明显无法在嵌入式设备上进行运行的。而网络应该服务于生活,所以轻量级网络的很重要的。

image.png

MobileNet网络是由google团队在2017年提出的,专注于移动端或者嵌入式设备中的轻量级CNN网络。相比传统卷积神经网络,在准确率小幅降低的前提下大大减少模型参数与运算量。(相比VGG16准确率减少了0.9%,但模型参数只有VGG的1/32)


MobileNet_v1的亮点:


  • Depthwise Convolution( 大大减少运算量和参数数量)
  • 增加超参数 增加超参数α 、β

(其中α是控制卷积层卷积核个数的超参数,β是控制输入图像的大小)


2.MobileNetV1的结构


传统的卷积

image.png


  • 卷积核channel=输入特征矩阵channel
  • 输出特征矩阵channel=卷积核个数

1)DW卷积(Depthwise Conv)

image.png


  • 卷积核channel=1
  • 输入特征矩阵channel=卷积核个数=输出特征矩阵channel

也就是DW卷积中的每一个卷积核,只会和输入特征矩阵的一个channel进行卷积计算,所以输出的特征矩阵就等于输入的特征矩阵。


2)PW卷积(Pointwise Conv)

image.png

其实PW卷积和普通的卷积类似,只是采用了1x1的卷积核,输出的特征矩阵channel的个数与使用的卷积核数相等,而输入特征矩阵的channel的个数与卷积核的channel数相等。所以其就是一个普通的卷积。


一般来说,以上的PW卷积与DW卷积是放在一起操作的,共同组成深度可分卷积操作。


3)深度可分卷积操作(Depthwise Separable Conv)

深度可分卷积操作是有两步分组成,一部分是DW卷积(Depthwise Conv),另外一部分是PW卷积(Pointwise Conv)

image.png


两者的计算量对比:


  • DSC:Dk * Dk * M * Df * Df + M * N * Df * Df
  • 普通:Dk * Dk * M * N * Df * Df

理论上普通卷积计算量是 DW+PW 的8到9倍


3.MobileNetV1的性能统计


  • Multiply-Add计算量

image.png

  • α-Width Multiplier(卷积核个数的倍率)

image.png

  • β-Resolution Multiplier(图像尺寸的大小)

image.png

4.MobileNetV1的pytorch实现


MobileNetV1模型结构

20210516102545536.png

参考代码


import torch
import torch.nn as nn
# 定义DSC结构:DW+PW操作
def BottleneckV1(in_channels, out_channels, stride):
    # 深度可分卷积操作模块: DSC卷积 = DW卷积 + PW卷积
    return  nn.Sequential(
        # dw卷积,也是RexNeXt中的组卷积,当分组个数等于输入通道数时,输出矩阵的通道输也变成了输入通道数时,组卷积就是dw卷积
        nn.Conv2d(in_channels=in_channels,out_channels=in_channels,kernel_size=3,stride=stride,padding=1,groups=in_channels),
        nn.BatchNorm2d(in_channels),
        nn.ReLU6(inplace=True),
        # pw卷积,与普通的卷积一样,只是使用了1x1的卷积核
        nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=1),
        nn.BatchNorm2d(out_channels),
        nn.ReLU6(inplace=True)
    )
# 定义MobileNetV1结构
class MobileNetV1(nn.Module):
    def __init__(self, num_classes=5):
        super(MobileNetV1, self).__init__()
        # torch.Size([1, 3, 224, 224])
        self.first_conv = nn.Sequential(
            nn.Conv2d(in_channels=3,out_channels=32,kernel_size=3,stride=2,padding=1),
            nn.BatchNorm2d(32),
            nn.ReLU6(inplace=True),
        )
        # torch.Size([1, 32, 112, 112])
        # 叠加的基本结构是: DW+PW(DW用来减小尺寸stride=2实现,PW用来增加通道out_channels增加实现)
        self.bottleneck = nn.Sequential(
            BottleneckV1(32, 64, stride=1),     # torch.Size([1, 64, 112, 112]), stride=1
            BottleneckV1(64, 128, stride=2),    # torch.Size([1, 128, 56, 56]), stride=2
            BottleneckV1(128, 128, stride=1),   # torch.Size([1, 128, 56, 56]), stride=1
            BottleneckV1(128, 256, stride=2),   # torch.Size([1, 256, 28, 28]), stride=2
            BottleneckV1(256, 256, stride=1),   # torch.Size([1, 256, 28, 28]), stride=1
            BottleneckV1(256, 512, stride=2),   # torch.Size([1, 512, 14, 14]), stride=2
            BottleneckV1(512, 512, stride=1),   # torch.Size([1, 512, 14, 14]), stride=1
            BottleneckV1(512, 512, stride=1),   # torch.Size([1, 512, 14, 14]), stride=1
            BottleneckV1(512, 512, stride=1),   # torch.Size([1, 512, 14, 14]), stride=1
            BottleneckV1(512, 512, stride=1),   # torch.Size([1, 512, 14, 14]), stride=1
            BottleneckV1(512, 512, stride=1),   # torch.Size([1, 512, 14, 14]), stride=1
            BottleneckV1(512, 1024, stride=2),  # torch.Size([1, 1024, 7, 7]), stride=2
            BottleneckV1(1024, 1024, stride=1), # torch.Size([1, 1024, 7, 7]), stride=1
        )
        # torch.Size([1, 1024, 7, 7])
        self.avg_pool = nn.AvgPool2d(kernel_size=7,stride=1)  # torch.Size([1, 1024, 1, 1])
        self.linear = nn.Linear(in_features=1024,out_features=num_classes)
        self.dropout = nn.Dropout(p=0.2)
        self.softmax = nn.Softmax(dim=1)
        self.init_params()
    # 初始化操作
    def init_params(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
                nn.init.constant_(m.bias,0)
            elif isinstance(m, nn.Linear) or isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)
    def forward(self, x):
        x = self.first_conv(x)      # torch.Size([1, 32, 112, 112])
        x = self.bottleneck(x)      # torch.Size([1, 1024, 7, 7])
        x = self.avg_pool(x)        # torch.Size([1, 1024, 1, 1])
        x = x.view(x.size(0),-1)    # torch.Size([1, 1024])
        x = self.dropout(x)
        x = self.linear(x)          # torch.Size([1, 5])
        out = self.softmax(x)       # 概率化
        return x
if __name__=='__main__':
    model = MobileNetV1()
    # print(model)
    input = torch.randn(1, 3, 224, 224)
    out = model(input)
    print(out.shape)


后续:MobileNetV1出现的问题

对于DW卷积,训练完之后,会出现部分卷积核会费掉的问题,既卷积核参数大部分为零,也就是表示其实DW卷积没有起到多大的作用。对于这个问题,MobileNetV2有一定的改善。


参考:

https://www.bilibili.com/video/BV1yE411p7L7


目录
相关文章
|
18天前
|
机器学习/深度学习 计算机视觉 Python
【YOLOv11改进 - 注意力机制】SimAM:轻量级注意力机制,解锁卷积神经网络新潜力
【YOLOv11改进 - 注意力机制】SimAM:轻量级注意力机制,解锁卷积神经网络新潜力本文提出了一种简单且高效的卷积神经网络(ConvNets)注意力模块——SimAM。与现有模块不同,SimAM通过优化能量函数推断特征图的3D注意力权重,无需添加额外参数。SimAM基于空间抑制理论设计,通过简单的解决方案实现高效计算,提升卷积神经网络的表征能力。代码已在Pytorch-SimAM开源。
【YOLOv11改进 - 注意力机制】SimAM:轻量级注意力机制,解锁卷积神经网络新潜力
|
1月前
|
机器学习/深度学习 Web App开发 人工智能
轻量级网络论文精度笔(一):《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》
《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》这篇论文提出了一种基于YOLOv3-Tiny的轻量级目标检测模型Micro-YOLO,通过渐进式通道剪枝和轻量级卷积层,显著减少了参数数量和计算成本,同时保持了较高的检测性能。
33 2
轻量级网络论文精度笔(一):《Micro-YOLO: Exploring Efficient Methods to Compress CNN based Object Detection Model》
|
1月前
|
机器学习/深度学习 编解码 算法
轻量级网络论文精度笔记(三):《Searching for MobileNetV3》
MobileNetV3是谷歌为移动设备优化的神经网络模型,通过神经架构搜索和新设计计算块提升效率和精度。它引入了h-swish激活函数和高效的分割解码器LR-ASPP,实现了移动端分类、检测和分割的最新SOTA成果。大模型在ImageNet分类上比MobileNetV2更准确,延迟降低20%;小模型准确度提升,延迟相当。
58 1
轻量级网络论文精度笔记(三):《Searching for MobileNetV3》
|
1月前
|
编解码 人工智能 文件存储
轻量级网络论文精度笔记(二):《YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object ..》
YOLOv7是一种新的实时目标检测器,通过引入可训练的免费技术包和优化的网络架构,显著提高了检测精度,同时减少了参数和计算量。该研究还提出了新的模型重参数化和标签分配策略,有效提升了模型性能。实验结果显示,YOLOv7在速度和准确性上超越了其他目标检测器。
47 0
轻量级网络论文精度笔记(二):《YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object ..》
|
6月前
|
机器学习/深度学习 计算机视觉 知识图谱
【YOLOv8改进】MobileViT 更换主干网络: 轻量级、通用且适合移动设备的视觉变压器 (论文笔记+引入代码)
MobileViT是针对移动设备的轻量级视觉Transformer网络,结合CNN的局部特征、Transformer的全局注意力和ViT的表示学习。在ImageNet-1k上,它以600万参数实现78.4%的top-1准确率,超越MobileNetv3和DeiT。MobileViT不仅适用于图像分类,还在目标检测等任务中表现出色,且优化简单,代码已开源。YOLOv8引入了MobileViT块,整合卷积和Transformer结构,提升模型性能。更多详情可参考相关专栏和链接。
|
3月前
|
数据采集 资源调度 JavaScript
Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
【8月更文挑战第4天】Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
58 5
|
4月前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLOv8改进- Backbone主干】YOLOv8 更换主干网络之 PP-LCNet,轻量级CPU卷积神经网络,降低参数量
YOLO目标检测专栏介绍了PP-LCNet,一种基于MKLDNN加速的轻量级CPU网络,提升了模型在多任务中的性能。PP-LCNet利用H-Swish、大核卷积、SE模块和全局平均池化后的全连接层,实现低延迟下的高准确性。代码和预训练模型可在PaddlePaddle的PaddleClas找到。文章提供了网络结构、核心代码及性能提升的详细信息。更多实战案例和YOLO改进见相关链接。
|
5月前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLOv8改进-卷积Conv】DualConv( Dual Convolutional):用于轻量级深度神经网络的双卷积核
**摘要:** 我们提出DualConv,一种融合$3\times3$和$1\times1$卷积的轻量级DNN技术,适用于资源有限的系统。它通过组卷积结合两种卷积核,减少计算和参数量,同时增强准确性。在MobileNetV2上,参数减少54%,CIFAR-100精度仅降0.68%。在YOLOv3中,DualConv提升检测速度并增4.4%的PASCAL VOC准确性。论文及代码已开源。
|
5月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【YOLOv8改进 - 注意力机制】SimAM:轻量级注意力机制,解锁卷积神经网络新潜力
YOLO目标检测专栏介绍了SimAM,一种无参数的CNN注意力模块,基于神经科学理论优化能量函数,提升模型表现。SimAM通过计算3D注意力权重增强特征表示,无需额外参数。文章提供论文链接、Pytorch实现代码及详细配置,展示了如何在目标检测任务中应用该模块。
|
6月前
|
机器学习/深度学习 算法 计算机视觉
【CVPR轻量级网络】- 追求更高的FLOPS(FasterNet)
【CVPR轻量级网络】- 追求更高的FLOPS(FasterNet)
282 2