技术解读EfficientNet系列模型——图片分类的领域的扛把子

EfficientNet系列模型作为图片分类领域精度最高的模型(没有之一)。它到底用了哪些技术?有哪些值得我们借鉴的地方?本文将详细阐述一下这个事情。具体内容如下:

EfficientNet模型是Google公司通过机器搜索得来的模型。该模型是一个快速高精度模型。它使用了深度(depth)、宽度(width)、输入图片分辨率(resolution)共同调节技术。

谷歌使用这种技术开发了一系列版本。目前已经从EfficientNet-B0到EfficientNet-B8再加上EfficientNet-L2和Noisy Student共11个系列的版本。其中性能最好的是Noisy Student版本。以下是图片分类模型在ImageNet数据集上的精度对比结果。

从结果可以看出,Noisy Student模型是目前精度最高的模型,在Imagenet数据集上达到了 87.4%的top1准确性和98.2%的top5准确性。

回顾一下EfficientNet系列模型的发展过程,里面的主要技术如下。

1. EfficientNet系列模型的主要结构

EfficientNet系列模型的主要结构要从该模型的构建方法说起。该模型的构建方法主要包括以下2个步骤:

(1)使用强化学习算法实现的MnasNet模型生成基线模型EfficientNet-B0。

(2)采用复合缩放的方法,在预先设定的内存和计算量大小的限制条件下,对EfficientNet-B0模型的深度、宽度(特征图的通道数)、图片大小这三个维度都同时进行缩放,这三个维度的缩放比例由网格搜索得到。最终输出了EfficientNet模型。

提示:

MnasNet模型是Google 团队提出的一种资源约束的终端 CNN 模型的自动神经结构搜索方法。该方法使用强化学习的思路进行实现。

EfficientNet模型的调参示意图,如图3-10所示。

图3-10 EfficientNet模型

在图3-10中的各个子图含义是:

(1)子图是基准模型。

(2)子图在基准模型的基础上进行宽度缩放,即增加图片的通道数量。

(3)子图在基准模型的基础上进行深度缩放,即增加网络的层数。

(4)子图在基准模型的基础上对图片的大小进行缩放。

(5)子图在基准模型的基础上对图片的深度、宽度、大小都同时进行缩放。

原始模型

EfficientNet模型论文的网址是:

https://arxiv.org/abs/1905.11946

2. MBConv卷积块

EfficientNet模型的内部是通过多个MBConv卷积块实现的,每个MBConv卷积块的具体结构如下:

其中将ReLU激活函数缓存了Swish激活函数。MBConv卷积块也使用了类似残差链接的结构,不同的是在短连接部分使用了SE层。另外使用了drop_connect方法来代替传统的drop方法。

注意:

在SE层中没有使用BN操作,而且其中的sigmoid激活函数也没有被Swish替换。

在其它层中,BN是放在激活函数与卷积层之间的。(这么做的原理见本书7.6.3小节)

DropConnect与Dropout不同的地方是在训练神经网络模型过程中,它不是对隐层节点的输出进行随机的丢弃,而是对隐层节点的输入进行随机的丢弃。如下图所示:

在深度神经网络中DropConnect与Dropout的作用都是防止模型产生过拟合的情况。相比之下DropConnect的效果会更好一些。

3. 模型的规模和训练方式

EfficientNet系列模型主要从2个方面进行衍化。

(1)模型结构的规模:

EfficientNet系列模型中从EfficientNet-B0到EfficientNet-L2版本,模型的精度越来越高,规模越来越大,同样,对内存的需求也会随之变大。

模型的规模主要是由宽度、深度、分辨率这三个维度的缩放参数决定的。这三个维度并不是相互独立的,对于输入的图片分辨率更高的情况,需要有更深的网络来获得更大的感受视野。同样的,对于更高分辨率的图片,需要有更多的通道来获取更精确的特征。在EfficientNet的论文中,也用公式介绍了三者之间的计算原则(详见论文arXiv:1906.11946, 2019)。

下表中显示了每个版本的缩放参数。

从上表中可以看到,随着模型缩放参数的逐渐变大,其dropout的丢弃率参数也在增大。这是因为模型中的参数越多,模型的拟合效果越强,也越容易产生过拟合。

为了避免过拟合问题,单靠增加dropout的丢弃率是不够的。还需要借助于训练方式的改进来提升模型的泛化能力。

(2)模型的训练方式:

EfficientNet系列模型在EfficientNet-B7版本之前主要是通过调整缩放参数,增大网络规模来提升精度。在EfficientNet-B7版本之后主要是通过改进训练方式和增大网络规模2种方法并行来提升模型精度。主要的训练方法如下:

  • 随机数据增强:又叫Randaugment,是一种更高效的数据增强方法。该方法EfficientNet-B7版本中使用。
  • 用对抗样本训练模型:应用在EfficientNet-B8和EfficientNet-L2版本,该版本又叫做AdvProp。
  • 使用自训练框架:应用在Noisy Student版本。

其中随机数据增强是在原有的训练框架中,可以直接替换原有的自动数据增强方法AutoAugment。而AdvProp和Noisy Student则是使用了新的训练框架所完成的训练方法,这部分内容将在后面详细介绍。

4. 随机数据增强方法(RandAugment)

随机数据增强RandAugment方法是一种新的数据增强方法,比自动数据增强AutoAugment方法简单又好用。在原有的训练框架中,可以直接替换原有的AutoAugment方法。

AutoAugment方法包含了30多个参数,可以对图片数据进行各种变换(可以参考论文arXiv:1805.09501, 2018)。

随机数据增强RandAugment方法是在AutoAugment方法的基础之上,将30多个参数进行策略级的优化管理。使这30多个参数被简化成为2个参数:图像的N个变换和每个转换的强度M。其中每次变换的强度参数M,取值在0到10的整数范围内,表示使原有图片增强失真(augmentation distortion)的大小。

RandAugment方法以结果为导向,使数据增强过程更加“面向用户”。在减少AutoAugment的运算消耗的同时,又使增强的效果变得可控。详细内容可以参考论文(arXiv:1909.13719, 2019)

5. 用对抗样本训练模型(AdvProp)

AdvProp模型是一种使用对抗性样本来减少过度拟合的训练方法。在实现时,使用了独立的辅助批处理规范来处理对抗性样本。即使用额外的一个辅助BN单独作用于对抗性样本。

对抗样本是指通过在图像上添加不可察觉的扰动而产生的对抗性样本可能导致卷积神经网络(ConvNets)做出错误的预测。

为了进一步提升模型精度,放大EfficientNet-B7版本的模型规模,并用AdvProp的方法进行训练,于是便推出了EfficientNet-B8版本,该版本也叫AdvProp模型。

AdvProp模型在不需要添加额外的训练数据情况下,通过对抗性样本的方式进行训练,在ImageNet上获得了85.5%的top-1精度。这一结果超过了《Exploring the limits of weakly supervised pretraining. In ECCV, 2018》中使用3.5B Instagram图像(比ImageNet多约3000倍)和多约9.4倍参数训练的最佳模型。

(1)AdvProp模型中的对抗样本算法

在AdvProp模型中,使用了3种对抗样本的生成算法,分别为PGD、I-FGSM和GD。具体如下:

  • PGD:投影梯度下降(Project Gradient Descent)攻击是一种迭代攻击,即带有多次迭代的FGSM——K-FGSM (K表示迭代的次数)。FGSM是仅仅做一次迭代,走一大步,而PGD是做多次迭代,每次走一小步,每次迭代都会将扰动投影(Project)到规定范围内。在AdvProp模型中,将PGD的扰动级别分为0到4,生成扰动的迭代次数n按照扰动级别+1进行计算。攻击的步长固定为1。参考论文(arXiv:1706.06083, 2017)
  • I-FGSM:在PGD的基础上,将随机初始化的步骤去掉,直接基于原始样本做扰动。同时将扰动级别设为4,迭代次数为5,攻击步长为1。这种方式生成的对抗样本针对性更强,泛化攻击的能力较弱。
  • GD:在PGD基础之上,将投影的环节去掉,不再对扰动大小进行限制,直接将扰动级别设为4,迭代次数为5,攻击步长为1。这种方式生成的对抗样本更为宽松,但有可能失真更大(对原有样本的分布空间改变更大)。

这3种算法分别作用在EfficientNet的B3、B5、B7版本上,其效果如图所示:

可以看到。总体来说,3种算法的的效果相差不大。在模型规模较小时FGSM效果更好,在模型规模较大时GD效果更好。

有关对抗样本的更多内容和配套代码可以参考《深度学习之TensorFlow:工程化项目实战》一书第11章,模型的攻防。

(2)AdvProp模型中的关键技术

使用对抗样本进行训练的方法并不是绝对有效的,因为普通样本和对抗性样本之间的分布不匹配,在训练过程中,有可能会改变模型所适应的样本空间。一旦模型适应了对抗样本的分布,则在真实样本中,便无法取得很好的效果。这种情况会导致模型的精度下降。如图所示

图中显示了直接使用对抗样本和使用AdvProp的方法在ResNet模型上训练的效果,可以看到,直接使用对抗样本对模型的精度都造成了下降的影响。而AdvProp的方法可以使模型的精度有所提升。

AdvProp模型在使用对抗样本进行训练时,与真实的样本做了区分,使用了两个独立的BN本别对其进行处理。可以在归一化层上正确分解这两个分布,以便进行准确的统计估计。它使模型能够通过对抗性样本成功地改进而又不会降低性能。传统的BN与辅助BN的结构比较,见下图:

具体步骤如下:

(1)在训练时,取出一批次原数据。

(2)用该批次原数据攻击网络,生成对应的对抗样本

(3)将该批次原数据和抗样本一起输入网络,其中批次原数据输入主BN进行处理,对抗样本输入辅助BN进行处理。而网络中的其它层同时处理二者的联合数据。

(4)在计算损失时,对批次原数据和对抗样本的损失分别单独计算。在将它们加和。作为总的损失值进行迭代优化.

(5)在测试时,将所有的辅助BN接口丢弃。保留主BN接口。验证模型性能。

有关AdvProp的更多内容请参考论文(arXiv:1911.09665, 2019)。

有趣的是,该篇论文的方法与代码医生工作室6月份推出的“鉴黄师”产品非常相似。详见精炼鉴黄师背后的故事(点击图片浏览)。

在鉴黄师产品中。我们也是使用了自己改良后的FGSM方法进行对抗样本的制作。其中改良的部分主要是将PGD算法的随机初始化部分换成了数据增强算法。

与AdvProp不同的是,我们没有在原始模型上进行结构的调整(增加辅助BN)而是通过对抗神经网络在生成对抗样本阶段将数据分布硬拉到原始数据的分布中(其实就是在loss部分加了KL散度的计算)。

该做法与AdvProp的做法所解决的问题是一样的,即对抗样本与真实样本的空间分布不同。相比之下,我们的方法可移植性更高,更容易被做成通用框架,因为它不会去修改原始模型的结构。

这种方式稍加变换还可以被融合进数据增强的训练框架,从工程学角度来看更有意义。

6.用自训练框架训练的模型(Noisy Studen)

Noisy Student模型可以代表目前图片分类界的最高精度。该模型在训练模型的过程中使用了自训练框架,自训练框架可以为以下步骤:

(1)用常规方法在带有标注的数据集上(ImageNet)训练一个模型,将其当作教师模型;

(2)利用该教师模型对一些未标注过的图像进行分类(在论文中,作者直接使用了JFT 数据集的图像,忽略其标签部分)。并将分类分数大于指定阈值(0.3)的样本收集起来,作为伪标注数据集;

(3)在标注和伪标注混合数据集上重新训练一个学生模型;

(4)将训练好的学生模型当做教师模型,重复(2)到(3)步。进行多次迭代,最终得到的学生模型便是目标模型。

提示:

在Noisy Student模型的训练细节上也用了一些技巧,具体如下:

  • 第(2)步可以直接用模型输出的分数结果当作数据集的标签(软标签),这种效果会比直接使用one-hot编码的标注(硬标签)效果更好。
  • 在训练学生模型时,为其增加了更多的噪声源,使用了诸如数据增强、dropout、随机深度等方法,使得学生模型在从伪标签训练的过程中更加艰难。这种方法使得训练出来的学生模型更加稳定,能够生成质量更高的伪标注数据集。
  • 在制作伪标签数据集时,需要按照每个分类相同的数量提取伪标签数据(论文中的做法是:每个类别,挑选具有最高信任度的 13 万张图片,对于不足 13万张的类别,随机再复制一些),这样做可以可以保证样本样本均衡。
  • 引入了一个修复训练测试分辨率差异的技术来训练学生模型,首先在小分辨率图片下正常训练 350 个周期,然后基于未进行数据增强的大分辨率图片下微调训练1.5 个周期,微调阶段浅层被固定。可以参考论文(arXiv:1906.06423, 2019)

Noisy Student模型的精度不依赖于训练过程的批次大小,可以根据实际内存进行调节。

Noisy Student模型的自训练框架具有一定的通用性。在实际应用时,对于大模型,在无标注数据集上的批次是有标准数据集的 3 倍,在小模型上则可以使用相同批次。该方法对EfficientNet系列模型的各个版本都能带来 0.8% 左右的性能提升。

除此之外,该模型也被证明是鲁棒性最好的模型。其在Image-A数据集下的比较结果如下:

Image-A数据集号称为最难数据集。也是目前在ImageNet上训练的众多分类模型的试金石。它包含了来自真实世界的7500 张图片,这些图片的类别与ImageNet数据集的标签一致。它们为经过任何的修改却具有对抗样本等同的效果。

图中红色的是标签是 ResNet-50 模型给出的,黑色的标签是实际真实标签,而且以很高的信任度识别错误,要注意虽然这些样本是对抗样本,但都是来自真实世界未加对抗调整的自然图片。

许多在ImageNet 下训练好的知名模型,经过Image-A数据集的测试,其准确率都大幅下降。以 DenseNet-121 为例,其测试准确率仅为 2%,准确率下降了约 90%。所以,该数据集能够很好的测试出分类模型的泛化能力。详见论文(arXiv:1907.07174, 2019),对应的链接:

https://github.com/hendrycks/natural-adv-examples

Noisy Student模型在Image-A数据集上,Top1的识别率达到了74.2%,远远领先了第二名的49.6%。这主要归功于其自学习框架的训练方式。

有关Noisy Student模型的更多详细内容请参考论文:

https://arxiv.org/abs/1911.04252

7 未来的展望

自训练方法是一种半监督的模型训练方法。它开阔了一个新的训练高精度模型思路。沿着这个思路还有很多监督方式训练模型的方法可以进行融合。比如使用对抗样本、随机增强等。而对于挑选伪标签样本过程,还可以更加精确一些,例如在候选样本中做特征聚类,剔除特征相同的伪标签样本,使学生模型的训练更高效、所学习的特征更全面。

为了提高模型的精度,扩充数据集已经是一个主流的思想。如何更为有效的扩充数据集则是训练方法未来优化的空间。

其实代码医生工作室的鉴黄师产品在训练过程中,也使用了扩充数据集的方式优化模型精度。只不多我们的扩充框架是半自动的。这与具体的分类业务有关,因为涉黄图片分类任务不同于普通的分类,在扩充样本过程中,本身就可以自带标签。而收集学生模型的训练样本工作,则可以从教师模型的出错样本中进行选取。这种使用业务与技术结合的方式,才会使专项模型在自己的领域达到最优。

讲这个案例也是为了给读者一个启发。在优化模型过程中,不要死盯着技术这一个方向,要最大化的利用任务的周边信息,将可以利用的优势条件融入技术,从多个角度来提升模型。

8 当前的代码资源

有关efficientnet系列的代码早已经开源。在Github上也可以搜索到许多有关efficientnet的工程。大多都是关于EfficientNet-B0到EfficientNet-B7的。其中包括了TensorFlow版本和PyTorch版本。

另外在TensorFlow的官方版本中,最新的代码里也已经合入了EfficientNet-B0到EfficientNet-B7的模型代码,在tf.keras框架下,可以像使用ResNet模型一样,一行代码就可以完成预训练模型的下载和加载的过程。

具体路径在”tensorflow/python/keras/applications/efficientnet.py” 下面。不过该部分代码是在TensorFlow的2.0版本和1.15版本正式发布之后添加的。需要使用该版本以上的TensorFlow框架才可以使用。

注意:

由于TensorFlow的2.0版本对深度卷积(见4.9.7小节)的处理性能稍慢,所以在该框架下的EfficientNet模型运行效率会有一定影响。但该问题有望在后续版本中被修复。

对于单纯的端到端分类任务,EfficientNet的系列模型是最优选择。但作为更细粒度的语义分割任务,在骨干网的特征环节,如果显存有限,则EfficientNet系列模型并不是最优选择。主要原因是该系列模型对GPU的显存占有率过高。

对于EfficientNet系列的高精度模型(B7以上),只有在TensorFlow的tpu项目下可以找到。可以从如下链接进行获取:

https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet

在该链接中包含了EfficientNet系列从B0到L2的全部代码。不过预训练模型目前只提供到EfficientNet的B8版本。同时配套的训练源码只提供到B7版本的随机数据增强,对于B8版本对应的AdvProp方法,以及Noisy Student对应的自训练框架源码尚未公开。

以上内容节选自《机器视觉之TensorFlow2:入门、原理与应用实战》。预计2020年3月上市。