黄靖淞,左颢睿,张建林
(1.中国科学院光电技术研究所,成都 610209;2.中国科学院大学 计算机学院,北京 100049)
近年来,卷积神经网络被广泛地应用到计算机视觉、自然语言处理等领域,各种新的检测算法被不断提出,然而设计的深度学习模型多数是为了追求更高的精度[1]和更好的性能,而忽略了模型的大小和推理速度。
在目标检测领域,REDMON 等提出了YOLOv1[2]、YOLOv2[3]、YOLOv3[4]系列算法。因其在速度和精度之间实现了较好的权衡,而引起了学术界和工业界的广泛关注。以Faster R-CNN[5]为代表的双阶段网络先生成候选区域,再提取特定的特征进行目标检测,虽然精度较高,但计算复杂度也很高,难以在有限算力的情况下实现实时检测。以YOLO 为代表的单阶段目标检测算法将生成候选区和检测合二为一,直接得到最终的检测结果,使得网络结构变得简单,检测速度较Faster R-CNN 有近10 倍的提升,这使得深度学习目标检测算法满足实时检测条件成为可能。
MobileNet 是由谷歌在2017 年提出的,是一款专注于在移动设备和嵌入式设备上的轻量级卷积神经网络,并逐步发展为MobileNetv1[6]、MobileNetv2[7]、MobileNetv3[8]3 个版本。相比于传统的卷积神经网络,在准确率小幅降低的前提下,大幅减小了模型参数和运算量,其中最重要的创新是提出了深度可分离卷积,用深度可分离卷积替换标准卷积可以减少计算量和参数量,提升前向推理速度。
另外,网络剪枝也是网络压缩和加速中一个重要的方向,剪枝就是去除网络中一些不重要的神经元,大幅降低了计算量和权重数量,提高了网络运行效率[9]。目前剪枝主要分权重剪枝和滤波器剪枝两种。滤波器剪枝相对于权重剪枝具有一系列优点,包括它可以得到规则的模型、减少内存消耗、加速网络推理等。
本文在YOLOv3 目标检测算法的基础上,使用轻量级的Mobilenet 基础网络,将深度可分离卷积替换为标准卷积,并在此基础上对网络进行剪枝,以在不损失检测精度的情况下提升检测速度。
YOLOv3 网络以Darknet53 网络为backbone,因其有52 个卷积层外加1 个全连接层,所以命名为Darknet53。其中卷积层是由1×1 和3×3 的卷积层组成,每个卷积层后都会有1 个BN 层和1 个LeakyReLU 层。YOLOv3 主体是由许多残差结构[10]组成,减少了梯度爆炸的风险,加强了网络的学习能力,Concatenate 层用于将当前层的多个输入进行拼接,UpSample 层表示上采样,每进行一次上采样操作,输出特征层就扩大1 倍。YOLOv3 预测的3 个特征层大小由浅到深分别是输入特征图的1/32、1/16、1/8,对3 个不同尺度的特征图进行检测,因而实现了多尺度检测[11]。另外由于浅层网络提取到的边缘、纹理等几何特征较多,感受野较小,对小目标敏感,而深层网络提取到的语义信息较多,感受野较大,对大目标敏感,所以浅层输出适合检测小型目标,中层输出适合检测中型目标,最深层输出适合检测大型目标。每个预测的输出可以表示为S×S×3×(5+类别数)。YOLO 将图像划分为S×S的网格,当目标中心落在某个网格中时,即用该网格去检测,另外每个网格需要检测3 个尺度的anchorbox,5 表示的是(x,y,w,h)以及置信度5 种位置信息。最后3 个输出经过非极大抑制[12]得到最终的坐标信息和类别的预测值。YOLOv3 算法网络结构如图1 所示。
图1 YOLOv3 算法网络结构Fig.1 Network structure of YOLOv3 algorithm
本文借鉴了Mobilenetv1 网络深度可分离卷积的思想[13],将YOLOv3 的backbone 由Darknet53 替换为Mobilenetv1,并将YOLO head 网络中的部分3×3标准卷积替换为深度可分离卷积,深度可分离卷积包括深度卷积和逐点卷积两部分[14],其在尽量提取特征的同时减少了计算量。标准卷积和深度可分离卷积的结构如图2 所示。
图2 标准卷积和深度可分离卷积结构Fig.2 Structure of standard convolution and depthwise separable convolution
假设输入的特征图大小为Wi×Hi×C,分别代表输入特征图的宽、高、通道数,标准卷积大小为Wc×Hc×C×N,分别代表标准卷积的宽、高、通道数、滤波器个数,输出特征图大小为Wo×Ho×N。那么标准卷积的计算量如下:
相应的深度可分离卷积是用Wc×Hc×1×C(分别表示宽、高、通道数、组数)的卷积先进行逐通道卷积,再用1×1×C×N的卷积进行逐点卷积,其计算量如下:
两者之比为:
Amount(dw)/Amount(Conv)=1/N+1/(Wc×Hc)
若输入3×608×608 的特征图,经过256×3×3×3的卷积核,那么计算量的比值为1/256+1/(3×3),也就是说将标准卷积替换为深度可分离卷积后,计算量会减少8~9 倍。
基础网络Mobilenetv1 输入为1×3×608×608 的图片,网络参数如表1 所示。网络包括1 层标准卷积,后面接13 层深度可分离卷积,每1 层卷积后都跟1 个Batch_norm 层 和Relu 层。其中,Conv3_2、Conv4_2、Conv6 层深度可分离卷积的3 个输出分别作为YOLO_head 网络部分的3 个输入,另外YOLO_head 网络中只包含1×1 和3×3 的卷积,将其中部分3×3 卷积也改为深度可分离卷积。表1 是Mobilenetv1 的网络结构。
表1 Mobilnetv1 网络结构Table 1 Structure of Mobilenetv1 network
网络剪枝的目的是减掉对检测结果贡献不大的网络层,以提升前向推理的速度[15],由于大量的运算量都在卷积层部分,因此本文主要讨论对卷积层滤波器个数的剪枝,对于某一层卷积层,对其所有filter进行重要性排序,将排在后面不重要的filter减掉,这样能在减少整体运算量的同时,对检测精度没有太大影响。
对滤波器重要性排序的方法如下:
1)以filter 非零权重值的个数为基准进行排序,即权重L0 范数[16]。
2)对filter 每个权重值求绝对值之和进行排序,即权重L1 范数[17]。
3)基于几何中心的卷积核剪枝方法FPGM[18]。
L0范数以当前卷积层的每个滤波器矩阵非零元素个数为排序依据,非零元素个数越多就越重要,对检测结果的贡献也越大。L1范数以当前卷积层的每个滤波器矩阵元素绝对值之和为排序依据,绝对值之和越大,该滤波器就越重要。文献[18]提出了基于几何中心的滤波器评价指标FPGM(Filter Pruning via Geometric Median),认为很多方法都是基于“较小范数不重要”的准则进行剪枝,其有效性依赖于2个要求:卷积核的范数值分布偏差必须大,即方差大;卷积核中的最小范数必须足够小。为解决在不满足上述2个要求的情况下也能压缩网络,该方法的思想是计算每个filter与其他所有filter的欧式距离之和作为得分,得分越低表示该滤波器信息跟其他滤波器重合度越高,可以用其他滤波器替代该滤波器。
本文依据L1 范数对滤波器进行重要性排序,只对YOLO_head 网络进行剪枝,保持基础网络Mobilenetv1的完整性。剪枝率取0.1~0.9、步长为0.1 的一系列剪枝比率,然后对所需要剪的每一层卷积层按不同剪枝率进行剪枝,分析不同剪枝情况下检测精度的损失情况,并绘制敏感度曲线。卷积层敏感度曲线如图3 所示,如果曲线上升很快,则表示当前卷积层比较敏感,如果剪枝率过大会有较大的精度损失,否则如果曲线上升平缓,则表示该卷积层对检测结果的贡献不大,可以采用较大的剪枝率。据此对于给定的可接受的精度损失来确定每个层的剪枝率。
图3 卷积层敏感度曲线Fig.3 Sensitivity curve of convolution layer
从图3 可以看出,某些卷积层比如yolo_block.0.0.1_sep_weights、yolo_block.0.1.1_sep_weights、yolo_block.0.tip_sep_weights等层上升曲线很快,对检测结果的贡献很大,所以只剪很少比例的filter数目,而对于例如yolo_block.2.1.1_sep_weights、yolo_block.2.2.conv.weights、yolo_block.2.tip_sep_weights等层,当剪枝率达到0.9 时也几乎不丢失精度,本文实验以剪枝率0.7 作为剪枝上限。
对于标准卷积(Conv)和逐点卷积(sep),给定剪枝率后,其filter 的个数会相应减少,而深度卷积(dw)的组数等于输入特征图的通道数,所以不需给出剪枝率,其组数会随上一层卷积层滤波器的个数而变化。表2 是剪枝前后YOLO_head 的网络结构。
表2 剪枝前后YOLO_head 网络结构Table 2 YOLO_head network structure before and after pruning
本文实验训练平台是远程云端GPU Tesla V100,显存16 GB,推理部署平台是英伟达嵌入式GPU Jetson TX2,该平台拥有256 颗Pascal 架构CUDA 核心,6 颗CPU 核心[19-20]。所用训练集和测试集来自VOC2007、VOC2012,模型的评估指标mAP。所使用深度学习框架为百度飞桨Paddle[21]框架、PaddleSlim 压缩框架以及Paddle Inference C++推理预测库,并用CMake 管理项目文件,CMake全称为Cross platform Make,是一个跨平台的构建系统,可以编写一个与平台无关的CMakeLists.txt 文件定制整个编译流程,然后再进一步生成所需的Makefile 和工程文件[22]。使用pycharm 作为python 集成开发环境,clion 作为C++开发环境。
在进行训练时,与预训练模型相匹配的层直接加载该部分网络的参数,不匹配的部分则读取程序中定义的网络结构。训练的最大batch 数设置为28 万,batch_size 为16,初始学习率为0.000 5,在batch 数为11 万和12.4 万的地方学习率变为之前的0.1 倍。
表3 是在Tesla V100 显卡上进行测试的结果,可以看出在YOLOv3_MobileNetV1 网络基础上,将YOLO_head 网络部分卷积改为深度可分离卷积之后再进行剪枝,在几乎不损失精度的前提下,使得FPS 分别提升了25.9%和40.8%。实验结果表明:单纯增大batch_size 后速度并不一定会比减小batch_size 快,并且GPU 利用率也会明显增加,这可能跟CPU 与GPU 之间的数据传输、硬盘的读写速度等因素有关。
表3 Tesla V100 测试结果Table 3 Test results of Tesla V100
如果将训练好的模型用到实际工程中,需要在一些嵌入式硬件平台进行部署,以达到项目落地的效果。将训练好的模型导出为推理模型,并在嵌入式GPU TX2 平台以C++进行前向推理,并用CMake管理头文件和库文件。除Paddle 本身的依赖库之外,还用到了第三方开源库gflags,gflags 是Google的一个命令行参数处理的开源库,用于将命令行参数传入到程序中,另外还有yaml-cpp 开源库,用于对yaml 文件的读取,两者也都是用CMake 来进行构建和编译的。在TX2 上的部署流程如图4 所示,首先通过命令行判断读取磁盘图片或者板载摄像头读取视频帧,然后进行目标检测,最后将检测结果进行显示,并不断重复。
图4 TX2 推理流程Fig.4 TX2 inferential procedure
表4 是在嵌入式GPU TX2 平台上的测试结果,计算4 952 张VOC 测试数据集的网络前向推理帧率。YOLOv3_MobileNetV1 的帧率是5.0 frame/s,将YOLO_head 网络中部分卷积层改为深度可分离卷积后的帧率为9.6 frame/s,在此基础上进行剪枝后帧率达到了12.0 frame/s,分别实现了1.92 倍和2.4 的加速,模型规模分别减小了67.9%和78.5%,有效提升了嵌入式设备上目标检测的推理速度。这是在尽可能不丢失精度的前提下的实验结果,如果实际情况对速度有更高的要求,则还可以提高剪枝率,进一步加速前向推理。
表4 TX2 测试结果Table 4 TX2 test results
本文在YOLOv3 目标检测算法的基础上,采用轻量级的Mobilenet 分类网络作为backbone,并将深度可分离卷积替换YOLO_head 网络部分标准卷积,在此基础上通过L1 范数对卷积层filter 打分,并以此作为排序依据对网络做剪枝。测试结果表明,改进算法在检测精度丢失很少的前提下,较大地提高了算法的检测速度,并实现了算法在嵌入式平台上的部署。由于该算法具有通用性,下一步将研究算法在其他不同平台的部署,以实现诸如手机移动端等硬件平台的目标检测。