『高性能模型』轻量级网络MobileNet_v2
论文地址:MobileNetV2: Inverted Residuals and Linear Bottlenecks
前文链接:『高性能模型』深度可分离卷积和MobileNet_v1
一、MobileNet v1 的不足
Relu 和数据坍缩
Moblienet V2文中提出,假设在2维空间有一组由 个点组成的螺旋线
数据,经随机矩阵
映射到
维并进行ReLU运算,即:
再通过 矩阵的广义逆矩阵
将
映射回2维空间:
对比 和
发现,当映射维度
时,数据坍塌;当
时,数据基本被保存。虽然这不是严格的数学证明,但是至少说明:channel少的feature map不应后接ReLU,否则会破坏feature map。

简单说一下上图:对于一个输入图像,首先通过一个随机矩阵T将数据转换为n维,然后对这n维数据进行ReLU操作,最后再使用T的逆矩阵转换回来,实验发现当n很小的时候,后面接ReLU非线性变换的话会导致很多信息的丢失,而且维度越高还原的图片和原图越相似。
ResNet 、Relu 和神经元死亡
在神经网络训练中如果节点的值变为0就会“死掉”。因为ReLU对0值的梯度是0,后续无论怎么迭代这个节点的值都不会恢复了。而通过ResNet结构的特征复用,可以很大程度上缓解这种特征退化问题(这也从一个侧面说明ResNet为何好于VGG)。另外,一般情况训练网络使用的是float32浮点数;当使用低精度的float16时,这种特征复用可以更加有效的减缓退化。
二、Inverted residual block
理解之前的问题后看,其实Mobilenet V2使用的基本卷积单元结构有以下特点:
- 整体上继续使用Mobilenet V1的Separable convolution降低卷积运算量
- 引入了特征复用结构,即采取了ResNet的思想
- 采用Inverted residual block结构,对Relu的缺陷进行回避
Inverted residuals 可以认为是residual block的拓展,其重点聚焦在残差网络各层的层数,进入block后会先将特征维数放大,然后再压缩回去,呈现梭子的外形,而传统残差设计是沙漏形,下面是MobileNetV1、MobileNetV2 和ResNet微结构对比:

下面则对比了近年来比较先进的压缩网络子模块:


可以看到MobileNetV2 和ResNet基本结构很相似。不过ResNet是先降维(0.25倍)、提特征、再升维。而MobileNetV2 则是先升维(6倍)、提特征、再降维。、
注:模型中使用 ReLU6 作为非线性层,在低精度计算时能压缩动态范围,算法更稳健。
ReLU6 定义为:f(x) = min(max(x, 0), 6),详见 tf.nn.relu6 API
至于Linear Bottlenecks,论文中用很多公式表达这个思想,但是实现上非常简单,就是在MobileNetV2微结构中第二个PW后无ReLU6,对于低维空间而言,进行线性映射会保存特征,而非线性映射会破坏特征,实际代码如下:
def _bottleneck(inputs, nb_filters, t):
x = Conv2D(filters=nb_filters * t, kernel_size=(1,1), padding='same')(inputs)
x = Activation(relu6)(x)
x = DepthwiseConv2D(kernel_size=(3,3), padding='same')(x)
x = Activation(relu6)(x)
x = Conv2D(filters=nb_filters, kernel_size=(1,1), padding='same')(x)
# do not use activation function
if not K.get_variable_shape(inputs)[3] == nb_filters:
inputs = Conv2D(filters=nb_filters, kernel_size=(1,1), padding='same')(inputs)
outputs = add([x, inputs])
return outputs
相对应的,主结构堆叠上面的block 即可,下面是一个简单的版本,
def MobileNetV2_relu(input_shape, k):
inputs = Input(shape = input_shape)
x = Conv2D(filters=32, kernel_size=(3,3), padding='same')(inputs)
x = _bottleneck_relu(x, 8, 6)
x = MaxPooling2D((2,2))(x)
x = _bottleneck_relu(x, 16, 6)
x = _bottleneck_relu(x, 16, 6)
x = MaxPooling2D((2,2))(x)
x = _bottleneck_relu(x, 32, 6)
x = GlobalAveragePooling2D()(x)
x = Dense(128, activation='relu')(x)
outputs = Dense(k, activation='softmax')(x)
model = Model(inputs, outputs)
return model
原文网络结构如下:

『高性能模型』轻量级网络MobileNet_v2的更多相关文章
- 『高性能模型』轻量级网络ShuffleNet_v1及v2
项目实现:GitHub 参考博客:CNN模型之ShuffleNet v1论文:ShuffleNet: An Extremely Efficient Convolutional Neural Netwo ...
- 『高性能模型』HetConv: HeterogeneousKernel-BasedConvolutionsforDeepCNNs
论文地址:HetConv 一.现有网络加速技术 1.卷积加速技术 作者对已有的新型卷积划分如下:标准卷积.Depthwise 卷积.Pointwise 卷积.群卷积(相关介绍见『高性能模型』深度可分离 ...
- 『高性能模型』卷积复杂度以及Inception系列
转载自知乎:卷积神经网络的复杂度分析 之前的Inception学习博客: 『TensorFlow』读书笔记_Inception_V3_上 『TensorFlow』读书笔记_Inception_V3_下 ...
- 『高性能模型』Roofline Model与深度学习模型的性能分析
转载自知乎:Roofline Model与深度学习模型的性能分析 在真实世界中,任何模型(例如 VGG / MobileNet 等)都必须依赖于具体的计算平台(例如CPU / GPU / ASIC 等 ...
- 『高性能模型』深度可分离卷积和MobileNet_v1
论文原址:MobileNets v1 TensorFlow实现:mobilenet_v1.py TensorFlow预训练模型:mobilenet_v1.md 一.深度可分离卷积 标准的卷积过程可以看 ...
- 『深度应用』NLP机器翻译深度学习实战课程·壹(RNN base)
深度学习用的有一年多了,最近开始NLP自然处理方面的研发.刚好趁着这个机会写一系列NLP机器翻译深度学习实战课程. 本系列课程将从原理讲解与数据处理深入到如何动手实践与应用部署,将包括以下内容:(更新 ...
- ShuffleNetV1/V2简述 | 轻量级网络
ShuffleNet系列是轻量级网络中很重要的一个系列,ShuffleNetV1提出了channel shuffle操作,使得网络可以尽情地使用分组卷积来加速,而ShuffleNetV2则推倒V1的大 ...
- 『Python进阶』专题汇总
基础知识 Python3内置函数 『Python』库安装 『流畅的Python』第1~4章_数据结构.编码 『Python』基础数据结构常见使用方法 『Python CoolBook』数据结构和算法_ ...
- 2017-2018-2 165X 『Java程序设计』课程 助教总结
2017-2018-2 165X 『Java程序设计』课程 助教总结 本学期完成的助教工作主要包括: 编写300道左右测试题,用于蓝墨云课下测试: 发布博客三篇:<2017-2018-2 165 ...
随机推荐
- CentOS 搭建git服务
git服务器的搭建是非常简单的. 1. 安装git yum install git 2. 创建用户git groupadd git adduser git -g git passwd git 3. 创 ...
- Python多维数组切片
1. array如果维度多了,就变成ndarray. 2. list切片类似C数组,多维度分别用”[]“索引,单维度切片用”:“,如: >>> a [[1, 2, 3], [4, 5 ...
- python练习--利用while循环和if语句,完成猜骰子的数字大小
#exampleimport random# 骰子投掷的随机叔numnum = random.randint(1,6)# 输入一个猜测的数字temp = input("请输入一个整数:&qu ...
- The type com.google.protobuf.GeneratedMessageV3$Builder cannot be resolved. It is indirectly referenced from required .classfiles
在做项目的时候,导入了几个类,导入了相关的jar. 结果在package处报了The type com.google.protobuf.GeneratedMessageV3$Builder canno ...
- 【转】LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
用VS2010编译C++项目时出现这样的错误: LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 方案一:(这个方法比较好,在用qt运行时出现问题也能解决) 复制 C:\Windows\ ...
- Django数据查询方法总结
__exact 精确等于 like ‘aaa’__iexact 精确等于 忽略大小写 ilike ‘aaa’__contains 包含 like ‘%aaa%’__icontains 包含 忽略大 ...
- Servlet+jSP+java实现商品信息和流水的操作
设计思路:先是创建两个表,一个用来操作库内商品的增删改查,一个用来记录商品的流水信息. 设计过程:先对商品的属性进行创建javaBean编写,之后编写数据库连接类,之后编写数据库操作类,之后编写服务类 ...
- Redis学习-持久化机制
Redis持久化的意义 在于故障恢复 比如你部署了一个redis,作为cache缓存,当然也可以保存一些较为重要的数据 如果没有持久化的话,redis遇到灾难性故障的时候(断电.宕机),就会丢失所有的 ...
- 利用mybatis-generator自动生成代码,发生:Plugin execution not covered by lifecycle configuration后解决方案
1,报错信息 Plugin execution not covered by lifecycle configuration: org.mybatis.generator:mybatis-genera ...
- Haproxy官方文档翻译(第三章)全局参数(1) 附英文原文
3.全局参数 在global这个节点里的参数是“进程范围的”并且经常是“操作系统指定”的.它们通常是一次性设置而且一旦正确设置不需要动来动去的.它们中的一些和命令行对应. global节点支持以下关键 ...