张 良,张 增 ,舒伟华,梅魁志
1.武汉数字工程研究所,武汉 430074
2.西安交通大学 电子与信息工程学部,西安 710049
3.中国航发南方工业有限公司,湖南 株洲 412002
卷积神经网络是深度学习[1]中重要的算法,在模式识别、图像处理、自动控制和智能机器人等方面有着广泛的应用。随着研究中对精度、数据集要求提高,卷积神经网络的网络层数、计算复杂度也随之增加。
目前,卷积神经网络主要在GPU(Graphics Processing Unit)或高性能 CPU(Central Processing Unit)上面运行,可以达到很流畅的运行效果,但是在各类移动设备、嵌入式设备中,会面临功耗、体积、计算速度等限制。如何在保证卷积神经网络精度不下降的情况下,降低网络计算量,削减网络模型存储空间,使之能在资源受限的设备上高效运行是亟需解决的问题。本文中提出的结构化剪枝就是一种对卷积神经网络压缩和优化的方法。网络剪枝能够通过去除模型中的部分连接加速卷积神经网络。剪枝的主要步骤是:训练原始网络,更新网络中各个参数的权值;对网络中权重较低的参数进行修剪;重新训练网络,恢复神经网络精度[2]。
剪枝可以分为结构化剪枝和非结构化剪枝两类。结构化剪枝相对非结构化剪枝的最明显特点是它产生的稀疏矩阵是有规则的,剪枝后网络加速需要的运算量更少[3]。
结构化剪枝按照剪枝依据可分为基于重要性和基于正则化的剪枝方法,本文采用的是基于重要性的剪枝方法[4]。结构化剪枝按照被剪枝单元可分为向量级、核级[5]、组级和通道级剪枝[6]四种。本文选择的是卷积核级的结构化剪枝方案。
对YOLOv3模型的研究很多,在汲取其中精华思想后[7-10],本文对YOLOv3[11-12]结构化剪枝的方法是:单层一种卷积过滤器,设计公式计算每层重要性得分,并给出了一种可靠简易的稀疏值分配策略,更快速、准确地给每层分配合适的稀疏值以及卷积过滤器。
结构化剪枝是在牺牲极限压缩率的前提下,用以弥补非结构化剪枝在硬件实现、在线推理内存访问效率不高的缺陷。
将7×7的卷积核剪枝成5×7或更小的卷积核,对应到参数矩阵,即删掉若干行。虽然输入矩阵的列数需要减少,但是这样剪枝并没有改变通道个数,不仅有着绝对的压缩效果,而且在进行im2col[13](重排图像块为矩阵列)操作(修改步长等参数)后,对输入特征图和输出矩阵没有任何影响。
对YOLOv3卷积层参数压缩方法研究与设计如图1所示,中间部分为模型结构化剪枝的主流程,左边虚线框内为计算层重要性得分的具体过程,右边虚线框内为稀疏值配置的具体过程。通过对模型的权值参数计算得到每个可结构化剪枝卷积层的重要性得分,根据重要性得分以及稀疏值分配策略,给每个可结构化剪枝的卷积层匹配合适的稀疏值并选择适当的卷积过滤器。在结构化剪枝压缩优化之后,还能加入定点化压缩优化过程,定点化压缩优化效果需要在合适的硬件平台上才能得到更好的展示。
ANWAR 等人[14]在论文中使用N个卷积过滤器对相应的N个输入数据矩阵进行的剪枝操作如图2[14]所示。这种剪枝操作因为每层有多种卷积算子,导致剪枝过程非常耗时,故本文只使用很小的验证数据集,用于卷积层单元打分,测试算法的性能。
在此基础上进行的主要改进是:每层只使用一种单元过滤器;通过对各层重要性评估来决定每层使用的单元过滤器,而不需要耗时的训练;改进每个卷积对于整个网络结构重要性公式。
本文结构化剪枝原理如图3 所示。对于每一层只使用一种卷积过滤器,对于一张输入数据矩阵,因为每一层只使用一种卷积过滤器,所以经过im2col操作选取的数据区域也是完全一样的。根据卷积运算原理可知,上一层的输出矩阵(即该层的输入矩阵),需要与多组卷积核进行卷积计算,每一个输入数据矩阵只需要经过一次比原始矩阵小的im2col 变化,就能反复地被其他的卷积核利用,这样做可以节省大量的存储资源和运算资源。
接下来需要解决的问题为:确定符合结构化剪枝的卷积过滤器;确定待剪枝卷积层相应的卷积过滤器;确定合适的模型调整策略,保证模型性能不变的同时得到最大模型压缩效果。
图1 YOLOv3模型结构化剪枝流程图
图2 Anwar等人卷积核级别结构化剪枝示意图
图3 本文结构化剪枝原理示意图
通过前面对YOLOv3 模型网络结构的研究发现,YOLOv3 模型的卷积层只有3×3 和1×1 两种尺寸(当前模型优化趋势,且类似5×5、7×7等大卷积核可以优化为由多个3×3卷积核替代)。由于1×1尺寸的卷积层的权值参数相对较少并且不适合本文的结构化剪枝方法,于是只对3×3的卷积层进行剪枝压缩操作,后续可以做相关实验评估1×1 层卷积核参数对YOLOv3 整个网络性能的影响。
为了制作3×3 卷积算子结构化剪枝所需单元过滤器,引入三个参数:Kp_stride 为剪枝(或保留)步长,Kp_offset=i为剪去的第一个值的位置编号为i,Kp_keepset=j为保留的第一个值的位置编号为j。0~8 为3×3 卷积算子9 个数据的编号。如图2 所示,原始卷积核的参数为1~9,剪枝后用0代替,现在列举几组不同参数的卷积算子剪枝情况。
枚举出四种离散的结构规范的卷积过滤器如图4~图7 所示。每种稀疏值有一种或者多种不同的卷积过滤器形状,其中“1”表示保留卷积核算子的相应位置数值,“0”表示剪枝掉卷积核算子的相应位置数值。当确定一个卷积层的稀疏值后,可以选择该稀疏值中任何一种卷积过滤器形状,然后对网络中的3×3的卷积核进行规则的结构化剪枝操作。
图4 稀疏值为1/3(0.33)
图5 稀疏值为4/9(0.44)
图6 稀疏值为5/9(0.56)
图7 稀疏值为2/3(0.67)
卷积神经网络的实现需要依托深度学习框架。本文中采用的深度学习框架是Caffe[15],它是一个简约高效、应用广泛的开源深度学习框架。
前期使用自制小数据集进行了相关测试,实验结果表现良好。为了理论的证实更加科学,这里使用的数据集是Pascal VOC 2012 数据集(http://host.robots.ox.ac.uk/pascal/VOC),训练集包括11 540张图片,测试集包括4 952 张图片(VOC 2007 数据集测试集部分)。训练集与测试集的图片数量比例为1∶2,属于规范数据集。
本文对 YOLOv3 中卷积算子尺寸为 3×3 的 38 个卷积层进行结构化剪枝。同时对多个卷积层进行结构化剪枝,最大的问题在于如何分配每层的稀疏值。改进Liu等人[16]提出的冗余度度量公式(1)用于实验。
第l层的第n个卷积核Sl(n) 的稀疏性公式如公式(2)所示:
式中,Ml为所有卷积核权值绝对值的平均值;l为指定层序号;kl,nchw为卷积核权值;N为输入通道数;C为输出通道数;H、W为卷积核的高和宽;Sl(n)为卷积核稀疏性;n,c,h,w为正整数且n∈[1,N],c∈[1,C],h∈[1,H],w∈[1,W]。
简而言之,如果卷积核有几个系数小于该层的平均值,则Sl(n)接近1,这意味着该卷积核比其他卷积核的参数更冗余。
借鉴公式(1)与(2)的思路,提出层重要性得分Ml*(即在全局网络中贡献度),计算方法如公式(3):
对YOLOv3的38个待剪枝卷积层进行重要度定量评估,并通过每层的分配各层的稀疏率。将38个层的Ml*累加得到,每个层在全局网络中重要性程度为,具体分布情况如图8所示。
对各层稀疏值的分配,遵循重要度和稀疏值成正相关(即重要性越大,分配的稀疏值越大),并且对重要度不同的层分配具有梯度的稀疏值,为了简化实验步骤,拟将相近重要度卷积层分配相同的稀疏值。
图8 38个可剪枝层重要度全局网络占比情况
根据图9所示的稀疏值分配与调整策略对YOLOv3的38个可结构化剪枝的卷积层进行合理的稀疏值分配与调整。
图9 稀疏值分配与调整策略示意图
图8 的纵坐标为单层重要性程度Dl,按照从小到大对Dl进行排序,根据Dl最大、最小值进行等间距区间分段,遵循每一个区段使用一种稀疏值,区间数量需要通过观察Dl数据规律结合经验给出,保证总段数不超过层总数的一半,尽量区分开各卷积层。每改变一次稀疏值进行一次再训练操作,若模型性能保持良好,继续增大稀疏值,直至模型性能有较大的损失,用此次试验上一次的稀疏值为最终值。
模型性能的评价标准为准确率或者目标识别网络中的mAP 值;若保持准确率或者mAP 值不下降则为模型性能保持良好,若下降超过预设阈值则表示模型性能有较大的损失。然后,在前面基础上对下一个重要性得分区间的卷积层重复上述工作,直至完成对最后一个区间的卷积层稀疏值配置工作,得到全可剪枝卷积层的稀疏值初始配置。
最后,可以修改少数卷积层的稀疏值进行再训练微调,得到最终稀疏值配置;以上步骤按重要性同时将一个或者几个卷积层稀疏值设置为相同的值,导致靠近重要性区段两端的卷积层稀疏值分配准确度不高,需要对这些靠近重要性区段两端的一些卷积层进行如下微调:数值小的一端稀疏值变大、数值大的一端稀疏值变小,遵循改变一次立即进行再训练操作,比较模型性能前后的变化,得到最终全可剪枝卷积层的稀疏值配置,模型性能的评判依据准确率或者目标识别中的mAP值。
YOLOv3 模型各层重要性得分、全局占比、层参数量等参数如表1所示。
表1 YOLOv3模型Mj 值、全局占比及层参数量
依据重要性得分公式(3)计算出每个可结构化剪枝卷积层的得分Mj值,然后将38个层的重要性累加得到;每个层重要性全局占比为最后根据稀疏值配置策略,得到了全部38 层卷积层结构化剪枝的三个参数 kp_stride、kp_offset、kp_keepset。除去第一层重要性得分过大不做结构化剪枝操作,其他37个层都分配了合适的稀疏值以及选择适当的卷积过滤器。
最终调试完成后确定的各层稀疏值,以及个卷积层结构化剪枝使用的卷积过滤器的3 个参数kp_stride、kp_offset、kp_keepset如表2所示。
表2 每层稀疏率及卷积过滤器参数
表2 中的 1~80、88~92、100~104 与表1 中的层相对应,包含上下界限;stride、offset、keepset即为卷积层结构化剪枝的三个参数kp_stride、kp_offset、kp_keepset。
根据表1 中对每个可结构化剪枝卷积层的参数设置,进行了结构化剪枝压缩训练,并测得相应的mAP值,整理如表3所示。
表3 结构化剪枝前后mAP及模型文件大小比较
从表3 中可以得到剪枝后的模型mAP 值下降了0.054 45 左右(与原始模型相比,mAP 值下降5.5%),虽然模型精度在数值上下降了,但是模型对目标物体的识别实际情况没有影响。随机抽取图像进行目标物体检测,并将剪枝前后的模型对图像中物体的识别框标注情况以及识别的概率值进行比较。随机选取三张图片对比结构化剪枝前后目标识别概率,如图10~图12所示。
图10 结构化剪枝目标检测对比结果一
图11 结构化剪枝目标检测对比结果二
图12 结构化剪枝目标检测对比结果三
图10 中,3 个比较完整的目标 person1、person2、horse1 在剪枝后识别概率值仍为100%,不完整且比较靠后的目标Person3、Person4、Horse2、Horse3 剪枝后识别概率有少许下降,但是对物体的识别准确率(top-1)没有变化,图中每个目标都可以被准确无误的识别,对于实验结论不会产生影响。通过观察,剪枝前后,识别框无明显差别(数量与位置,说明识别概率较高),并且识别准确率无明显下降。
目前算法更加注重于理论的建立,新方法的提出;本文只对3×3的算子进行结构化剪枝,下一步会在其他卷积神经网络模型中对其他诸如7×7、5×5 的卷积核进行结构化剪枝,使得算法在识别所有目标时都能达到更高的识别概率,并在实际的工程应用中有更好的表现。
从这三幅图的测试对比结果可以看出,剪枝前后的模型都能检测出所有物体,只是剪枝后模型在物体分类识别准确率方面要稍逊于剪枝前模型。
接下来,从计算资源使用角度对结构化剪枝后的YOLOv3模型进行评估,使用的模型为YOLOv3-416模型;参考数值为YOLOv3官方网站的数据。
使用FLOPS(Floating-point Operations Per Second,每秒浮点运算次数)来评估YOLOv3 运算资源占用情况。FLOPS 的计算方法为:假设有m×k的矩阵A和k×n的矩阵B相乘,最终得到m×n的矩阵C,总的运算量为m×k×n次乘加,将一次乘加看成两次运算,则最终需要2×m×k×n次运算。
根据表1、依据重要性得分公式(3)计算出每个可结构化剪枝卷积层的得分Mj值,然后将38 个层的重要性累加得到;每个层重要性全局占比为Dl=,最后根据稀疏值配置策略,得到了全部38层卷积层结构化剪枝的3个参数kp_stride、kp_offset、kp_keepset。除去第一层重要性得分过大不做结构化剪枝操作,其他37 个层都分配了合适的稀疏值以及选择适当的卷积过滤器。
最终调试完成后确定的各层稀疏值,以及个卷积层结构化剪枝使用的卷积过滤器的3 个参数kp_stride、kp_offset、kp_keepset 如表2 所示。表中的输入、输出数据以及卷积过滤器信息结合图4、图5、图6、图7卷积过滤器结构,可以得到卷积运算过程中im2col操作后得到的矩阵相关长宽信息,继而使用上述的计算方法得到剪枝后YOLOv3 模型预测一次需要的总浮点运算量,如表4所示。
表4 YOLOv3预测一次总浮点运算量
可以得到剪枝后,模型预测一次需要的总浮点运算量减少了46%左右,再加上接下来全部卷积层定点化压缩优化操作,理论上经过本文压缩优化后的YOLOv3模型在硬件上平台上能获得非常高效的性能。
在Darknet上实现YOLOv3卷积层结构化剪枝的参数压缩方法。通过单层剪枝实验得到的YOLOv3 模型参数具有冗余性,根据YOLOv3 具有卷积层多、卷积核尺寸大小单一等特点,提出了一种针对卷积层每层只使用一种卷积过滤器的结构化剪枝方法。设计评估卷积层相对整个网络重要性的公式,计算得分并排序,然后对卷积层分配稀疏值以及卷积过滤器,最后在结构化剪枝的基础上增加定点化操作,使得模型能在硬件平台上稳定运行。