# PP-LCNet 系列
---

## 目录

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

<a name="1"></a>

## 1. 摘要

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

<a name="2"></a>
## 2. 介绍

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

<a name="3"></a>
## 3. 方法

网络结构整体如下图所示。
![](../../images/PP-LCNet/PP-LCNet.png)
我们经过大量的实验发现，在基于 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>
## 4. 实验部分

<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>

## 5. 基于 V100 GPU 的预测速度

| Models        | Crop Size | Resize Short Size | FP32<br>Batch Size=1<br>(ms) | FP32<br/>Batch Size=1\4<br/>(ms) | FP32<br/>Batch Size=8<br/>(ms) |
| ------------- | --------- | ----------------- | ---------------------------- | -------------------------------- | ------------------------------ |
| PPLCNet_x0_25 | 224       | 256               | 0.72                         | 1.17                             | 1.71                           |
| PPLCNet_x0_35 | 224       | 256               | 0.69                         | 1.21                             | 1.82                           |
| PPLCNet_x0_5  | 224       | 256               | 0.70                         | 1.32                             | 1.94                           |
| PPLCNet_x0_75 | 224       | 256               | 0.71                         | 1.49                             | 2.19                           |
| PPLCNet_x1_0  | 224       | 256               | 0.73                         | 1.64                             | 2.53                           |
| PPLCNet_x1_5  | 224       | 256               | 0.82                         | 2.06                             | 3.12                           |
| PPLCNet_x2_0  | 224       | 256               | 0.94                         | 2.58                             | 4.08                           |

<a name="6"></a>

## 6. 基于 SD855 的预测速度

| Models        | SD855 time(ms)<br>bs=1, thread=1 | SD855 time(ms)<br/>bs=1, thread=2 | SD855 time(ms)<br/>bs=1, thread=4 |
| ------------- | -------------------------------- | --------------------------------- | --------------------------------- |
| PPLCNet_x0_25 | 2.30                             | 1.62                              | 1.32                              |
| PPLCNet_x0_35 | 3.15                             | 2.11                              | 1.64                              |
| PPLCNet_x0_5  | 4.27                             | 2.73                              | 1.92                              |
| PPLCNet_x0_75 | 7.38                             | 4.51                              | 2.91                              |
| PPLCNet_x1_0  | 10.78                            | 6.49                              | 3.98                              |
| PPLCNet_x1_5  | 20.55                            | 12.26                             | 7.54                              |
| PPLCNet_x2_0  | 33.79                            | 20.17                             | 12.10                             |
| PPLCNet_x2_5  | 49.89                            | 29.60                             | 17.82                             |

<a name="7"></a>

## 7. 总结

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

<a name="8"></a>

## 8. 引用

如果你的论文用到了 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}
}
```
