EfficientNet

介绍

作者希望找到一个可以同时兼顾速度与精度的模型放缩方法,为此,作者重新审视了前人提出的模型放缩的几个维度:网络深度、网络宽度、图像分辨率,前人的文章多是放大其中的一个维度以达到更高的准确率,比如 ResNet-18 到 ResNet-152 是通过增加网络深度的方法来提高准确率。
在这里插入图片描述

在这里插入图片描述
图中红色的那条就是 EfficientNet 的曲线,横轴为模型大小,纵轴为准确率。这个网络还是比较牛的。

问题抽象化

在这里插入图片描述

在这里插入图片描述
w、d、r 分别是网络宽度,网络高度,分辨率的倍率。

实验

第一个实验,对三个维度固定两个,只放大其中一个,得到结果如下:
在这里插入图片描述
图中从左至右分别是只放大网络宽度(width, w 为放大倍率)、网络深度(depth, d 为放大倍率)、图像分辨率(resolution, r 为放大倍率) 的结果,可以观察到单个维度的放大最高精度只在 80 左右。本次实验作者得出一个观点:三个维度中任一维度的放大都可以带来精度的提升,但随着倍率越来越大,提升却越来越小。

第二个实验,尝试在不同的 d, r 组合下变动 w,得到下图:

在这里插入图片描述
得到更高的精度以及效率的关键是平衡网络宽度,网络深度,图像分辨率三个维度的放缩倍率(d, r, w)。

混合维度放大法&EfficientNet-B0~B7

为了找到满足前面工事中的3个维度参数,这篇论文引入Φ参数,并将3个待优化参数都用Φ指数表示。

作者提出了一种混合维度放大法(compound scaling method),该方法使用一个混合系数来决定三个维度的放大倍率:
在这里插入图片描述
准备好优化公式后,作者还通过网络结构搜索设计了一个baseline网络,也就是EfficientNet-B0:
在这里插入图片描述

class MBConv(tf.keras.layers.Layer):
    def __init__(self, in_channels, out_channels, expansion_factor, stride, k, drop_connect_rate):
        super(MBConv, self).__init__()
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.stride = stride
        self.drop_connect_rate = drop_connect_rate
        self.conv1 = tf.keras.layers.Conv2D(filters=in_channels * expansion_factor,
                                            kernel_size=(1, 1),
                                            strides=1,
                                            padding="same")
        self.bn1 = tf.keras.layers.BatchNormalization()
        self.dwconv = tf.keras.layers.DepthwiseConv2D(kernel_size=(k, k),
                                                      strides=stride,
                                                      padding="same")
        self.bn2 = tf.keras.layers.BatchNormalization()
        self.se = SEBlock(input_channels=in_channels * expansion_factor)
        self.conv2 = tf.keras.layers.Conv2D(filters=out_channels,
                                            kernel_size=(1, 1),
                                            strides=1,
                                            padding="same")
        self.bn3 = tf.keras.layers.BatchNormalization()
        self.dropout = tf.keras.layers.Dropout(rate=drop_connect_rate)

    def call(self, inputs, training=None, **kwargs):
        x = self.conv1(inputs)
        x = self.bn1(x, training=training)
        x = swish(x)
        x = self.dwconv(x)
        x = self.bn2(x, training=training)
        x = self.se(x)
        x = swish(x)
        x = self.conv2(x)
        x = self.bn3(x, training=training)
        if self.stride == 1 and self.in_channels == self.out_channels:
            if self.drop_connect_rate:
                x = self.dropout(x, training=training)
            x = tf.keras.layers.add([x, inputs])
        return x

优化求解:

  • 第一步是固定Φ=1,然后通过网格搜索找到满足公式3的最优α、β、γ,比如对于EfficientNet-B0网络而言,最佳的参数分别是α=1.2、β=1.1、γ=1.15(此时得到的也就是EfficientNet-B1)。
  • 第二步是固定第一步求得的α、β、γ参数,然后用不同的Φ参数得到EfficientNet-B1到EfficientNet-B7网络

EfficientNet-B1~B7相对于B0来说改变了4个参数:width_coefficient, depth_coefficient, resolution和dropout_rate,分别是宽度系数、深度系数、输入图片分辨率和dropout比例。具体参数如下:

b0 = get_efficient_net(1.0, 1.0, 224, 0.2)
b1 = get_efficient_net(1.0, 1.1, 240, 0.2)
b2 = get_efficient_net(1.1, 1.2, 260, 0.3)
b3 = get_efficient_net(1.2, 1.4, 300, 0.3)
b4 = get_efficient_net(1.4, 1.8, 380, 0.4)
b5 = get_efficient_net(1.6, 2.2, 456, 0.4)
b6 = get_efficient_net(1.8, 2.6, 528, 0.5)
b7 = get_efficient_net(2.0, 3.1, 600, 0.5)

在这里插入图片描述
参考:
https://www.jianshu.com/p/2ac06d97a830

https://blog.csdn.net/u014380165/article/details/90812249
https://zhuanlan.zhihu.com/p/84836782

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值