# PP-LCNet系列
---

## 目录

- [摘要](#1)
- [介绍](#2)
- [方法](#3)
   - [3.1 更好的激活函数](#3.1)
   - [3.2 合适的位置添加SE模块](#3.2)
   - [3.3 合适的位置添加更大的卷积核](#3.3)
   - [3.4 GAP后使用更大的1x1卷积层](#3.4)
- [实验部分](#4)
   - [图像分类](#4.1)
   - [目标检测](#4.2)
   - [语义分割](#4.3)
- [总结](#5)
- [引用](#6)

<a name="1"></a>
## 一、摘要

在计算机视觉领域中，骨干网络的好坏直接影响到整个视觉任务的结果。在之前的一些工作中，相关的研究者普遍将FLOPs或者Params作为优化目的，但是在工业界真实落地的场景中，推理速度才是考量模型好坏的重要指标，然而，推理速度和准确性很难兼得。考虑到工业界有很多基于Intel CPU的应用，所以我们本次的工作旨在使骨干网络更好的适应Intel CPU，从而得到一个速度更快、准确率更高的轻量级骨干网络，与此同时，目标检测、语义分割等下游视觉任务的性能也同样得到提升。

<a name="2"></a>
## 二、介绍

近年来，有很多轻量级的骨干网络问世，尤其最近两年，各种NAS搜索出的网络层出不穷，这些网络要么主打FLOPs或者Params上的优势，要么主打ARM设备上的推理速度的优势，很少有网络专门针对Intel CPU做特定的优化，导致这些网络在Intel CPU端的推理速度并不是很完美。基于此，我们针对Intel CPU设备以及其加速库MKLDNN设计了特定的骨干网络PP-LCNet，比起其他的轻量级的SOTA模型，该骨干网络可以在不增加推理时间的情况下，进一步提升模型的性能，最终大幅度超越现有的SOTA模型。与其他模型的对比图如下。
<div align=center><img src="../../images/PP-LCNet/PP-LCNet-Acc.png" width="500" height="400"/></div>

<a name="3"></a>
## 三、方法

网络结构整体如下图所示。
<div align=center><img src="../../images/PP-LCNet/PP-LCNet.png" width="700" height="400"/></div>

我们经过大量的实验发现，在基于Intel CPU设备上，尤其当启用MKLDNN加速库后，很多看似不太耗时的操作反而会增加延时，比如elementwise-add操作、split-concat结构等。所以最终我们选用了结构尽可能精简、速度尽可能快的block组成我们的BaseNet（类似MobileNetV1）。基于BaseNet，我们通过实验，总结了四条几乎不增加延时但是可以提升模型精度的方法，融合这四条策略，我们组合成了PP-LCNet。下面对这四条策略一一介绍：

<a name="3.1"></a>
### 3.1 更好的激活函数

自从卷积神经网络使用了ReLU激活函数后，网络性能得到了大幅度提升，近些年ReLU激活函数的变体也相继出现，如Leaky-ReLU、P-ReLU、ELU等，2017年，谷歌大脑团队通过搜索的方式得到了swish激活函数，该激活函数在轻量级网络上表现优异，在2019年，MobileNetV3的作者将该激活函数进一步优化为H-Swish，该激活函数去除了指数运算，速度更快，网络精度几乎不受影响。我们也经过很多实验发现该激活函数在轻量级网络上有优异的表现。所以在PP-LCNet中，我们选用了该激活函数。

<a name="3.2"></a>
### 3.2 合适的位置添加SE模块

SE模块是SENet提出的一种通道注意力机制，可以有效提升模型的精度。但是在Intel CPU端，该模块同样会带来较大的延时，如何平衡精度和速度是我们要解决的一个问题。虽然在MobileNetV3等基于NAS搜索的网络中对SE模块的位置进行了搜索，但是并没有得出一般的结论，我们通过实验发现，SE模块越靠近网络的尾部对模型精度的提升越大。下表也展示了我们的一些实验结果：


| SE Location       | Top-1 Acc(\%) | Latency(ms) |
|-------------------|---------------|-------------|
| 1100000000000     | 61.73           | 2.06         |
| 0000001100000     | 62.17           | 2.03         |
| <b>0000000000011<b>     | <b>63.14<b>           | <b>2.05<b>         |
| 1111111111111     | 64.27           | 3.80         |

    
最终，PP-LCNet中的SE模块的位置选用了表格中第三行的方案。

<a name="3.3"></a>
### 3.3 合适的位置添加更大的卷积核

在MixNet的论文中，作者分析了卷积核大小对模型性能的影响，结论是在一定范围内大的卷积核可以提升模型的性能，但是超过这个范围会有损模型的性能，所以作者组合了一种split-concat范式的MixConv，这种组合虽然可以提升模型的性能，但是不利于推理。我们通过实验总结了一些更大的卷积核在不同位置的作用，类似SE模块的位置，更大的卷积核在网络的中后部作用更明显，下表展示了5x5卷积核的位置对精度的影响：

| large-kernel Location       | Top-1 Acc(\%) | Latency(ms) |
|-------------------|---------------|-------------|
| 1111111111111     | 63.22           | 2.08         |
| 1111111000000     | 62.70           | 2.07        |
| <b>0000001111111<b>     | <b>63.14<b>           | <b>2.05<b>         |


实验表明，更大的卷积核放在网络的中后部即可达到放在所有位置的精度，与此同时，获得更快的推理速度。PP-LCNet最终选用了表格中第三行的方案。
    
<a name="3.4"></a>
### 3.4 GAP后使用更大的1x1卷积层

在GoogLeNet之后，GAP（Global-Average-Pooling）后往往直接接分类层，但是在轻量级网络中，这样会导致GAP后提取的特征没有得到进一步的融合和加工。如果在此后使用一个更大的1x1卷积层（等同于FC层），GAP后的特征便不会直接经过分类层，而是先进行了融合，并将融合的特征进行分类。这样可以在不影响模型推理速度的同时大大提升准确率。
BaseNet经过以上四个方面的改进，得到了PP-LCNet。下表进一步说明了每个方案对结果的影响：

| Activation | SE-block | Large-kernel | last-1x1-conv | Top-1 Acc(\%) | Latency(ms) |
|------------|----------|--------------|---------------|---------------|-------------|
| 0       | 1       | 1               | 1                | 61.93 | 1.94 |
| 1       | 0       | 1               | 1                | 62.51 | 1.87 |
| 1       | 1       | 0               | 1                | 62.44 | 2.01 |
| 1       | 1       | 1               | 0                | 59.91 | 1.85 |
| <b>1<b>       | <b>1<b>       | <b>1<b>               | <b>1<b>                | <b>63.14<b> | <b>2.05<b> |

<a name="4"></a>
## 四、实验部分

<a name="4.1"></a>
### 4.1 图像分类

图像分类我们选用了ImageNet数据集，相比目前主流的轻量级网络，PP-LCNet在相同精度下可以获得更快的推理速度。当使用百度自研的SSLD蒸馏策略后，精度进一步提升，在Intel cpu端约5ms的推理速度下ImageNet的Top-1 Acc超过了80%。

| Model | Params(M) | FLOPs(M) | Top-1 Acc(\%) | Top-5 Acc(\%) | Latency(ms) | 
|-------|-----------|----------|---------------|---------------|-------------|
| PP-LCNet-0.25x  | 1.5 | 18  | 51.86 | 75.65 | 1.74 |
| PP-LCNet-0.35x  | 1.6 | 29  | 58.09 | 80.83 | 1.92 |
| PP-LCNet-0.5x   | 1.9 | 47  | 63.14 | 84.66 | 2.05 |
| PP-LCNet-0.75x  | 2.4 | 99  | 68.18 | 88.30 | 2.29 |
| PP-LCNet-1x     | 3.0 | 161 | 71.32 | 90.03 | 2.46 |
| PP-LCNet-1.5x   | 4.5 | 342 | 73.71 | 91.53 | 3.19 |
| PP-LCNet-2x     | 6.5 | 590 | 75.18 | 92.27 | 4.27 |
| PP-LCNet-2.5x   | 9.0 | 906 | 76.60 | 93.00 | 5.39 |
| PP-LCNet-0.5x\* | 1.9 | 47  | 66.10 | 86.46 | 2.05 |
| PP-LCNet-1.0x\* | 3.0 | 161 | 74.39 | 92.09 | 2.46 |
| PP-LCNet-2.5x\* | 9.0 | 906 | 80.82 | 95.33 | 5.39 |
    
其中\*表示使用SSLD蒸馏后的模型。

与其他轻量级网络的性能对比：

| Model | Params(M) | FLOPs(M) | Top-1 Acc(\%) | Top-5 Acc(\%) | Latency(ms) |
|-------|-----------|----------|---------------|---------------|-------------|
| MobileNetV2-0.25x  | 1.5 | 34  | 53.21 | 76.52 | 2.47 |
| MobileNetV3-small-0.35x  | 1.7 | 15  | 53.03 | 76.37 | 3.02 |
| ShuffleNetV2-0.33x  | 0.6 | 24  | 53.73 | 77.05 | 4.30 |
| <b>PP-LCNet-0.25x<b>  | <b>1.5<b> | <b>18<b>  | <b>51.86<b> | <b>75.65<b> | <b>1.74<b> |
| MobileNetV2-0.5x  | 2.0 | 99  | 65.03 | 85.72 | 2.85 |
| MobileNetV3-large-0.35x  | 2.1 | 41  | 64.32 | 85.46 | 3.68 |
| ShuffleNetV2-0.5x  | 1.4 | 43  | 60.32 | 82.26 | 4.65 |
| <b>PP-LCNet-0.5x<b>   | <b>1.9<b> | <b>47<b>  | <b>63.14<b> | <b>84.66<b> | <b>2.05<b> |
| MobileNetV1-1x  | 4.3 | 578  | 70.99 | 89.68 | 3.38 |
| MobileNetV2-1x  | 3.5 | 327  | 72.15 | 90.65 | 4.26 |
| MobileNetV3-small-1.25x  | 3.6 | 100  | 70.67 | 89.51 | 3.95 |
| <b>PP-LCNet-1x<b>     |<b> 3.0<b> | <b>161<b> | <b>71.32<b> | <b>90.03<b> | <b>2.46<b> |

<a name="4.2"></a>
### 4.2 目标检测

目标检测的方法我们选用了百度自研的PicoDet，该方法主打轻量级目标检测场景，下表展示了在COCO数据集上、backbone选用PP-LCNet与MobileNetV3的结果的比较，无论在精度还是速度上，PP-LCNet的优势都非常明显。

| Backbone | mAP(%) | Latency(ms) |
|-------|-----------|----------|
MobileNetV3-large-0.35x | 19.2 | 8.1 |
<b>PP-LCNet-0.5x<b> | <b>20.3<b> | <b>6.0<b> |
MobileNetV3-large-0.75x | 25.8 | 11.1 |
<b>PP-LCNet-1x<b> | <b>26.9<b> | <b>7.9<b> | 

<a name="4.3"></a>
### 4.3 语义分割

语义分割的方法我们选用了DeeplabV3+，下表展示了在Cityscapes数据集上、backbone选用PP-LCNet与MobileNetV3的比较，在精度和速度方面，PP-LCNet的优势同样明显。

| Backbone | mIoU(%) | Latency(ms) |
|-------|-----------|----------|
MobileNetV3-large-0.5x | 55.42 | 135 |
<b>PP-LCNet-0.5x<b> | <b>58.36<b> | <b>82<b> |
MobileNetV3-large-0.75x | 64.53 | 151 |
<b>PP-LCNet-1x<b> | <b>66.03<b> | <b>96<b> |

<a name="5"></a>
## 五、总结

PP-LCNet没有像学术界那样死扣极致的FLOPs与Params，而是着眼于分析如何添加对Intel CPU友好的模块来提升模型的性能，这样可以更好的平衡准确率和推理时间，其中的实验结论也很适合其他网络结构设计的研究者，同时也为NAS搜索研究者提供了更小的搜索空间和一般结论。最终的PP-LCNet在产业界也可以更好的落地和应用。

<a name="6"></a>
## 六、引用

如果你的论文用到了PP-LCNet的方法，请添加如下cite：
```
@misc{cui2021pplcnet,
      title={PP-LCNet: A Lightweight CPU Convolutional Neural Network}, 
      author={Cheng Cui and Tingquan Gao and Shengyu Wei and Yuning Du and Ruoyu Guo and Shuilong Dong and Bin Lu and Ying Zhou and Xueying Lv and Qiwen Liu and Xiaoguang Hu and Dianhai Yu and Yanjun Ma},
      year={2021},
      eprint={2109.15099},
      archivePrefix={arXiv},
      primaryClass={cs.CV}
}
```
