MobileNetV1架构解析

本文涉及的产品
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: MobileNets基于一种流线型架构,使用深度可分离卷积构建轻量级深度神经网络。我们引入了两个简单的全局超参数,可以有效地在延迟和准确性之间进行权衡。这些超参数允许模型生成器根据问题的约束为其应用程序选择适当大小的模型。我们在资源和准确性权衡方面进行了大量实验,与其他流行的ImageNet分类模型相比,我们表现出了强大的性能。然后,我们展示了MobileNet在广泛的应用和用例中的有效性,包括目标检测、精细分类、人脸属性和大规模地理定位。

@toc

参考论文:MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications

1、简介

  MobileNets基于一种流线型架构,使用深度可分离卷积构建轻量级深度神经网络。我们引入了两个简单的全局超参数,可以有效地在延迟和准确性之间进行权衡。这些超参数允许模型生成器根据问题的约束为其应用程序选择适当大小的模型。我们在资源和准确性权衡方面进行了大量实验,与其他流行的ImageNet分类模型相比,我们表现出了强大的性能。然后,我们展示了MobileNet在广泛的应用和用例中的有效性,包括目标检测、精细分类、人脸属性和大规模地理定位。

  MobileNet模型可应用于各种识别任务,以实现高效的设备智能。

image-20220803200424571

2、Model Architecture

2.1 Depthwise Separable Convolution

  MobileNet模型基于深度可分离卷积,这是一种分解卷积的形式,将标准卷积分解为深度卷积和1*1的点卷积。对于MobileNet,深度卷积将单个滤波器应用于每个输入通道,然后,逐点卷积应用1*1卷积将输出与深度卷积相结合。

  标准卷积在一个步骤中将输入滤波并组合成一组新的输出。深度可分离卷积将标准的卷积层分解为两层来做:

  • 首先是各个通道单独做卷积运算,称之为Depthwise Convolution
  • 然后用一个1*1的标准卷积层进行各个通道间的合并,称之为Pointwise Convolution

  论文中原图如下所示:

image-20220803201346429

  论文中将标准卷积(a)分级为深度卷积(b)和1*1逐点卷积的图如下:

image-20220803201549326

2.2 Network Structure

  MobileNet结构建立在深度可分离卷积上,第一层是全卷积。MobileNet架构如下表所示,除过最后的全连接层,所有层后面都是BatchNorm和ReLU非线性激活函数,最后的全连接层没有非线性,并馈送到softmax层进行分类。将深度卷积和点卷积计算为单独的层,MobileNet有28层。

image-20220803202051799

3、传统卷积与深度可分离卷积图解

3.1 传统卷积

image-20220803202627239

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

3.2 Depthwise卷积

在这里插入图片描述

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

3.3 Pointwise卷积

在这里插入图片描述

  Pointwise卷积和普通的卷积一样,只不过使用了1*1卷积核。

3.3 Depthwise Separable Convolution(深度可分离卷积)

  深度可分离卷积由Depthwise卷积和Pointwise卷积两部分组成

在这里插入图片描述

4、Width Multiplier: Thinner Models

  虽然基本MobileNet架构已经很小且延迟很低,但很多时候,特定用例或应用程序可能需要更小更快的模型。为了构造这些较小且计算成本较低的模型,我们引入了一个非常简单的参数α,称为宽度乘数。宽度倍增器α的作用是在每一层均匀地薄化网络。对于给定的层和宽度乘数α,输入通道数M变为αM,输出通道数N变为αN

5、Resolution Multiplier:Reduced Representation

  降低神经网络计算成本的第二个超参数是分辨率乘数ρ。我们将其应用于输入图像,然后通过相同的乘法器减少每个层的内部表示。

  表3显示了当架构收缩方法顺序应用于层时,层的计算和参数数量。第一行显示了全卷积层的Mult加法和参数,输入特征图的大小为14×14×512,核K的大小为3×3×512×512。

image-20220803203729286

6、模型计算量与精度之间的权衡

  首先,我们展示了具有深度可分离卷积的MobileNet与使用全卷积构建的模型相比的结果。在表4中,我们看到,与全卷积相比,使用深度可分离卷积在ImageNet上仅降低了1%的准确度,并在多个加法和参数上节省了大量成本。

image-20220803203851307

  表5显示,在类似的计算和参数数量下,使MobileNets变薄比使其变浅要好3%。

image-20220803204030629

  表6显示了使用宽度乘数α缩小MobileNet架构的精度、计算和尺寸权衡。精度平稳下降,直到在α=0.25时架构变得太小。

image-20220803204120758

  表7显示了通过使用降低的输入分辨率训练MobileNet,不同分辨率乘法器的精度、计算和大小权衡。精度在整个分辨率范围内平稳下降。

image-20220803204151086

7、模型搭建(Tensorflow2.0)

这里是手动搭建的,你也可以直接使用迁移学习相关的API。
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.layers import DepthwiseConv2D,BatchNormalization,ReLU,Conv2D
from tensorflow.keras.layers import GlobalAvgPool2D,Dense
# 定义可分离卷积块结构
def depthwise_conv_block(inputs,pointwise_conv_filters,strides=(1,1)):
    x=DepthwiseConv2D((3,3),padding='same',strides=strides,use_bias=False)(inputs)
    x=BatchNormalization()(x)
    x=ReLU(6.0)(x)
    
    x=Conv2D(pointwise_conv_filters,kernel_size=(1,1),padding='same',use_bias=False)(x)
    x=BatchNormalization()(x)
    x=ReLU(6.0)(x)
    return x
# 定义MobileNet第一层普通卷积结构
def conv_block(inputs,filters,kernel_size=(3,3),strides=(1,1)):
    x=Conv2D(filters,kernel_size=kernel_size,strides=strides,padding='same',
             use_bias=False)(inputs)
    x=BatchNormalization()(x)
    x=ReLU(6.0)(x)
    return x
def mobilenet_v1(inputs,classes):
    # 第一层普通卷积
    #[32,32,3]=>[16,16,32]
    x=conv_block(inputs,32,strides=(2,2))
    # [16,16,32]=>[16,16,64]
    x=depthwise_conv_block(x,64)
    # [16,16,64]=>[8,8,128]
    x=depthwise_conv_block(x,128,strides=(2,2))
    # [8,8,128]=>[8,8,128]
    x=depthwise_conv_block(x,128)
    # [8,8,128]=>[4,4,256]
    x=depthwise_conv_block(x,256,strides=(2,2))
    # [4,4,256]=>[4,4,256]
    x=depthwise_conv_block(x,256)
    # [4,4,256]=>[2,2,512]
    x=depthwise_conv_block(x,512,strides=(2,2))
    # [2,2,512]=>[2,2,512]
    x=depthwise_conv_block(x,512)
    # [2,2,512]=>[2,2,512]
    x=depthwise_conv_block(x,512)
    # [2,2,512]=>[2,2,512]
    x=depthwise_conv_block(x,512)
    # [2,2,512]=>[2,2,512]
    x=depthwise_conv_block(x,512)
    # [2,2,512]=>[2,2,512]
    x=depthwise_conv_block(x,512)
    # [2,2,512]=>[1,1,1024]
    x=depthwise_conv_block(x,1024,strides=(2,2))
    # [1,1,1024]=>[1,1,1024]
    x=depthwise_conv_block(x,1024)
    # [1,1,1024]=>[1024,]
    x=GlobalAvgPool2D()(x)
    # [1024,]=>[classes,]
    x=Dense(classes,activation='softmax')(x)
    return x
这里顺便在CIFAR10数据集上面测试一下。
INPUT_WIDTH=32
INPUT_HEIGHT=32
N_CHANNELS=3
N_CLASSES=10
batch_size=128
epochs=10
inputs=tf.keras.Input(shape=(INPUT_WIDTH,INPUT_HEIGHT,N_CHANNELS))
outputs=mobilenet_v1(inputs,N_CLASSES)
model=tf.keras.Model(inputs=inputs,outputs=outputs)
model.summary()

image-20220803204420275

# 数据准备
(x_train,y_train),(x_test,y_test)=tf.keras.datasets.cifar10.load_data()
# 归一化
x_train,x_test=x_train/255.0,x_test/255.0
# 转为独热编码
y_train=tf.keras.utils.to_categorical(y_train,N_CLASSES)
y_test=tf.keras.utils.to_categorical(y_test,N_CLASSES)
# 模型编译
adam=tf.keras.optimizers.Adam(1e-4)
model.compile(optimizers=adam,loss='categorical_crossentropy',
              metrics=['accuracy'])
# 模型训练
history = model.fit(
    x_train,
    y_train,
    batch_size=batch_size,
    epochs=epochs,
    validation_data=(x_test, y_test),
    validation_freq=1
)

image-20220803204521905

accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
fig,ax = plt.subplots(1,2,figsize=(12,6)) # figsize=(width, height)
ax[0].plot(epochs, accuracy, "bo", label="Training accuracy")
ax[0].plot(epochs, val_accuracy, "b", label="Validation accuracy")
ax[0].set_title("Training and validation accuracy")
ax[0].legend()
ax[1].plot(epochs, loss, "bo", label="Training loss")
ax[1].plot(epochs, val_loss, "b", label="Validation loss")
ax[1].set_title("Training and validation loss")
ax[1].legend()

image-20220803204548647

References

Howard A G , Zhu M , Chen B , et al. MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications[J]. 2017.

MobileNets(V1)简介及两个初步的代码实验

轻量级网络——MobileNetV1

MobileNet V1 网络结构的原理与 Tensorflow2.0 实现

MobileNets(V1)的Tensorflow实现

目录
相关文章
|
3天前
|
存储 SQL BI
深入解析实时数仓Doris:介绍、架构剖析、应用场景与数据划分细节
深入解析实时数仓Doris:介绍、架构剖析、应用场景与数据划分细节
|
9天前
|
前端开发 JavaScript 测试技术
安卓应用开发中的架构模式解析
【6月更文挑战第21天】在软件开发领域,架构模式是设计优雅、高效、可维护应用程序的基石。本文深入探讨了安卓应用开发中常见的架构模式,包括MVC、MVP、MVVM和Clean Architecture,旨在为开发者提供一个清晰的指导,帮助他们选择最适合自己项目的架构风格。通过对比分析这些架构模式的特点、优势以及适用场景,文章揭示了如何根据项目需求和团队能力来采用恰当的架构模式,以实现代码的可维护性、可扩展性和可测试性。
25 7
|
4天前
|
存储 缓存 监控
深入解析Elasticsearch的内存架构与管理
深入解析Elasticsearch的内存架构与管理
深入解析Elasticsearch的内存架构与管理
|
11天前
|
弹性计算 负载均衡 API
微服务架构下的API网关模式解析
在现代软件工程中,微服务架构因其灵活性和可维护性而受到青睐。本文将探讨API网关模式在微服务架构中的关键角色,分析其设计原则、实现方式及面临的挑战,并结合实际案例阐述如何有效整合API网关以提升系统整体性能和安全性。
|
9天前
|
存储 弹性计算 安全
构建高效企业应用架构:阿里云产品组合实践深度解析
该方案展现了阿里云产品组合的强大能力和灵活性,不仅满足了当前业务需求,也为未来的扩展打下了坚实的基础。希望本文的分享能为读者在设计自己的IT解决方案时提供一定的参考和启发。
108 1
|
1天前
|
存储 前端开发 JavaScript
构建高性能返利App的技术架构解析
构建高性能返利App的技术架构解析
|
2天前
|
网络协议 安全 分布式数据库
技术分享:分布式数据库DNS服务器的架构思路
技术分享:分布式数据库DNS服务器的架构思路
7 0
|
10天前
|
机器学习/深度学习 缓存 算法
netty源码解解析(4.0)-25 ByteBuf内存池:PoolArena-PoolChunk
netty源码解解析(4.0)-25 ByteBuf内存池:PoolArena-PoolChunk
|
12天前
|
XML Java 数据格式
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
23 3
|
4天前
|
Java 数据库连接 Spring
Spring 整合 MyBatis 底层源码解析
Spring 整合 MyBatis 底层源码解析

推荐镜像

更多