第5章〓图像分类算法原理与实战 图像分类任务是最早使用深度学习方法的计算机视觉任务,很多经典的网络架构都是首先应用到图像分类任务上。因此,图像分类中的深度学习网络模型可以看作其他计算机视觉任务的基石。 5.1图像分类任务的基本介绍 图像分类任务是对一个给定的图像赋予一个分类结果,用户向系统输入一幅图像,计算机系统通过计算输出该图像所对应的分类标签。例如,CIFAR10是图像分类经典数据集,共包含10个类别。图51展示的是CIFAR10的部分数据,它们根据图像中的主体内容的不同,被归入不同的类别。 图51图像分类数据集CIFAR10示例 5.1.1图像分类技术的发展 早期的图像分类方法主要通过手工提取特征对整个图像进行描述,然后使用分类器判别图像类别。因此,图像分类的核心在于对特征进行分类,而如何提取图像的特征至关重要。传统方法使用较多的是基于词袋模型的图像特征表示方法,词袋法是从自然语言处理领域引入视觉领域的。在自然语言领域中,一句话可以用一个装了词的袋子表示其特征,袋子中的词为句子中的单词、短语。在图像领域,词袋模型框架可以视作特征表达的过程。 常用的局部特征包括尺度不变特征变换(Scaleinvariant Feature Transform,SIFT)[1]、方向梯度直方图(Histogram of Oriented Gradient,HOG)[2]、局部二值模式(Local Binary Patterns,LBP)[3]等。一般也同时采用多种特征描述,防止丢失过多的有用信息。底层特征通常从图像中按照固定步长、尺度提取大量局部特征描述。底层特征中包含了大量冗余与噪声,为了提高特征表达的鲁棒性,需要使用一种特征变换算法对底层特征进行编码,称作特征编码。常用的特征编码方法包括向量量化编码、稀疏编码、局部线性约束编码、Fisher向量编码等。特征编码之后一般会经过空间特征约束,也称作特征汇聚,具体指在一个空间范围内,对每一维特征取最大值或者平均值,可以获得一定特征不变性的特征表达。金字塔特征匹配是一种常用的特征汇聚方法,它将图像均匀分块,在每个块内做特征汇聚。 图像经过底层特征提取、特征编码、特征汇聚后,可以表示为一个固定维度的向量描述,将该特征向量经过分类器分类便可实现对图像的分类。通常使用的分类器包括支持向量机(SVM)、随机森林等,其中,基于核方法的SVM是传统方法中使用最广泛的分类器,在传统图像分类任务上性能很好。传统的图像分类方法对于一些简单且具有明显特征的图像分类场景是有效的,但由于实际情况非常复杂,在面对复杂场景时传统的分类方法就无法达到满意的分类效果。这是因为传统分类方法使用的手工提取特征方法无法全面准确地描述图像特征,并且手工提取的特征无法应对多视角、多尺度、不同光照、遮挡、同物多形态等问题。 图像分类任务是深度学习在计算机视觉应用方面最先取得良好效果的任务,在前馈神经网络思想形成后,就有学者尝试将图像送入网络完成图像分类,图像维度通常比较高,用前馈网络实现图像分类需要有数以万计的神经元,导致神经网络面临着巨大的计算量以及“维数灾难”等问题。为了解决这些问题,卷积神经网络通过卷积和池化操作来降低维度,同时通过权值共享来降低计算量,从而使图像分类任务得到了可喜的效果。从此之后卷积神经网络就在图像分类任务中占据了“舞台中心”。 随后,基于注意力机制的Transformer网络在图像分类中表现出色,其中Vision Transformer得到了广泛的应用。卷积操作聚焦于提取图像的局部信息,而Transformer能够通过构造patch embeddings提取到图像的全局表示,从CNN转变到Transformer类似从着眼于局部转变到着眼于全局,更加符合人类的视觉特点(人类擅长快速捕获全局中的特征)。CNN擅长提取局部小而精的信息但存在提取能力不足的缺点; Transformer 依赖全局长距离的建模,不关注局部信息,也就丧失了CNN平移不变、翻转不变等特性,会产生捕捉信息冗余和对数据需求量更大的缺点。 近年来除了Transformer之外,基于MLP结构的网络也表现突出。2021年谷歌人工智能研究院在CVPR提出的MLPMixer[4]包含两种类型的MLP层: 一种是独立应用于图像patches的MLP,即“混合”每个位置特征; 另一种是跨patches应用的MLP,即“混合”空间信息。当在大数据集上训练或使用正则化训练方案时,MLPMixer在图像分类基准上获得了有竞争力的分数,并且预训练和推理成本与最先进的模型相当。 综合来看,深度学习方法在图像分类问题上,经历了朴素MLP、CNN、Transformer、复杂MLP等模型发展的过程。这些模型都具有各自的特点,卷积仅包含局部连接,因此计算高效; 自注意力采用了动态权值,因此模型容量更大,它同时还具有全局感受野; MLP同样具有全局感受野,但没有使用动态权值。可以看出,卷积与自注意力具有互补特性,卷积具有最好的泛化能力,而Transformer在三种架构中具有最大的模型容量。卷积是设计轻量级模型的最佳选择,但设计大型模型应考虑 Transformer。因此,可以考虑使用卷积的局部建模帮助提升Transformer与MLP的性能。考虑到上述结构特性,稀疏连接有助于提升泛化性能,而动态权值与全局感受野有助于提升模型容量。因此,在图像分类任务上,不断有革新性的方法出现,为计算机视觉提供了更广泛的应用空间。 5.1.2图像分类的评价指标 对于图像分类任务而言,结果评测通常发生在模型训练结束后,让分类器来预测它未曾见过的图像,并以此来评价分类器的质量。分类器预测的分类标签和图像真正的分类标签如果一致则为正确,正确的情况越多越好。通过把分类器预测的标签和图像真正的分类标签对比,就可以计算出分类正确的图像数量,进而得到图像分类正确率等指标。 下面以单标签分类为例,对图像分类评价指标进行介绍。首先明确一些概念,假反例(False Negative, FN),即被误判为负样本的正样本; 假正例(False Positive, FP),即被误判为正样本的负样本; 真反例(True Negative, TN),即被判定为负样本,事实上也是负样本; 真正例(True Positive, TP),即被判定为正样本,事实上也是正样本,具体变量定义如表51所示。 表51分类结果统计表 真实标签情况 预测分类结果 正例反例 正例 TP(真正例) FN(假反例) 反例 FP(假正例) TN(真反例) 其次,准确率(Accuracy,A)表示预测正确的样本数占总样本数量的比例。查准率(Precision,P),即在返回的分类结果中真正正确的个数占整个结果的比例。召回率(Recall, R),即在分类结果中真正正确的正样本个数占整个数据集中所有正样本个数(包含分类正确和分类错误的样本)的比例。 在表51所示变量的定义下,准确率A、查准率P和召回率R分别定义为 A=TP+TNTP+FP+TN+FN(51) P=TPTP+FP(52) R=TPTP+FN(53) F1度量是查准率P和召回率R的调和平均: F1=2×P×RP+R=2×TP2×TP+FP+FN(54) 查准率P和召回率R共同组成的曲线是PR曲线,一般情况下,将R设置为横坐标,P设置为纵坐标来表示查准率P和召回率R的关系。在PR曲线图中,可以根据PR曲线与坐标轴包围的面积来对图像分类效果进行定量评估。 5.2基于残差的网络 在图像分类深度网络模型中,网络的深度对于分类任务的性能至关重要,深层的网络可以更好地拟合更加复杂的特征模式,有着更加优良的分类表现; 但是随着网络层数的增加,却又造成了梯度消失现象与网络退化两个严重问题。为了解决这些问题,研究者提出了基于直接映射来连接网络不同层之间的思想,残差网络(Residual Networks,ResNet)应运而生。 5.2.1ResNet模型 残差网络通过在网络中引入残差连接的机制实现网络层数增加与网络性能的优化。其中, 2015年由何恺明等提出的ResNet[5]是基于残差网络的重要设计,在深度学习的历史上有着里程碑式的地位,其最大的意义就是将神经网络的层数增加至几百甚至上千层,使得网络提取更高级的语义信息成为了可能。 图52ResNet单元结构块[5] ResNet单元结构块中引入的残差连接机制如图52所示。通过增加一个恒等映射(identity mapping),将原始所需要学习的函数F(x)转换成F(x)+x。该操作不会给网络带来额外的参数和计算量,但却可以提高模型的训练速度并提升训练结果。事实上,在此前的Highway Network与长短期记忆网络LSTM上也都有类似的映射机制。 在ResNet的基础上,其变体架构也在不断发展。ResNeXt[6]是ResNet的变种,其修改了ResNet的内部单元结构块Block,由一条残差路径变成了多条残差路径。如图53所示,对比了两个网络的Block结构,可以看出,图53(b)是将一条路径分成了32条(即32paths),对这些路径进行卷积操作,最后相加在一起,两者的通道数不变。 图53ResNet Block与ResNeXt Block 对比[6] 5.2.2DenseNet模型 ResNet的跨层连接设计启发了许多科研人员,也因此出现了很多在此基础上的后续工作,稠密连接网络(Dense Convolutional Network,DenseNet)[7]就是其中之一。 正如其名称所描述的那样,DenseNet相比于ResNet一个改进之处就是每个Block内建立了前面所有层与后面层的稠密连接。ResNet Block是将当前层与前面的某一层逐元素相加进行连接,而DenseNet Block是将当前层与前面所有层进行通道方向的连接(这个操作称为concatenate)来作为下一层的输入, 如图54所示。想要实现这个操作,就得保证 图54DenseNet Block示意图[7] 每一层的特征图大小相同,因此,DenseNet的结构由许多的Dense Block单元组成,每个Block中的特征图尺寸都相同,Block之间进行降低特征图维度的操作,称为过渡(transition),包括1×1的卷积和平均池化等操作。 DenseNet的密集连接只在单个密集单元块内部,密集单元块之间没有密集连接,相邻的密集单元块之间通过卷积和池化进行操作,其结构如图55所示。DenseNet效果有一定的提升,但并不是说就已经全方位地超越了ResNet。稠密连接一个不可忽视的问题便是显存占用较高,因此对于DenseNet和ResNet,二者孰优孰劣,还应当具体问题具体分析,选择最合适的网络。 图55DenseNet示意图[7] 5.2.3DPN模型 双路径网络(Dual Path Network,DPN)[8]是一种融合了ResNet与DenseNet的简单、高效、模块化图像分类网络模型。ResNet和DenseNet是短接(shortcut)系列网络经典的两个基础网络,其中ResNet通过单位加的方式直接将输入加到输出的卷积上,DenseNet则是通过拼接的方式将输出与之后的每一层的输入进行拼接。DPN对ResNet和DenseNet进行分析,证明了ResNet更侧重于特征的复用,而DenseNet则更侧重于特征的生成。结合分析两个模型的优劣,DPN通过高阶RNN(High Order RNN,HORNN)将ResNet和DenseNet进行了融合。所谓双路径,即一条路径是ResNet,另一条路径是DenseNet。 为了便于理解,图56对比分析了ResNet、DenseNet和DPN的核心结构。其中,图56(a)是ResNet的部分残差结构,对于一个输入,通过短接直接恒等映射到经过图56(a)右侧Bottleneck(包括1×1卷积、3×3卷积、1×1卷积)的输出,将它们进行对应值相加(elementwise addition)作为下一个相同模块的输入,具体如图56(a)左侧的矩形框所示。图56(b)表示DenseNet的核心结构,输入与经过多层卷积后的结果进行通道合并(concat),得到的输出再作为下一个模块输入,这样的结构不断累加,以此类推。图56(c)展示了DPN的主要设计思想,其中左侧的竖矩形框和多边形框表示了ResNeXt和DenseNet的合体含义。右侧表示对输入进行1×1卷积、3×3卷积、1×1卷积操作,获得的结果与输入分布都进行通道分裂,包含两部分,一部分直接相加,类似ResNet; 另一部分进行合并,类似DenseNet。值得一提的是,DPN中的3×3卷积采用的是Group操作,类似ResNeXt。由此,形成了一个DPN Block,其输出作为下一个阶段的输入,如此构成DPN中一个stage中的一个substage。 图56DPN网络设计示意图[8] 5.3基于Transformer的网络 近年来,在自然语言处理领域应用非常广泛的Transformer模型也被迁移到了计算机视觉领域,并且取得了非常好的效果,这使得图像分类任务有了一条新的技术路线。 5.3.1ViT模型 2020年10月提出的Vision Transformer (ViT)[9],是使用了Transformer结构的图像分类网络,具有开创性意义。ViT的总体想法是基于Transformer结构来做图像分类任务,相关研究证明在大规模数据集上做完预训练后的ViT模型,迁移到中小规模数据集的分类任务上,能够取得比深度卷积神经网络更好的性能。 ViT原始架构如图57所示,首先将输入图像分为很多大小相同的图像块(patches),将每个图像块拉伸成向量输入一个线性变换的嵌入层(embedding),得到一个向量(通常就称作token)。此外,还需要对每个图像块的位置信息进行编码,加到token前面,然后输入图57右边对应的Transformer 编码器中,将编码器模块重复堆叠L次。最后将编码器的输出,输入到MLP分类头(MLP Head)进行预测分类输出。 图57ViT架构示意图[9] 对于位置编码,使用2D以及相对位置编码其实和1D差不多,即位置编码的差异其实不是特别重要。因为1D位置编码简单、参数少且效果好,所以默认使用1D的位置编码,从而训练得到位置编码与其他位置编码之间的余弦相似度。在第一层的图像块划分中,设定将图像划分成32×32的小块,对于大小为224×224的图像,每行图像块的个数为224/32=7,即图像块的位置为7×7。图58(a)显示了学习的嵌入滤波器前28个主组件,它们类似每个图像块内精细结构的低维表示。投影后,将模型学习出来的位置嵌入添加到该表示中。在每个token上叠加一个位置编码,因此图58(b)中的位置嵌入有49个小图,每个小图也是7×7。图58(b)第一行第一列图像块的位置编码与其本身的位置编码是一样的,余弦相似度是1; 然后与其他位置编码进行计算,就得到了左上角的小图,其他的也都是类似的规律。图58(b)显示了模型学习将图像中的距离编码为位置嵌入的相似性,即越接近的图像块往往具有更相似的位置嵌入。自注意力使ViT能够整合图像的全局信息,图58(c)从图像空间中信息所经过的平均距离出发,基于注意力权重,展示了网络对图像全局信息的整合程度。从图58(c)中可以看出,一些注意头会注意到已经位于最底层的大部分图像,这表明该模型确实具有全局整合信息能力。其他一些注意头,始终保持较小的注意距离,这种高度局部化的注意力在Transformer之前的混合ResNet的模型中不太明显,这在一定程度上与CNN中的早期卷积层具有类似的功能。 图58Position Embedding示意图[9](见彩插) Transformer编码层就是将图57右边的编码模块重复堆叠L次。以单个编码模块进行分析,首先输入一个归一化层,这里的归一化采用的是层归一化。经过层归一化后进行多头注意力处理,然后残差之后再经过归一化层、MLP模块、dropout/DropPath 之后残差即可完成一次Transformer 编码。 MLP模块的构成顺序如下: 全连接层、高斯误差线性单元(Gaussian Error Linerar Units,GELU)激活函数、dropout、全连接层、dropout。其中,第一个全连接层的节点个数是输入向量长度的4倍,第二个全连接层会还原回原来向量的长度。MLP Head层在训练时是由Linear+Tanh激活函数+Linear构成的,但是做迁移学习时,只需要一个Linear就足够了。最后,为了获得类别概率需要一个Softmax结构。 5.3.2SwinTransformer模型 ViT将Transformer从自然语言处理领域直接迁移到计算机视觉领域的工作取得了一定的成果,但是仍然遇到一些困难。首先,两个领域涉及的尺度不同,自然语言处理的尺度是标准固定的,而计算机视觉的尺度变化范围非常大。其次,图像中的像素与文本中的单词相比分辨率高,而且计算机视觉中使用Transformer的计算复杂度是图像尺度的平方,这会导致基于全局自注意力的计算量过于庞大。为此,Swin Transformer[10]通过合并图像块来构建层次化的Transformer,使得模型具有与输入图像大小呈线性的计算量,从而降低计算复杂度。Swin Transformer是当前取得里程碑意义的Transformer类型网络模型,可以作为通用的视觉骨干网络,应用于图像分类、目标检测和语义分割等任务。 相比同样使用Transformer结构的ViT,Swin Transformer做了两点改进。首先,引入CNN中常用的层次化构建方式,构建层次化Transformer; 其次,引入局部思想,对无重合的窗口区域内进行自注意力计算。Swin Transformer构建的层次化Transformer如图59所示,通过从小尺寸的图像块开始,逐渐合并成更深层次的图像块,从而构造不同粒度的层次。与ViT划分图像块的方式类似,Swin Transformer也是先确定每个图像块的大小,然后计算确定图像块数量。不同的是,随着网络加深ViT的图像块数量不会变化,而Swin Transformer的图像块数量随着网络加深会逐渐减少并且每个图像块的感知范围会扩大,这个设计是为了方便Swin Transformer的层级构建,并且能够适应视觉任务的多尺度。 图59Swin Transformer与ViT对比[10] 整个Swin Transformer架构如图510所示,整体看起来和CNN架构非常相似,构建了4个阶段,每个阶段中都是类似的重复单元。首先需要对输入的图像做切分,与ViT的切分方法相同,假设输入图像的大小为H×W×3,通过切分模块将图像分成不重叠的图像块。每个图像块被视为一个token,其特征被设置为原始像素RGB值的串联,输入到Swin Transformer的第一阶段。 图510Swin Transformer架构示意图[10] 在第一阶段中,使用了4×4的图像块大小,因此每个图像块的特征维数为4×4×3=48。在这个特征上应用一个线性嵌入层,将其投影到任意维(记作C)。变化过的Swin Transformer Blocks被应用到这些图像块token上。Swin Transformer Block保留了token的个数H4×W4并且使用了线性嵌入层。 在第二阶段中,为了生成一个层次化的表示,当网络变得更深,token的数量会通过图像块的合并层而减少。第一块拼接层连接了每组2×2相邻的图像块的特征,并在4C维级联特征上应用线性层。这将token的数量减少了2×2=4的倍数(分辨率的2×降采样),并且输出维度设置为2C。之后应用Swin Transformer Block进行特征变换,分辨率保持在H8×W8。 第三、四阶段操作相同,先通过一个图像块合并,将输入按照2×2的相邻图像块合并,这样图像块的数量就变成了H16×W16和H32×W32,特征维度就变成了4C和8C。 图511Swin Transformer Block[10] 在Swin Transformer架构中,存在若干Swin Transformer Block串联的情况。图511展示了两个连续Block的串联,这两个连续的Block结构基本一样,差别在于前一个Block使用的是标准的基于窗口的多头自注意力(Multihead SelfAttention, MSA)模块,而后一个Block使用的是基于移位窗口的MSA模块。在每个MSA模块和每个MLP之前使用LayerNorm(LN)层,并在每个MSA和MLP之后使用残差连接。 标准Transformer体系结构需要进行全局自注意力计算,获得每个token和其他所有token之间的关系。全局计算导致了token数量的二次复杂度,这使得它不适用于需要大量token进行密集预测或表示高分辨率图像的视觉问题。 Swin Transformer和普通Transformer的区别就在于WMSA模块,而它就是降低复杂度计算的主要方法。假设存在一个输入,其宽和高分别为9和9(如图512(a)所示)。MSA的复杂度是图像大小的平方,根据MSA的复杂度,可以得出一个图像块的复杂度是(9×9)2,最后复杂度是812=6561。Swin Transformer是在每个local windows(如图512(b)的小窗口)计算自注意力n,根据MSA的复杂度可以得出每个小窗口的复杂度是(3×3)2,最后小窗口复杂度是92=81。然后将9个小窗口的复杂度加和,最后图512(b)整体的复杂度为729,这个计算量远远小于大窗口。由于窗口的图像块数量远小于图像的图像块数量,因此WMSA的计算复杂度和图像尺寸呈线性关系。 图512局部窗口自注意力机制[10] WMSA虽然降低了计算复杂度,但是不重合的窗口之间缺乏信息交流。为了解决不同窗口的信息交互问题,于是引入移位窗口分区(shifted window partition)。在两个连续的Swin Transformer Block中交替使用WMSA和SWMSA,如图513所示。前一层Swin Transformer Block的8×8尺寸特征图划分成2×2个图像块,每个图像块的尺寸为4×4。然后将下一层Swin Transformer Block的窗口位置进行移动,得到3×3个不重合的图像块。移动窗口的划分方式使上一层相邻的不重合窗口之间引入连接,大大增加了感受野。移位窗口分区方法引入了前一层相邻非重叠窗口之间的连接,在图像分类、目标检测和语义分割上都非常有效。 SwinTransformer在各种视觉问题上表现出强大的性能,将促进视觉和语言信号的统一建模。 图513移动窗口[10] 5.4轻量化的网络 深度学习在很多任务上的效果和表现超过了传统算法,但使用深度神经网络的最终意义还是落地于实际应用。随着网络模型深度越来越大,复杂度越来越高,过于庞大的模型给部署带来了困扰,例如显存不足、实时性不够等。因此,轻量化图像分类模型也成为一个研究热点。 5.4.1MobileNet模型 基于端侧算力和存储资源受限的考量,谷歌公司在2017年提出的MobileNet[11]是一种轻量化的、专注于移动端和嵌入式设备的卷积神经网络。 MobileNet的基本结构单元是深度可分离卷积(depthwise separable convolution),其将传统的标准卷积分解为逐深度卷积(depthwise)和逐点卷积(pointwise)两个步骤。MobileNet整个网络实际上也是深度可分离模块的堆叠,这样设计的好处是可以大幅度降低参数量和计算量,但也会损失一定的准确率。在同样的模型参数和计算资源下,轻量的MobileNet准确率要超过同规模的其他网络,在移动端和嵌入式等应用场景下,使用同样的计算资源MobileNet能有更好的表现。 深度可分离卷积与标准卷积的实现过程不同,具体如图514所示。在图514(a)的标准卷积过程中,卷积核要作用于特征图的所有通道。但是对于深度可分离卷积,其由图514(b)的逐深度卷积和图514(c)的逐点卷积组合而成。首先,逐深度卷积将卷积核拆分成为单通道形式,在不改变输入特征图像的深度的情况下,对每个通道分别进行卷积操作,输出和输入特征图通道数一样的特征图。然而采用1×1卷积核的逐点卷积将逐深度卷积输出特征图进行升维和降维。通过采用这种两步式的操作,能够实现与标准卷积相近的性能,而且会极大地降低计算开销与模型的参数量。 图514MobileNet基本结构单元(深度可分离卷积)示意图[11] 为了直观地比较深度可分离卷积与标准卷积在计算量上的差异,假定用W表示特征图的宽度,H表示特征图的高度,C表示特征通道数,输入特征图的大小可表示为Win×Hin×Cin,经过卷积核大小为D×D的卷积操作后,输出特征图的大小为Wout×Hout×Cout。采用标准卷积的总计算量可以表示为 Q1=Wout×Hout×Cout×D×D×Cin(55) 当采用深度可分离卷积时,总计算量为逐深度卷积与逐点卷积的计算量之和,可以表示为 Q2=Wout×Hout×D×D×Cin+Wout×Hout×Cout×Cin (56) 标准卷积与深度可分离卷积的总计算量比值为 Q2Q1=Wout×Hout×D×D×Cin+Wout×Hout×Cout×CinWout×Hout×Cout×D×D×Cin=1Cout+1D2 (57) 从式(57)可以看出,由于Cout和D2均大于或等于1,所以深度可分离卷积的总计算量小于标准卷积。 后续也有一系列工作对MobileNet的不足进行了改进,例如MobileNet V2[12]引入了反残差模块(inverted residuals)解决了深度方向卷积时卷积核浪费的问题,并针对激活函数进行了调整,使得准确率和计算速度相比MobileNet都有较大的提升; MobileNet V3[13]改进了计算资源耗费较多的网络的输入层和输出层,并引入了通道注意力机制SE模块与神经结构搜索(NAS)来搜索最佳的网络配置与参数,其相比于MobileNet V2在准确率与计算速度上又有了进一步的提升。 5.4.2PPLCNet模型 虽然已有不少轻量型网络可以在ARM端具有非常快的推理速度,但很少有网络可以在CPU端取得快速的推理速度,尤其当启动MKLDNN加速时。2021年百度团队针对IntelCPU端加速设计了一种基于MKLDNN加速的高推理速度和高性能的模型PPLCNet[14]。PPLCNet在图像分类任务上取得了比ShuffleNetV2[15]、MobileNetV2、MobileNetV3以及GhostNet[16]更优的延迟精度均衡(如图515所示)。在其他下游任务(如目标检测、语义分割等),也同样表现优异。 图515不同模型的延迟精度对比[14] PPLCNet以MobileNetV1中的DepthSepConv作为基础模块,通过堆叠模块构建了一个类似MobileNetV1的基础网络,将基础网络与一些现有技术进行组合,从而构建了一种更强力的网络,其网络结构示意图如图516所示。 图516PPLCNet网络结构示意图[14] PPLCNet主要使用了以下几种可以提升模型性能又几乎不会造成推理延迟的方法。 (1) 使用HSwish作为激活函数,使用HSwish替换掉了MobileNet中的ReLU激活函数。该激活函数可以在推理速度不变的情况下大幅提升模型性能。 (2) 在模型尾部使用SE模块。SE模块自提出以来,被广泛应用到不同的网络架构中,例如MobileNetV3。然而,在CPU端SE模块会提升模型的推理耗时,所以,PPLCNet没有在整个网络中广泛使用它,而是将其添加到网络尾部的模块中,这种处理方式具有更好的精度速度平衡。 (3) 使用大卷积核。卷积核的尺寸通常会影响模型最终的性能,PPLCNet仅使用一个尺寸的卷积,并在低延迟和高精度情形下使用大尺度卷积核。通过实验发现,类似SE模块的位置,在网络的尾部采用5×5卷积核可以取得全部替换相近的效果。因此,PPLCNet仅在网络的尾部采用5×5的卷积 。 (4) 在全局平均池化(Global Average Pooling,GAP)层之后使用了1×1卷积层。GAP后的输出维度比较小,直接添加分类层会有相对低的性能。为提升模型的强拟合能力,PPLCNet在GAP后添加了一个1280维的1×1卷积,它仅需很小的推理延迟即可取得更强的性能。 5.5飞桨实现图像分类案例 飞桨提供了视觉领域的高层API,这些高层API包含内置数据集相关的API、数据预处理相关的API、内置模型相关的API等。本节以ResNet18分类模型为例,详细介绍如何使用飞桨高层API进行图像分类。 5.5.1环境安装与配置 本实验建议使用飞桨官方提供的 Docker 运行飞桨。如果未使用Docker,可以直接通过pip安装 PaddlePaddle,详细安装方式见4.3.1节。其他环境依赖的版本要求如下: CUDA≥10.1(如果使用 paddlepaddlegpu); CUDNN≥7.6.4(如果使用 paddlepaddlegpu); nccl≥2.1.2(如果使用分布式训练/评估); gcc≥8.2; python 3.x。 5.5.2数据准备 本实验使用的是4个类别的桃子分拣数据集,如图517所示,该数据集来自真实农业应用案例。桃农在桃子成熟后,需要将桃子按照品相分为不同类别,各类别有不同的售价。为了提升分拣效率,有厂商制作了桃子分拣机,该机器的核心部分是使用图像分类技术对传送带上的桃子进行分类; 在识别出桃子所属类别后,由机器的机械部分将桃子送入对应的收集框。 图517桃子分拣示例图像 桃子图像数据被分别存储在4个文件夹中,每个文件夹的名字对应着一类桃子,分别为R0、B1、M2、S3。每个类别下有两个文件夹,分别为训练集和测试集。训练集文件夹下: train_B1有1601张图像、train_M2有1800张图像、train_R0有1601张图像、train_S3有1635张图像。测试集文件夹下: test_B1有16张图像、test_M2有18张图像、test_R0有18张图像、test_S3有15张图像。训练和测试数据集存储在AI Studio网站的data/enhancement_data/对应的4个子文件夹下。 5.5.3模型构建 飞桨高层API可以很方便地使用内置模型,真正的一行代码实现深度学习模型调用。飞桨视觉领域的内置模型在paddle.vision.models目录下,具体包含如下模型: ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152', 'VGG', 'vgg11', 'vgg13', 'vgg16', 'vgg19', 'MobileNetV1', 'mobilenet_v1', 'MobileNetV2', 'mobilenet_v2', 'LeNet']。 因此,本实验直接调用飞桨内置的ResNet模型,具体模型的搭建过程可以参看项目链接,查看飞桨模型库中各模型的底层文件。 # 使用内置的模型,可以根据需要选择多种不同网络,这里选了resnet18网络 # pretrained (bool,可选) - 是否加载在imagenet数据集上的预训练权重 model = paddle.vision.models.resnet18(pretrained=True, num_classes=4) # 尝试不同的网络结构:MobileNetV2 # MobileNetV2参考文档:https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/models/MobileNetV2_cn.html # model = paddle.vision.models.mobilenet_v2(pretrained=True, num_classes=4) # 使用paddle.Model完成模型的封装,将网络结构组合成一个可快速使用高层API进行训练和预测 # 的类 model = paddle.Model(model) 使用model.summary可视化网络模型结构。 # 使用 summary 可视化网络模型信息 model.summary(input_size=(1, 3, 224, 224), dtype='float32') 开发者也可以按照自己的想法搭建CNN网络模型或者其他网络模型,但是这对开发者的技术水平要求很高,更多时候开发者可以使用已经成熟的、经典的网络模型,例如VGG、ResNet等。 5.5.4模型训练 用paddle.Model完成模型的封装后,在训练前,需要对模型进行配置,通过model.prepare接口来对训练进行提前的配置准备工作,包括设置模型优化器、Loss计算方法、精度计算方法等。 # 学习率衰减策略 scheduler_StepDecay = paddle.optimizer.lr.StepDecay(learning_rate=0.1, step_size=50, gamma=0.9, verbose=False) # 尝试使用学习率衰减的SGD方法 sgd = paddle.optimizer.SGD( learning_rate=scheduler_StepDecay, parameters=model.parameters()) 尝试使用固定学习率的 SGD方法 sgd = paddle.optimizer.SGD( learning_rate=0.01, parameters=model.parameters()) # 模型配置 model.prepare(optimizer= sgd,#sgd loss=paddle.nn.CrossEntropyLoss(), metrics=paddle.metric.Accuracy()) 做好模型训练的前期准备工作后,开发者正式调用fit()接口来启动训练过程,需要指定以下至少3个关键参数: 训练数据集(data)、训练轮次(epoch)和单次训练数据批次大小(batch size)。 # 启动模型训练,指定训练数据集,设置训练轮次,设置每次数据集计算批次大小,设置日志格式 # epochs:总共训练的轮数 # batch_size:一个批次的样本数量 # 如果提示内存不足,可以尝试将batch_size调低 # verbose:日志显示,0为不在标准输出流输出日志信息,1为输出进度条记录,2为每个epoch输出 # 一行记录 model.fit(train_dataset, val_dataset, epochs=1, batch_size=2, callbacks=callback, verbose=1) 训练过程比较费时,在CPU上运行10个epoch,大约需要1.5h; 在GPU上运行10个epoch,大约需要30min。 5.5.5模型预测 模型训练结束后得到了一个训练好的模型,下面需要做模型评估。将预留的测试数据放到所得到的模型中进行实际的预测,并基于标签进行校验,来看模型在测试集上的表现。 本节直接使用飞桨高层API进行模型评估,对训练好的模型进行评估操作可以使用model.evaluate接口,调用结束后会根据prepare接口配置的loss和metric来进行相关指标计算返回。 本次实验采用的评价指标是准确率(Accuracy,A)。在该实验中如果开发者进行了合理的数据增强,准确率可以达到90%。 # 模型评估 # 对于训练好的模型进行评估操作可以使用 model.evaluate 接口; 操作结束后会根据 prepare 接 # 口配置的 loss 和 metric 来进行相关指标计算返回 model.evaluate(test_dataset,verbose=1) # 模型保存 model.save('./saved_model/saved_model') 在模型被评估为效果可以接受后,就可以开始模型预测。飞桨高层API中提供了model.predict接口来方便用户对训练好的模型进行预测,开发者只需要将“预测数据+保存的模型”放到该接口进行计算即可,接口会把模型计算得到的预测结果返回。 #预测模型 results = model.predict(test_dataset) 5.6本章小结 图像分类在计算机视觉中属于基础任务,是其他任务的基础。本章首先介绍了多年来使用深度卷积神经网络做图像分类的主流技术路线,以ResNet模型、DenseNet模型、DPN模型为基于残差的网络代表。随着近年来基于注意力机制的Transformer路线和多层感知机(MLP)的发展,基于它们开发的图像分类模型ViT和SwinTransformer都取得了不错的效果。在考虑到模型云侧和端侧具体运行环境时,还对轻量级模型MobileNet和PPLCNet进行了分析介绍。最后,本章使用飞桨端到端工具 PaddleClas中的代码,以实际生活中桃子图像数据分类任务为例,完成了ResNet18模型下的图像分类案例分析。 参考文献 [1]Ng P C,Henikoff S.SIFT: Predicting amino acid changes that affect protein function[J].Nucleic acids research,2003,31(13): 38123814. [2]Dalal N,Triggs B.Histograms of oriented gradients for human detection[C]//2005 IEEE computer society conference on computer vision and pattern recognition (CVPR'05).IEEE,2005,1: 886893. [3]Ahonen T,Hadid A,Pietikinen M.Face recognition with local binary patterns[C]//European conference on computer vision.Springer,Berlin,Heidelberg,2004: 469481. [4]Tolstikhin I,Houlsby N,Kolesnikov A,et al.Mlpmixer: An allmlp architecture for vision[J].arXiv preprint arXiv:2105.01601,2021. [5]He K,Zhang X,Ren S,et al.Deep residual learning for image recognition[C]//Proceedings of the IEEE conference on computer vision and pattern recognition.2016: 770778. [6]Xie S,Girshick R,Dollár P,et al.Aggregated residual transformations for deep neural networks[C]//Proceedings of the IEEE conference on computer vision and pattern recognition.2017: 14921500. [7]Huang G,Liu Z,Van Der Maaten L,et al.Densely connected convolutional networks[C]//Proceedings of the IEEE conference on computer vision and pattern recognition.2017: 47004708. [8]Chen Y,Li J,Xiao H,et al.Dual path networks[J].arXiv preprint arXiv:1707.01629,2017. [9]Dosovitskiy A,Beyer L,Kolesnikov A,et al.An image is worth 16x16 words: Transformers for image recognition at scale[J].arXiv preprint arXiv:2010.11929,2020. [10]Liu Z,Lin Y,Cao Y,et al.Swin transformer: Hierarchical vision transformer using shifted windows[J].arXiv preprint arXiv:2103.14030,2021. [11]Howard A G,Zhu M,Chen B,et al.Mobilenets: Efficient convolutional neural networks for mobile vision applications[J].arXiv preprint arXiv:1704.04861,2017. [12]Sandler M,Howard A,Zhu M,et al.Mobilenetv2: Inverted residuals and linear bottlenecks[C]//Proceedings of the IEEE conference on computer vision and pattern recognition.2018: 45104520. [13]Howard A,Sandler M,Chu G,et al.Searching for mobilenetv3[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision.2019: 13141324. [14]Cui C,Gao T,Wei S,et al.PPLCNet: A Lightweight CPU convolutional neural network[J].arXiv preprint arXiv:2109.15099,2021. [15]Ma N,Zhang X,Zheng H T,et al.Shufflenet v2: Practical guidelines for efficient cnn architecture design[C]//Proceedings of the European conference on computer vision (ECCV).2018: 116131. [16]Han K,Wang Y,Tian Q,et al.Ghostnet: More features from cheap operations[C]//Proceedings of the IEEE/CVF conference on computer vision and pattern recognition.2020: 15801589.