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

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

被折叠的 条评论
为什么被折叠?



