MobileNet

MobileNet

参考
题外话
  • 本文是在复现MobileNet的时候顺便看了一下原文,因此会用简短的语言简单解释下网络思想,对于某些概念不懂的可以看参考中的文章(主要是深度可分离这个结构)
主体思想
  • 文章中作者的贡献是减少了计算复杂度——用了以下两种方式
    • Depthwise Separable Convolution
    • 使用超参 α \alpha α统一减少channel,从而进一步实现减少计算量的效果
Depthwise Separable Convolution
  • 作者认为:卷积是基于卷积核的特征过滤和特征组合以产生新的表示,因此可以将这两个过程分开(有点类似于因式分解的思想),从而达到减少计算量的效果。
  • 因此作者提出两种卷积:Depthwise Convolutional & Pointwise Convolution
    • image-20211117002727753
    • depthwise convolutions
      • 可以理解为每一个kernel只有一层,只计算一个channel的特征,然后有channel个kernel
    • pointwise convolutions
      • 可以理解为每个kernel都是一条1x1的卷积,总共hxw个kernel
    • 下面这个图比较形象
      • image-20211117003106880
torch实现(模块)
  • depthwise conv的实现就是groups这个参数,将groups设置为channel的个数就能实现

  • pointwise conv就更简单了,kernel_size=1即可

  • 注意代码中的ConvBNReLU只是简单的Conv+BN+ReLU的Sequential而已

  • 还有一点就是这份代码中加了残差边

  • class InvertedResidual(nn.Module):
        def __init__(self, in_channel, out_channel, stride, expand_ratio):
            super(InvertedResidual, self).__init__()
            hidden_channel = in_channel * expand_ratio
            self.use_shortcut = stride == 1 and in_channel == out_channel
    
            layers = []
            if expand_ratio != 1:
                # 1x1 pointwise conv
                layers.append(ConvBNReLU(in_channel, hidden_channel,
                                         kernel_size=1))
            layers.extend([
                # 这里深度可分离的实现就是1、groups=hidden_channel实现depthwise 2、kernel_size=1实现pointwise
                # 3x3 depthwise conv
                ConvBNReLU(hidden_channel,
                           hidden_channel,
                           stride=stride,
                           groups=hidden_channel),
                # 1x1 pointwise conv(linear)
                nn.Conv2d(hidden_channel, out_channel, kernel_size=1, bias=False),
                nn.BatchNorm2d(out_channel),
            ])
    
            self.conv = nn.Sequential(*layers)
    
        def forward(self, x):
            if self.use_shortcut:
                return x + self.conv(x)
            else:
                return self.conv(x)
    
Width Multiplier
  • 超参 α \alpha α
  • 成比例的减少channel维度的大小,其实这个在设计的时候就可以做到,作者在3.3说了这个,我理解可能是为了统一方便吧
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MobileNet 是一种轻量级的深度学习模型,专为移动设备和嵌入式系统设计,以减少计算资源和内存占用,同时保持较高的性能。它是 Google 在 2017 年 ICLR 大会上提出的,由 Inception 模型发展而来,但采用了深度可分离卷积(Depthwise Separable Convolution)来大幅度减少参数数量。 在 Keras 中,你可以使用 `tf.keras.applications.MobileNet` 或 `keras.applications.mobilenet_v2.MobileNetV2` 来导入预训练的 MobileNet 模型。这个模型通常包括以下几个部分: 1. **输入层**:接受图像数据作为输入。 2. **卷积层**:包括深度可分离卷积层,它们分别对空间维度和通道维度进行操作,大大减少了参数数量。 3. **瓶颈层**:使用扩张路径(Expanded Path),包含一个深度可分离卷积后接一个1x1卷积来增加通道数。 4. **全局平均池化**(Global Average Pooling):代替全连接层,减少过拟合并使网络更易于部署。 5. **分类层**:如 `tf.keras.layers.Dense`,用于输出分类结果。 如果你想要在 Keras 中使用 MobileNet,可以直接加载预训练权重,然后可以选择冻结部分层进行微调,或者从头开始训练。以下是使用 Keras 导入 MobileNet 的基本步骤: ```python from tensorflow.keras.applications import MobileNet from tensorflow.keras.models import Model from tensorflow.keras.layers import Dense, GlobalAveragePooling2D # 加载预训练模型 base_model = MobileNet(weights='imagenet', include_top=False, input_shape=(img_height, img_width, 3)) # 添加全局平均池化和全连接层进行分类任务 x = base_model.output x = GlobalAveragePooling2D()(x) predictions = Dense(num_classes, activation='softmax')(x) # 创建新的模型 model = Model(inputs=base_model.input, outputs=predictions) # 选择是否训练或冻结预训练层 if fine_tuning: # 冻结所有层 for layer in base_model.layers: layer.trainable = False # 再定义几个顶部的层进行微调 num_frozen_layers = len(base_model.layers) - num_top_layers_to_freeze for layer in model.layers[:num_frozen_layers]: layer.trainable = False else: # 训练整个模型 model.trainable = True ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椰子奶糖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值