EfficientNet网络详解并使用pytorch搭建模型

本文深入探讨EfficientNet网络的设计理念,它通过平衡网络的深度、宽度和输入分辨率来提升性能。作者通过网络搜索确定了合适的缩放系数,以在有限的计算资源下最大化模型的准确率。EfficientNet-B0作为基础模型,通过调整宽度系数、深度系数和输入分辨率构建了不同规模的变体。文章还详细介绍了MBConv块的结构,包括深度可分离卷积、通道注意力机制等,并提供了PyTorch实现的代码示例。最后,给出了EfficientNet网络的构建流程和关键参数设置。

1.EfficientNet网络设计思想

在原论文中,作者通过网络搜索技术同时探索输入分辨率,网络的深度depth、channel的宽度width对准确率的影响,构建EfficientNet网络。

根据以往的经验,增加网络的深度depth能够得到更加丰富、复杂的特征,但网络的深度过深会面临梯度消失,训练困难的问题。

增加网络的width能够获得更高细粒度的特征并且也更容易训练,但对于width很大而深度较浅的网络往往很难学习到更深层次的特征。

增加输入网络的图像分辨率能够潜在得获得更高细粒度的特征模板,但对于非常高的输入分辨率,准确率的增益也会减小,并且大分辨率图像会增加计算量。

而本论文会同时增加网络的width、网络的深度以及输入网络的分辨率来提升网络的性能:
在这里插入图片描述
(a)为传统的卷积神经网络
(b)在(a)的基础上增大了特征矩阵的channel(对于每个卷积层使用更多的卷积核
(c.)在(a)的基础上增加了网路网络的深度(增加layer)
(d)在(a)的基础上增加输入图像分辨率,即增加特征矩阵的高和宽
(e)为同时增加网路宽度、深度、输入图像的分辨率。

在EfficientNet模型中,作者使用一组固定的缩放系数统一缩放网络深度、宽度和分辨率。
假设想使用 2N倍的计算资源,可以对网络深度扩大αN倍、宽度扩大βN 、图像尺寸扩大γN倍,这里的α,β,γ都是由原来的小模型上做微小的网格搜索决定的常量系数。

2.EfficientNet网络结构

EfficientNet网络是在EfficientNet-B0的基础上进行不同的调整

EfficientNet-B0 baseline network

在这里插入图片描述

分辨率Resolution对应输入每个stage时特征矩阵的高和宽;Channels对应每个stage的输入特征矩阵的channel;Layers为Operator重复的次数;表中的卷积层后默认都跟有BN以及Swish激活函数。

stage1由3x3卷积层组成;
stage2~stage8则是在重复堆叠MBConv,1、6对应1x1卷积层channel的倍率因子;
stage9由1x1卷积层、平均池化层、全连接层组成。

MBConv

Moblienetv3所使用的block是一样的
在这里插入图片描述
Block是一个结合深度可分离卷积和注意力机制的逆残差结构,每个Block可分为两部分:

主干部分,首先利用1x1卷积升维,再使用3x3或者5x5的逐层卷积进行跨特征点的特征提取,完成特征提取后添加一个通道注意力机制,最后利用1x1卷积降维

第一个升维的1x1卷积层,卷积核个数是输入特征矩阵channel的n倍;
当n=1时,不要第一个升维的1x1卷积层,即stage2中的MBConv结构都没有第一个升维的1x1卷积层;

残差分支不进行处理。
关于shortcut连接,仅当输入MBConv结构的特征矩阵与输入特征矩阵的shape相同时才存在。

SE模块

在这里插入图片描述
对输入特征矩阵的feature map的每一个channel进行平均池化下采样,通过两个全连接层与原feature map进行乘法操作。

第一个全连接层的节点个数是输入该MBConv特征矩阵channel的1/4,且使用Swish激活函数;
第二个全连接层的节点个数等于Depthwise Conv层输出的特征矩阵channels,且使用Sigmoid激活函数。

注意力机制就是块砖,哪要往哪搬!

EfficientNet-B1~B7

在这里插入图片描述
width_coefficient代表Channel维度上的倍率因子,如EfficientNetB0中stage1的3x3卷积层所使用的卷积核个数为32,bane在B6中就是32x1.8=57.6,取整到理它最近的8的整数倍即56,其他stage同理;

depth_corfficient代表depth维度上倍率因子(因针对stage2到stage8),如EfficientNetB0中stage7的L=4,那么在B6中就是4x2.6=10.4,向上取整即11,将stage7的MBConv重复堆叠11次。

drop_connect_rate是在MBConv结构中dropout层使用的drop_rate,在官方keras模块的实现中MBConv结构的drop_rate是从0递增到drop_connect_rate的。还需要注意的是,这里的Dropout层是Stochastic Depth,即会随机丢掉整个block的主分支(只剩捷径分支,相当于直接跳过了这个block)也可以理解为减少了网络的深度。

dropout_rate是最后一个全连接层前的dropout层(在stage9的Pooling与FC之间)的dropout_rate。

EfficientNet网络准确率很高且参数个数很少,但非常占GPU显存。

3.使用Pytorch搭建MobileNetv3网络

卷积+BN+激活函数模块

class ConvBNActivation(nn.Sequential):   #卷积+BN+激活函数
    def __init__(self,
                 in_planes: int,         #输入特征矩阵channel
                 out_planes: int,        #输出特征矩阵channel
                 kernel_size: int = 3,   #卷积核大小
                 stride: int = 1,        #步距
                 groups: int = 1,        #g=1使用dw卷积,g=2使用普通卷积
                 norm_layer: Optional[Callable[..., nn.Module]] = None,   #BN结构
                 activation_layer: Optional[Callable[..., nn.Module]] = None):  #BN结构后的激活函数
        padding = (kernel_size - 1) // 2    #根据kernel_size计算padding
        if norm_layer is None:              #如果没有传入norm_layer则使用BN
            norm_layer = nn.BatchNorm2d
        if activation_layer is None:        #如果没有传入activation_layer则使用SiLU激活函数(和swish激活函数一样)
            activation_layer = nn.SiLU  # alias Swish  (torch>=1.7)
        #传入所需要构建的一系列层结构
        super(ConvBNActivation, self).__init__(nn.Conv2d(in_channels=in_planes,   #传入卷积层所需要参数
                                                         out_channels=out_planes,
                                                         kernel_size=kernel_size,
                                                         stride=stride,
                                                         padding=padding,
                                                         groups=groups,
                                                         bias=False),             #使用BN结构则不使用bias
                                               norm_layer(out_planes),            #BN结构,传入的参数为上一层的输出channel
                                               activation_layer())                #不传入参数默认使用SiLU激活函数

注意力模块

class SqueezeExcitation(nn.Module):      #SE模块
    def __init__(self,
                 input_c: int,   # block input channel   对应MBConv输入特征矩阵的channel
                 expand_c: int,  # block expand channel  对应第一个1x1卷积层升维后的channel(dw卷积不改变channel)
                 squeeze_factor: int = 4):              #对应第一个全连接层的节点个数,论文中默认等于4
        super(SqueezeExcita
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值