学习笔记——轻量型神经网络

前言

前段时间沉迷于centos7,好长时间没写博客了。liunx真的安装使用有点复杂,就当学习了。这段时间回到Windows,最近在准备开题题目,准备做算法优化,关注了一下轻量型神经网络。了解了一下MobileNet系列。我们直接来学习最近版本MobileNetV3。

配置

其他配置不用谈,首先我用的代码地址是https://github.com/Bisonai/mobilenetv3-tensorflow
关于代码其他不用多说唯独有一点,TensorFlow版本,官网要求版本TensorFlow 1.13+,也就是高于1.13就行其实不是只能是,13/14/15否则太低你安装不了TensorFlow—dataset,太高你会发现有一些函数找不到,因为·被·弃用了,或者写法不一样了。我用的1.14完美运行。

框架介绍

为啥要用MobileNetV3?VGG16他不香吗?大家在运行MobileNetV3的时候会发现他也挺大的,我跑了一天(我电脑次),你可能觉得她挺慢的,其实不是,一是你的循环次数多,二是她的网络比较深,比我们普通练习的卷积神经网络要深一点。其实相对来说他更加快而且更加准确。我最终测试集准确率97左右(而且我跑的还是small更快一点,但是准确率低一点很优秀的成绩)。MobileNetV3是轻量级网络,优点是又快又准,让我们先看一下两种MobileNetV3的结构;
在这里插入图片描述
这就是MobileNetV3两种结构。
其中要讲解一下就是这个结构:线性瓶颈,Bottleneck结构首次被提出是在ResNet网络中。该结构第一层使用逐点卷积,第二层使用3×3大小卷积核进行深度卷积,第三层再使用逐点卷积。MobileNet中的瓶颈结构最后一层逐点卷积使用的激活函数是Linear,所以称其为线性瓶颈结构(Linear Bottleneck)。线性瓶颈结构有两种,第一种是步长为1时使用残差结构,第二种是步长为2时不使用残差结构。
在这里插入图片描述
其中输入通道数为M,扩大倍数系数为T。T的值为大于0 的正数,当 0<T<1时,第一层逐点卷积起到的作用是降维。当 1<T时,第一层逐点卷积起到的作用是升维。
第二层为深度卷积,输入通道数 = 输出通道数 = M×T。
第三层为逐点卷积,作用是关联深度卷积后的特征图并输出指定通道数N。
线性瓶颈结构相对标准卷积能够减少参数数量,减少卷积计算量。从空间和时间上优化了网络。
这里要说一下逐点卷积和深度卷积。
逐点卷积(Pointwise Convolution, PW)的运算与标准卷积运算非常相似。
逐点卷积卷积核大小为1×1xM(M为输入数据的维度),每次卷积一个像素的区域。逐点卷积运算会将上一层的特征图在深度方向上进行加权组合,生成新的特征图,新的特征图的大小与输入数据大小一致;然后组合各通道的特征图,以较少的计算量进行降维或升维操作(改变输出数据的维度)。
以一张5x5x3(长和宽为5,RGB3通道)的彩色图片举例,使用4个1x1x3的逐点卷积核进行卷积,逐点卷积运算后生成了4个特征图。这个例子是使用逐点卷积进行升维的操作,特征图从5x5x3 升维到5x5x4。如下图所示:
在这里插入图片描述
1X1卷积核可以更好地减少计算量,且起到升维或者降维的作用。而且可以很好地整合深度卷积分离开的通道间信息。
然后是深度卷积:
在这里插入图片描述
首先进行深度卷积操作,得出的特征图各通道之间是不关联的。接着进行逐点卷积把深度卷积输出的特征图各通道关联起来。
深度可分离卷积使用了更小的空间代价(参数减少)和更少的时间代价(计算量更少)实现了标准卷积层一样的效果(提取特征)。
一般的设Df为输入特征图边长,Dk为卷积核边长,特征图和卷积核均为长宽一致,输入通道数为M,输出通道数为N,则:
标准卷积计算量为:Df×Df×Dk×Dk×M×N
深度卷积的计算量为:Df×Df×Dk×Dk×M
逐点卷积的计算量为:Df×Df×M×N
计算大大下降,但是通道间信息被忽略了所以后面还要逐点卷积整合一下。
然后MobileNetV3中,深度卷积大量使用5x5大小的卷积核。这是因为使用神经结构搜索(NAS)技术计算出的MobileNetV3网络结构的过程中,发现了在深度卷积中使用5x5大小的Squeeze-and-Excitation模块(简称SE模块)的首次提出是在2017年的Squeeze-and-Excitation Networks(SENet)网络结构中,在MNasNet中进行了改进,之后在MobileNetV3中大量使用。研究人员期望通过精确的建模卷积特征各个通道之间的作用关系来改善网络模型的表达能力。为了达到这个期望,提出了一种能够让网络模型对特征进行校准的机制,使得有效的权重大,无效或效果小的权重小的效果,这就是SE模块。

下图表示一个SE 模块。主要包含Squeeze和Excitation两部分。W,H表示特征图宽,高。C表示通道数,输入特征图大小为W×H×C。
在这里插入图片描述
压缩(Squeeze)

第一步是压缩(Squeeze)操作,如下图所示
在这里插入图片描述
这个操作就是一个全局平均池化(global average pooling)。经过压缩操作后特征图被压缩为1×1×C向量。
激励(Excitation)

接下来就是激励(Excitation)操作,如下图所示

在这里插入图片描述
由两个全连接层组成,其中SERatio是一个缩放参数,这个参数的目的是为了减少通道个数从而降低计算量。
第一个全连接层有C*SERatio个神经元,输入为1×1×C,输出1×1×C×SERadio。
第二个全连接层有C个神经元,输入为1×1×C×SERadio,输出为1×1×C。
scale操作
最后是scale操作,在得到1×1×C向量之后,就可以对原来的特征图进行scale操作了。很简单,就是通道权重相乘,原有特征向量为W×H×C,将SE模块计算出来的各通道权重值分别和原特征图对应通道的二维矩阵相乘,得出的结果输出。
这里我们可以得出SE模块的属性:
参数量 = 2×C×C×SERatio
计算量 = 2×C×C×SERatio
总体来讲SE模块会增加网络的总参数量,总计算量,因为使用的是全连接层计算量相比卷积层并不大,但是参数量会有明显上升。SE模块的使用是很灵活的,可以在已有网络上添加而不打乱网络原有的主体结构。
ResNet中添加SE模块形成SE-ResNet网络,SE模块是在bottleneck结构之后加入的,如下图左边所示。
在这里插入图片描述
MobileNetV3版本中SE模块加在了bottleneck结构的内部,在深度卷积后增加SE块,scale操作后再做逐点卷积,如上图右边所示。MobileNetV3版本的SERadio系数为0.25。使用SE模块后的MobileNetV3的参数量上升,达到5.4M,但是MobileNetV3的精度得到了很大的提升,在图像分类和目标检测中准确率都有明显提升。

另外一个是:h-swish激活函数

MobileNetV3中发现swish激活函数能够有效提高网络的精度,但是swish的计算量太大了,并不适合轻量级神经网络。MobileNetV3找到了类似swish激活函数但是计算量却少很多的替代激活函数h-swish(hard version of swish)如下所示:

在这里插入图片描述
这就是结构,很神奇,用了1X1卷积操作和分离卷积大大减少了参数量,虽然5X5和SE会增加参数量但是总体还是减少,且精度上升。

运行

作者在网页上写了运行命令,但是有一点要注意如果你用pycharm的terminal运行,要去掉换行,也就是原来这样:

python train.py \
    --model_type small \
    --width_multiplier 1.0 \
    --height 128 \
    --width 128 \
    --dataset mnist \
    --lr 0.01 \
    --optimizer rmsprop \
    --train_batch_size 256 \
    --valid_batch_size 256 \
    --num_epoch 10 \
    --logdir logdir

换成这样:

python evaluate.py  --model_type small --width_multiplier 1.0 --height 128 --width 128 --dataset mnist --valid_batch_size 256 --model_path mobilenetv3_small_mnist_10.h5

即可正确运行,报错的话一般是库安得少,缺什么安什么就行。数据会自己下不用提前准备,两个模型间换只需要把Samall改成large。其他就额没有神魔了就这样。

最后

这篇文章,写的比较简便,细节并不全,但是亮点说了一些,还是一样,为和我一样的小白而写,供大家参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值