提交 0fa1fd71 编写于 作者: S sibo2rr 提交者: gaotingquan

add menue to documentations

上级 2d335119
# 数据增强分类实战 # 数据增强分类实战
--- ---
本节将基于ImageNet-1K的数据集详细介绍数据增强实验,如果想快速体验此方法,可以参考[**30分钟玩转PaddleClas(进阶版)**](../quick_start/quick_start_classification_professional.md)中基于CIFAR100的数据增强实验。如果想了解相关算法的内容,请参考[数据增强算法介绍](../algorithm_introduction/DataAugmentation.md) 本节将基于 ImageNet-1K 的数据集详细介绍数据增强实验,如果想快速体验此方法,可以参考 [**30分钟玩转PaddleClas(进阶版)**](../quick_start/quick_start_classification_professional.md)中基于 CIFAR100 的数据增强实验。如果想了解相关算法的内容,请参考[数据增强算法介绍](../algorithm_introduction/DataAugmentation.md)
## 目录 ## 目录
- [参数配置](#1) - [1. 参数配置](#1)
- [1.1 AutoAugment](#1.1) - [1.1 AutoAugment](#1.1)
- [1.2 RandAugment](#1.2) - [1.2 RandAugment](#1.2)
- [1.3 TimmAutoAugment](#1.3) - [1.3 TimmAutoAugment](#1.3)
...@@ -16,22 +16,22 @@ ...@@ -16,22 +16,22 @@
- [1.7 GridMask](#1.7) - [1.7 GridMask](#1.7)
- [1.8 Mixup](#1.8) - [1.8 Mixup](#1.8)
- [1.9 Cutmix](#1.9) - [1.9 Cutmix](#1.9)
- [1.10 Mixup与Cutmix同时使用](#1.10) - [1.10 Mixup 与 Cutmix 同时使用](#1.10)
- [启动命令](#2) - [2. 启动命令](#2)
- [注意事项](#3) - [3. 注意事项](#3)
- [实验结果](#4) - [4. 实验结果](#4)
<a name="1"></a> <a name="1"></a>
## 一、参数配置 ## 1. 参数配置
由于不同的数据增强方式含有不同的超参数,为了便于理解和使用,我们在`configs/DataAugment`里分别列举了8种训练ResNet50的数据增强方式的参数配置文件,用户可以在`tools/run.sh`里直接替换配置文件的路径即可使用。此处分别挑选了图像变换、图像裁剪、图像混叠中的一个示例展示,其他参数配置用户可以自查配置文件。 由于不同的数据增强方式含有不同的超参数,为了便于理解和使用,我们在 `configs/DataAugment` 里分别列举了 8 种训练 ResNet50 的数据增强方式的参数配置文件,用户可以在 `tools/run.sh` 里直接替换配置文件的路径即可使用。此处分别挑选了图像变换、图像裁剪、图像混叠中的一个示例展示,其他参数配置用户可以自查配置文件。
<a name="1.1"></a> <a name="1.1"></a>
### 1.1 AutoAugment ### 1.1 AutoAugment
`AotoAugment`的图像增广方式的配置如下。`AutoAugment`是在uint8的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`之前。 `AotoAugment` 的图像增广方式的配置如下。`AutoAugment` 是在 uint8 的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`)之前。
```yaml ```yaml
transform_ops: transform_ops:
- DecodeImage: - DecodeImage:
to_rgb: True to_rgb: True
...@@ -51,9 +51,9 @@ ...@@ -51,9 +51,9 @@
<a name="1.2"></a> <a name="1.2"></a>
### 1.2 RandAugment ### 1.2 RandAugment
`RandAugment`的图像增广方式的配置如下,其中用户需要指定其中的参数`num_layers``magnitude`,默认的数值分别是`2``5``RandAugment`是在uint8的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`之前。 `RandAugment` 的图像增广方式的配置如下,其中用户需要指定其中的参数 `num_layers``magnitude`,默认的数值分别是 `2``5``RandAugment` 是在 uint8 的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`)之前。
```yaml ```yaml
transform_ops: transform_ops:
- DecodeImage: - DecodeImage:
to_rgb: True to_rgb: True
...@@ -75,9 +75,9 @@ ...@@ -75,9 +75,9 @@
<a name="1.3"></a> <a name="1.3"></a>
### 1.3 TimmAutoAugment ### 1.3 TimmAutoAugment
`TimmAutoAugment`的图像增广方式的配置如下,其中用户需要指定其中的参数`config_str``interpolation``img_size`,默认的数值分别是`rand-m9-mstd0.5-inc1``bicubic``224``TimmAutoAugment`是在uint8的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`之前。 `TimmAutoAugment` 的图像增广方式的配置如下,其中用户需要指定其中的参数 `config_str``interpolation``img_size`,默认的数值分别是 `rand-m9-mstd0.5-inc1``bicubic``224``TimmAutoAugment` 是在 uint8 的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`)之前。
```yaml ```yaml
transform_ops: transform_ops:
- DecodeImage: - DecodeImage:
to_rgb: True to_rgb: True
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
<a name="1.4"></a> <a name="1.4"></a>
### 1.4 Cutout ### 1.4 Cutout
`Cutout`的图像增广方式的配置如下,其中用户需要指定其中的参数`n_holes``length`,默认的数值分别是`1``112`。类似其他图像裁剪类的数据增强方式,`Cutout`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`后的数据上操作,此处给出的是在归一化后的操作。 `Cutout` 的图像增广方式的配置如下,其中用户需要指定其中的参数 `n_holes``length`,默认的数值分别是 `1``112`。类似其他图像裁剪类的数据增强方式,`Cutout` 既可以在 uint8 格式的数据上操作,也可以在归一化)(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml ```yaml
transform_ops: transform_ops:
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
<a name="1.5"></a> <a name="1.5"></a>
### 1.5 RandomErasing ### 1.5 RandomErasing
`RandomErasing`的图像增广方式的配置如下,其中用户需要指定其中的参数`EPSILON``sl``sh``r1``attempt``use_log_aspect``mode`,默认的数值分别是`0.25``0.02``1.0/3.0``0.3``10``True``pixel`。类似其他图像裁剪类的数据增强方式,`RandomErasing`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`后的数据上操作,此处给出的是在归一化后的操作。 `RandomErasing` 的图像增广方式的配置如下,其中用户需要指定其中的参数 `EPSILON``sl``sh``r1``attempt``use_log_aspect``mode`,默认的数值分别是 `0.25``0.02``1.0/3.0``0.3``10``True``pixel`。类似其他图像裁剪类的数据增强方式,`RandomErasing` 既可以在 uint8 格式的数据上操作,也可以在归一化(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml ```yaml
transform_ops: transform_ops:
...@@ -153,7 +153,7 @@ ...@@ -153,7 +153,7 @@
<a name="1.6"></a> <a name="1.6"></a>
### 1.6 HideAndSeek ### 1.6 HideAndSeek
`HideAndSeek`的图像增广方式的配置如下。类似其他图像裁剪类的数据增强方式,`HideAndSeek`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`后的数据上操作,此处给出的是在归一化后的操作。 `HideAndSeek` 的图像增广方式的配置如下。类似其他图像裁剪类的数据增强方式,`HideAndSeek` 既可以在 uint8 格式的数据上操作,也可以在归一化(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml ```yaml
transform_ops: transform_ops:
...@@ -173,9 +173,10 @@ ...@@ -173,9 +173,10 @@
``` ```
<a name="1.7"></a> <a name="1.7"></a>
### 1.7 GridMask ### 1.7 GridMask
`GridMask`的图像增广方式的配置如下,其中用户需要指定其中的参数`d1``d2``rotate``ratio``mode`, 默认的数值分别是`96``224``1``0.5``0`。类似其他图像裁剪类的数据增强方式,`GridMask`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`后的数据上操作,此处给出的是在归一化后的操作。 `GridMask` 的图像增广方式的配置如下,其中用户需要指定其中的参数 `d1``d2``rotate``ratio``mode`, 默认的数值分别是 `96``224``1``0.5``0`。类似其他图像裁剪类的数据增强方式,`GridMask` 既可以在 uint8 格式的数据上操作,也可以在归一化(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml ```yaml
transform_ops: transform_ops:
...@@ -202,7 +203,7 @@ ...@@ -202,7 +203,7 @@
<a name="1.8"></a> <a name="1.8"></a>
### 1.8 Mixup ### 1.8 Mixup
`Mixup`的图像增广方式的配置如下,其中用户需要指定其中的参数`alpha`,默认的数值是`0.2`。类似其他图像混合类的数据增强方式,`Mixup`是在图像做完数据处理后将每个batch内的数据做图像混叠,将混叠后的图像和标签输入网络中训练,所以其是在图像数据处理(图像变换、图像裁剪)后操作。 `Mixup` 的图像增广方式的配置如下,其中用户需要指定其中的参数 `alpha`,默认的数值是 `0.2`。类似其他图像混合类的数据增强方式,`Mixup` 是在图像做完数据处理后将每个 batch 内的数据做图像混叠,将混叠后的图像和标签输入网络中训练,所以其是在图像数据处理(图像变换、图像裁剪)后操作。
```yaml ```yaml
transform_ops: transform_ops:
...@@ -226,7 +227,7 @@ ...@@ -226,7 +227,7 @@
<a name="1.9"></a> <a name="1.9"></a>
### 1.9 Cutmix ### 1.9 Cutmix
`Cutmix`的图像增广方式的配置如下,其中用户需要指定其中的参数`alpha`,默认的数值是`0.2`。类似其他图像混合类的数据增强方式,`Cutmix`是在图像做完数据处理后将每个batch内的数据做图像混叠,将混叠后的图像和标签输入网络中训练,所以其是在图像数据处理(图像变换、图像裁剪)后操作。 `Cutmix` 的图像增广方式的配置如下,其中用户需要指定其中的参数 `alpha`,默认的数值是 `0.2`。类似其他图像混合类的数据增强方式,`Cutmix` 是在图像做完数据处理后将每个 batch 内的数据做图像混叠,将混叠后的图像和标签输入网络中训练,所以其是在图像数据处理(图像变换、图像裁剪)后操作。
```yaml ```yaml
transform_ops: transform_ops:
...@@ -250,7 +251,8 @@ ...@@ -250,7 +251,8 @@
<a name="1.10"></a> <a name="1.10"></a>
### 1.10 Mixup与Cutmix同时使用 ### 1.10 Mixup与Cutmix同时使用
`Mixup``与Cutmix`同时使用的配置如下,其中用户需要指定额外的参数`prob`,该参数控制不同数据增强的概率,默认为`0.5` `Mixup``Cutmix`同时使用的配置如下,其中用户需要指定额外的参数 `prob`,该参数控制不同数据增强的概率,默认为 `0.5`
```yaml ```yaml
transform_ops: transform_ops:
- DecodeImage: - DecodeImage:
...@@ -275,11 +277,11 @@ ...@@ -275,11 +277,11 @@
``` ```
<a name="2"></a> <a name="2"></a>
## 二、启动命令 ## 2. 启动命令
当用户配置完训练环境后,类似于训练其他分类任务,只需要将`tools/train.sh`中的配置文件替换成为相应的数据增强方式的配置文件即可。 当用户配置完训练环境后,类似于训练其他分类任务,只需要将 `tools/train.sh` 中的配置文件替换成为相应的数据增强方式的配置文件即可。
其中`train.sh`中的内容如下: 其中 `train.sh` 中的内容如下:
```bash ```bash
...@@ -290,27 +292,27 @@ python3 -m paddle.distributed.launch \ ...@@ -290,27 +292,27 @@ python3 -m paddle.distributed.launch \
-c ./ppcls/configs/ImageNet/DataAugment/ResNet50_Cutout.yaml -c ./ppcls/configs/ImageNet/DataAugment/ResNet50_Cutout.yaml
``` ```
运行`train.sh` 运行 `train.sh`
```bash ```bash
sh tools/train.sh sh tools/train.sh
``` ```
<a name="3"></a> <a name="3"></a>
## 三、注意事项 ## 3. 注意事项
* 由于图像混叠时需对label进行混叠,无法计算训练数据的准确率,所以在训练过程中没有打印训练准确率。 * 由于图像混叠时需对 label 进行混叠,无法计算训练数据的准确率,所以在训练过程中没有打印训练准确率。
* 在使用数据增强后,由于训练数据更难,所以训练损失函数可能较大,训练集的准确率相对较低,但其有拥更好的泛化能力,所以验证集的准确率相对较高。 * 在使用数据增强后,由于训练数据更难,所以训练损失函数可能较大,训练集的准确率相对较低,但其有拥更好的泛化能力,所以验证集的准确率相对较高。
* 在使用数据增强后,模型可能会趋于欠拟合状态,建议可以适当的调小`l2_decay`的值来获得更高的验证集准确率。 * 在使用数据增强后,模型可能会趋于欠拟合状态,建议可以适当的调小 `l2_decay` 的值来获得更高的验证集准确率。
* 几乎每一类图像增强均含有超参数,我们只提供了基于ImageNet-1k的超参数,其他数据集需要用户自己调试超参数,具体超参数的含义用户可以阅读相关的论文,调试方法也可以参考训练技巧的章节。 * 几乎每一类图像增强均含有超参数,我们只提供了基于 ImageNet-1k 的超参数,其他数据集需要用户自己调试超参数,具体超参数的含义用户可以阅读相关的论文,调试方法也可以参考训练技巧的章节。
<a name="4"></a> <a name="4"></a>
## 四、实验结果 ## 4. 实验结果
基于PaddleClas,在ImageNet1k数据集上的分类精度如下。 基于 PaddleClas,在 ImageNet1k 数据集上的分类精度如下。
| 模型 | 初始学习率策略 | l2 decay | batch size | epoch | 数据变化策略 | Top1 Acc | 论文中结论 | | 模型 | 初始学习率策略 | l2 decay | batch size | epoch | 数据变化策略 | Top1 Acc | 论文中结论 |
|-------------|------------------|--------------|------------|-------|----------------|------------|----| |-------------|------------------|--------------|------------|-------|----------------|------------|----|
...@@ -325,5 +327,5 @@ sh tools/train.sh ...@@ -325,5 +327,5 @@ sh tools/train.sh
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | hide and seek | 0.7743 | 0.7720 | | ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | hide and seek | 0.7743 | 0.7720 |
**注意** **注意**
* 在这里的实验中,为了便于对比,我们将l2 decay固定设置为1e-4,在实际使用中,我们推荐尝试使用更小的l2 decay。结合数据增强,我们发现将l2 decay由1e-4减小为7e-5均能带来至少0.3~0.5%的精度提升。 * 在这里的实验中,为了便于对比,我们将 l2 decay 固定设置为 1e-4,在实际使用中,我们推荐尝试使用更小的 l2 decay。结合数据增强,我们发现将 l2 decay 由 1e-4 减小为 7e-5 均能带来至少 0.3~0.5% 的精度提升。
* 我们目前尚未对不同策略进行组合并验证效果,这一块后续我们会开展更多的对比实验,敬请期待。 * 我们目前尚未对不同策略进行组合并验证效果,这一块后续我们会开展更多的对比实验,敬请期待。
# PaddleClas代码解析 # PaddleClas 代码解析
## 目录 ## 目录
- [整体代码和目录概览](#1) - [1. 整体代码和目录概览](#1)
- [训练模块定义](#2) - [2. 训练模块定义](#2)
- [2.1 数据](#2.1) - [2.1 数据](#2.1)
- [2.2 模型结构](#2.2) - [2.2 模型结构](#2.2)
- [2.3 损失函数](#2.3) - [2.3 损失函数](#2.3)
...@@ -11,39 +11,39 @@ ...@@ -11,39 +11,39 @@
- [2.5 训练时评估](#2.5) - [2.5 训练时评估](#2.5)
- [2.6 模型存储](#2.6) - [2.6 模型存储](#2.6)
- [2.7 模型裁剪与量化](#2.7) - [2.7 模型裁剪与量化](#2.7)
- [预测部署代码和方式](#3) - [3. 预测部署代码和方式](#3)
<a name="1"></a> <a name="1"></a>
## 一、整体代码和目录概览 ## 1. 整体代码和目录概览
PaddleClas主要代码和目录结构如下 PaddleClas 主要代码和目录结构如下
* benchmark: 文件夹下存放了一些shell脚本,主要是为了测试PaddleClas中不同模型的速度指标,如单卡训练速度指标、多卡训练速度指标等。 * benchmark: 文件夹下存放了一些 shell 脚本,主要是为了测试 PaddleClas 中不同模型的速度指标,如单卡训练速度指标、多卡训练速度指标等。
* dataset:文件夹下存放数据集和用于处理数据集的脚本。脚本负责将数据集处理为适合Dataloader处理的格式。 * dataset:文件夹下存放数据集和用于处理数据集的脚本。脚本负责将数据集处理为适合 Dataloader 处理的格式。
* deploy:部署核心代码,文件夹存放的是部署工具,支持 python/cpp inference、Hub Serveing、Paddle Lite、Slim离线量化等多种部署方式。 * deploy:部署核心代码,文件夹存放的是部署工具,支持 python/cpp inference、Hub Serveing、Paddle Lite、Slim 离线量化等多种部署方式。
* ppcls:训练核心代码,文件夹下存放PaddleClas框架主体。配置文件、模型训练、评估、预测、动转静导出等具体代码实现均在这里。 * ppcls:训练核心代码,文件夹下存放 PaddleClas 框架主体。配置文件、模型训练、评估、预测、动转静导出等具体代码实现均在这里。
* tools:训练、评估、预测、模型动转静导出的入口函数和脚本均在该文件下。 * tools:训练、评估、预测、模型动转静导出的入口函数和脚本均在该文件下。
* requirements.txt 文件用于安装 PaddleClas 的依赖项。使用pip进行升级安装使用。 * requirements.txt 文件用于安装 PaddleClas 的依赖项。使用 pip 进行升级安装使用。
* tests:PaddleClas模型从训练到预测的全链路测试,验证各功能是否能够正常使用。 * tests:PaddleClas 模型从训练到预测的全链路测试,验证各功能是否能够正常使用。
<a name="2"></a> <a name="2"></a>
## 二、训练模块定义 ## 2. 训练模块定义
深度学习模型训练过程中,主要包含数据、模型结构、损失函数、优化器和学习率衰减、权重衰减策略等,以下一一解读。 深度学习模型训练过程中,主要包含数据、模型结构、损失函数、优化器和学习率衰减、权重衰减策略等,以下一一解读。
<a name="2.1"></a> <a name="2.1"></a>
## 2.1 数据 ### 2.1 数据
对于有监督任务来说,训练数据一般包含原始数据及其标注。在基于单标签的图像分类任务中,原始数据指的是图像数据,而标注则是该图像数据所属的类比。PaddleClas中,训练时需要提供标签文件,形式如下,每一行包含一条训练样本,分别表示图片路径和类别标签,用分隔符隔开(默认为空格)。 对于有监督任务来说,训练数据一般包含原始数据及其标注。在基于单标签的图像分类任务中,原始数据指的是图像数据,而标注则是该图像数据所属的类比。PaddleClas 中,训练时需要提供标签文件,形式如下,每一行包含一条训练样本,分别表示图片路径和类别标签,用分隔符隔开(默认为空格)。
``` ```
train/n01440764/n01440764_10026.JPEG 0 train/n01440764/n01440764_10026.JPEG 0
train/n01440764/n01440764_10027.JPEG 0 train/n01440764/n01440764_10027.JPEG 0
``` ```
在代码`ppcls/data/dataloader/common_dataset.py`中,包含`CommonDataset`类,继承自`paddle.io.Dataset`,该数据集类可以通过一个键值进行索引并获取指定样本。`ImageNetDataset`, `LogoDataset`, `CommonDataset` 等数据集类都继承自这个类别 在代码 `ppcls/data/dataloader/common_dataset.py` 中,包含 `CommonDataset` 类,继承自 `paddle.io.Dataset`,该数据集类可以通过一个键值进行索引并获取指定样本。`ImageNetDataset`, `LogoDataset`, `CommonDataset` 等数据集类都对这个类别
对于读入的数据,需要通过数据转换,将原始的图像数据进行转换。训练时,标准的数据预处理包含:`DecodeImage`, `RandCropImage`, `RandFlipImage`, `NormalizeImage`, `ToCHWImage`。在配置文件中体现如下,数据预处理主要包含在`transforms`字段中,以列表形式呈现,会按照顺序对数据依次做这些转换。 对于读入的数据,需要通过数据转换,将原始的图像数据进行转换。训练时,标准的数据预处理包含:`DecodeImage`, `RandCropImage`, `RandFlipImage`, `NormalizeImage`, `ToCHWImage`。在配置文件中体现如下,数据预处理主要包含在 `transforms` 字段中,以列表形式呈现,会按照顺序对数据依次做这些转换。
```yaml ```yaml
DataLoader: DataLoader:
...@@ -74,7 +74,7 @@ PaddleClas 中也包含了 `AutoAugment`, `RandAugment` 等数据增广方法, ...@@ -74,7 +74,7 @@ PaddleClas 中也包含了 `AutoAugment`, `RandAugment` 等数据增广方法,
图像分类中,数据后处理主要为 `argmax` 操作,在此不再赘述。 图像分类中,数据后处理主要为 `argmax` 操作,在此不再赘述。
<a name="2.2"></a> <a name="2.2"></a>
## 2.2 模型结构 ### 2.2 模型结构
在配置文件中,模型结构定义如下 在配置文件中,模型结构定义如下
...@@ -100,9 +100,9 @@ def build_model(config): ...@@ -100,9 +100,9 @@ def build_model(config):
``` ```
<a name="2.3"></a> <a name="2.3"></a>
## 2.3 损失函数 ### 2.3 损失函数
PaddleClas中,包含了 `CELoss` , `JSDivLoss`, `TripletLoss`, `CenterLoss` 等损失函数,均定义在 `ppcls/loss` 中。 PaddleClas 中,包含了 `CELoss` , `JSDivLoss`, `TripletLoss`, `CenterLoss` 等损失函数,均定义在 `ppcls/loss` 中。
`ppcls/loss/__init__.py` 文件中,使用 `CombinedLoss` 来构建及合并损失函数,不同训练策略中所需要的损失函数与计算方法不同,PaddleClas 在构建损失函数过程中,主要考虑了以下几个因素。 `ppcls/loss/__init__.py` 文件中,使用 `CombinedLoss` 来构建及合并损失函数,不同训练策略中所需要的损失函数与计算方法不同,PaddleClas 在构建损失函数过程中,主要考虑了以下几个因素。
...@@ -125,7 +125,7 @@ Loss: ...@@ -125,7 +125,7 @@ Loss:
``` ```
<a name="2.4"></a> <a name="2.4"></a>
## 2.4 优化器和学习率衰减、权重衰减策略 ### 2.4 优化器和学习率衰减、权重衰减策略
图像分类任务中,`Momentum` 是一种比较常用的优化器, PaddleClas 中提供了 `Momentum``RMSProp``Adam``AdamW`等几种优化器策略。 图像分类任务中,`Momentum` 是一种比较常用的优化器, PaddleClas 中提供了 `Momentum``RMSProp``Adam``AdamW`等几种优化器策略。
...@@ -183,9 +183,9 @@ def build_optimizer(config, epochs, step_each_epoch, parameters): ...@@ -183,9 +183,9 @@ def build_optimizer(config, epochs, step_each_epoch, parameters):
不同优化器和权重衰减策略均以类的形式实现,具体实现可以参考文件 `ppcls/optimizer/optimizer.py` ;不同的学习率衰减策略可以参考文件 `ppcls/optimizer/learning_rate.py` 不同优化器和权重衰减策略均以类的形式实现,具体实现可以参考文件 `ppcls/optimizer/optimizer.py` ;不同的学习率衰减策略可以参考文件 `ppcls/optimizer/learning_rate.py`
<a name="2.5"></a> <a name="2.5"></a>
## 2.5 训练时评估 ### 2.5 训练时评估
模型在训练的时候,可以设置模型保存的间隔,也可以选择每隔若干个epoch对验证集进行评估,从而可以保存在验证集上精度最佳的模型。配置文件中,可以通过下面的字段进行配置。 模型在训练的时候,可以设置模型保存的间隔,也可以选择每隔若干个 epoch 对验证集进行评估,从而可以保存在验证集上精度最佳的模型。配置文件中,可以通过下面的字段进行配置。
```yaml ```yaml
Global: Global:
...@@ -195,7 +195,7 @@ Global: ...@@ -195,7 +195,7 @@ Global:
``` ```
<a name="2.6"></a> <a name="2.6"></a>
## 2.6 模型存储 ### 2.6 模型存储
模型存储是通过 Paddle 框架的 `paddle.save()` 函数实现的,存储的是模型的动态图版本,以字典的形式存储,便于继续训练。具体实现如下 模型存储是通过 Paddle 框架的 `paddle.save()` 函数实现的,存储的是模型的动态图版本,以字典的形式存储,便于继续训练。具体实现如下
```python ```python
...@@ -217,7 +217,7 @@ def save_model(program, model_path, epoch_id, prefix='ppcls'): ...@@ -217,7 +217,7 @@ def save_model(program, model_path, epoch_id, prefix='ppcls'):
如果想对模型进行压缩训练,则通过下面字段进行配置 如果想对模型进行压缩训练,则通过下面字段进行配置
<a name="2.7"></a> <a name="2.7"></a>
## 2.7 模型裁剪与量化 ### 2.7 模型裁剪与量化
1.模型裁剪: 1.模型裁剪:
...@@ -239,11 +239,11 @@ Slim: ...@@ -239,11 +239,11 @@ Slim:
训练方法详见模型[裁剪量化使用介绍](../advanced_tutorials/model_prune_quantization.md), 算法介绍详见[裁剪量化算法介绍](../algorithm_introduction/model_prune_quantization.md) 训练方法详见模型[裁剪量化使用介绍](../advanced_tutorials/model_prune_quantization.md), 算法介绍详见[裁剪量化算法介绍](../algorithm_introduction/model_prune_quantization.md)
<a name="3"></a> <a name="3"></a>
## 三、预测部署代码和方式 ## 3. 预测部署代码和方式
* 如果希望将对分类模型进行离线量化,可以参考 [模型量化裁剪教程](../advanced_tutorials/model_prune_quantization.md) 中离线量化部分。 * 如果希望将对分类模型进行离线量化,可以参考 [模型量化裁剪教程](../advanced_tutorials/model_prune_quantization.md) 中离线量化部分。
* 如果希望在服务端使用 python 进行部署,可以参考 [python inference 预测教程](../inference_deployment/python_deploy.md) * 如果希望在服务端使用 python 进行部署,可以参考 [python inference 预测教程](../inference_deployment/python_deploy.md)
* 如果希望在服务端使用 cpp 进行部署,可以参考 [cpp inference 预测教程](../inference_deployment/cpp_deploy.md) * 如果希望在服务端使用 cpp 进行部署,可以参考 [cpp inference 预测教程](../inference_deployment/cpp_deploy.md)
* 如果希望将分类模型部署为服务,可以参考 [hub serving 预测部署教程](../inference_deployment/paddle_hub_serving_deploy.md) * 如果希望将分类模型部署为服务,可以参考 [hub serving 预测部署教程](../inference_deployment/paddle_hub_serving_deploy.md)
* 如果希望在移动端使用分类模型进行预测,可以参考 [PaddleLite 预测部署教程](../inference_deployment/paddle_lite_deploy.md) * 如果希望在移动端使用分类模型进行预测,可以参考 [PaddleLite 预测部署教程](../inference_deployment/paddle_lite_deploy.md)
* 如果希望使用whl包对分类模型进行预测,可以参考 [whl包预测](../inference_deployment/whl_deploy.md) * 如果希望使用 whl 包对分类模型进行预测,可以参考 [whl包预测](../inference_deployment/whl_deploy.md)
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## 目录 ## 目录
- [如何贡献代码](#1) - [1. 如何贡献代码](#1)
- [1.1 PaddleClas 分支说明](#1.1) - [1.1 PaddleClas 分支说明](#1.1)
- [1.2 PaddleClas 代码提交流程与规范](#1.2) - [1.2 PaddleClas 代码提交流程与规范](#1.2)
- [1.2.1 fork 和 clone 代码](#1.2.1) - [1.2.1 fork 和 clone 代码](#1.2.1)
...@@ -17,11 +17,11 @@ ...@@ -17,11 +17,11 @@
- [1.2.9 签署 CLA 协议和通过单元测试](#1.2.9) - [1.2.9 签署 CLA 协议和通过单元测试](#1.2.9)
- [1.2.10 删除分支](#1.2.10) - [1.2.10 删除分支](#1.2.10)
- [1.2.11 提交代码的一些约定](#1.2.11) - [1.2.11 提交代码的一些约定](#1.2.11)
- [总结](#2) - [2. 总结](#2)
- [参考文献](#3) - [3. 参考文献](#3)
<a name="1"></a> <a name="1"></a>
## 一、如何贡献代码 ## 1. 如何贡献代码
<a name="1.1"></a> <a name="1.1"></a>
### 1.1 PaddleClas 分支说明 ### 1.1 PaddleClas 分支说明
...@@ -45,7 +45,7 @@ PaddleClas 欢迎大家向 repo 中积极贡献代码,下面给出一些贡献 ...@@ -45,7 +45,7 @@ PaddleClas 欢迎大家向 repo 中积极贡献代码,下面给出一些贡献
<a name="1.2.1"></a> <a name="1.2.1"></a>
#### 1.2.1 fork 和 clone 代码 #### 1.2.1 fork 和 clone 代码
* 跳转到 [PaddleClas GitHub首页](https://github.com/PaddlePaddle/PaddleClas) ,然后单击 Fork 按钮,生成自己目录下的仓库,比如 `https://github.com/USERNAME/PaddleClas` * 跳转到 [PaddleClas GitHub 首页](https://github.com/PaddlePaddle/PaddleClas) ,然后单击 Fork 按钮,生成自己目录下的仓库,比如 `https://github.com/USERNAME/PaddleClas`
<div align="center"> <div align="center">
...@@ -123,7 +123,7 @@ Switched to a new branch 'new_branch' ...@@ -123,7 +123,7 @@ Switched to a new branch 'new_branch'
<a name="1.2.4"></a> <a name="1.2.4"></a>
#### 1.2.4 使用 pre-commit 勾子 #### 1.2.4 使用 pre-commit 勾子
Paddle 开发人员使用 pre-commit 工具来管理 Git 预提交钩子。 它可以帮助我们格式化源代码(C++,Python),在提交(commit)前自动检查一些基本事宜(如每个文件只有一个 EOL,Git 中不要添加大文件等)。 Paddle 开发人员使用 pre-commit 工具来管理 Git 预提交钩子。 它可以帮助我们格式化源代码(C++,Python),在提交(commit)前自动检查一些基本事宜(如每个文件只有一个 EOL,Git 中不要添加大文件等)。
pre-commit 测试是 Travis-CI 中单元测试的一部分,不满足钩子的 PR 不能被提交到 PaddleClas ,首先安装并在当前目录运行它: pre-commit 测试是 Travis-CI 中单元测试的一部分,不满足钩子的 PR 不能被提交到 PaddleClas ,首先安装并在当前目录运行它:
...@@ -192,7 +192,7 @@ git push origin new_branch ...@@ -192,7 +192,7 @@ git push origin new_branch
#### 1.2.9 签署 CLA 协议和通过单元测试 #### 1.2.9 签署 CLA 协议和通过单元测试
* 签署 CLA * 签署 CLA
在首次向 PaddlePaddle 提交 Pull Request 时,您需要您签署一次 CLA (Contributor License Agreement) 协议,以保证您的代码可以被合入,具体签署方式如下: 在首次向 PaddlePaddle 提交 Pull Request 时,您需要您签署一次 CLA (Contributor License Agreement)协议,以保证您的代码可以被合入,具体签署方式如下:
1. 请您查看 PR 中的 Check 部分,找到 license/cla ,并点击右侧 detail ,进入 CLA 网站 1. 请您查看 PR 中的 Check 部分,找到 license/cla ,并点击右侧 detail ,进入 CLA 网站
2. 点击 CLA 网站中的 `Sign in with GitHub to agree` , 点击完成后将会跳转回您的 Pull Request 页面 2. 点击 CLA 网站中的 `Sign in with GitHub to agree` , 点击完成后将会跳转回您的 Pull Request 页面
...@@ -228,7 +228,7 @@ git branch -D new_branch ...@@ -228,7 +228,7 @@ git branch -D new_branch
1)请保证 Travis-CI 中单元测试能顺利通过。如果没过,说明提交的代码存在问题,官方维护人员一般不做评审。 1)请保证 Travis-CI 中单元测试能顺利通过。如果没过,说明提交的代码存在问题,官方维护人员一般不做评审。
2)提交 Pull Request前: 2)提交 Pull Reques t前:
请注意 commit 的数量。 请注意 commit 的数量。
...@@ -253,11 +253,11 @@ git branch -D new_branch ...@@ -253,11 +253,11 @@ git branch -D new_branch
- 请采用 `start a review` 进行回复,而非直接回复的方式。原因是每个回复都会发送一封邮件,会造成邮件灾难。 - 请采用 `start a review` 进行回复,而非直接回复的方式。原因是每个回复都会发送一封邮件,会造成邮件灾难。
<a name="2"></a> <a name="2"></a>
## 二、总结 ## 2. 总结
* 开源社区依赖于众多开发者与用户的贡献和反馈,在这里感谢与期待大家向 PaddleClas 提出宝贵的意见与 Pull Request ,希望我们可以一起打造一个领先实用全面的图像识别代码仓库! * 开源社区依赖于众多开发者与用户的贡献和反馈,在这里感谢与期待大家向 PaddleClas 提出宝贵的意见与 Pull Request ,希望我们可以一起打造一个领先实用全面的图像识别代码仓库!
<a name="3"></a> <a name="3"></a>
## 三、参考文献 ## 3. 参考文献
1. [PaddlePaddle本地开发指南](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/08_contribution/index_cn.html) 1. [PaddlePaddle 本地开发指南](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/08_contribution/index_cn.html)
2. [向开源框架提交pr的过程](https://blog.csdn.net/vim_wj/article/details/78300239) 2. [向开源框架提交 pr 的过程](https://blog.csdn.net/vim_wj/article/details/78300239)
...@@ -2,42 +2,41 @@ ...@@ -2,42 +2,41 @@
# 知识蒸馏 # 知识蒸馏
## 目录 ## 目录
- [1. 模型压缩与知识蒸馏方法简介](#1)
- [模型压缩与知识蒸馏方法简介](#1) - [2. SSLD 蒸馏策略](#2)
- [SSLD 蒸馏策略](#2)
- [2.1 简介](#2.1) - [2.1 简介](#2.1)
- [2.2 数据选择](#2.2) - [2.2 数据选择](#2.2)
- [实验](#3) - [3. 实验](#3)
- [3.1 教师模型的选择](#3.1) - [3.1 教师模型的选择](#3.1)
- [3.2 大数据蒸馏](#3.2) - [3.2 大数据蒸馏](#3.2)
- [3.3 ImageNet1k 训练集 finetune](#3.3) - [3.3 ImageNet1k 训练集 finetune](#3.3)
- [3.4 数据增广以及基于 Fix 策略的微调](#3.4) - [3.4 数据增广以及基于 Fix 策略的微调](#3.4)
- [3.5 实验过程中的一些问题](#3.5) - [3.5 实验过程中的一些问题](#3.5)
- [蒸馏模型的应用](#4) - [4. 蒸馏模型的应用](#4)
- [4.1 使用方法](#4.1) - [4.1 使用方法](#4.1)
- [4.2 迁移学习 finetune](#4.2) - [4.2 迁移学习 finetune](#4.2)
- [4.3 目标检测](#4.3) - [4.3 目标检测](#4.3)
- [SSLD实战](#5) - [5. SSLD实战](#5)
- [5.1 参数配置](#5.1) - [5.1 参数配置](#5.1)
- [5.2 启动命令](#5.2) - [5.2 启动命令](#5.2)
- [5.3 注意事项](#5.3) - [5.3 注意事项](#5.3)
- [参考文献](#6) - [6. 参考文献](#6)
<a name="1"></a> <a name="1"></a>
## 一、模型压缩与知识蒸馏方法简介 ## 1. 模型压缩与知识蒸馏方法简介
近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。 近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。
在数据量足够大的情况下,通过合理构建网络模型的方式增加其参数量,可以显著改善模型性能,但是这又带来了模型复杂度急剧提升的问题。大模型在实际场景中使用的成本较高。 在数据量足够大的情况下,通过合理构建网络模型的方式增加其参数量,可以显著改善模型性能,但是这又带来了模型复杂度急剧提升的问题。大模型在实际场景中使用的成本较高。
深度神经网络一般有较多的参数冗余,目前有几种主要的方法对模型进行压缩,减小其参数量。如裁剪、量化、知识蒸馏等,其中知识蒸馏是指使用教师模型 (teacher model) 去指导学生模型 (student model) 学习特定任务,保证小模型在参数量不变的情况下,得到比较大的性能提升,甚至获得与大模型相似的精度指标 [1]。 PaddleClas 融合已有的蒸馏方法 [2,3] ,提供了一种简单的半监督标签知识蒸馏方案 (SSLD,Simple Semi-supervised Label Distillation) ,基于 ImageNet1k 分类数据集,在 ResNet_vd 以及 MobileNet 系列上的精度均有超过 3% 的绝对精度提升,具体指标如下图所示。 深度神经网络一般有较多的参数冗余,目前有几种主要的方法对模型进行压缩,减小其参数量。如裁剪、量化、知识蒸馏等,其中知识蒸馏是指使用教师模型(teacher model)去指导学生模型(student model)学习特定任务,保证小模型在参数量不变的情况下,得到比较大的性能提升,甚至获得与大模型相似的精度指标 [1]。 PaddleClas 融合已有的蒸馏方法 [2,3] ,提供了一种简单的半监督标签知识蒸馏方案(SSLD,Simple Semi-supervised Label Distillation),基于 ImageNet1k 分类数据集,在 ResNet_vd 以及 MobileNet 系列上的精度均有超过 3% 的绝对精度提升,具体指标如下图所示。
<div align="center"> <div align="center">
<img src="../../images/distillation/distillation_perform_s.jpg" width = "600" /> <img src="../../images/distillation/distillation_perform_s.jpg" width = "600" />
</div> </div>
<a name="2"></a> <a name="2"></a>
## 二、SSLD 蒸馏策略 ## 2. SSLD 蒸馏策略
<a name="2.1"></a> <a name="2.1"></a>
### 2.1 简介 ### 2.1 简介
...@@ -48,17 +47,17 @@ SSLD 的流程图如下图所示。 ...@@ -48,17 +47,17 @@ SSLD 的流程图如下图所示。
<img src="../../images/distillation/ppcls_distillation.png" width = "600" /> <img src="../../images/distillation/ppcls_distillation.png" width = "600" />
</div> </div>
首先,我们从 ImageNet22k 中挖掘出了近400万张图片,同时与 ImageNet-1k 训练集整合在一起,得到了一个新的包含 500 万张图片的数据集。然后,我们将学生模型与教师模型组合成一个新的网络,该网络分别输出学生模型和教师模型的预测分布,与此同时,固定教师模型整个网络的梯度,而学生模型可以做正常的反向传播。最后,我们将两个模型的 logits 经过 softmax 激活函数转换为 soft label ,并将二者的 soft label 做 JS 散度作为损失函数,用于蒸馏模型训练。下面以 MobileNetV3 (该模型直接训练,精度为 75.3%) 的知识蒸馏为例,介绍该方案的核心关键点( baseline 为 79.12% 的 ResNet50_vd 模型蒸馏 MobileNetV3 ,训练集为 ImageNet1k 训练集, loss 为 cross entropy loss ,迭代轮数为 120epoch ,精度指标为 75.6% )。 首先,我们从 ImageNet22k 中挖掘出了近 400 万张图片,同时与 ImageNet-1k 训练集整合在一起,得到了一个新的包含 500 万张图片的数据集。然后,我们将学生模型与教师模型组合成一个新的网络,该网络分别输出学生模型和教师模型的预测分布,与此同时,固定教师模型整个网络的梯度,而学生模型可以做正常的反向传播。最后,我们将两个模型的 logits 经过 softmax 激活函数转换为 soft label ,并将二者的 soft label 做 JS 散度作为损失函数,用于蒸馏模型训练。下面以 MobileNetV3 (该模型直接训练,精度为 75.3%) 的知识蒸馏为例,介绍该方案的核心关键点(baseline 为 79.12% 的 ResNet50_vd 模型蒸馏 MobileNetV3 ,训练集为 ImageNet1k 训练集, loss 为 cross entropy loss ,迭代轮数为 120epoch ,精度指标为 75.6%)。
* 教师模型的选择。在进行知识蒸馏时,如果教师模型与学生模型的结构差异太大,蒸馏得到的结果反而不会有太大收益。相同结构下,精度更高的教师模型对结果也有很大影响。相比于 79.12% 的 ResNet50_vd 教师模型,使用 82.4% 的 ResNet50_vd 教师模型可以带来 0.4% 的绝对精度收益( `75.6%->76.0%` )。 * 教师模型的选择。在进行知识蒸馏时,如果教师模型与学生模型的结构差异太大,蒸馏得到的结果反而不会有太大收益。相同结构下,精度更高的教师模型对结果也有很大影响。相比于 79.12% 的 ResNet50_vd 教师模型,使用 82.4% 的 ResNet50_vd 教师模型可以带来 0.4% 的绝对精度收益( `75.6%->76.0%` )。
* 改进 loss 计算方法。分类 loss 计算最常用的方法就是 cross entropy loss ,我们经过实验发现,在使用 soft label 进行训练时,相对于 cross entropy loss , KL div loss 对模型性能提升几乎无帮助,但是使用具有对称特性的 JS div loss 时,在多个蒸馏任务上相比 cross entropy loss 均有 0.2% 左右的收益( `76.0%->76.2%` ), SSLD 中也基于 JS div loss 展开实验。 * 改进 loss 计算方法。分类 loss 计算最常用的方法就是 cross entropy loss ,我们经过实验发现,在使用 soft label 进行训练时,相对于 cross entropy loss , KL div loss 对模型性能提升几乎无帮助,但是使用具有对称特性的 JS div loss 时,在多个蒸馏任务上相比 cross entropy loss 均有 0.2% 左右的收益(`76.0%->76.2%`), SSLD 中也基于 JS div loss 展开实验。
* 更多的迭代轮数。蒸馏的 baseline 实验只迭代了 120 个 epoch 。实验发现,迭代轮数越多,蒸馏效果越好,最终我们迭代了 360epoch ,精度指标可以达到 77.1%(`76.2%->77.1%`) 。 * 更多的迭代轮数。蒸馏的 baseline 实验只迭代了 120 个 epoch 。实验发现,迭代轮数越多,蒸馏效果越好,最终我们迭代了 360 epoch ,精度指标可以达到 77.1%(`76.2%->77.1%`) 。
* 无需数据集的真值标签,很容易扩展训练集。 SSLD 的 loss 在计算过程中,仅涉及到教师和学生模型对于相同图片的处理结果(经过 softmax 激活函数处理之后的 soft label ),因此即使图片数据不包含真值标签,也可以用来进行训练并提升模型性能。该蒸馏方案的无标签蒸馏策略也大大提升了学生模型的性能上限`77.1%->78.5%` * 无需数据集的真值标签,很容易扩展训练集。 SSLD 的 loss 在计算过程中,仅涉及到教师和学生模型对于相同图片的处理结果(经过 softmax 激活函数处理之后的 soft label ),因此即使图片数据不包含真值标签,也可以用来进行训练并提升模型性能。该蒸馏方案的无标签蒸馏策略也大大提升了学生模型的性能上限( `77.1%->78.5%`)
* ImageNet1k 蒸馏 finetune 。 我们仅使用 ImageNet1k 数据,使用蒸馏方法对上述模型进行 finetune ,最终仍然可以获得 0.4% 的性能提升( `78.5%->78.9%` )。 * ImageNet1k 蒸馏 finetune 。 我们仅使用 ImageNet1k 数据,使用蒸馏方法对上述模型进行 finetune ,最终仍然可以获得 0.4% 的性能提升(`78.5%->78.9%`)。
<a name="2.2"></a> <a name="2.2"></a>
...@@ -72,11 +71,11 @@ SSLD 的流程图如下图所示。 ...@@ -72,11 +71,11 @@ SSLD 的流程图如下图所示。
</div> </div>
* 大数据集 soft label 获取,对于去重后的 ImageNet22k 数据集,我们使用 `ResNeXt101_32x16d_wsl` 模型进行预测,得到每张图片的 soft label 。 * 大数据集 soft label 获取,对于去重后的 ImageNet22k 数据集,我们使用 `ResNeXt101_32x16d_wsl` 模型进行预测,得到每张图片的 soft label 。
* Top-k 数据选择, ImageNet1k 数据共有 1000 类,对于每一类,找出属于该类并且得分最高的 `k` 张图片,最终得到一个数据量不超过`1000*k`的数据集(某些类上得到的图片数量可能少于 `k` 张)。 * Top-k 数据选择, ImageNet1k 数据共有 1000 类,对于每一类,找出属于该类并且得分最高的 `k` 张图片,最终得到一个数据量不超过 `1000*k` 的数据集(某些类上得到的图片数量可能少于 `k` 张)。
* 将该数据集与 ImageNet1k 的训练集融合组成最终蒸馏模型所使用的数据集,数据量为 500 万。 * 将该数据集与 ImageNet1k 的训练集融合组成最终蒸馏模型所使用的数据集,数据量为 500 万。
<a name="3"></a> <a name="3"></a>
## 三、实验 ## 3. 实验
* PaddleClas 的蒸馏策略为`大数据集训练 + ImageNet1k 蒸馏 finetune`的策略。选择合适的教师模型,首先在挑选得到的 500 万数据集上进行训练,然后在 ImageNet1k 训练集上进行 finetune,最终得到蒸馏后的学生模型。 * PaddleClas 的蒸馏策略为`大数据集训练 + ImageNet1k 蒸馏 finetune`的策略。选择合适的教师模型,首先在挑选得到的 500 万数据集上进行训练,然后在 ImageNet1k 训练集上进行 finetune,最终得到蒸馏后的学生模型。
...@@ -99,7 +98,7 @@ SSLD 的流程图如下图所示。 ...@@ -99,7 +98,7 @@ SSLD 的流程图如下图所示。
> 教师模型与学生模型的模型大小差异不宜过大,否则反而会影响蒸馏结果的精度。 > 教师模型与学生模型的模型大小差异不宜过大,否则反而会影响蒸馏结果的精度。
因此最终在蒸馏实验中,对于ResNet系列学生模型,我们使用 `ResNeXt101_32x16d_wsl` 作为教师模型;对于 MobileNet 系列学生模型,我们使用蒸馏得到的 `ResNet50_vd` 作为教师模型。 因此最终在蒸馏实验中,对于 ResNet 系列学生模型,我们使用 `ResNeXt101_32x16d_wsl` 作为教师模型;对于 MobileNet 系列学生模型,我们使用蒸馏得到的 `ResNet50_vd` 作为教师模型。
<a name="3.2"></a> <a name="3.2"></a>
### 3.2 大数据蒸馏 ### 3.2 大数据蒸馏
...@@ -154,13 +153,13 @@ SSLD 的流程图如下图所示。 ...@@ -154,13 +153,13 @@ SSLD 的流程图如下图所示。
| ResNet50_vd | 82.35% | MobileNetV3_large_x1_0 | 75.84% | | ResNet50_vd | 82.35% | MobileNetV3_large_x1_0 | 75.84% |
<a name="4"></a> <a name="4"></a>
## 四、蒸馏模型的应用 ## 4. 蒸馏模型的应用
<a name="4.1"></a> <a name="4.1"></a>
### 4.1 使用方法 ### 4.1 使用方法
* 中间层学习率调整。蒸馏得到的模型的中间层特征图更加精细化,因此将蒸馏模型预训练应用到其他任务中时,如果采取和之前相同的学习率,容易破坏中间层特征。而如果降低整体模型训练的学习率,则会带来训练收敛速度慢的问题。因此我们使用了中间层学习率调整的策略。具体地: * 中间层学习率调整。蒸馏得到的模型的中间层特征图更加精细化,因此将蒸馏模型预训练应用到其他任务中时,如果采取和之前相同的学习率,容易破坏中间层特征。而如果降低整体模型训练的学习率,则会带来训练收敛速度慢的问题。因此我们使用了中间层学习率调整的策略。具体地:
* 针对 ResNet50_vd ,我们设置一个学习率倍数列表, res block 之前的 3 个 conv2d 卷积参数具有统一的学习率倍数, 4 个 res block 的 conv2d 分别有一个学习率参数,共需设置 5 个学习率倍数的超参。在实验中发现。用于迁移学习finetune分类模型时, `[0.1,0.1,0.2,0.2,0.3]` 的中间层学习率倍数设置在绝大多数的任务中都性能更好;而在目标检测任务中, `[0.05,0.05,0.05,0.1,0.15]` 的中间层学习率倍数设置能够带来更大的精度收益。 * 针对 ResNet50_vd ,我们设置一个学习率倍数列表, res block 之前的 3 个 conv2d 卷积参数具有统一的学习率倍数, 4 个 res block 的 conv2d 分别有一个学习率参数,共需设置 5 个学习率倍数的超参。在实验中发现。用于迁移学习 finetune 分类模型时, `[0.1,0.1,0.2,0.2,0.3]` 的中间层学习率倍数设置在绝大多数的任务中都性能更好;而在目标检测任务中, `[0.05,0.05,0.05,0.1,0.15]` 的中间层学习率倍数设置能够带来更大的精度收益。
* 对于 MoblileNetV3_large_x1_0 ,由于其包含 15 个 block ,我们设置每 3 个 block 共享一个学习率倍数参数,因此需要共 5 个学习率倍数的参数,最终发现在分类和检测任务中, `[0.25,0.25,0.5,0.5,0.75]` 的中间层学习率倍数能够带来更大的精度收益。 * 对于 MoblileNetV3_large_x1_0 ,由于其包含 15 个 block ,我们设置每 3 个 block 共享一个学习率倍数参数,因此需要共 5 个学习率倍数的参数,最终发现在分类和检测任务中, `[0.25,0.25,0.5,0.5,0.75]` 的中间层学习率倍数能够带来更大的精度收益。
...@@ -169,7 +168,7 @@ SSLD 的流程图如下图所示。 ...@@ -169,7 +168,7 @@ SSLD 的流程图如下图所示。
<a name="4.2"></a> <a name="4.2"></a>
### 4.2 迁移学习 finetune ### 4.2 迁移学习 finetune
* 为验证迁移学习的效果,我们在 10 个小的数据集上验证其效果。在这里为了保证实验的可对比性,我们均使用 ImageNet1k 数据集训练的标准预处理过程,对于蒸馏模型我们也添加了蒸馏模型中间层学习率的搜索。 * 为验证迁移学习的效果,我们在 10 个小的数据集上验证其效果。在这里为了保证实验的可对比性,我们均使用 ImageNet1k 数据集训练的标准预处理过程,对于蒸馏模型我们也添加了蒸馏模型中间层学习率的搜索。
* 对于 ResNet50_vd baseline 为 Top1 Acc 79.12% 的预训练模型基于 grid search 搜索得到的最佳精度,对比实验则为基于该精度对预训练和中间层学习率进一步搜索得到的最佳精度。下面给出 10 个数据集上所有 baseline 和蒸馏模型的精度对比。 * 对于 ResNet50_vd, baseline 为 Top1 Acc 79.12% 的预训练模型基于 grid search 搜索得到的最佳精度,对比实验则为基于该精度对预训练和中间层学习率进一步搜索得到的最佳精度。下面给出 10 个数据集上所有 baseline 和蒸馏模型的精度对比。
| Dataset | Model | Baseline Top1 Acc | Distillation Model Finetune | | Dataset | Model | Baseline Top1 Acc | Distillation Model Finetune |
...@@ -205,9 +204,9 @@ SSLD 的流程图如下图所示。 ...@@ -205,9 +204,9 @@ SSLD 的流程图如下图所示。
在这里可以看出,对于未蒸馏模型,过度调整中间层学习率反而降低最终检测模型的性能指标。基于该蒸馏模型,我们也提供了领先的服务端实用目标检测方案,详细的配置与训练代码均已开源,可以参考 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/master/configs/rcnn_enhance) 在这里可以看出,对于未蒸馏模型,过度调整中间层学习率反而降低最终检测模型的性能指标。基于该蒸馏模型,我们也提供了领先的服务端实用目标检测方案,详细的配置与训练代码均已开源,可以参考 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/master/configs/rcnn_enhance)
<a name="5"></a> <a name="5"></a>
## 五、SSLD实战 ## 5. SSLD实战
本节将基于 ImageNet-1K 的数据集详细介绍 SSLD 蒸馏实验,如果想快速体验此方法,可以参考 [**30分钟玩转PaddleClas(进阶版)**](../quick_start/quick_start_classification_professional.md) 中基于 CIFAR100 的 SSLD 蒸馏实验。 本节将基于 ImageNet-1K 的数据集详细介绍 SSLD 蒸馏实验,如果想快速体验此方法,可以参考 [**30分钟玩转 PaddleClas(进阶版)**](../quick_start/quick_start_classification_professional.md) 中基于 CIFAR100 的 SSLD 蒸馏实验。
<a name="5.1"></a> <a name="5.1"></a>
### 5.1 参数配置 ### 5.1 参数配置
...@@ -271,7 +270,7 @@ sh tools/train.sh ...@@ -271,7 +270,7 @@ sh tools/train.sh
* 若用户准备添加无标签的训练数据,只需要将新的训练数据放置在原本训练数据的路径下,生成新的数据 list 即可,另外,新生成的数据 list 需要将无标签的数据添加伪标签(只是为了统一读数据)。 * 若用户准备添加无标签的训练数据,只需要将新的训练数据放置在原本训练数据的路径下,生成新的数据 list 即可,另外,新生成的数据 list 需要将无标签的数据添加伪标签(只是为了统一读数据)。
<a name="6"></a> <a name="6"></a>
## 六、参考文献 ## 6. 参考文献
[1] Hinton G, Vinyals O, Dean J. Distilling the knowledge in a neural network[J]. arXiv preprint arXiv:1503.02531, 2015. [1] Hinton G, Vinyals O, Dean J. Distilling the knowledge in a neural network[J]. arXiv preprint arXiv:1503.02531, 2015.
......
...@@ -4,32 +4,34 @@ ...@@ -4,32 +4,34 @@
复杂的模型有利于提高模型的性能,但也导致模型中存在一定冗余。此部分提供精简模型的功能,包括两部分:模型量化(量化训练、离线量化)、模型剪枝。 复杂的模型有利于提高模型的性能,但也导致模型中存在一定冗余。此部分提供精简模型的功能,包括两部分:模型量化(量化训练、离线量化)、模型剪枝。
其中模型量化将全精度缩减到定点数减少这种冗余,达到减少模型计算复杂度,提高模型推理性能的目的。 其中模型量化将全精度缩减到定点数减少这种冗余,达到减少模型计算复杂度,提高模型推理性能的目的。
模型量化可以在基本不损失模型的精度的情况下,将FP32精度的模型参数转换为Int8精度,减小模型参数大小并加速计算,使用量化后的模型在移动端等部署时更具备速度优势。 模型量化可以在基本不损失模型的精度的情况下,将 FP32 精度的模型参数转换为 Int8 精度,减小模型参数大小并加速计算,使用量化后的模型在移动端等部署时更具备速度优势。
模型剪枝将CNN中不重要的卷积核裁剪掉,减少模型参数量,从而降低模型计算复杂度。 模型剪枝将 CNN 中不重要的卷积核裁剪掉,减少模型参数量,从而降低模型计算复杂度。
本教程将介绍如何使用飞桨模型压缩库PaddleSlim做PaddleClas模型的压缩,即裁剪、量化功能。 本教程将介绍如何使用飞桨模型压缩库 PaddleSlim 做 PaddleClas 模型的压缩,即裁剪、量化功能。
[PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim) 集成了模型剪枝、量化(包括量化训练和离线量化)、蒸馏和神经网络搜索等多种业界常用且领先的模型压缩功能,如果您感兴趣,可以关注并了解。 [PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim) 集成了模型剪枝、量化(包括量化训练和离线量化)、蒸馏和神经网络搜索等多种业界常用且领先的模型压缩功能,如果您感兴趣,可以关注并了解。
在开始本教程之前,建议先了解[PaddleClas模型的训练方法](../models_training/classification.md)以及[PaddleSlim](https://paddleslim.readthedocs.io/zh_CN/latest/index.html),相关裁剪、量化方法可以参考[模型裁剪量化算法介绍文档](../algorithm_introduction/model_prune_quantization.md) 在开始本教程之前,建议先了解 [PaddleClas模型的训练方法](../models_training/classification.md) 以及 [PaddleSlim](https://paddleslim.readthedocs.io/zh_CN/latest/index.html),相关裁剪、量化方法可以参考[模型裁剪量化算法介绍文档](../algorithm_introduction/model_prune_quantization.md)
-----------
## 目录 ## 目录
- [准备环境](#1) - [1. 准备环境](#1)
- [1.1 安装PaddleSlim](#1.1) - [1.1 安装 PaddleSlim](#1.1)
- [1.2 准备训练好的模型](#1.2) - [1.2 准备训练好的模型](#1.2)
- [快速开始](#2) - [2. 快速开始](#2)
- [2.1 模型量化](#2.1) - [2.1 模型量化](#2.1)
- [2.1.1 在线量化训练](#2.1.1) - [2.1.1 在线量化训练](#2.1.1)
- [2.1.2 离线量化](#2.1.2) - [2.1.2 离线量化](#2.1.2)
- [2.2 模型剪枝](#2.2) - [2.2 模型剪枝](#2.2)
- [导出模型](#3) - [3. 导出模型](#3)
- [模型部署](#4) - [4. 模型部署](#4)
- [训练超参数建议](#5) - [5. 训练超参数建议](#5)
<a name="1"></a> <a name="1"></a>
## 一、准备环境 ## 1. 准备环境
当训练出一个模型后,如果希望进一步的压缩模型大小并加速预测,可使用量化或者剪枝的方法压缩模型。 当训练出一个模型后,如果希望进一步的压缩模型大小并加速预测,可使用量化或者剪枝的方法压缩模型。
模型压缩主要包括五个步骤: 模型压缩主要包括五个步骤:
...@@ -40,15 +42,15 @@ ...@@ -40,15 +42,15 @@
5. 量化模型预测部署 5. 量化模型预测部署
<a name="1.1"></a> <a name="1.1"></a>
### 1.1 安装PaddleSlim ### 1.1 安装 PaddleSlim
* 可以通过pip install的方式进行安装。 * 可以通过 pip install 的方式进行安装。
```bash ```bash
pip install paddleslim -i https://pypi.tuna.tsinghua.edu.cn/simple pip install paddleslim -i https://pypi.tuna.tsinghua.edu.cn/simple
``` ```
* 如果获取PaddleSlim的最新特性,可以从源码安装。 * 如果获取 PaddleSlim 的最新特性,可以从源码安装。
```bash ```bash
git clone https://github.com/PaddlePaddle/PaddleSlim.git git clone https://github.com/PaddlePaddle/PaddleSlim.git
...@@ -59,18 +61,18 @@ python3.7 setup.py install ...@@ -59,18 +61,18 @@ python3.7 setup.py install
<a name="1.2"></a> <a name="1.2"></a>
### 1.2 准备训练好的模型 ### 1.2 准备训练好的模型
PaddleClas提供了一系列训练好的[模型](../models/models_intro.md),如果待量化的模型不在列表中,需要按照[常规训练](../models_training/classification.md)方法得到训练好的模型。 PaddleClas 提供了一系列训练好的[模型](../models/models_intro.md),如果待量化的模型不在列表中,需要按照[常规训练](../models_training/classification.md)方法得到训练好的模型。
<a name="2"></a> <a name="2"></a>
## 二、 快速开始 ## 2. 快速开始
进入PaddleClas根目录 进入 PaddleClas 根目录
```bash ```bash
cd PaddleClas cd PaddleClas
``` ```
`slim`训练相关代码已经集成到`ppcls/engine/`下,离线量化代码位于`deploy/slim/quant_post_static.py` `slim` 训练相关代码已经集成到 `ppcls/engine/` 下,离线量化代码位于 `deploy/slim/quant_post_static.py`
<a name="2.1"></a> <a name="2.1"></a>
### 2.1 模型量化 ### 2.1 模型量化
...@@ -82,15 +84,15 @@ cd PaddleClas ...@@ -82,15 +84,15 @@ cd PaddleClas
训练指令如下: 训练指令如下:
* CPU/单卡GPU * CPU/单卡 GPU
CPU为例,若使用GPU,则将命令中改成`cpu`改成`gpu` CPU 为例,若使用 GPU,则将命令中改成 `cpu` 改成 `gpu`
```bash ```bash
python3.7 tools/train.py -c ppcls/configs/slim/ResNet50_vd_quantization.yaml -o Global.device=cpu python3.7 tools/train.py -c ppcls/configs/slim/ResNet50_vd_quantization.yaml -o Global.device=cpu
``` ```
其中`yaml`文件解析详见[参考文档](../models_training/config_description.md)。为了保证精度,`yaml`文件中已经使用`pretrained model`. 其中 `yaml` 文件解析详见[参考文档](../models_training/config_description.md)。为了保证精度,`yaml` 文件中已经使用 `pretrained model`.
* 单机多卡/多机多卡启动 * 单机多卡/多机多卡启动
...@@ -106,28 +108,28 @@ python3.7 -m paddle.distributed.launch \ ...@@ -106,28 +108,28 @@ python3.7 -m paddle.distributed.launch \
<a name="2.1.2"></a> <a name="2.1.2"></a>
#### 2.1.2 离线量化 #### 2.1.2 离线量化
**注意**:目前离线量化,必须使用已经训练好的模型,导出的`inference model`进行量化。一般模型导出`inference model`可参考[教程](../inference_deployment/export_model.md). **注意**:目前离线量化,必须使用已经训练好的模型,导出的 `inference model` 进行量化。一般模型导出 `inference model` 可参考[教程](../inference_deployment/export_model.md).
一般来说,离线量化损失模型精度较多。 一般来说,离线量化损失模型精度较多。
生成`inference model`后,离线量化运行方式如下 生成 `inference model` 后,离线量化运行方式如下
```bash ```bash
python3.7 deploy/slim/quant_post_static.py -c ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml -o Global.save_inference_dir=./deploy/models/class_ResNet50_vd_ImageNet_infer python3.7 deploy/slim/quant_post_static.py -c ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml -o Global.save_inference_dir=./deploy/models/class_ResNet50_vd_ImageNet_infer
``` ```
`Global.save_inference_dir``inference model`存放的目录。 `Global.save_inference_dir``inference model` 存放的目录。
执行成功后,在`Global.save_inference_dir`的目录下,生成`quant_post_static_model`文件夹,其中存储生成的离线量化模型,其可以直接进行预测部署,无需再重新导出模型。 执行成功后,在 `Global.save_inference_dir` 的目录下,生成 `quant_post_static_model` 文件夹,其中存储生成的离线量化模型,其可以直接进行预测部署,无需再重新导出模型。
<a name="2.2"></a> <a name="2.2"></a>
### 2.2 模型剪枝 ### 2.2 模型剪枝
训练指令如下: 训练指令如下:
- CPU/单卡GPU - CPU/单卡 GPU
CPU为例,若使用GPU,则将命令中改成`cpu`改成`gpu` CPU 为例,若使用 GPU,则将命令中改成 `cpu` 改成 `gpu`
```bash ```bash
python3.7 tools/train.py -c ppcls/configs/slim/ResNet50_vd_prune.yaml -o Global.device=cpu python3.7 tools/train.py -c ppcls/configs/slim/ResNet50_vd_prune.yaml -o Global.device=cpu
...@@ -144,9 +146,9 @@ python3.7 -m paddle.distributed.launch \ ...@@ -144,9 +146,9 @@ python3.7 -m paddle.distributed.launch \
``` ```
<a name="3"></a> <a name="3"></a>
## 三、导出模型 ## 3. 导出模型
在得到在线量化训练、模型剪枝保存的模型后,可以将其导出为inference model,用于预测部署,以模型剪枝为例: 在得到在线量化训练、模型剪枝保存的模型后,可以将其导出为 inference model,用于预测部署,以模型剪枝为例:
```bash ```bash
python3.7 tools/export.py \ python3.7 tools/export.py \
...@@ -156,16 +158,16 @@ python3.7 tools/export.py \ ...@@ -156,16 +158,16 @@ python3.7 tools/export.py \
``` ```
<a name="4"></a> <a name="4"></a>
## 四、模型部署 ## 4. 模型部署
上述步骤导出的模型可以直接使用inferecne进行部署,参考[inference部署](../inference_deployment/) 上述步骤导出的模型可以直接使用 inferecne 进行部署,参考 [inference部署](../inference_deployment/)
也通过PaddleLite的opt模型转换工具,完成inference模型到移动端模型转换,用于移动端的模型部署。 也通过 PaddleLite 的 opt 模型转换工具,完成 inference 模型到移动端模型转换,用于移动端的模型部署。
移动端模型部署的可参考 [移动端模型部署](../inference_deployment/paddle_lite_deploy.md) 移动端模型部署的可参考 [移动端模型部署](../inference_deployment/paddle_lite_deploy.md)
<a name="5"></a> <a name="5"></a>
## 五、训练超参数建议 ## 5. 训练超参数建议
* 量化、裁剪训练时,建议加载常规训练得到的预训练模型,加速量化训练收敛。 * 量化、裁剪训练时,建议加载常规训练得到的预训练模型,加速量化训练收敛。
* 量化训练时,建议初始学习率修改为常规训练的`1/20~1/10`,同时将训练epoch数修改为常规训练的`1/5~1/2`,学习率策略方面,加上Warmup,其他配置信息不建议修改。 * 量化训练时,建议初始学习率修改为常规训练的 `1/20~1/10`,同时将训练 epoch 数修改为常规训练的 `1/5~1/2`,学习率策略方面,加上 Warmup,其他配置信息不建议修改。
* 裁剪训练时,建议超参数配置与普通训练一致。 * 裁剪训练时,建议超参数配置与普通训练一致。
# 一、数据增强 ## 目录
在图像分类任务中,图像数据的增广是一种常用的正则化方法,常用于数据量不足或者模型参数较多的场景。在本章节中,我们将对除 ImageNet 分类任务标准数据增强外的8种数据增强方式进行简单的介绍和对比,用户也可以将这些增广方法应用到自己的任务中,以获得模型精度的提升。这8种数据增强方式在ImageNet上的精度指标如下所示。 - [1. 数据增强](#1)
- [2. 常用数据增强方法](#2)
- [3. 图像变换类](#3)
- [3.1 AutoAugment](#3.1)
- [3.2 RandAugment](#3.2)
- [3.3 TimmAutoAugment](#3.3)
- [4. 图像裁剪类](#4)
- [4.1 Cutout](#4.1)
- [4.2 RandomErasing](#4.2)
- [4.3 HideAndSeek](#4.3)
- [4.4 GridMask](#4.4)
- [5. 图像混叠](#5)
- [5.1 Mixup](#5.1)
- [5.2 Cutmix](#5.2)
<a name="1"></a>
## 1. 数据增强
在图像分类任务中,图像数据的增广是一种常用的正则化方法,常用于数据量不足或者模型参数较多的场景。在本章节中,我们将对除 ImageNet 分类任务标准数据增强外的 8 种数据增强方式进行简单的介绍和对比,用户也可以将这些增广方法应用到自己的任务中,以获得模型精度的提升。这 8 种数据增强方式在 ImageNet 上的精度指标如下所示。
![](../../images/image_aug/main_image_aug.png) ![](../../images/image_aug/main_image_aug.png)
<a name="2"></a>
# 二、常用数据增强方法 ## 2. 常用数据增强方法
如果没有特殊说明,本章节中所有示例为 ImageNet 分类,并且假设最终输入网络的数据维度为:`[batch-size, 3, 224, 224]` 如果没有特殊说明,本章节中所有示例为 ImageNet 分类,并且假设最终输入网络的数据维度为:`[batch-size, 3, 224, 224]`
...@@ -46,32 +64,32 @@ ...@@ -46,32 +64,32 @@
PaddleClas中集成了上述所有的数据增强策略,每种数据增强策略的参考论文与参考开源代码均在下面的介绍中列出。下文将介绍这些策略的原理与使用方法,并以下图为例,对变换后的效果进行可视化。为了说明问题,本章节中将 `RandCrop` 替换为 `Resize` PaddleClas中集成了上述所有的数据增强策略,每种数据增强策略的参考论文与参考开源代码均在下面的介绍中列出。下文将介绍这些策略的原理与使用方法,并以下图为例,对变换后的效果进行可视化。为了说明问题,本章节中将 `RandCrop` 替换为 `Resize`
![][test_baseline] ![][test_baseline]
<a name="3"></a>
# 三、图像变换类 ## 3. 图像变换类
图像变换类指的是对 `RandCrop` 后的 224 的图像进行一些变换,主要包括 图像变换类指的是对 `RandCrop` 后的 224 的图像进行一些变换,主要包括
+ AutoAugment + AutoAugment
+ RandAugment + RandAugment
+ TimmAutoAugment + TimmAutoAugment
<a name="3.1"></a>
## 3.1 AutoAugment ### 3.1 AutoAugment
论文地址:[https://arxiv.org/abs/1805.09501v1](https://arxiv.org/abs/1805.09501v1) 论文地址:[https://arxiv.org/abs/1805.09501v1](https://arxiv.org/abs/1805.09501v1)
开源代码github地址:[https://github.com/DeepVoltaire/AutoAugment](https://github.com/DeepVoltaire/AutoAugment) 开源代码 github 地址:[https://github.com/DeepVoltaire/AutoAugment](https://github.com/DeepVoltaire/AutoAugment)
不同于常规的人工设计图像增广方式,AutoAugment 是在一系列图像增广子策略的搜索空间中通过搜索算法找到的适合特定数据集的图像增广方案。针对 ImageNet 数据集,最终搜索出来的数据增强方案包含 25 个子策略组合,每个子策略中都包含两种变换,针对每幅图像都随机的挑选一个子策略组合,然后以一定的概率来决定是否执行子策略中的每种变换。 不同于常规的人工设计图像增广方式,AutoAugment 是在一系列图像增广子策略的搜索空间中通过搜索算法找到的适合特定数据集的图像增广方案。针对 ImageNet 数据集,最终搜索出来的数据增强方案包含 25 个子策略组合,每个子策略中都包含两种变换,针对每幅图像都随机的挑选一个子策略组合,然后以一定的概率来决定是否执行子策略中的每种变换。
经过AutoAugment数据增强后结果如下图所示。 经过 AutoAugment 数据增强后结果如下图所示。
![][test_autoaugment] ![][test_autoaugment]
<a name="3.2"></a>
## 3.2 RandAugment ### 3.2 RandAugment
论文地址:[https://arxiv.org/pdf/1909.13719.pdf](https://arxiv.org/pdf/1909.13719.pdf) 论文地址:[https://arxiv.org/pdf/1909.13719.pdf](https://arxiv.org/pdf/1909.13719.pdf)
开源代码github地址:[https://github.com/heartInsert/randaugment](https://github.com/heartInsert/randaugment) 开源代码 github 地址:[https://github.com/heartInsert/randaugment](https://github.com/heartInsert/randaugment)
`AutoAugment` 的搜索方法比较暴力,直接在数据集上搜索针对该数据集的最优策略,其计算量很大。在 `RandAugment` 文章中作者发现,一方面,针对越大的模型,越大的数据集,使用 `AutoAugment` 方式搜索到的增广方式产生的收益也就越小;另一方面,这种搜索出的最优策略是针对该数据集的,其迁移能力较差,并不太适合迁移到其他数据集上。 `AutoAugment` 的搜索方法比较暴力,直接在数据集上搜索针对该数据集的最优策略,其计算量很大。在 `RandAugment` 文章中作者发现,一方面,针对越大的模型,越大的数据集,使用 `AutoAugment` 方式搜索到的增广方式产生的收益也就越小;另一方面,这种搜索出的最优策略是针对该数据集的,其迁移能力较差,并不太适合迁移到其他数据集上。
...@@ -79,84 +97,84 @@ PaddleClas中集成了上述所有的数据增强策略,每种数据增强策 ...@@ -79,84 +97,84 @@ PaddleClas中集成了上述所有的数据增强策略,每种数据增强策
`RandAugment` 中,作者提出了一种随机增广的方式,不再像 `AutoAugment` 中那样使用特定的概率确定是否使用某种子策略,而是所有的子策略都会以同样的概率被选择到,论文中的实验也表明这种数据增强方式即使在大模型的训练中也具有很好的效果。 `RandAugment` 中,作者提出了一种随机增广的方式,不再像 `AutoAugment` 中那样使用特定的概率确定是否使用某种子策略,而是所有的子策略都会以同样的概率被选择到,论文中的实验也表明这种数据增强方式即使在大模型的训练中也具有很好的效果。
经过RandAugment数据增强后结果如下图所示。 经过 RandAugment 数据增强后结果如下图所示。
![][test_randaugment] ![][test_randaugment]
<a name="3.3"></a>
### 3.3 TimmAutoAugment
## 3.3 TimmAutoAugment 开源代码 github 地址:[https://github.com/rwightman/pytorch-image-models/blob/master/timm/data/auto_augment.py](https://github.com/rwightman/pytorch-image-models/blob/master/timm/data/auto_augment.py)
开源代码github地址:[https://github.com/rwightman/pytorch-image-models/blob/master/timm/data/auto_augment.py](https://github.com/rwightman/pytorch-image-models/blob/master/timm/data/auto_augment.py)
`TimmAutoAugment`是开源作者对AutoAugment和RandAugment的改进,事实证明,其在很多视觉任务上有更好的表现,目前绝大多数VisionTransformer模型都是基于TimmAutoAugment去实现的。
`TimmAutoAugment`是开源作者对 AutoAugment 和 RandAugment 的改进,事实证明,其在很多视觉任务上有更好的表现,目前绝大多数 VisionTransformer 模型都是基于 TimmAutoAugment 去实现的。
# 四、图像裁剪类 <a name="4"></a>
## 4. 图像裁剪类
图像裁剪类主要是对`Transpose` 后的 224 的图像进行一些裁剪,并将裁剪区域的像素值置为特定的常数(默认为0),主要包括: 图像裁剪类主要是对`Transpose` 后的 224 的图像进行一些裁剪,并将裁剪区域的像素值置为特定的常数(默认为 0),主要包括:
+ CutOut + CutOut
+ RandErasing + RandErasing
+ HideAndSeek + HideAndSeek
+ GridMask + GridMask
图像裁剪的这些增广并非一定要放在归一化之后,也有不少实现是放在归一化之前的,也就是直接对 uint8 的图像进行操作,两种方式的差别是:如果直接对 uint8 的图像进行操作,那么再经过归一化之后被裁剪的区域将不再是纯黑或纯白(减均值除方差之后像素值不为0)。而对归一后之后的数据进行操作,裁剪的区域会是纯黑或纯白。 图像裁剪的这些增广并非一定要放在归一化之后,也有不少实现是放在归一化之前的,也就是直接对 uint8 的图像进行操作,两种方式的差别是:如果直接对 uint8 的图像进行操作,那么再经过归一化之后被裁剪的区域将不再是纯黑或纯白(减均值除方差之后像素值不为 0)。而对归一后之后的数据进行操作,裁剪的区域会是纯黑或纯白。
上述的裁剪变换思路是相同的,都是为了解决训练出的模型在有遮挡数据上泛化能力较差的问题,不同的是他们的裁剪方式、区域不太一样。 上述的裁剪变换思路是相同的,都是为了解决训练出的模型在有遮挡数据上泛化能力较差的问题,不同的是他们的裁剪方式、区域不太一样。
<a name="4.1"></a>
## 4.1 Cutout ### 4.1 Cutout
论文地址:[https://arxiv.org/abs/1708.04552](https://arxiv.org/abs/1708.04552) 论文地址:[https://arxiv.org/abs/1708.04552](https://arxiv.org/abs/1708.04552)
开源代码github地址:[https://github.com/uoguelph-mlrg/Cutout](https://github.com/uoguelph-mlrg/Cutout) 开源代码 github 地址:[https://github.com/uoguelph-mlrg/Cutout](https://github.com/uoguelph-mlrg/Cutout)
Cutout 可以理解为 Dropout 的一种扩展操作,不同的是 Dropout 是对图像经过网络后生成的特征进行遮挡,而 Cutout 是直接对输入的图像进行遮挡,相对于Dropout对噪声的鲁棒性更好。作者在论文中也进行了说明,这样做法有以下两点优势:(1) 通过 Cutout 可以模拟真实场景中主体被部分遮挡时的分类场景;(2) 可以促进模型充分利用图像中更多的内容来进行分类,防止网络只关注显著性的图像区域,从而发生过拟合。 Cutout 可以理解为 Dropout 的一种扩展操作,不同的是 Dropout 是对图像经过网络后生成的特征进行遮挡,而 Cutout 是直接对输入的图像进行遮挡,相对于 Dropout 对噪声的鲁棒性更好。作者在论文中也进行了说明,这样做法有以下两点优势:(1) 通过 Cutout 可以模拟真实场景中主体被部分遮挡时的分类场景;(2) 可以促进模型充分利用图像中更多的内容来进行分类,防止网络只关注显著性的图像区域,从而发生过拟合。
经过RandAugment数据增强后结果如下图所示。 经过 RandAugment 数据增强后结果如下图所示。
![][test_cutout] ![][test_cutout]
<a name="4.2"></a>
## 4.2 RandomErasing ### 4.2 RandomErasing
论文地址:[https://arxiv.org/pdf/1708.04896.pdf](https://arxiv.org/pdf/1708.04896.pdf) 论文地址:[https://arxiv.org/pdf/1708.04896.pdf](https://arxiv.org/pdf/1708.04896.pdf)
开源代码github地址:[https://github.com/zhunzhong07/Random-Erasing](https://github.com/zhunzhong07/Random-Erasing) 开源代码 github 地址:[https://github.com/zhunzhong07/Random-Erasing](https://github.com/zhunzhong07/Random-Erasing)
`RandomErasing``Cutout` 方法类似,同样是为了解决训练出的模型在有遮挡数据上泛化能力较差的问题,作者在论文中也指出,随机裁剪的方式与随机水平翻转具有一定的互补性。作者也在行人再识别(REID)上验证了该方法的有效性。与`Cutout`不同的是,在`RandomErasing`中,图片以一定的概率接受该种预处理方法,生成掩码的尺寸大小与长宽比也是根据预设的超参数随机生成。 `RandomErasing``Cutout` 方法类似,同样是为了解决训练出的模型在有遮挡数据上泛化能力较差的问题,作者在论文中也指出,随机裁剪的方式与随机水平翻转具有一定的互补性。作者也在行人再识别(REID)上验证了该方法的有效性。与 `Cutout` 不同的是,在 `RandomErasing` 中,图片以一定的概率接受该种预处理方法,生成掩码的尺寸大小与长宽比也是根据预设的超参数随机生成。
PaddleClas中`RandomErasing`的使用方法如下所示。 PaddleClas中 `RandomErasing` 的使用方法如下所示。
经过RandomErasing数据增强后结果如下图所示。 经过 RandomErasing 数据增强后结果如下图所示。
![][test_randomerassing] ![][test_randomerassing]
<a name="4.3"></a>
## 4.3 HideAndSeek ### 4.3 HideAndSeek
论文地址:[https://arxiv.org/pdf/1811.02545.pdf](https://arxiv.org/pdf/1811.02545.pdf) 论文地址:[https://arxiv.org/pdf/1811.02545.pdf](https://arxiv.org/pdf/1811.02545.pdf)
开源代码github地址:[https://github.com/kkanshul/Hide-and-Seek](https://github.com/kkanshul/Hide-and-Seek) 开源代码 github 地址:[https://github.com/kkanshul/Hide-and-Seek](https://github.com/kkanshul/Hide-and-Seek)
`HideAndSeek`论文将图像分为若干块区域(patch),对于每块区域,都以一定的概率生成掩码,不同区域的掩码含义如下图所示。 `HideAndSeek` 论文将图像分为若干块区域(patch),对于每块区域,都以一定的概率生成掩码,不同区域的掩码含义如下图所示。
![][hide_and_seek_mask_expanation] ![][hide_and_seek_mask_expanation]
PaddleClas中`HideAndSeek`的使用方法如下所示。 PaddleClas中 `HideAndSeek` 的使用方法如下所示。
经过HideAndSeek数据增强后结果如下图所示。 经过 HideAndSeek数据增强后结果如下图所示。
![][test_hideandseek] ![][test_hideandseek]
<a name="4.4"></a>
## 4.4 GridMask ### 4.4 GridMask
论文地址:[https://arxiv.org/abs/2001.04086](https://arxiv.org/abs/2001.04086) 论文地址:[https://arxiv.org/abs/2001.04086](https://arxiv.org/abs/2001.04086)
开源代码github地址:[https://github.com/akuxcw/GridMask](https://github.com/akuxcw/GridMask) 开源代码 github 地址:[https://github.com/akuxcw/GridMask](https://github.com/akuxcw/GridMask)
作者在论文中指出,此前存在的基于对图像 crop 的方法存在两个问题,如下图所示: 作者在论文中指出,此前存在的基于对图像 crop 的方法存在两个问题,如下图所示:
...@@ -169,21 +187,21 @@ PaddleClas中`HideAndSeek`的使用方法如下所示。 ...@@ -169,21 +187,21 @@ PaddleClas中`HideAndSeek`的使用方法如下所示。
因此如果避免过度删除或过度保留成为需要解决的核心问题。 因此如果避免过度删除或过度保留成为需要解决的核心问题。
`GridMask`是通过生成一个与原图分辨率相同的掩码,并将掩码进行随机翻转,与原图相乘,从而得到增广后的图像,通过超参数控制生成的掩码网格的大小。 `GridMask` 是通过生成一个与原图分辨率相同的掩码,并将掩码进行随机翻转,与原图相乘,从而得到增广后的图像,通过超参数控制生成的掩码网格的大小。
在训练过程中,有两种以下使用方法: 在训练过程中,有两种以下使用方法:
1. 设置一个概率p,从训练开始就对图片以概率p使用`GridMask`进行增广。 1. 设置一个概率 p,从训练开始就对图片以概率 p 使用 `GridMask` 进行增广。
2. 一开始设置增广概率为0,随着迭代轮数增加,对训练图片进行`GridMask`增广的概率逐渐增大,最后变为p。 2. 一开始设置增广概率为 0,随着迭代轮数增加,对训练图片进行 `GridMask` 增广的概率逐渐增大,最后变为 p。
论文中验证上述第二种方法的训练效果更好一些。 论文中验证上述第二种方法的训练效果更好一些。
经过GridMask数据增强后结果如下图所示。 经过 GridMask 数据增强后结果如下图所示。
![][test_gridmask] ![][test_gridmask]
<a name="5"></a>
# 五、图像混叠 ## 5. 图像混叠
图像混叠主要对 `Batch` 后的数据进行混合,包括: 图像混叠主要对 `Batch` 后的数据进行混合,包括:
...@@ -191,38 +209,38 @@ PaddleClas中`HideAndSeek`的使用方法如下所示。 ...@@ -191,38 +209,38 @@ PaddleClas中`HideAndSeek`的使用方法如下所示。
+ Cutmix + Cutmix
前文所述的图像变换与图像裁剪都是针对单幅图像进行的操作,而图像混叠是对两幅图像进行融合,生成一幅图像,两种方法的主要区别为混叠的方式不太一样。 前文所述的图像变换与图像裁剪都是针对单幅图像进行的操作,而图像混叠是对两幅图像进行融合,生成一幅图像,两种方法的主要区别为混叠的方式不太一样。
<a name="5.1"></a>
## 5.1 Mixup ### 5.1 Mixup
论文地址:[https://arxiv.org/pdf/1710.09412.pdf](https://arxiv.org/pdf/1710.09412.pdf) 论文地址:[https://arxiv.org/pdf/1710.09412.pdf](https://arxiv.org/pdf/1710.09412.pdf)
开源代码github地址:[https://github.com/facebookresearch/mixup-cifar10](https://github.com/facebookresearch/mixup-cifar10) 开源代码 github 地址:[https://github.com/facebookresearch/mixup-cifar10](https://github.com/facebookresearch/mixup-cifar10)
Mixup 是最先提出的图像混叠增广方案,其原理简单、方便实现,不仅在图像分类上,在目标检测上也取得了不错的效果。为了便于实现,通常只对一个 batch 内的数据进行混叠,在 `Cutmix` 中也是如此。 Mixup 是最先提出的图像混叠增广方案,其原理简单、方便实现,不仅在图像分类上,在目标检测上也取得了不错的效果。为了便于实现,通常只对一个 batch 内的数据进行混叠,在 `Cutmix` 中也是如此。
如下是 `imaug` 中的实现,需要指出的是,下述实现会出现对同一幅进行相加的情况,也就是最终得到的图和原图一样,随着 `batch-size` 的增加这种情况出现的概率也会逐渐减小。 如下是 `imaug` 中的实现,需要指出的是,下述实现会出现对同一幅进行相加的情况,也就是最终得到的图和原图一样,随着 `batch-size` 的增加这种情况出现的概率也会逐渐减小。
经过Mixup数据增强结果如下图所示。 经过 Mixup 数据增强结果如下图所示。
![][test_mixup] ![][test_mixup]
<a name="5.2"></a>
## 5.2 Cutmix ### 5.2 Cutmix
论文地址:[https://arxiv.org/pdf/1905.04899v2.pdf](https://arxiv.org/pdf/1905.04899v2.pdf) 论文地址:[https://arxiv.org/pdf/1905.04899v2.pdf](https://arxiv.org/pdf/1905.04899v2.pdf)
开源代码github地址:[https://github.com/clovaai/CutMix-PyTorch](https://github.com/clovaai/CutMix-PyTorch) 开源代码 github 地址:[https://github.com/clovaai/CutMix-PyTorch](https://github.com/clovaai/CutMix-PyTorch)
`Mixup` 直接对两幅图进行相加不一样,`Cutmix` 是从一幅图中随机裁剪出一个 `ROI`,然后覆盖当前图像中对应的区域,代码实现如下所示: `Mixup` 直接对两幅图进行相加不一样,`Cutmix` 是从一幅图中随机裁剪出一个 `ROI`,然后覆盖当前图像中对应的区域,代码实现如下所示:
经过Cutmix数据增强后结果如下图所示。 经过 Cutmix 数据增强后结果如下图所示。
![][test_cutmix] ![][test_cutmix]
关于数据增强相关的实战部分实参考[数据增强实战](../advanced_tutorials/DataAugmentation.md) 关于数据增强相关的实战部分实参考[数据增强实战](../advanced_tutorials/DataAugmentation.md)
# 参考文献 ## 参考文献
[1] Cubuk E D, Zoph B, Mane D, et al. Autoaugment: Learning augmentation strategies from data[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2019: 113-123. [1] Cubuk E D, Zoph B, Mane D, et al. Autoaugment: Learning augmentation strategies from data[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2019: 113-123.
......
# 图像分类
---
------
## 目录 ## 目录
- [数据集介绍](#1)
- [1.1 ImageNet-1k](#1.1) - [1. 数据集介绍](#1)
- [1.2 CIFAR-10/CIFAR-100](#1.2) - [1.1 ImageNet-1k](#1.1)
- [图像分类的流程](#2) - [1.2 CIFAR-10/CIFAR-100](#1.2)
- [2.1 数据及其预处理](#2.1) - [2. 图像分类的流程](#2)
- [2.2 模型准备](#2.2) - [2.1 数据及其预处理](#2.1)
- [2.3 模型训练](#2.3) - [2.2 模型准备](#2.2)
- [2.4 模型评估](#2.4) - [2.3 模型训练](#2.3)
- [主要算法简介](#3) - [2.4 模型评估](#2.4)
- [3. 主要算法简介](#3)
图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题,也是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在很多领域有广泛应用,包括安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等。 图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题,也是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在很多领域有广泛应用,包括安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等。
一般来说,图像分类通过手工特征或特征学习方法对整个图像进行全部描述,然后使用分类器判别物体类别,因此如何提取图像的特征至关重要。在深度学习算法之前使用较多的是基于词袋(Bag of Words)模型的物体分类方法。而基于深度学习的图像分类方法,可以通过有监督或无监督的方式学习层次化的特征描述,从而取代了手工设计或选择图像特征的工作。深度学习模型中的卷积神经网络(Convolution Neural Network, CNN)近年来在图像领域取得了惊人的成绩,CNN直接利用图像像素信息作为输入,最大程度上保留了输入图像的所有信息,通过卷积操作进行特征的提取和高层抽象,模型输出直接是图像识别的结果。这种基于"输入-输出"直接端到端的学习方法取得了非常好的效果,得到了广泛的应用。 一般来说,图像分类通过手工特征或特征学习方法对整个图像进行全部描述,然后使用分类器判别物体类别,因此如何提取图像的特征至关重要。在深度学习算法之前使用较多的是基于词袋(Bag of Words)模型的物体分类方法。而基于深度学习的图像分类方法,可以通过有监督或无监督的方式学习层次化的特征描述,从而取代了手工设计或选择图像特征的工作。深度学习模型中的卷积神经网络(Convolution Neural Network, CNN)近年来在图像领域取得了惊人的成绩,CNN 直接利用图像像素信息作为输入,最大程度上保留了输入图像的所有信息,通过卷积操作进行特征的提取和高层抽象,模型输出直接是图像识别的结果。这种基于"输入-输出"直接端到端的学习方法取得了非常好的效果,得到了广泛的应用。
图像分类是计算机视觉里很基础但又重要的一个领域,其研究成果一直影响着计算机视觉甚至深度学习的发展,图像分类有很多子领域,如多标签分类、细粒度分类等,此处只对单标签图像分类做一个简述。 图像分类是计算机视觉里很基础但又重要的一个领域,其研究成果一直影响着计算机视觉甚至深度学习的发展,图像分类有很多子领域,如多标签分类、细粒度分类等,此处只对单标签图像分类做一个简述。
<a name="1"></a> <a name="1"></a>
## 一、数据集介绍 ## 1. 数据集介绍
<a name="1.1"></a> <a name="1.1"></a>
### 1.1 ImageNet-1k ### 1.1 ImageNet-1k
ImageNet项目是一个大型视觉数据库,用于视觉目标识别软件研究。该项目已手动注释了1400多万张图像,以指出图片中的对象,并在至少100万张图像中提供了边框。ImageNet-1k是ImageNet数据集的子集,其包含1000个类别。训练集包含1281167个图像数据,验证集包含50000个图像数据。2010年以来,ImageNet项目每年举办一次图像分类竞赛,即ImageNet大规模视觉识别挑战赛(ILSVRC)。挑战赛使用的数据集即为ImageNet-1k。到目前为止,ImageNet-1k已经成为计算机视觉领域发展的最重要的数据集之一,其促进了整个计算机视觉的发展,很多计算机视觉下游任务的初始化模型都是基于该数据集训练得到的权重。 ImageNet 项目是一个大型视觉数据库,用于视觉目标识别软件研究。该项目已手动注释了 1400 多万张图像,以指出图片中的对象,并在至少 100 万张图像中提供了边框。ImageNet-1k 是 ImageNet 数据集的子集,其包含 1000 个类别。训练集包含 1281167 个图像数据,验证集包含 50000 个图像数据。2010 年以来,ImageNet 项目每年举办一次图像分类竞赛,即 ImageNet 大规模视觉识别挑战赛(ILSVRC)。挑战赛使用的数据集即为 ImageNet-1k。到目前为止,ImageNet-1k 已经成为计算机视觉领域发展的最重要的数据集之一,其促进了整个计算机视觉的发展,很多计算机视觉下游任务的初始化模型都是基于该数据集训练得到的权重。
<a name="1.2"></a> <a name="1.2"></a>
### 1.2 CIFAR-10/CIFAR-100 ### 1.2 CIFAR-10/CIFAR-100
CIFAR-10数据集由10个类的60000个彩色图像组成,图像分辨率为32x32,每个类有6000个图像,其中训练集5000张,验证集1000张,10个不同的类代表飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、轮船和卡车。CIFAR-100数据集是CIFAR-10的扩展,由100个类的60000个彩色图像组成,图像分辨率为32x32,每个类有600个图像,其中训练集500张,验证集100张。由于这两个数据集规模较小,因此可以让研究人员快速尝试不同的算法。这两个数据集也是图像分类领域测试模型好坏的常用数据集。 CIFAR-10 数据集由 10 个类的 60000 个彩色图像组成,图像分辨率为 32x32,每个类有 6000 个图像,其中训练集 5000 张,验证集 1000 张,10 个不同的类代表飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、轮船和卡车。CIFAR-100 数据集是 CIFAR-10 的扩展,由 100 个类的 60000 个彩色图像组成,图像分辨率为 32x32,每个类有 600 个图像,其中训练集 500 张,验证集 100 张。由于这两个数据集规模较小,因此可以让研究人员快速尝试不同的算法。这两个数据集也是图像分类领域测试模型好坏的常用数据集。
<a name="2"></a> <a name="2"></a>
## 二、图像分类的流程 ## 2. 图像分类的流程
将准备好的训练数据做相应的数据预处理后经过图像分类模型,模型的输出与真实标签做交叉熵损失函数,该损失函数描述了模型的收敛方向,遍历所有的图片数据输入模型,对最终损失函数通过某些优化器做相应的梯度下降,将梯度信息回传到模型中,更新模型的权重,如此循环往复遍历多次数据,即可得到一个图像分类的模型。 将准备好的训练数据做相应的数据预处理后经过图像分类模型,模型的输出与真实标签做交叉熵损失函数,该损失函数描述了模型的收敛方向,遍历所有的图片数据输入模型,对最终损失函数通过某些优化器做相应的梯度下降,将梯度信息回传到模型中,更新模型的权重,如此循环往复遍历多次数据,即可得到一个图像分类的模型。
<a name="2.1"></a> <a name="2.1"></a>
### 2.1 数据及其预处理 ### 2.1 数据及其预处理
数据的质量及数量往往可以决定一个模型的好坏。在图像分类领域,数据包括图像及标签。在大部分情形下,带有标签的数据比较匮乏,所以数量很难达到使模型饱和的程度,为了可以使模型学习更多的图像特征,图像数据在进入模型之前要经过很多图像变换或者数据增强,来保证输入图像数据的多样性,从而保证模型有更好的泛化能力。PaddleClas提供了训练ImageNet-1k的标准图像变换,也提供了8中数据增强的方法,相关代码可以[数据处理](../../../ppcls/data/preprocess),配置文件可以参考[数据增强配置文件](../../../ppcls/configs/ImageNet/DataAugment) 数据的质量及数量往往可以决定一个模型的好坏。在图像分类领域,数据包括图像及标签。在大部分情形下,带有标签的数据比较匮乏,所以数量很难达到使模型饱和的程度,为了可以使模型学习更多的图像特征,图像数据在进入模型之前要经过很多图像变换或者数据增强,来保证输入图像数据的多样性,从而保证模型有更好的泛化能力。PaddleClas 提供了训练 ImageNet-1k 的标准图像变换,也提供了 8 中数据增强的方法,相关代码可以[数据处理](../../../ppcls/data/preprocess),配置文件可以参考[数据增强配置文件](../../../ppcls/configs/ImageNet/DataAugment)
<a name="2.2"></a> <a name="2.2"></a>
### 2.2 模型准备 ### 2.2 模型准备
在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了36个系列共175个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](./ImageNet_models.md) 在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas 提供了 36 个系列共 175 个 ImageNet 预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](./ImageNet_models.md)
<a name="2.3"></a> <a name="2.3"></a>
### 2.3 模型训练 ### 2.3 模型训练
在准备好数据、模型后,便可以开始迭代模型并更新模型的参数。经过多次迭代最终可以得到训练好的模型来做图像分类任务。图像分类的训练过程需要很多经验,涉及很多超参数的设置,PaddleClas提供了一些列的[训练调优方法](../models/Tricks.md),可以快速助你获得高精度的模型。 在准备好数据、模型后,便可以开始迭代模型并更新模型的参数。经过多次迭代最终可以得到训练好的模型来做图像分类任务。图像分类的训练过程需要很多经验,涉及很多超参数的设置,PaddleClas 提供了一些列的[训练调优方法](../models/Tricks.md),可以快速助你获得高精度的模型。
<a name="2.4"></a> <a name="2.4"></a>
### 2.4 模型评估 ### 2.4 模型评估
当训练得到一个模型之后,如何确定模型的好坏,需要将模型在验证集上进行评估。评估指标一般是Top1-Acc或者Top5-Acc,该指标越高往往代表模型性能越好。 当训练得到一个模型之后,如何确定模型的好坏,需要将模型在验证集上进行评估。评估指标一般是 Top1-Acc 或者 Top5-Acc,该指标越高往往代表模型性能越好。
<a name="3"></a> <a name="3"></a>
## 三、主要算法简介 ## 3. 主要算法简介
- LeNet:Yan LeCun等人于上个世纪九十年代第一次将卷积神经网络应用到图像分类任务上,创造性的提出了LeNet,在手写数字识别任务上取得了巨大的成功。 - LeNet:Yan LeCun 等人于上个世纪九十年代第一次将卷积神经网络应用到图像分类任务上,创造性的提出了 LeNet,在手写数字识别任务上取得了巨大的成功。
- AlexNet:Alex Krizhevsky等人在2012年提出了AlexNet,并应用于ImageNet上,获得了2012年ImageNet分类比赛的冠军,从此,掀起了深度学习的热潮。 - AlexNet:Alex Krizhevsky 等人在 2012 年提出了 AlexNet,并应用于 ImageNet 上,获得了 2012 年 ImageNet 分类比赛的冠军,从此,掀起了深度学习的热潮。
- VGG:Simonyan和Zisserman于2014年提出了VGG网络结构,该网络结构使用了更小的卷积核堆叠整个网络,在ImageNet分类上取得了更好的性能,也为之后的网络结构设计提供了新的思路。 - VGG:Simonyan 和 Zisserman 于 2014 年提出了 VGG 网络结构,该网络结构使用了更小的卷积核堆叠整个网络,在 ImageNet 分类上取得了更好的性能,也为之后的网络结构设计提供了新的思路。
- GoogLeNet:Christian Szegedy等人在2014年提出了GoogLeNet,该网络使用了多分支结构和全局平均池化层(GAP),在保持模型精度的同时,模型存储和计算量大大缩减。该网络取得了2014年ImageNet分类比赛的冠军。 - GoogLeNet:Christian Szegedy 等人在 2014 年提出了 GoogLeNet,该网络使用了多分支结构和全局平均池化层(GAP),在保持模型精度的同时,模型存储和计算量大大缩减。该网络取得了 2014 年 ImageNet 分类比赛的冠军。
- ResNet:Kaiming He等人在2015年提出了ResNet,通过引入残差模块加深了网络的深度,最终该网络将ImageNet分类的识别错误率降低到了3.6\%,首次超出正常人眼的识别精度。 - ResNet:Kaiming He 等人在 2015 年提出了 ResNet,通过引入残差模块加深了网络的深度,最终该网络将 ImageNet 分类的识别错误率降低到了 3.6\%,首次超出正常人眼的识别精度。
- DenseNet:Huang Gao等人在2017年提出了DenseNet,该网络设计了一种更稠密连接的block,在更小的参数量上获得了更高的性能。 - DenseNet:Huang Gao 等人在 2017 年提出了 DenseNet,该网络设计了一种更稠密连接的 block,在更小的参数量上获得了更高的性能。
- EfficientNet:Mingxing Tan等人在2019年提出了EfficientNet,该网络平衡了网络的宽度、网络的深度、以及输入图片的分辨率,在同样FLOPS与参数量的情况下,精度达到了state-of-the-art的效果。 - EfficientNet:Mingxing Tan 等人在 2019 年提出了 EfficientNet,该网络平衡了网络的宽度、网络的深度、以及输入图片的分辨率,在同样 FLOPS 与参数量的情况下,精度达到了 state-of-the-art 的效果。
关于更多的算法介绍,请参考[算法介绍](../models) 关于更多的算法介绍,请参考[算法介绍](../models)
# 知识蒸馏 # 知识蒸馏
---
## 1. 模型压缩和知识蒸馏方法简介 ## 目录
* [1. 模型压缩和知识蒸馏方法简介](#1)
* [2. 知识蒸馏应用](#2)
* [3. 知识蒸馏算法介绍](#3)
* [3.1 Response based distillation](#3.1)
* [3.2 Feature based distillation](#3.2)
* [3.3 Relation based distillation](#3.3)
* [4. 参考文献](#4)
<a name='1'></a>
## 1. 模型压缩和知识蒸馏方法简介
近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。 近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。
...@@ -15,8 +24,8 @@ ...@@ -15,8 +24,8 @@
* Feature based distillation:教师模型对学生模型的中间层 feature map 进行监督。 * Feature based distillation:教师模型对学生模型的中间层 feature map 进行监督。
* Relation based distillation:对于不同的样本,使用教师模型和学生模型同时计算样本之间 feature map 的相关性,使得学生模型和教师模型得到的相关性矩阵尽可能一致。 * Relation based distillation:对于不同的样本,使用教师模型和学生模型同时计算样本之间 feature map 的相关性,使得学生模型和教师模型得到的相关性矩阵尽可能一致。
<a name='2'></a>
## 2. 知识蒸馏应用 ## 2. 知识蒸馏应用
知识蒸馏算法在模型轻量化过程任务中应用广泛,对于需要满足特定的精度的任务,通过使用知识蒸馏的方法,我们可以使用更小的模型便能达到要求的精度,从而减小了模型部署的成本。 知识蒸馏算法在模型轻量化过程任务中应用广泛,对于需要满足特定的精度的任务,通过使用知识蒸馏的方法,我们可以使用更小的模型便能达到要求的精度,从而减小了模型部署的成本。
...@@ -24,25 +33,25 @@ ...@@ -24,25 +33,25 @@
此外,对于相同的模型结构,使用知识蒸馏训练得到的预训练模型精度往往更高,这些预训练模型往往也可以提升下游任务的模型精度。比如在图像分类任务中,基于知识蒸馏算法得到的精度更高的预训练模型,也能够在目标检测、图像分割、OCR、视频分类等任务中获得明显的精度收益。 此外,对于相同的模型结构,使用知识蒸馏训练得到的预训练模型精度往往更高,这些预训练模型往往也可以提升下游任务的模型精度。比如在图像分类任务中,基于知识蒸馏算法得到的精度更高的预训练模型,也能够在目标检测、图像分割、OCR、视频分类等任务中获得明显的精度收益。
<a name='3'></a>
## 3. 知识蒸馏算法介绍 ## 3. 知识蒸馏算法介绍
<a name='3.1'></a>
### 3.1 Response based distillation ### 3.1 Response based distillation
最早的知识蒸馏算法KD,由Hinton提出,训练的损失函数中除了 gt loss 之外,还引入了学生模型与教师模型输出的 KL 散度,最终精度超过单纯使用 gt loss 训练的精度。这里需要注意的是,在训练的时候,需要首先训练得到一个更大的教师模型,来指导学生模型的训练过程。 最早的知识蒸馏算法 KD,由 Hinton 提出,训练的损失函数中除了 gt loss 之外,还引入了学生模型与教师模型输出的 KL 散度,最终精度超过单纯使用 gt loss 训练的精度。这里需要注意的是,在训练的时候,需要首先训练得到一个更大的教师模型,来指导学生模型的训练过程。
PaddleClas 中提出了一种简单使用的 SSLD 知识蒸馏算法 [6],在训练的时候去除了对 gt label 的依赖,结合大量无标注数据,最终蒸馏训练得到的预训练模型在 15 个模型上的精度提升平均高达 3%。 PaddleClas 中提出了一种简单使用的 SSLD 知识蒸馏算法 [6],在训练的时候去除了对 gt label 的依赖,结合大量无标注数据,最终蒸馏训练得到的预训练模型在 15 个模型上的精度提升平均高达 3%。
上述标准的蒸馏方法是通过一个大模型作为教师模型来指导学生模型提升效果,而后来又发展出 DML (Deep Mutual Learning) 互学习蒸馏方法 [7],即通过两个结构相同的模型互相学习。具体的。相比于 KD 等依赖于大的教师模型的知识蒸馏算法,DML 脱离了对大的教师模型的依赖,蒸馏训练的流程更加简单,模型产出效率也要更高一些。 上述标准的蒸馏方法是通过一个大模型作为教师模型来指导学生模型提升效果,而后来又发展出 DML (Deep Mutual Learning) 互学习蒸馏方法 [7],即通过两个结构相同的模型互相学习。具体的。相比于 KD 等依赖于大的教师模型的知识蒸馏算法,DML 脱离了对大的教师模型的依赖,蒸馏训练的流程更加简单,模型产出效率也要更高一些。
<a name='3.2'></a>
### 3.2 Feature based distillation ### 3.2 Feature based distillation
Heo 等人提出了 OverHaul [8], 计算学生模型与教师模型的 feature map distance,作为蒸馏的 loss,在这里使用了学生模型、教师模型的转移,来保证二者的 feature map 可以正常地进行 distance 的计算。 Heo 等人提出了 OverHaul [8], 计算学生模型与教师模型的 feature map distance,作为蒸馏的 loss,在这里使用了学生模型、教师模型的转移,来保证二者的 feature map 可以正常地进行 distance 的计算。
基于 feature map distance 的知识蒸馏方法也能够和 `3.1章节` 中的基于 response 的知识蒸馏算法融合在一起,同时对学生模型的输出结果和中间层 feature map 进行监督。而对于 DML 方法来说,这种融合过程更为简单,因为不需要对学生和教师模型的 feature map 进行转换,便可以完成对齐 (alignment) 过程。PP-OCRv2 系统中便使用了这种方法,最终大幅提升了 OCR 文字识别模型的精度。 基于 feature map distance 的知识蒸馏方法也能够和 `3.1 章节` 中的基于 response 的知识蒸馏算法融合在一起,同时对学生模型的输出结果和中间层 feature map 进行监督。而对于 DML 方法来说,这种融合过程更为简单,因为不需要对学生和教师模型的 feature map 进行转换,便可以完成对齐 (alignment) 过程。PP-OCRv2 系统中便使用了这种方法,最终大幅提升了 OCR 文字识别模型的精度。
<a name='3.3'></a>
### 3.3 Relation based distillation ### 3.3 Relation based distillation
 
...@@ -53,7 +62,7 @@ Park 等人提出了 RKD [10],基于关系的知识蒸馏算法,RKD 中进 ...@@ -53,7 +62,7 @@ Park 等人提出了 RKD [10],基于关系的知识蒸馏算法,RKD 中进
本论文提出的算法关系知识蒸馏(RKD)迁移教师模型得到的输出结果间的结构化关系给学生模型,不同于之前的只关注个体输出结果,RKD 算法使用两种损失函数:二阶的距离损失 (distance-wise) 和三阶的角度损失 (angle-wise)。在最终计算蒸馏损失函数的时候,同时考虑KD loss 和 RKD loss。最终精度优于单独使用 KD loss 蒸馏得到的模型精度。 本论文提出的算法关系知识蒸馏(RKD)迁移教师模型得到的输出结果间的结构化关系给学生模型,不同于之前的只关注个体输出结果,RKD 算法使用两种损失函数:二阶的距离损失 (distance-wise) 和三阶的角度损失 (angle-wise)。在最终计算蒸馏损失函数的时候,同时考虑KD loss 和 RKD loss。最终精度优于单独使用 KD loss 蒸馏得到的模型精度。
<a name='4'></a>
## 4. 参考文献 ## 4. 参考文献
[1] Hinton G, Vinyals O, Dean J. Distilling the knowledge in a neural network[J]. arXiv preprint arXiv:1503.02531, 2015. [1] Hinton G, Vinyals O, Dean J. Distilling the knowledge in a neural network[J]. arXiv preprint arXiv:1503.02531, 2015.
......
# Metric Learning # Metric Learning
----
## 目录
## 简介 * [1. 简介](#1)
在机器学习中,我们经常会遇到度量数据间距离的问题。一般来说,对于可度量的数据,我们可以直接通过欧式距离(Euclidean Distance),向量内积(Inner Product)或者是余弦相似度(Cosine Similarity)来进行计算。但对于非结构化数据来说,我们却很难进行这样的操作,如计算一段视频和一首音乐的匹配程度。由于数据格式的不同,我们难以直接进行上述的向量运算,但先验知识告诉我们ED(laugh_video, laugh_music) < ED(laugh_video, blue_music), 如何去有效得表征这种”距离”关系呢? 这就是Metric Learning所要研究的课题。 * [2. 应用](#2)
* [3. 算法](#3)
Metric learning全称是 Distance Metric Learning,它是通过机器学习的形式,根据训练数据,自动构造出一种基于特定任务的度量函数。Metric Learning的目标是学习一个变换函数(线性非线性均可)L,将数据点从原始的向量空间映射到一个新的向量空间,在新的向量空间里相似点的距离更近,非相似点的距离更远,使得度量更符合任务的要求,如下图所示。 Deep Metric Learning,就是用深度神经网络来拟合这个变换函数。 * [3.1 Classification based](#3.1)
* [3.2 Pairwise based](#3.2)
<a name='1'></a>
## 1. 简介
在机器学习中,我们经常会遇到度量数据间距离的问题。一般来说,对于可度量的数据,我们可以直接通过欧式距离(Euclidean Distance),向量内积(Inner Product)或者是余弦相似度(Cosine Similarity)来进行计算。但对于非结构化数据来说,我们却很难进行这样的操作,如计算一段视频和一首音乐的匹配程度。由于数据格式的不同,我们难以直接进行上述的向量运算,但先验知识告诉我们 ED(laugh_video, laugh_music) < ED(laugh_video, blue_music), 如何去有效得表征这种”距离”关系呢? 这就是 Metric Learning 所要研究的课题。
Metric learning 全称是 Distance Metric Learning,它是通过机器学习的形式,根据训练数据,自动构造出一种基于特定任务的度量函数。Metric Learning 的目标是学习一个变换函数(线性非线性均可)L,将数据点从原始的向量空间映射到一个新的向量空间,在新的向量空间里相似点的距离更近,非相似点的距离更远,使得度量更符合任务的要求,如下图所示。 Deep Metric Learning,就是用深度神经网络来拟合这个变换函数。
![example](../../images/ml_illustration.jpg) ![example](../../images/ml_illustration.jpg)
<a name='2'></a>
## 2. 应用
Metric Learning 技术在生活实际中应用广泛,如我们耳熟能详的人脸识别(Face Recognition)、行人重识别(Person ReID)、图像检索(Image Retrieval)、细粒度分类(Fine-gained classification)等. 随着深度学习在工业实践中越来越广泛的应用,目前大家研究的方向基本都偏向于 Deep Metric Learning(DML).
## 应用 一般来说, DML 包含三个部分: 特征提取网络来 map embedding, 一个采样策略来将一个 mini-batch 里的样本组合成很多个 sub-set, 最后 loss function 在每个 sub-set 上计算 loss. 如下图所示:
Metric Learning技术在生活实际中应用广泛,如我们耳熟能详的人脸识别(Face Recognition)、行人重识别(Person ReID)、图像检索(Image Retrieval)、细粒度分类(Fine-gained classification)等. 随着深度学习在工业实践中越来越广泛的应用,目前大家研究的方向基本都偏向于Deep Metric Learning(DML).
一般来说, DML包含三个部分: 特征提取网络来map embedding, 一个采样策略来将一个mini-batch里的样本组合成很多个sub-set, 最后loss function在每个sub-set上计算loss. 如下图所示:
![image](../../images/ml_pipeline.jpg) ![image](../../images/ml_pipeline.jpg)
<a name='3'></a>
## 算法 ## 3. 算法
Metric Learning主要有如下两种学习范式: Metric Learning 主要有如下两种学习范式:
### 1. Classification based: <a name='3.1'></a>
这是一类基于分类标签的Metric Learning方法。这类方法通过将每个样本分类到正确的类别中,来学习有效的特征表示,学习过程中需要每个样本的显式标签参与Loss计算。常见的算法有[L2-Softmax](https://arxiv.org/abs/1703.09507), [Large-margin Softmax](https://arxiv.org/abs/1612.02295), [Angular Softmax](https://arxiv.org/pdf/1704.08063.pdf), [NormFace](https://arxiv.org/abs/1704.06369), [AM-Softmax](https://arxiv.org/abs/1801.05599), [CosFace](https://arxiv.org/abs/1801.09414), [ArcFace](https://arxiv.org/abs/1801.07698)等。 ### 3.1 Classification based:
这类方法也被称作是proxy-based, 因为其本质上优化的是样本和一堆proxies之间的相似度。 这是一类基于分类标签的 Metric Learning 方法。这类方法通过将每个样本分类到正确的类别中,来学习有效的特征表示,学习过程中需要每个样本的显式标签参与 Loss 计算。常见的算法有 [L2-Softmax](https://arxiv.org/abs/1703.09507), [Large-margin Softmax](https://arxiv.org/abs/1612.02295), [Angular Softmax](https://arxiv.org/pdf/1704.08063.pdf), [NormFace](https://arxiv.org/abs/1704.06369), [AM-Softmax](https://arxiv.org/abs/1801.05599), [CosFace](https://arxiv.org/abs/1801.09414), [ArcFace](https://arxiv.org/abs/1801.07698)等。
### 2. Pairwise based: 这类方法也被称作是 proxy-based, 因为其本质上优化的是样本和一堆 proxies 之间的相似度。
<a name='3.2'></a>
### 3.2 Pairwise based:
这是一类基于样本对的学习范式。他以样本对作为输入,通过直接学习样本对之间的相似度来得到有效的特征表示,常见的算法包括:[Contrastive loss](http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf), [Triplet loss](https://arxiv.org/abs/1503.03832), [Lifted-Structure loss](https://arxiv.org/abs/1511.06452), [N-pair loss](https://papers.nips.cc/paper/2016/file/6b180037abbebea991d8b1232f8a8ca9-Paper.pdf), [Multi-Similarity loss](https://arxiv.org/pdf/1904.06627.pdf) 这是一类基于样本对的学习范式。他以样本对作为输入,通过直接学习样本对之间的相似度来得到有效的特征表示,常见的算法包括:[Contrastive loss](http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf), [Triplet loss](https://arxiv.org/abs/1503.03832), [Lifted-Structure loss](https://arxiv.org/abs/1511.06452), [N-pair loss](https://papers.nips.cc/paper/2016/file/6b180037abbebea991d8b1232f8a8ca9-Paper.pdf), [Multi-Similarity loss](https://arxiv.org/pdf/1904.06627.pdf)
2020年发表的[CircleLoss](https://arxiv.org/abs/2002.10857),从一个全新的视角统一了两种学习范式,让研究人员和从业者对Metric Learning问题有了更进一步的思考。 2020 年发表的[CircleLoss](https://arxiv.org/abs/2002.10857),从一个全新的视角统一了两种学习范式,让研究人员和从业者对 Metric Learning 问题有了更进一步的思考。
# 模型裁剪、量化算法介绍 # 模型裁剪、量化算法介绍
深度学习因其计算复杂度或参数冗余,在一些场景和设备上限制了相应的模型部署,需要借助模型压缩、优化加速、异构计算等方法突破瓶颈。模型压缩算法能够有效降低参数冗余,从而减少存储占用、通信带宽和计算复杂度,有助于深度学习的应用部署。其中模型量化、裁剪应用比较广泛。在PaddleClas中,主要应该应用以下两种算法。 深度学习因其计算复杂度或参数冗余,在一些场景和设备上限制了相应的模型部署,需要借助模型压缩、优化加速、异构计算等方法突破瓶颈。模型压缩算法能够有效降低参数冗余,从而减少存储占用、通信带宽和计算复杂度,有助于深度学习的应用部署。其中模型量化、裁剪应用比较广泛。在 PaddleClas 中,主要应该应用以下两种算法。
- 量化方法:PACT量化 - 量化方法:PACT 量化
- 裁剪:FPGM裁剪 - 裁剪:FPGM 裁剪
其中具体算法参数请参考[PaddeSlim](https://github.com/PaddlePaddle/PaddleSlim/) 其中具体算法参数请参考 [PaddeSlim](https://github.com/PaddlePaddle/PaddleSlim/)
## PACT量化方法 ## 目录
模型量化主要包括两个部分,一是对权重Weight量化,一是针对激活值Activation量化。同时对两部分进行量化,才能获得最大的计算效率收益。权重可以借助网络正则化等手段,让权重分布尽量紧凑,减少离群点、不均匀分布情况发生,而对于激活值还缺乏有效的手段。 * [1. PACT 量化方法](#1)
* [2. FPGM 裁剪](#2)
**PACT量化(PArameterized Clipping acTivation**是一种新的量化方法,该方法通过在量化激活值之前去掉一些离群点,将模型量化带来的精度损失降到最低,甚至比原模型准确率更高。提出方法的背景是作者发现:“在运用权重量化方案来量化activation时,激活值的量化结果和全精度结果相差较大”。作者发现,activation的量化可能引起的误差很大(相较于weight基本在 0到1范围内,activation的值的范围是无限大的,这是RELU的结果),所以提出**截断式RELU** 的激活函数。该截断的上界,即$α$ 是可学习的参数,这保证了每层能够通过训练学习到不一样的量化范围,最大程度降低量化带来的舍入误差。其中量化的示意图如下图所示,**PACT**解决问题的方法是,不断裁剪激活值范围,使得激活值分布收窄,从而降低量化映射损失。**PACT**通过对激活数值做裁剪,从而减少激活分布中的离群点,使量化模型能够得到一个更合理的量化scale,降低量化损失。 <a name='1'></a>
## 1. PACT 量化方法
模型量化主要包括两个部分,一是对权重 Weight 量化,一是针对激活值 Activation 量化。同时对两部分进行量化,才能获得最大的计算效率收益。权重可以借助网络正则化等手段,让权重分布尽量紧凑,减少离群点、不均匀分布情况发生,而对于激活值还缺乏有效的手段。
**PACT 量化(PArameterized Clipping acTivation**是一种新的量化方法,该方法通过在量化激活值之前去掉一些离群点,将模型量化带来的精度损失降到最低,甚至比原模型准确率更高。提出方法的背景是作者发现:“在运用权重量化方案来量化 activation 时,激活值的量化结果和全精度结果相差较大”。作者发现,activation 的量化可能引起的误差很大(相较于 weight 基本在 0 到 1 范围内,activation 的值的范围是无限大的,这是 RELU 的结果),所以提出**截断式 RELU** 的激活函数。该截断的上界,即$α$ 是可学习的参数,这保证了每层能够通过训练学习到不一样的量化范围,最大程度降低量化带来的舍入误差。其中量化的示意图如下图所示,**PACT** 解决问题的方法是,不断裁剪激活值范围,使得激活值分布收窄,从而降低量化映射损失。**PACT** 通过对激活数值做裁剪,从而减少激活分布中的离群点,使量化模型能够得到一个更合理的量化 scale,降低量化损失。
<div align="center"> <div align="center">
<img src="../../images/algorithm_introduction/quantization.jpg" width = "600" /> <img src="../../images/algorithm_introduction/quantization.jpg" width = "600" />
</div> </div>
**PACT**量化公式如下: **PACT** 量化公式如下:
<div align="center"> <div align="center">
<img src="../../images/algorithm_introduction/quantization_formula.png" width = "800" height="100"/> <img src="../../images/algorithm_introduction/quantization_formula.png" width = "800" height="100"/>
...@@ -26,7 +32,7 @@ ...@@ -26,7 +32,7 @@
可以看出PACT思想是用上述量化代替*ReLU*函数,对大于零的部分进行一个截断操作,截断阈值为$a$。但是在*PaddleSlim*中对上述公式做了进一步的改进,其改进如下: 可以看出 PACT 思想是用上述量化代替 *ReLU* 函数,对大于零的部分进行一个截断操作,截断阈值为$a$。但是在*PaddleSlim*中对上述公式做了进一步的改进,其改进如下:
<div align="center"> <div align="center">
<img src="../../images/algorithm_introduction/quantization_formula_slim.png" width = "550" height="120"/> <img src="../../images/algorithm_introduction/quantization_formula_slim.png" width = "550" height="120"/>
...@@ -34,18 +40,19 @@ ...@@ -34,18 +40,19 @@
经过如上改进后,在激活值和待量化的OP(卷积,全连接等)之间插入*PACT*预处理,不只对大于0的分布进行截断,同时也对小于0的部分做同样的限制,从而更好地得到待量化的范围,降低量化损失。同时,截断阈值是一个可训练的参数,在量化训练过程中,模型会自动的找到一个合理的截断阈值,从而进一步降低量化精度损失。 经过如上改进后,在激活值和待量化的 OP(卷积,全连接等)之间插入 *PACT* 预处理,不只对大于 0 的分布进行截断,同时也对小于 0 的部分做同样的限制,从而更好地得到待量化的范围,降低量化损失。同时,截断阈值是一个可训练的参数,在量化训练过程中,模型会自动的找到一个合理的截断阈值,从而进一步降低量化精度损失。
算法具体参数请参考PaddleSlim[参数介绍](https://github.com/PaddlePaddle/PaddleSlim/blob/release/2.0.0/docs/zh_cn/api_cn/dygraph/quanter/qat.rst#qat) 算法具体参数请参考 PaddleSlim [参数介绍](https://github.com/PaddlePaddle/PaddleSlim/blob/release/2.0.0/docs/zh_cn/api_cn/dygraph/quanter/qat.rst#qat)
## FPGM裁剪 <a name='2'></a>
## FPGM 裁剪
模型剪枝是减小模型大小,提升预测效率的一种非常重要的手段。在之前的网络剪枝文章中一般将网络filter的范数作为其重要性度量,**范数值较小的代表的filter越不重要**,将其从网络中裁剪掉,反之也就越重要。而**FPGM**认为之前的方法要依赖如下两点 模型剪枝是减小模型大小,提升预测效率的一种非常重要的手段。在之前的网络剪枝文章中一般将网络 filter 的范数作为其重要性度量,**范数值较小的代表的 filter 越不重要**,将其从网络中裁剪掉,反之也就越重要。而**FPGM**认为之前的方法要依赖如下两点
- filter的范数偏差应该比较大,这样重要和非重要的filter才可以很好区分开 - filter 的范数偏差应该比较大,这样重要和非重要的 filter 才可以很好区分开
- 不重要的filter的范数应该足够的小 - 不重要的 filter 的范数应该足够的小
基于此,**FPGM**利用层中filter的几何中心特性,由于那些靠近中心的filter可以被其它的表达,因而可以将其剔除,从而避免了上面提到的两点剪枝条件,从信息的冗余度出发,而不是选择范数少的进行剪枝。下图展示了**FPGM**方法与之前方法的不同,具体细节请详看[论文](https://openaccess.thecvf.com/content_CVPR_2019/papers/He_Filter_Pruning_via_Geometric_Median_for_Deep_Convolutional_Neural_Networks_CVPR_2019_paper.pdf) 基于此,**FPGM**利用层中 filter 的几何中心特性,由于那些靠近中心的 filter 可以被其它的表达,因而可以将其剔除,从而避免了上面提到的两点剪枝条件,从信息的冗余度出发,而不是选择范数少的进行剪枝。下图展示了 **FPGM** 方法与之前方法的不同,具体细节请详看[论文](https://openaccess.thecvf.com/content_CVPR_2019/papers/He_Filter_Pruning_via_Geometric_Median_for_Deep_Convolutional_Neural_Networks_CVPR_2019_paper.pdf)
<div align="center"> <div align="center">
<img src="../../images/algorithm_introduction/fpgm.png" width = "600" /> <img src="../../images/algorithm_introduction/fpgm.png" width = "600" />
...@@ -54,4 +61,4 @@ ...@@ -54,4 +61,4 @@
算法具体参数请参考PaddleSlim[参数介绍](https://github.com/PaddlePaddle/PaddleSlim/blob/release/2.0.0/docs/zh_cn/api_cn/dygraph/pruners/fpgm_filter_pruner.rst#fpgmfilterpruner) 算法具体参数请参考 PaddleSlim [参数介绍](https://github.com/PaddlePaddle/PaddleSlim/blob/release/2.0.0/docs/zh_cn/api_cn/dygraph/pruners/fpgm_filter_pruner.rst#fpgmfilterpruner)
...@@ -6,16 +6,16 @@ ...@@ -6,16 +6,16 @@
## 目录 ## 目录
- [数据集格式说明](#数据集格式说明) - [1. 数据集格式说明](#1)
- [图像分类任务常见数据集介绍](#图像分类任务常见数据集介绍) - [2. 图像分类任务常见数据集介绍](#2)
- [2.1 ImageNet1k](#ImageNet1k) - [2.1 ImageNet1k](#2.1)
- [2.2 Flowers102](#Flowers102) - [2.2 Flowers102](#2.2)
- [2.3 CIFAR10 / CIFAR100](#CIFAR10/CIFAR100) - [2.3 CIFAR10 / CIFAR100](#2.3)
- [2.4 MNIST](#MNIST) - [2.4 MNIST](#2.4)
- [2.5 NUS-WIDE](#NUS-WIDE) - [2.5 NUS-WIDE](#2.5)
<a name="数据集格式说明"></a> <a name="1"></a>
## 一、数据集格式说明 ## 1. 数据集格式说明
PaddleClas 使用 `txt` 格式文件指定训练集和测试集,以 `ImageNet1k` 数据集为例,其中 `train_list.txt``val_list.txt` 的格式形如: PaddleClas 使用 `txt` 格式文件指定训练集和测试集,以 `ImageNet1k` 数据集为例,其中 `train_list.txt``val_list.txt` 的格式形如:
...@@ -30,12 +30,12 @@ train/n01440764/n01440764_10026.JPEG 0 ...@@ -30,12 +30,12 @@ train/n01440764/n01440764_10026.JPEG 0
val/ILSVRC2012_val_00000001.JPEG 65 val/ILSVRC2012_val_00000001.JPEG 65
... ...
``` ```
<a name="图像分类任务常见数据集介绍"></a> <a name="2"></a>
## 二、 图像分类任务常见数据集介绍 ## 2. 图像分类任务常见数据集介绍
这里整理了常用的图像分类任务数据集,持续更新中,欢迎各位小伙伴补充完善~ 这里整理了常用的图像分类任务数据集,持续更新中,欢迎各位小伙伴补充完善~
<a name="ImageNet1k"></a> <a name="2.1"></a>
### 2.1 ImageNet1k ### 2.1 ImageNet1k
[ImageNet](https://image-net.org/)项目是一个大型视觉数据库,用于视觉目标识别研究任务,该项目已手动标注了 1400 多万张图像。ImageNet-1k 是 ImageNet 数据集的子集,其包含 1000 个类别。训练集包含 1281167 个图像数据,验证集包含 50000 个图像数据。2010 年以来,ImageNet 项目每年举办一次图像分类竞赛,即 ImageNet 大规模视觉识别挑战赛(ILSVRC)。挑战赛使用的数据集即为 ImageNet-1k。到目前为止,ImageNet-1k 已经成为计算机视觉领域发展的最重要的数据集之一,其促进了整个计算机视觉的发展,很多计算机视觉下游任务的初始化模型都是基于该数据集训练得到的。 [ImageNet](https://image-net.org/)项目是一个大型视觉数据库,用于视觉目标识别研究任务,该项目已手动标注了 1400 多万张图像。ImageNet-1k 是 ImageNet 数据集的子集,其包含 1000 个类别。训练集包含 1281167 个图像数据,验证集包含 50000 个图像数据。2010 年以来,ImageNet 项目每年举办一次图像分类竞赛,即 ImageNet 大规模视觉识别挑战赛(ILSVRC)。挑战赛使用的数据集即为 ImageNet-1k。到目前为止,ImageNet-1k 已经成为计算机视觉领域发展的最重要的数据集之一,其促进了整个计算机视觉的发展,很多计算机视觉下游任务的初始化模型都是基于该数据集训练得到的。
...@@ -65,7 +65,7 @@ PaddleClas/dataset/ILSVRC2012/ ...@@ -65,7 +65,7 @@ PaddleClas/dataset/ILSVRC2012/
|_ val_list.txt |_ val_list.txt
``` ```
<a name="Flowers102"></a> <a name="2.2"></a>
### 2.2 Flowers102 ### 2.2 Flowers102
数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注| 数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注|
...@@ -101,21 +101,21 @@ PaddleClas/dataset/flowers102/ ...@@ -101,21 +101,21 @@ PaddleClas/dataset/flowers102/
|_ val_list.txt |_ val_list.txt
``` ```
<a name="CIFAR10/CIFAR100"></a> <a name="2.3"></a>
### 2.3 CIFAR10 / CIFAR100 ### 2.3 CIFAR10 / CIFAR100
CIFAR-10 数据集由 10 个类的 60000 个彩色图像组成,图像分辨率为 32x32,每个类有 6000 个图像,其中训练集 5000 张,验证集 1000 张,10 个不同的类代表飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、轮船和卡车。CIFAR-100 数据集是CIFAR-10的扩展,由 100 个类的 60000 个彩色图像组成,图像分辨率为 32x32,每个类有 600 个图像,其中训练集 500 张,验证集 100 张。 CIFAR-10 数据集由 10 个类的 60000 个彩色图像组成,图像分辨率为 32x32,每个类有 6000 个图像,其中训练集 5000 张,验证集 1000 张,10 个不同的类代表飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、轮船和卡车。CIFAR-100 数据集是 CIFAR-10 的扩展,由 100 个类的 60000 个彩色图像组成,图像分辨率为 32x32,每个类有 600 个图像,其中训练集 500 张,验证集 100 张。
数据集地址:http://www.cs.toronto.edu/~kriz/cifar.html 数据集地址:http://www.cs.toronto.edu/~kriz/cifar.html
<a name="MNIST"></a> <a name="2.4"></a>
### 2.4 MNIST ### 2.4 MNIST
MMNIST是一个非常有名的手写体数字识别数据集,在很多资料中,这个数据集都会被用作深度学习的入门样例。其包含 60000 张图片数据,50000 张作为训练集,10000 张作为验证集,每张图片的大小为 28 * 28。 MMNIST 是一个非常有名的手写体数字识别数据集,在很多资料中,这个数据集都会被用作深度学习的入门样例。其包含 60000 张图片数据,50000 张作为训练集,10000 张作为验证集,每张图片的大小为 28 * 28。
数据集地址:http://yann.lecun.com/exdb/mnist/ 数据集地址:http://yann.lecun.com/exdb/mnist/
<a name="NUS-WIDE"></a> <a name="2.5"></a>
### 2.5 NUS-WIDE ### 2.5 NUS-WIDE
NUS-WIDE 是一个多分类数据集。该数据集包含 269648 张图片, 81 个类别, 每张图片被标记为该 81 个类别中的某一类或某几类。 NUS-WIDE 是一个多分类数据集。该数据集包含 269648 张图片, 81 个类别, 每张图片被标记为该 81 个类别中的某一类或某几类。
......
...@@ -7,18 +7,18 @@ ...@@ -7,18 +7,18 @@
## 目录 ## 目录
- [数据集格式说明](#数据集格式说明) - [1. 数据集格式说明](#1)
- [图像识别任务常见数据集介绍](#图像识别任务常见数据集介绍) - [2. 图像识别任务常见数据集介绍](#2)
- [2.1 通用图像识别数据集](#通用图像识别数据集) - [2.1 通用图像识别数据集](#2.1)
- [2.2 垂类图像识别数据集](#垂类图像识别数据集) - [2.2 垂类图像识别数据集](#2.2)
- [2.2.1 动漫人物识别](#动漫人物识别) - [2.2.1 动漫人物识别](#2.2.1)
- [2.2.2 商品识别](#商品识别) - [2.2.2 商品识别](#2.2.2)
- [2.2.3 Logo识别](#Logo识别) - [2.2.3 Logo 识别](#2.2.3)
- [2.2.4 车辆识别](#车辆识别) - [2.2.4 车辆识别](#2.2.4)
<a name="数据集格式说明"></a> <a name="1"></a>
## 一、数据集格式说明 ## 1. 数据集格式说明
与分类任务数据集不同,图像检索任务的数据集分为以下三部分: 与分类任务数据集不同,图像检索任务的数据集分为以下三部分:
...@@ -37,7 +37,7 @@ train/99/Ovenbird_0128_93366.jpg 99 6 ...@@ -37,7 +37,7 @@ train/99/Ovenbird_0128_93366.jpg 99 6
... ...
``` ```
验证数据集(`CUB_200_2011`中既是gallery dataset,也是query dataset) `test_list.txt` 文件内容格式如下所示: 验证数据集(`CUB_200_2011`中既是 gallery dataset,也是 query dataset) `test_list.txt` 文件内容格式如下所示:
```shell ```shell
# 采用"空格"作为分隔符号 # 采用"空格"作为分隔符号
...@@ -48,85 +48,85 @@ test/200/Common_Yellowthroat_0114_190501.jpg 200 6 ...@@ -48,85 +48,85 @@ test/200/Common_Yellowthroat_0114_190501.jpg 200 6
... ...
``` ```
每行数据使用“空格”分割,三列数据的含义分别是训练数据的路径、训练数据的label信息、训练数据的unique id。 每行数据使用“空格”分割,三列数据的含义分别是训练数据的路径、训练数据的 label 信息、训练数据的 unique id。
**注意** **注意**
1.gallery dataset和query dataset相同时,为了去掉检索得到的第一个数据(检索图片本身无须评估),每个数据需要对应一个unique id(每张图片的id不同即可,可以用行号来表示unique id),用于后续评测mAP、recall@1等指标。yaml配置文件的数据集选用`VeriWild` 1. gallery dataset 和 query dataset 相同时,为了去掉检索得到的第一个数据(检索图片本身无须评估),每个数据需要对应一个 unique id(每张图片的 id 不同即可,可以用行号来表示 unique id),用于后续评测 mAP、recall@1 等指标。yaml 配置文件的数据集选用`VeriWild`
2.gallery dataset和query dataset不同时,无需增加unique id,`query_list.txt``gallery_list.txt` 均为两列,分别是训练数据的路径、训练数据的label信息。yaml配置文件的数据集选用`ImageNetDataset` 2. gallery dataset 和 query dataset 不同时,无需增加 unique id,`query_list.txt``gallery_list.txt` 均为两列,分别是训练数据的路径、训练数据的 label 信息。yaml 配置文件的数据集选用`ImageNetDataset`
<a name="图像识别任务常见数据集介绍"></a> <a name="2"></a>
## 二、图像识别任务常见数据集介绍 ## 2. 图像识别任务常见数据集介绍
这里整理了常用的图像识别任务数据集,持续更新中,欢迎各位小伙伴补充完善~ 这里整理了常用的图像识别任务数据集,持续更新中,欢迎各位小伙伴补充完善~
<a name="通用图像识别数据集"></a> <a name="2.1"></a>
### 2.1 通用图像识别数据集 ### 2.1 通用图像识别数据集
- SOP: SOP数据集是通用识别研究领域、MetricLearning技术研究方向常用的一个商品数据集, 其包含从eBay.com下载的22,634个产品的120,053张图片。其中, 训练集包含图片59551张, 类别数11318; 验证集包含图片60502张,类别数11316个。 - SOP: SOP 数据集是通用识别研究领域、MetricLearning 技术研究方向常用的一个商品数据集, 其包含从 eBay.com 下载的 22,634 个产品的 120,053 张图片。其中, 训练集包含图片 59551 张, 类别数 11318; 验证集包含图片 60502 张,类别数 11316 个。
地址: https://cvgl.stanford.edu/projects/lifted_struct/ 地址: https://cvgl.stanford.edu/projects/lifted_struct/
- Cars196: - Cars196:
Cars数据集包含了196类汽车的16185张图像。数据被分成8144张训练图像和8041张测试图像,每个类大致以50-50的比例分割。级别通常是在制造,模型,年,例如2012特斯拉模型S或2012宝马M3双门跑车。 Cars 数据集包含了 196 类汽车的 16185 张图像。数据被分成 8144 张训练图像和 8041 张测试图像,每个类大致以 50-50 的比例分割。级别通常是在制造,模型,年,例如 2012 特斯拉模型 S 或 2012 宝马 M3 双门跑车。
地址: https://ai.stanford.edu/~jkrause/cars/car_dataset.html 地址: https://ai.stanford.edu/~jkrause/cars/car_dataset.html
- CUB_200_2011: CUB_200_2011数据集是由加州理工学院在2010年提出的细粒度数据集,也是目前细粒度分类识别研究的基准图像数据集。该数据集共有11788张鸟类图像,包含200类鸟类子类,其中训练数据集有5994张图像,测试集有5794张图像,每张图像均提供了图像类标记信息,图像中鸟的bounding box,鸟的关键part信息,以及鸟类的属性信息,数据集如下图所示。 - CUB_200_2011: CUB_200_2011 数据集是由加州理工学院在 2010 年提出的细粒度数据集,也是目前细粒度分类识别研究的基准图像数据集。该数据集共有 11788 张鸟类图像,包含 200 类鸟类子类,其中训练数据集有 5994 张图像,测试集有 5794 张图像,每张图像均提供了图像类标记信息,图像中鸟的 bounding box,鸟的关键 part 信息,以及鸟类的属性信息,数据集如下图所示。
地址: http://www.vision.caltech.edu/visipedia/CUB-200-2011.html 地址: http://www.vision.caltech.edu/visipedia/CUB-200-2011.html
- In-shop Clothes: In-shop Clothes 是DeepFashion数据集的4个子集之一, 它是一个卖家秀图片集,每个商品id,有多张不同角度的卖家秀,放在同一个文件夹内。该数据集共包含7982件商品,共52712张图像,每张图片都有463中属性,Bbox,landmarks,以及店铺描述。 - In-shop Clothes: In-shop Clothes 是 DeepFashion 数据集的 4 个子集之一, 它是一个卖家秀图片集,每个商品 id,有多张不同角度的卖家秀,放在同一个文件夹内。该数据集共包含 7982 件商品,共 52712 张图像,每张图片都有 463 中属性,Bbox,landmarks,以及店铺描述。
地址: http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion.html 地址: http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion.html
<a name="垂类图像识别数据集"></a> <a name="2.2"></a>
### 2.2 垂类图像识别数据集 ### 2.2 垂类图像识别数据集
<a name="动漫人物识别"></a> <a name="2.2.1"></a>
#### 2.2.1 动漫人物识别 #### 2.2.1 动漫人物识别
+ iCartoonFace: iCartoonFace是由爱奇艺开放的目前全球最大的手工标注卡通人物检测数据集与识别数据集,它包含超过5013个卡通人物、389678张高质量实景图片。相比于其他数据集,它具有大规模、高质量、多样性丰富、挑战难度大等特点,是目前研究动漫人物识别最常用的数据集之一。 + iCartoonFace: iCartoonFace 是由爱奇艺开放的目前全球最大的手工标注卡通人物检测数据集与识别数据集,它包含超过 5013 个卡通人物、389678 张高质量实景图片。相比于其他数据集,它具有大规模、高质量、多样性丰富、挑战难度大等特点,是目前研究动漫人物识别最常用的数据集之一。
地址: http://challenge.ai.iqiyi.com/detail?raceId=5def69ace9fcf68aef76a75d 地址: http://challenge.ai.iqiyi.com/detail?raceId=5def69ace9fcf68aef76a75d
+ Manga109: Manga109是2020.5月发布的一个用于研究卡通人物检测和识别的数据集,其包含21142张图片,官方不允许用于商用。该数据集旗下的子集Manga109-s,可以供工业使用, 主要用于文本检测、基于线稿的任务检索、角色图像生成等任务。 + Manga109: Manga109 是 2020.5 月发布的一个用于研究卡通人物检测和识别的数据集,其包含 21142 张图片,官方不允许用于商用。该数据集旗下的子集 Manga109-s,可以供工业使用, 主要用于文本检测、基于线稿的任务检索、角色图像生成等任务。
地址:http://www.manga109.org/en/ 地址:http://www.manga109.org/en/
+ IIT-CFW:IIF-CFW数据集共包含8928个带有标注的明星人物卡通头像,覆盖100个人物形象,每个人卡通头像数不等。 另外,其还提供了1000张真实人脸照(100个公众人物,每个人10张真实头像)。该数据集既可以用于研究动漫人物识别,也经常被用于研究跨模态的检索任务。 + IIT-CFW:IIF-CFW 数据集共包含 8928 个带有标注的明星人物卡通头像,覆盖 100 个人物形象,每个人卡通头像数不等。 另外,其还提供了 1000 张真实人脸照(100 个公众人物,每个人 10 张真实头像)。该数据集既可以用于研究动漫人物识别,也经常被用于研究跨模态的检索任务。
地址: http://cvit.iiit.ac.in/research/projects/cvit-projects/cartoonfaces 地址: http://cvit.iiit.ac.in/research/projects/cvit-projects/cartoonfaces
<a name="商品识别"></a> <a name="2.2.2"></a>
#### 2.2.2 商品识别 #### 2.2.2 商品识别
+ AliProduct: AliProduct数据集是目前开源最大的商品数据集,它是一个SKU级别的图像分类数据集, 包含5万类别、300万张商品图像,商品图像的类别和总量均为业界之最。此数据集中涵盖了大量的生活用品、食物等,数据集中没有人工标注,数据较脏,数据分布较不均衡,且有很多相似的商品图片。 + AliProduct: AliProduct 数据集是目前开源最大的商品数据集,它是一个 SKU 级别的图像分类数据集, 包含 5 万类别、300 万张商品图像,商品图像的类别和总量均为业界之最。此数据集中涵盖了大量的生活用品、食物等,数据集中没有人工标注,数据较脏,数据分布较不均衡,且有很多相似的商品图片。
地址: https://retailvisionworkshop.github.io/recognition_challenge_2020/ 地址: https://retailvisionworkshop.github.io/recognition_challenge_2020/
+ Product-10k: Products-10k数据集中的所有图片均来自京东商城。数据集中共包含1万个经常购买的SKU。所有SKU组织成一个层次结构。总共有近19万张图片。在实际应用场景中,图像量的分布是不均衡的。所有图像都由生产专家团队手工检查/标记。 + Product-10k: Products-10k 数据集中的所有图片均来自京东商城。数据集中共包含 1 万个经常购买的 SKU。所有 SKU 组织成一个层次结构。总共有近 19 万张图片。在实际应用场景中,图像量的分布是不均衡的。所有图像都由生产专家团队手工检查/标记。
地址:https://www.kaggle.com/c/products-10k/data?select=train.csv 地址:https://www.kaggle.com/c/products-10k/data?select=train.csv
+ DeepFashion-Inshop: 同通用图像识别数据集中的In-shop Clothes + DeepFashion-Inshop: 同通用图像识别数据集中的 In-shop Clothes
<a name="Logo识别"></a> <a name="2.2.3"></a>
### 2.2.3 Logo识别 ### 2.2.3 Logo 识别
+ Logo-2K+: Logo-2K+是一个仅用于logo图像识别的数据集,其包含10个大类,2341个小类和167140张图片。 + Logo-2K+: Logo-2K+是一个仅用于 logo 图像识别的数据集,其包含 10 个大类,2341 个小类和 167140 张图片。
地址: https://github.com/msn199959/Logo-2k-plus-Dataset 地址: https://github.com/msn199959/Logo-2k-plus-Dataset
+ Tsinghua-Tencent 100K: 该数据集是从10万张腾讯街景全景图中创建的一个大型交通标志基准数据集。它提供包含30000个交通标志实例的100000张图像。这些图像涵盖了照度和天气条件的巨大变化。基准测试中的每个交通标志都标注了类别标签、边界框和像素掩码。 它总共包含222个类别 (0 background + 221 traffic signs) + Tsinghua-Tencent 100K: 该数据集是从 10 万张腾讯街景全景图中创建的一个大型交通标志基准数据集。它提供包含 30000 个交通标志实例的 100000 张图像。这些图像涵盖了照度和天气条件的巨大变化。基准测试中的每个交通标志都标注了类别标签、边界框和像素掩码。 它总共包含 222 个类别 (0 background + 221 traffic signs)
地址: https://cg.cs.tsinghua.edu.cn/traffic-sign/ 地址: https://cg.cs.tsinghua.edu.cn/traffic-sign/
<a name="车辆识别"></a> <a name="2.2.4"></a>
### 2.2.4 车辆识别 ### 2.2.4 车辆识别
+ CompCars: 图像主要来自网络和监控数据,其中网络数据包含163个汽车制造商、1716个汽车型号的汽车。共136,726张全车图像,27,618张部分车图像。其中网络汽车数据包含bounding box、视角、5个属性(最大速度、排量、车门数、车座数、汽车类型)。监控数据包含50,000张前视角图像。 + CompCars: 图像主要来自网络和监控数据,其中网络数据包含 163 个汽车制造商、1716 个汽车型号的汽车。共 136,726 张全车图像,27,618 张部分车图像。其中网络汽车数据包含 bounding box、视角、5 个属性(最大速度、排量、车门数、车座数、汽车类型)。监控数据包含 50,000 张前视角图像。
地址: http://mmlab.ie.cuhk.edu.hk/datasets/comp_cars/ 地址: http://mmlab.ie.cuhk.edu.hk/datasets/comp_cars/
+ BoxCars: 此数据集共包含21250辆车、63750张图像、27个汽车制造商、148个细类别,此数据集全部来自监控数据。 + BoxCars: 此数据集共包含 21250 辆车、63750 张图像、27 个汽车制造商、148 个细类别,此数据集全部来自监控数据。
地址: https://github.com/JakubSochor/BoxCars 地址: https://github.com/JakubSochor/BoxCars
+ PKU-VD Dataset:该数据集包含了两个大型车辆数据集(VD1和VD2),它们分别从两个城市的真实世界不受限制的场景拍摄图像。其中VD1是从高分辨率交通摄像头获得的,VD2中的图像则是从监视视频中获取的。作者对原始数据执行车辆检测,以确保每个图像仅包含一辆车辆。由于隐私保护的限制,所有车牌号码都已被黑色覆盖遮挡。所有车辆图像均从前视图进行拍摄。 数据集中为每个图像提供了多样化的属性注释,包括身份编号,精确的车辆模型和车辆颜色。VD1原先包含1097649张图像,1232种车俩模型,11种车辆颜色,但删除图像里面有多辆车辆以及从车辆后方拍摄的图片,该数据集仅剩846358张图像,141756辆车辆。 VD2包含807260张图像,79763辆车辆,1112种车辆模型,11种车辆颜色。 + PKU-VD Dataset:该数据集包含了两个大型车辆数据集(VD1 和 VD2),它们分别从两个城市的真实世界不受限制的场景拍摄图像。其中 VD1 是从高分辨率交通摄像头获得的,VD2 中的图像则是从监视视频中获取的。作者对原始数据执行车辆检测,以确保每个图像仅包含一辆车辆。由于隐私保护的限制,所有车牌号码都已被黑色覆盖遮挡。所有车辆图像均从前视图进行拍摄。 数据集中为每个图像提供了多样化的属性注释,包括身份编号,精确的车辆模型和车辆颜色。VD1 原先包含 1097649 张图像,1232 种车俩模型,11 种车辆颜色,但删除图像里面有多辆车辆以及从车辆后方拍摄的图片,该数据集仅剩 846358 张图像,141756 辆车辆。 VD2 包含 807260 张图像,79763 辆车辆,1112 种车辆模型,11 种车辆颜色。
地址: https://pkuml.org/resources/pku-vds.html 地址: https://pkuml.org/resources/pku-vds.html
# 特征提取 # 特征提取
## 目录
- [1. 简介](#1)
- [2. 网络结构](#2)
- [3. 通用识别模型](#3)
- [4. 自定义特征提取](#4)
- [4.1 数据准备](#4.1)
- [4.2 模型训练](#4.2)
- [4.3 模型评估](#4.3)
- [4.4 模型推理](#4.4)
- [4.4.1 导出推理模型](#4.4.1)
- [4.4.2 获取特征向量](#4.4.2)
<a name="1"></a>
## 1. 简介 ## 1. 简介
特征提取是图像识别中的关键一环,它的作用是将输入的图片转化为固定维度的特征向量,用于后续的[向量检索](./vector_search.md)。好的特征需要具备相似度保持性,即在特征空间中,相似度高的图片对其特征相似度要比较高(距离比较近),相似度低的图片对,其特征相似度要比较小(距离比较远)。[Deep Metric Learning](../algorithm_introduction/metric_learning.md)用以研究如何通过深度学习的方法获得具有强表征能力的特征。
特征提取是图像识别中的关键一环,它的作用是将输入的图片转化为固定维度的特征向量,用于后续的[向量检索](./vector_search.md)。好的特征需要具备相似度保持性,即在特征空间中,相似度高的图片对其特征相似度要比较高(距离比较近),相似度低的图片对,其特征相似度要比较小(距离比较远)。[Deep Metric Learning](../algorithm_introduction/metric_learning.md) 用以研究如何通过深度学习的方法获得具有强表征能力的特征。
<a name="2"></a>
## 2. 网络结构 ## 2. 网络结构
为了图像识别任务的灵活定制,我们将整个网络分为Backbone、 Neck、 Head以及Loss部分,整体结构如下图所示: 为了图像识别任务的灵活定制,我们将整个网络分为 Backbone、 Neck、 Head 以及 Loss 部分,整体结构如下图所示:
![](../../images/feature_extraction_framework.png) ![](../../images/feature_extraction_framework.png)
图中各个模块的功能为: 图中各个模块的功能为:
- **Backbone**: 指定所使用的骨干网络。 值得注意的是,PaddleClas提供的基于ImageNet的预训练模型,最后一层的输出为1000, 我们需要依据所需的特征维度定制最后一层的输出。
- **Neck**: 用以特征增强及特征维度变换。 这儿的Neck,可以是一个简单的Linear Layer,用来做特征维度变换;也可以是较复杂的FPN结构,用以做特征增强。 - **Backbone**: 指定所使用的骨干网络。 值得注意的是,PaddleClas 提供的基于 ImageNet 的预训练模型,最后一层的输出为 1000, 我们需要依据所需的特征维度定制最后一层的输出。
- **Head**: 用来将feature转化为logits。 除了常用的Fc Layer外,还可以替换为cosmargin, arcmargin, circlemargin等模块。 - **Neck**: 用以特征增强及特征维度变换。 这儿的 Neck,可以是一个简单的 Linear Layer,用来做特征维度变换;也可以是较复杂的 FPN 结构,用以做特征增强。
- **Loss**: 指定所使用的Loss函数。 我们将Loss设计为组合loss的形式, 可以方便得将Classification Loss和Pair_wise Loss组合在一起。 - **Head**: 用来将 feature 转化为 logits。 除了常用的 Fc Layer 外,还可以替换为 cosmargin, arcmargin, circlemargin 等模块。
- **Loss**: 指定所使用的 Loss 函数。 我们将 Loss 设计为组合 loss 的形式, 可以方便得将 Classification Loss 和 Pair_wise Loss 组合在一起。
<a name="3"></a>
## 3. 通用识别模型 ## 3. 通用识别模型
在PP-Shitu中, 我们采用[PP_LCNet_x2_5](../models/PP-LCNet.md)作为骨干网络, Neck部分选用Linear Layer, Head部分选用[ArcMargin](../../../ppcls/arch/gears/arcmargin.py), Loss部分选用CELoss,详细的配置文件见[通用识别配置文件](../../../ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml)。其中,训练数据为如下7个公开数据集的汇总:
在 PP-Shitu 中, 我们采用 [PP_LCNet_x2_5](../models/PP-LCNet.md) 作为骨干网络, Neck部分选用 Linear Layer, Head 部分选用 [ArcMargin](../../../ppcls/arch/gears/arcmargin.py), Loss 部分选用 CELoss,详细的配置文件见[通用识别配置文件](../../../ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml)。其中,训练数据为如下 7 个公开数据集的汇总:
| 数据集 | 数据量 | 类别数 | 场景 | 数据集地址 | | 数据集 | 数据量 | 类别数 | 场景 | 数据集地址 |
| :------------: | :-------------: | :-------: | :-------: | :--------: | | :------------: | :-------------: | :-------: | :-------: | :--------: |
| Aliproduct | 2498771 | 50030 | 商品 | [地址](https://retailvisionworkshop.github.io/recognition_challenge_2020/) | | Aliproduct | 2498771 | 50030 | 商品 | [地址](https://retailvisionworkshop.github.io/recognition_challenge_2020/) |
...@@ -30,16 +53,23 @@ ...@@ -30,16 +53,23 @@
PP-LCNet-2.5x | 0.839 | 0.888 | 0.861 | 0.841 | 0.793 | 0.892 | 5.0 PP-LCNet-2.5x | 0.839 | 0.888 | 0.861 | 0.841 | 0.793 | 0.892 | 5.0
* 采用的评测指标为:`Recall@1` * 采用的评测指标为:`Recall@1`
* 速度评测机器的CPU具体信息为:`Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz` * 速度评测机器的CPU具体信息为:`Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz`
* 速度指标的评测条件为: 开启MKLDNN, 线程数设置为10 * 速度指标的评测条件为: 开启 MKLDNN, 线程数设置为 10
* 预训练模型地址:[通用识别预训练模型](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/general_PPLCNet_x2_5_pretrained_v1.0.pdparams) * 预训练模型地址:[通用识别预训练模型](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/general_PPLCNet_x2_5_pretrained_v1.0.pdparams)
<a name="4"></a>
# 4. 自定义特征提取 # 4. 自定义特征提取
自定义特征提取,是指依据自己的任务,重新训练特征提取模型。主要包含四个步骤:1)数据准备;2)模型训练;3)模型评估;4)模型推理。 自定义特征提取,是指依据自己的任务,重新训练特征提取模型。主要包含四个步骤:1)数据准备;2)模型训练;3)模型评估;4)模型推理。
<a name="4.1"></a>
## 4.1 数据准备 ## 4.1 数据准备
首先,需要基于任务定制自己的数据集。数据集格式参见[格式说明](https://github.com/PaddlePaddle/PaddleClas/blob/develop/docs/zh_CN/data_preparation/recognition_dataset.md#%E6%95%B0%E6%8D%AE%E9%9B%86%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E)。在启动模型训练之前,需要在配置文件中修改数据配置相关的内容, 主要包括数据集的地址以及类别数量。对应到配置文件中的位置如下所示: 首先,需要基于任务定制自己的数据集。数据集格式参见[格式说明](https://github.com/PaddlePaddle/PaddleClas/blob/develop/docs/zh_CN/data_preparation/recognition_dataset.md#%E6%95%B0%E6%8D%AE%E9%9B%86%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E)。在启动模型训练之前,需要在配置文件中修改数据配置相关的内容, 主要包括数据集的地址以及类别数量。对应到配置文件中的位置如下所示:
``` ```
Head: Head:
name: ArcMargin name: ArcMargin
embedding_size: 512 embedding_size: 512
class_num: 185341 #此处表示类别数 class_num: 185341 #此处表示类别数
``` ```
...@@ -52,21 +82,23 @@ PP-LCNet-2.5x | 0.839 | 0.888 | 0.861 | 0.841 | 0.793 | 0.892 | 5.0 ...@@ -52,21 +82,23 @@ PP-LCNet-2.5x | 0.839 | 0.888 | 0.861 | 0.841 | 0.793 | 0.892 | 5.0
``` ```
``` ```
Query: Query:
dataset: dataset:
name: VeriWild name: VeriWild
image_root: ./dataset/Aliproduct/. #此处表示query数据集所在的目录 image_root: ./dataset/Aliproduct/. #此处表示query数据集所在的目录
cls_label_path: ./dataset/Aliproduct/val_list.txt. #此处表示query数据集label文件的地址 cls_label_path: ./dataset/Aliproduct/val_list.txt. #此处表示query数据集label文件的地址
``` ```
``` ```
Gallery: Gallery:
dataset: dataset:
name: VeriWild name: VeriWild
image_root: ./dataset/Aliproduct/ #此处表示gallery数据集所在的目录 image_root: ./dataset/Aliproduct/ #此处表示gallery数据集所在的目录
cls_label_path: ./dataset/Aliproduct/val_list.txt. #此处表示gallery数据集label文件的地址 cls_label_path: ./dataset/Aliproduct/val_list.txt. #此处表示gallery数据集label文件的地址
``` ```
<a name="4.2"></a>
## 4.2 模型训练 ## 4.2 模型训练
- 单机单卡训练 - 单机单卡训练
```shell ```shell
export CUDA_VISIBLE_DEVICES=0 export CUDA_VISIBLE_DEVICES=0
...@@ -79,8 +111,9 @@ python -m paddle.distributed.launch \ ...@@ -79,8 +111,9 @@ python -m paddle.distributed.launch \
--gpus="0,1,2,3" tools/train.py \ --gpus="0,1,2,3" tools/train.py \
-c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml
``` ```
**注意:** **注意:**
配置文件中默认采用`在线评估`的方式,如果你想加快训练速度,去除`在线评估`,只需要在上述命令后面,增加`-o eval_during_train=False`。训练完毕后,在output目录下会生成最终模型文件`latest``best_model`和训练日志文件`train.log`。其中,`best_model`用来存储当前评测指标下的最佳模型;`latest`用来存储最新生成的模型, 方便在任务中断的情况下从断点位置启动训练。 配置文件中默认采用`在线评估`的方式,如果你想加快训练速度,去除`在线评估`,只需要在上述命令后面,增加 `-o eval_during_train=False`。训练完毕后,在 output 目录下会生成最终模型文件 `latest``best_model` 和训练日志文件 `train.log`。其中,`best_model` 用来存储当前评测指标下的最佳模型;`latest` 用来存储最新生成的模型, 方便在任务中断的情况下从断点位置启动训练。
- 断点续训: - 断点续训:
```shell ```shell
export CUDA_VISIBLE_DEVICES=0,1,2,3 export CUDA_VISIBLE_DEVICES=0,1,2,3
...@@ -90,7 +123,10 @@ python -m paddle.distributed.launch \ ...@@ -90,7 +123,10 @@ python -m paddle.distributed.launch \
-o Global.checkpoint="output/RecModel/latest" -o Global.checkpoint="output/RecModel/latest"
``` ```
<a name="4.3"></a>
## 4.3 模型评估 ## 4.3 模型评估
- 单卡评估 - 单卡评估
```shell ```shell
export CUDA_VISIBLE_DEVICES=0 export CUDA_VISIBLE_DEVICES=0
...@@ -109,17 +145,28 @@ python -m paddle.distributed.launch \ ...@@ -109,17 +145,28 @@ python -m paddle.distributed.launch \
``` ```
**推荐:** 建议使用多卡评估。多卡评估方式可以利用多卡并行计算快速得到整体数据集的特征集合,能够加速评估的过程。 **推荐:** 建议使用多卡评估。多卡评估方式可以利用多卡并行计算快速得到整体数据集的特征集合,能够加速评估的过程。
<a name="4.4"></a>
## 4.4 模型推理 ## 4.4 模型推理
推理过程包括两个步骤: 1)导出推理模型; 2)获取特征向量 推理过程包括两个步骤: 1)导出推理模型; 2)获取特征向量
<a name="4.4.1"></a>
### 4.4.1 导出推理模型 ### 4.4.1 导出推理模型
``` ```
python tools/export_model \ python tools/export_model \
-c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml \ -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml \
-o Global.pretrained_model="output/RecModel/best_model" -o Global.pretrained_model="output/RecModel/best_model"
``` ```
生成的推理模型位于`inference`目录,里面包含三个文件,分别为`inference.pdmodel``inference.pdiparams``inference.pdiparams.info` 生成的推理模型位于 `inference` 目录,里面包含三个文件,分别为 `inference.pdmodel``inference.pdiparams``inference.pdiparams.info`
其中: `inference.pdmodel`用来存储推理模型的结构, `inference.pdiparams``inference.pdiparams.info`用来存储推理模型相关的参数信息。 其中: `inference.pdmodel` 用来存储推理模型的结构, `inference.pdiparams``inference.pdiparams.info` 用来存储推理模型相关的参数信息。
<a name="4.4.2"></a>
### 4.4.2 获取特征向量 ### 4.4.2 获取特征向量
``` ```
cd deploy cd deploy
python python/predict_rec.py \ python python/predict_rec.py \
......
...@@ -5,6 +5,23 @@ ...@@ -5,6 +5,23 @@
本部分主要从数据集、模型选择和模型训练 3 个方面对该部分内容进行介绍。 本部分主要从数据集、模型选择和模型训练 3 个方面对该部分内容进行介绍。
----------
## 目录
- [1. 数据集](#1)
- [2. 模型选择](#2)
- [2.1 轻量级主体检测模型](#2.1)
- [2.2 服务端主体检测模型](#2.2)
- [3. 模型训练](#3)
- [3.1 环境准备](#3.1)
- [3.2 数据准备](#3.2)
- [3.3 配置文件改动和说明](#3.3)
- [3.4 启动训练](#3.4)
- [3.5 模型预测与调试](#3.5)
- [3.6 模型导出与预测部署](#3.6)
<a name="1"></a>
## 1. 数据集 ## 1. 数据集
...@@ -15,15 +32,16 @@ ...@@ -15,15 +32,16 @@
| Objects365 | 170W | 6k | 通用场景 | [地址](https://www.objects365.org/overview.html) | | Objects365 | 170W | 6k | 通用场景 | [地址](https://www.objects365.org/overview.html) |
| COCO2017 | 12W | 5k | 通用场景 | [地址](https://cocodataset.org/) | | COCO2017 | 12W | 5k | 通用场景 | [地址](https://cocodataset.org/) |
| iCartoonFace | 2k | 2k | 动漫人脸检测 | [地址](https://github.com/luxiangju-PersonAI/iCartoonFace) | | iCartoonFace | 2k | 2k | 动漫人脸检测 | [地址](https://github.com/luxiangju-PersonAI/iCartoonFace) |
| LogoDet-3k | 3k | 2k | Logo检测 | [地址](https://github.com/Wangjing1551/LogoDet-3K-Dataset) | | LogoDet-3k | 3k | 2k | Logo 检测 | [地址](https://github.com/Wangjing1551/LogoDet-3K-Dataset) |
| RPC | 3k | 3k | 商品检测 | [地址](https://rpc-dataset.github.io/) | | RPC | 3k | 3k | 商品检测 | [地址](https://rpc-dataset.github.io/) |
在实际训练的过程中,将所有数据集混合在一起。由于是主体检测,这里将所有标注出的检测框对应的类别都修改为 `前景` 的类别,最终融合的数据集中只包含 1 个类别,即前景。 在实际训练的过程中,将所有数据集混合在一起。由于是主体检测,这里将所有标注出的检测框对应的类别都修改为 `前景` 的类别,最终融合的数据集中只包含 1 个类别,即前景。
<a name="2"></a>
## 2. 模型选择 ## 2. 模型选择
目标检测方法种类繁多,比较常用的有两阶段检测器(如FasterRCNN系列等);单阶段检测器(如YOLO、SSD等);anchor-free检测器(如PicoDet、FCOS等)。PaddleDetection中针对服务端使用场景,自研了 PP-YOLO 系列模型;针对端侧(CPU和移动端等)使用场景,自研了 PicoDet 系列模型,在服务端和端侧均处于业界较为领先的水平。 目标检测方法种类繁多,比较常用的有两阶段检测器(如 FasterRCNN 系列等);单阶段检测器(如 YOLO、SSD 等);anchor-free 检测器(如 PicoDet、FCOS 等)。PaddleDetection 中针对服务端使用场景,自研了 PP-YOLO 系列模型;针对端侧(CPU 和移动端等)使用场景,自研了 PicoDet 系列模型,在服务端和端侧均处于业界较为领先的水平。
基于上述研究,PaddleClas 中提供了 2 个通用主体检测模型,为轻量级与服务端主体检测模型,分别适用于端侧场景以及服务端场景。下面的表格中给出了在上述 5 个数据集上的平均 mAP 以及它们的模型大小、预测速度对比信息。 基于上述研究,PaddleClas 中提供了 2 个通用主体检测模型,为轻量级与服务端主体检测模型,分别适用于端侧场景以及服务端场景。下面的表格中给出了在上述 5 个数据集上的平均 mAP 以及它们的模型大小、预测速度对比信息。
...@@ -37,10 +55,11 @@ ...@@ -37,10 +55,11 @@
* 速度评测机器的CPU具体信息为:`Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz`,速度指标为开启 mkldnn ,线程数设置为 10 测试得到。 * 速度评测机器的CPU具体信息为:`Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz`,速度指标为开启 mkldnn ,线程数设置为 10 测试得到。
* 主体检测的预处理过程较为耗时,平均每张图在上述机器上的时间在 40~55 ms 左右,没有包含在上述的预测耗时统计中。 * 主体检测的预处理过程较为耗时,平均每张图在上述机器上的时间在 40~55 ms 左右,没有包含在上述的预测耗时统计中。
<a name="2.1"></a>
### 2.1 轻量级主体检测模型 ### 2.1 轻量级主体检测模型
PicoDet 由 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) 提出,是一个适用于CPU或者移动端场景的目标检测算法。具体地,它融合了下面一系列优化算法。 PicoDet 由 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) 提出,是一个适用于 CPU 或者移动端场景的目标检测算法。具体地,它融合了下面一系列优化算法。
- [ATSS](https://arxiv.org/abs/1912.02424) - [ATSS](https://arxiv.org/abs/1912.02424)
- [Generalized Focal Loss](https://arxiv.org/abs/2006.04388) - [Generalized Focal Loss](https://arxiv.org/abs/2006.04388)
...@@ -51,15 +70,16 @@ PicoDet 由 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) ...@@ -51,15 +70,16 @@ PicoDet 由 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection)
更多关于 PicoDet 的优化细节与 benchmark 可以参考 [PicoDet 系列模型介绍](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/configs/picodet/README.md) 更多关于 PicoDet 的优化细节与 benchmark 可以参考 [PicoDet 系列模型介绍](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/configs/picodet/README.md)
在轻量级主体检测任务中,为了更好地兼顾检测速度与效果,我们使用 PPLCNet_x2_5 作为主体检测模型的骨干网络,同时将训练与预测的图像尺度修改为了 640x640,其余配置与 [picodet_lcnet_1_5x_416_coco.yml](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/configs/picodet/more_config/picodet_lcnet_1_5x_416_coco.yml)完全一致。将数据集更换为自定义的主体检测数据集,进行训练,最终得到检测模型。 在轻量级主体检测任务中,为了更好地兼顾检测速度与效果,我们使用 PPLCNet_x2_5 作为主体检测模型的骨干网络,同时将训练与预测的图像尺度修改为了 640x640,其余配置与 [picodet_lcnet_1_5x_416_coco.yml](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/configs/picodet/more_config/picodet_lcnet_1_5x_416_coco.yml) 完全一致。将数据集更换为自定义的主体检测数据集,进行训练,最终得到检测模型。
<a name="2.2"></a>
### 2.2 服务端主体检测模型 ### 2.2 服务端主体检测模型
PP-YOLO 由 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) 提出,从骨干网络、数据增广、正则化策略、损失函数、后处理等多个角度对 yolov3 模型进行深度优化,最终在"速度-精度"方面达到了业界领先的水平。具体地,优化的策略如下。 PP-YOLO 由 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) 提出,从骨干网络、数据增广、正则化策略、损失函数、后处理等多个角度对 yolov3 模型进行深度优化,最终在“速度-精度”方面达到了业界领先的水平。具体地,优化的策略如下。
- 更优的骨干网络: ResNet50vd-DCN - 更优的骨干网络: ResNet50vd-DCN
- 更大的训练batch size: 8 GPUs,每GPU batch_size=24,对应调整学习率和迭代轮数 - 更大的训练 batch size: 8 GPUs,每 GPU batch_size=24,对应调整学习率和迭代轮数
- [Drop Block](https://arxiv.org/abs/1810.12890) - [Drop Block](https://arxiv.org/abs/1810.12890)
- [Exponential Moving Average](https://www.investopedia.com/terms/e/ema.asp) - [Exponential Moving Average](https://www.investopedia.com/terms/e/ema.asp)
- [IoU Loss](https://arxiv.org/pdf/1902.09630.pdf) - [IoU Loss](https://arxiv.org/pdf/1902.09630.pdf)
...@@ -73,14 +93,17 @@ PP-YOLO 由 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) ...@@ -73,14 +93,17 @@ PP-YOLO 由 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection)
在服务端主体检测任务中,为了保证检测效果,我们使用 ResNet50vd-DCN 作为检测模型的骨干网络,使用配置文件 [ppyolov2_r50vd_dcn_365e_coco.yml](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml) ,更换为自定义的主体检测数据集,进行训练,最终得到检测模型。 在服务端主体检测任务中,为了保证检测效果,我们使用 ResNet50vd-DCN 作为检测模型的骨干网络,使用配置文件 [ppyolov2_r50vd_dcn_365e_coco.yml](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml) ,更换为自定义的主体检测数据集,进行训练,最终得到检测模型。
<a name="3"></a>
## 3. 模型训练 ## 3. 模型训练
本节主要介绍怎样基于PaddleDetection,基于自己的数据集,训练主体检测模型。 本节主要介绍怎样基于 PaddleDetection,基于自己的数据集,训练主体检测模型。
<a name="3.1"></a>
### 3.1 环境准备 ### 3.1 环境准备
下载PaddleDetection代码,安装requirements。 下载 PaddleDetection 代码,安装 requirements。
```shell ```shell
cd <path/to/clone/PaddleDetection> cd <path/to/clone/PaddleDetection>
...@@ -93,16 +116,20 @@ pip install -r requirements.txt ...@@ -93,16 +116,20 @@ pip install -r requirements.txt
更多安装教程,请参考: [安装文档](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/docs/tutorials/INSTALL_cn.md) 更多安装教程,请参考: [安装文档](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/docs/tutorials/INSTALL_cn.md)
<a name="3.2"></a>
### 3.2 数据准备 ### 3.2 数据准备
对于自定义数据集,首先需要将自己的数据集修改为COCO格式,可以参考[自定义检测数据集教程](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/static/docs/tutorials/Custom_DataSet.md)制作COCO格式的数据集。 对于自定义数据集,首先需要将自己的数据集修改为 COCO 格式,可以参考[自定义检测数据集教程](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/static/docs/tutorials/Custom_DataSet.md)制作 COCO 格式的数据集。
主体检测任务中,所有的检测框均属于前景,在这里需要将标注文件中,检测框的`category_id`修改为1,同时将整个标注文件中的`categories`映射表修改为下面的格式,即整个类别映射表中只包含`前景`类别。 主体检测任务中,所有的检测框均属于前景,在这里需要将标注文件中,检测框的 `category_id` 修改为 1,同时将整个标注文件中的 `categories` 映射表修改为下面的格式,即整个类别映射表中只包含`前景`类别。
```json ```json
[{u'id': 1, u'name': u'foreground', u'supercategory': u'foreground'}] [{u'id': 1, u'name': u'foreground', u'supercategory': u'foreground'}]
``` ```
<a name="3.3"></a>
### 3.3 配置文件改动和说明 ### 3.3 配置文件改动和说明
我们使用 `configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml` 配置进行训练,配置文件摘要如下: 我们使用 `configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml` 配置进行训练,配置文件摘要如下:
...@@ -116,7 +143,7 @@ pip install -r requirements.txt ...@@ -116,7 +143,7 @@ pip install -r requirements.txt
``` ```
coco_detection.yml:主要说明了训练数据和验证数据的路径 coco_detection.yml:主要说明了训练数据和验证数据的路径
runtime.yml:主要说明了公共的运行参数,比如是否使用GPU、每多少个epoch存储checkpoint runtime.yml:主要说明了公共的运行参数,比如是否使用GPU、每多少个 epoch 存储 checkpoint
optimizer_365e.yml:主要说明了学习率和优化器的配置 optimizer_365e.yml:主要说明了学习率和优化器的配置
...@@ -129,6 +156,7 @@ ppyolov2_reader.yml:主要说明数据读取器配置,如 batch size,并 ...@@ -129,6 +156,7 @@ ppyolov2_reader.yml:主要说明数据读取器配置,如 batch size,并
此外,也可以根据实际情况,修改上述文件,比如,如果显存溢出,可以将 batch size 和学习率等比缩小等。 此外,也可以根据实际情况,修改上述文件,比如,如果显存溢出,可以将 batch size 和学习率等比缩小等。
<a name="3.4"></a>
### 3.4 启动训练 ### 3.4 启动训练
...@@ -142,7 +170,7 @@ export CUDA_VISIBLE_DEVICES=0 ...@@ -142,7 +170,7 @@ export CUDA_VISIBLE_DEVICES=0
python tools/train.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml python tools/train.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml
``` ```
* GPU多卡训练 * GPU 多卡训练
```bash ```bash
export CUDA_VISIBLE_DEVICES=0,1,2,3 export CUDA_VISIBLE_DEVICES=0,1,2,3
...@@ -152,7 +180,7 @@ python -m paddle.distributed.launch --gpus 0,1,2,3 tools/train.py -c configs/ppy ...@@ -152,7 +180,7 @@ python -m paddle.distributed.launch --gpus 0,1,2,3 tools/train.py -c configs/ppy
--eval:表示边训练边验证。 --eval:表示边训练边验证。
* (**推荐**)模型微调 * **推荐**模型微调
如果希望加载 PaddleClas 中已经训练好的主体检测模型,在自己的数据集上进行模型微调,可以使用下面的命令进行训练。 如果希望加载 PaddleClas 中已经训练好的主体检测模型,在自己的数据集上进行模型微调,可以使用下面的命令进行训练。
```bash ```bash
...@@ -170,8 +198,9 @@ export CUDA_VISIBLE_DEVICES=0,1,2,3 ...@@ -170,8 +198,9 @@ export CUDA_VISIBLE_DEVICES=0,1,2,3
python -m paddle.distributed.launch --gpus 0,1,2,3 tools/train.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml --eval -r output/ppyolov2_r50vd_dcn_365e_coco/10000 python -m paddle.distributed.launch --gpus 0,1,2,3 tools/train.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml --eval -r output/ppyolov2_r50vd_dcn_365e_coco/10000
``` ```
注意:如果遇到 "`Out of memory error`" 问题, 尝试在 `ppyolov2_reader.yml` 文件中调小`batch_size`,同时等比例调小学习率。 注意:如果遇到 "`Out of memory error`" 问题, 尝试在 `ppyolov2_reader.yml` 文件中调小 `batch_size`,同时等比例调小学习率。
<a name="3.5"></a>
### 3.5 模型预测与调试 ### 3.5 模型预测与调试
...@@ -184,6 +213,8 @@ python tools/infer.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml --infer ...@@ -184,6 +213,8 @@ python tools/infer.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml --infer
`--draw_threshold` 是个可选参数. 根据 [NMS](https://ieeexplore.ieee.org/document/1699659) 的计算,不同阈值会产生不同的结果 `keep_top_k` 表示设置输出目标的最大数量,默认值为 100 ,用户可以根据自己的实际情况进行设定。 `--draw_threshold` 是个可选参数. 根据 [NMS](https://ieeexplore.ieee.org/document/1699659) 的计算,不同阈值会产生不同的结果 `keep_top_k` 表示设置输出目标的最大数量,默认值为 100 ,用户可以根据自己的实际情况进行设定。
<a name="3.6"></a>
### 3.6 模型导出与预测部署。 ### 3.6 模型导出与预测部署。
执行导出模型脚本: 执行导出模型脚本:
...@@ -194,7 +225,7 @@ python tools/export_model.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml ...@@ -194,7 +225,7 @@ python tools/export_model.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml
预测模型会导出到 `inference/ppyolov2_r50vd_dcn_365e_coco` 目录下,分别为 `infer_cfg.yml` (预测不需要), `model.pdiparams`, `model.pdiparams.info`, `model.pdmodel` 预测模型会导出到 `inference/ppyolov2_r50vd_dcn_365e_coco` 目录下,分别为 `infer_cfg.yml` (预测不需要), `model.pdiparams`, `model.pdiparams.info`, `model.pdmodel`
注意: `PaddleDetection` 导出的inference模型的文件格式为 `model.xxx`,这里如果希望与PaddleClas的inference模型文件格式保持一致,需要将其 `model.xxx` 文件修改为 `inference.xxx` 文件,用于后续主体检测的预测部署。 注意: `PaddleDetection` 导出的 inference 模型的文件格式为 `model.xxx`,这里如果希望与 PaddleClas 的 inference 模型文件格式保持一致,需要将其 `model.xxx` 文件修改为 `inference.xxx` 文件,用于后续主体检测的预测部署。
更多模型导出教程,请参考: [EXPORT_MODEL](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/deploy/EXPORT_MODEL.md) 更多模型导出教程,请参考: [EXPORT_MODEL](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/deploy/EXPORT_MODEL.md)
......
# 向量检索 # 向量检索
向量检索技术在图像识别、图像检索中应用比较广泛。其主要目标是,对于给定的查询向量,在已经建立好的向量库中,与库中所有的待查询向量,进行特征向量的相似度或距离计算,得到相似度排序。在图像识别系统中,我们使用[Faiss](https://github.com/facebookresearch/faiss)对此部分进行支持,具体信息请详查[Faiss官网](https://github.com/facebookresearch/faiss)`Faiss`主要有以下优势 向量检索技术在图像识别、图像检索中应用比较广泛。其主要目标是,对于给定的查询向量,在已经建立好的向量库中,与库中所有的待查询向量,进行特征向量的相似度或距离计算,得到相似度排序。在图像识别系统中,我们使用 [Faiss](https://github.com/facebookresearch/faiss) 对此部分进行支持,具体信息请详查 [Faiss官网](https://github.com/facebookresearch/faiss)`Faiss` 主要有以下优势
- 适配性好:支持Windos、Linux、MacOS系统 - 适配性好:支持 Windos、Linux、MacOS 系统
- 安装方便: 支持`python`接口,直接使用`pip`安装 - 安装方便: 支持 `python` 接口,直接使用 `pip` 安装
- 算法丰富:支持多种检索算法,满足不同场景的需求 - 算法丰富:支持多种检索算法,满足不同场景的需求
- 同时支持CPU、GPU,能够加速检索过程 - 同时支持 CPU、GPU,能够加速检索过程
值得注意的是,为了更好是适配性,目前版本,`PaddleClas`中暂时**只使用CPU进行向量检索** 值得注意的是,为了更好是适配性,目前版本,`PaddleClas` 中暂时**只使用 CPU 进行向量检索**
本文档主要主要介绍PaddleClas中检索模块的安装、使用的检索算法,及使用过程中的相关配置文件中参数介绍。 <div align="center">
<img src="../../images/structure.jpg" width = "800" />
</div>
## 一、检索库安装 如上图中所示,向量检索部分,在整个 `PP-ShiTu` 系统中有两部分内容
- 图中绿色部分:建立检索库,供检索时查询使用,同时提供增、删等功能
- 图中蓝色部分:检索功能,即给定一张图的特征向量,返回库中相似图像的 label
本文档主要主要介绍 PaddleClas 中检索模块的安装、使用的检索算法、建库流程的及相关配置文件中参数介绍。
--------------------------
## 目录
- [1. 检索库安装](#1)
- [2. 使用的检索算法](#2)
- [3. 使用及配置文档介绍](#3)
- [3.1 建库及配置文件参数](#3.1)
- [3.2 检索配置文件参数](#3.2)
<a name="1"></a>
## 1. 检索库安装
`Faiss`具体安装方法如下: `Faiss`具体安装方法如下:
...@@ -19,25 +40,44 @@ ...@@ -19,25 +40,44 @@
pip install faiss-cpu==1.7.1post2 pip install faiss-cpu==1.7.1post2
``` ```
若使用时,不能正常引用,则`uninstall` 之后,重新`install`,尤其是`windows`下。 若使用时,不能正常引用,则 `uninstall` 之后,重新 `install`,尤其是 `windows` 下。
## 二、使用的检索算法 <a name="2"></a>
目前`PaddleClas`中检索模块,支持如下三种检索算法 ## 2. 使用的检索算法
目前 `PaddleClas` 中检索模块,支持如下三种检索算法
- **HNSW32**: 一种图索引方法。检索精度较高,速度较快。但是特征库只支持添加图像功能,不支持删除图像特征功能。(默认方法) - **HNSW32**: 一种图索引方法。检索精度较高,速度较快。但是特征库只支持添加图像功能,不支持删除图像特征功能。(默认方法)
- **IVF**:倒排索引检索方法。速度较快,但是精度略低。特征库支持增加、删除图像特征功能。 - **IVF**:倒排索引检索方法。速度较快,但是精度略低。特征库支持增加、删除图像特征功能。
- **FLAT**: 暴力检索算法。精度最高,但是数据量大时,检索速度较慢。特征库支持增加、删除图像特征功能。 - **FLAT**: 暴力检索算法。精度最高,但是数据量大时,检索速度较慢。特征库支持增加、删除图像特征功能。
每种检索算法,满足不同场景。其中`HNSW32`为默认方法,此方法的检索精度、检索速度可以取得一个较好的平衡,具体算法介绍可以查看[官方文档](https://github.com/facebookresearch/faiss/wiki) 每种检索算法,满足不同场景。其中 `HNSW32` 为默认方法,此方法的检索精度、检索速度可以取得一个较好的平衡,具体算法介绍可以查看[官方文档](https://github.com/facebookresearch/faiss/wiki)
<a name="3"></a>
## 三、相关配置文档参数介绍 ## 3. 使用及配置文档介绍
涉及检索模块配置文件位于:`deploy/configs/`下,其中`build_*.yaml`是建立特征库的相关配置文件,`inference_*.yaml`是检索或者分类的推理配置文件。 涉及检索模块配置文件位于:`deploy/configs/` 下,其中 `build_*.yaml` 是建立特征库的相关配置文件,`inference_*.yaml` 是检索或者分类的推理配置文件。
### 3.1 建库配置文件参数 <a name="3.1"></a>
示例建库的配置如下 ### 3.1 建库及配置文件参数
建库的具体操作如下:
```shell
# 进入deploy目录
cd deploy
# yaml文件根据需要改成自己所需的具体yaml文件
python python/build_gallery.py -c configs/build_***.yaml
```
其中 `yaml` 文件的建库的配置如下,在运行时,请根据实际情况进行修改。建库操作会将根据 `data_file` 的图像列表,将 `image_root` 下的图像进行特征提取,并在 `index_dir` 下进行存储,以待后续检索使用。
其中 `data_file` 文件存储的是图像文件的路径和标签,每一行的格式为:`image_path label`。中间间隔以 `yaml` 文件中 `delimiter` 参数作为间隔。
关于特征提取的具体模型参数,可查看 `yaml` 文件。
```yaml ```yaml
# indexing engine config # indexing engine config
...@@ -56,13 +96,19 @@ IndexProcess: ...@@ -56,13 +96,19 @@ IndexProcess:
- **index_dir**:构建的特征库所存放的文件夹 - **index_dir**:构建的特征库所存放的文件夹
- **image_root**:构建特征库所需要的标注图像所存储的文件夹位置 - **image_root**:构建特征库所需要的标注图像所存储的文件夹位置
- **data_file**:构建特征库所需要的标注图像的数据列表,每一行的格式:relative_path label - **data_file**:构建特征库所需要的标注图像的数据列表,每一行的格式:relative_path label
- **index_operation**: 此次运行建库的操作:`new`新建,`append`将data_file的图像特征添加到特征库中,`remove`将data_file的图像从特征库中删除 - **index_operation**: 此次运行建库的操作:`new` 新建,`append` 将 data_file 的图像特征添加到特征库中,`remove` 将 data_file 的图像从特征库中删除
- **delimiter****data_file**中每一行的间隔符 - **delimiter****data_file** 中每一行的间隔符
- **dist_type**: 特征匹配过程中使用的相似度计算方式。`IP`内积相似度计算方式,`L2`欧式距离计算方法 - **dist_type**: 特征匹配过程中使用的相似度计算方式。例如 `IP` 内积相似度计算方式,`L2` 欧式距离计算方法
- **embedding_size**:特征维度 - **embedding_size**:特征维度
<a name="3.2"></a>
### 3.2 检索配置文件参数 ### 3.2 检索配置文件参数
将检索的过程融合到 `PP-ShiTu` 的整体流程中,请参考 [README](../../../README_ch.md)`PP-ShiTu图像识别系统介绍` 部分。检索具体使用操作请参考[识别快速开始文档](../quick_start/quick_start_recognition.md)
其中,检索部分配置如下,整体检索配置文件,请参考 `deploy/configs/inference_*.yaml` 文件。
```yaml ```yaml
IndexProcess: IndexProcess:
index_dir: "./recognition_demo_data_v1.1/gallery_logo/index/" index_dir: "./recognition_demo_data_v1.1/gallery_logo/index/"
...@@ -72,5 +118,5 @@ IndexProcess: ...@@ -72,5 +118,5 @@ IndexProcess:
与建库配置文件不同,新参数主要如下: 与建库配置文件不同,新参数主要如下:
- `return_k`: 检索结果返回`k`个结果 - `return_k`: 检索结果返回 `k` 个结果
- `score_thres`: 检索匹配的阈值 - `score_thres`: 检索匹配的阈值
# 服务器端C++预测 # 服务器端 C++ 预测
本教程将介绍在服务器端部署PaddleClas分类模型的详细步骤,识别模型部署方式将在近期支持,敬请期待。 本教程将介绍在服务器端部署 PaddleClas 分类模型的详细步骤,识别模型部署方式将在近期支持,敬请期待。
--- ---
## 目录 ## 目录
- [准备环境](#1) - [1. 准备环境](#1)
- [1.1编译opencv](#1.1) - [1.1 编译 opencv ](#1.1)
- [1.2准备环境](#1.2) - [1.2 准备环境](#1.2)
- [1.2.1 预测库源码编译](#1.2.1) - [1.2.1 预测库源码编译](#1.2.1)
- [1.2.2 直接下载安装](#1.2.2) - [1.2.2 直接下载安装](#1.2.2)
- [编译](#2) - [2. 编译](#2)
- [2.1 编译 PaddleClas C++ 预测 demo](#2.1) - [2.1 编译 PaddleClas C++ 预测 demo](#2.1)
- [2.2 编译 config lib 预测库与 cls lib 预测库](#2.2) - [2.2 编译 config lib 预测库与 cls lib 预测库](#2.2)
- [运行](#3) - [3. 运行](#3)
- [3.1 准备 inference model](#3.1) - [3.1 准备 inference model](#3.1)
- [3.2 运行 demo](#3.2) - [3.2 运行 demo](#3.2)
...@@ -23,12 +23,12 @@ ...@@ -23,12 +23,12 @@
## 1. 准备环境 ## 1. 准备环境
- Linux 环境,推荐使用 docker。 - Linux 环境,推荐使用 docker。
- Windows 环境,目前支持基于 `Visual Studio 2019 Community` 进行编译;此外,如果您希望通过生成 `sln解决方案` 的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681) - Windows 环境,目前支持基于 `Visual Studio 2019 Community` 进行编译;此外,如果您希望通过生成 `sln 解决方案` 的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681)
* 该文档主要介绍基于 Linux 环境下的 PaddleClas C++ 预测流程,如果需要在 Windows 环境下使用预测库进行 C++ 预测,具体编译方法请参考 [Windows下编译教程](./cpp_deploy_on_windows.md) * 该文档主要介绍基于 Linux 环境下的 PaddleClas C++ 预测流程,如果需要在 Windows 环境下使用预测库进行 C++ 预测,具体编译方法请参考 [Windows 下编译教程](./cpp_deploy_on_windows.md)
<a name="1.1"></a> <a name="1.1"></a>
### 1.1 编译opencv ### 1.1 编译 opencv
* 首先需要从 opencv 官网上下载在 Linux 环境下源码编译的包,以 3.4.7 版本为例,下载及解压缩命令如下: * 首先需要从 opencv 官网上下载在 Linux 环境下源码编译的包,以 3.4.7 版本为例,下载及解压缩命令如下:
...@@ -95,9 +95,9 @@ opencv3/ ...@@ -95,9 +95,9 @@ opencv3/
<a name="1.2.1"></a> <a name="1.2.1"></a>
#### 1.2.1 预测库源码编译 #### 1.2.1 预测库源码编译
如果希望获取最新预测库特性,可以从 GitHub 上克隆 Paddle 最新代码,从源码编译预测库。对于不同平台的编译流程,请参考 [Paddle预测库官网](https://paddleinference.paddlepaddle.org.cn/v2.1/user_guides/source_compile.html) 的说明。编译示例如下: 如果希望获取最新预测库特性,可以从 GitHub 上克隆 Paddle 最新代码,从源码编译预测库。对于不同平台的编译流程,请参考 [Paddle 预测库官网](https://paddleinference.paddlepaddle.org.cn/v2.1/user_guides/source_compile.html) 的说明。编译示例如下:
1. 使用Git获取源代码: 1. 使用 Git 获取源代码:
```shell ```shell
git clone https://github.com/PaddlePaddle/Paddle.git git clone https://github.com/PaddlePaddle/Paddle.git
...@@ -140,7 +140,7 @@ build/paddle_inference_install_dir/ ...@@ -140,7 +140,7 @@ build/paddle_inference_install_dir/
<a name="1.2.2"></a> <a name="1.2.2"></a>
#### 1.2.2 直接下载安装 #### 1.2.2 直接下载安装
[Paddle预测库官网](https://paddleinference.paddlepaddle.org.cn/v2.1/user_guides/download_lib.html#c) 上提供了不同版本的 Paddle 预测库,包括多个操作系统平台和GPU、CPU等多个硬件平台的预编译库,可以在官网查找并选择合适的预测库版本进行下载,建议选择 `2.1.1` 版本。 [Paddle 预测库官网](https://paddleinference.paddlepaddle.org.cn/v2.1/user_guides/download_lib.html#c) 上提供了不同版本的 Paddle 预测库,包括多个操作系统平台和 GPU、CPU 等多个硬件平台的预编译库,可以在官网查找并选择合适的预测库版本进行下载,建议选择 `2.1.1` 版本。
**注意**:在选择预测库时,所选预测库版本需要与后续编译选项一致: **注意**:在选择预测库时,所选预测库版本需要与后续编译选项一致:
* CPU 预测库仅可用于 GPU 预测,具体又分为 `mkl``openblas`,分别对应其低层实现基于 `MKL` 数学运算库 和 `OpenBLAS` 数学运算库; * CPU 预测库仅可用于 GPU 预测,具体又分为 `mkl``openblas`,分别对应其低层实现基于 `MKL` 数学运算库 和 `OpenBLAS` 数学运算库;
...@@ -269,13 +269,13 @@ inference/ ...@@ -269,13 +269,13 @@ inference/
### 3.2 运行 demo ### 3.2 运行 demo
首先修改 `tools/config.txt` 中对应字段: 首先修改 `tools/config.txt` 中对应字段:
* use_gpu:是否使用GPU; * use_gpu:是否使用 GPU;
* gpu_id:使用的GPU卡号; * gpu_id:使用的 GPU 卡号;
* gpu_mem:显存; * gpu_mem:显存;
* cpu_math_library_num_threads:底层科学计算库所用线程的数量; * cpu_math_library_num_threads:底层科学计算库所用线程的数量;
* use_mkldnn:是否使用MKLDNN加速; * use_mkldnn:是否使用 MKLDNN 加速;
* use_tensorrt: 是否使用tensorRT进行加速; * use_tensorrt: 是否使用 tensorRT 进行加速;
* use_fp16:是否使用半精度浮点数进行计算,该选项仅在use_tensorrt为true时有效; * use_fp16:是否使用半精度浮点数进行计算,该选项仅在 use_tensorrt 为 true 时有效;
* cls_model_path:预测模型结构文件路径; * cls_model_path:预测模型结构文件路径;
* cls_params_path:预测模型参数文件路径; * cls_params_path:预测模型参数文件路径;
* resize_short_size:预处理时图像缩放大小; * resize_short_size:预处理时图像缩放大小;
......
# 基于 Visual Studio 2019 Community CMake 编译指南 # 基于 Visual Studio 2019 Community CMake 编译指南
PaddleClas 在 Windows 平台下基于 `Visual Studio 2019 Community` 进行了测试。微软从 `Visual Studio 2017` 开始即支持直接管理 `CMake` 跨平台编译项目,但是直到 `2019` 版才提供了稳定和完全的支持,所以如果你想使用 CMake 管理项目编译构建,我们推荐使用 `Visual Studio 2019`。如果您希望通过生成 `sln解决方案` 的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681) PaddleClas 在 Windows 平台下基于 `Visual Studio 2019 Community` 进行了测试。微软从 `Visual Studio 2017` 开始即支持直接管理 `CMake` 跨平台编译项目,但是直到 `2019` 版才提供了稳定和完全的支持,所以如果你想使用 CMake 管理项目编译构建,我们推荐使用 `Visual Studio 2019`。如果您希望通过生成 `sln 解决方案` 的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681)
## 1. 前置条件 -----
## 目录
* [1. 前置条件](#1)
* [1.1 下载 PaddlePaddle C++ 预测库 paddle_inference_install_dir](#1.1)
* [1.2 安装配置 OpenCV](#1.2)
* [2. 使用 Visual Studio 2019 编译](#2)
* [3. 预测](#3)
* [3.1 准备 inference model](#3.1)
* [3.2 运行预测](#3.2)
* [3.3 注意事项](#3.3)
<a name='1'></a>
## 1. 前置条件
* Visual Studio 2019 * Visual Studio 2019
* CUDA 9.0 / CUDA 10.0,cudnn 7.6+ (仅在使用GPU版本的预测库时需要) * CUDA 9.0 / CUDA 10.0,cudnn 7.6+ (仅在使用 GPU 版本的预测库时需要)
* CMake 3.0+ * CMake 3.0+
请确保系统已经正确安装并配置好上述基本软件,其中: 请确保系统已经正确安装并配置好上述基本软件,其中:
* 在安装 `Visual Studio 2019` 时,`工作负载` 需要勾选 `使用C++的桌面开发` * 在安装 `Visual Studio 2019` 时,`工作负载` 需要勾选 `使用 C++的桌面开发`
* CUDA需要正确安装并设置系统环境变量; * CUDA 需要正确安装并设置系统环境变量;
* CMake需要正确安装并将路径添加到系统环境变量中。 * CMake 需要正确安装并将路径添加到系统环境变量中。
以下示例基于 `Visual Studio 2019 Community` 版本,以工作目录为 `D:\projects` 进行演示。 以下示例基于 `Visual Studio 2019 Community` 版本,以工作目录为 `D:\projects` 进行演示。
...@@ -27,13 +39,14 @@ PaddlePaddle C++ 预测库针对不同的 `CPU `和 `CUDA` 版本提供了不同 ...@@ -27,13 +39,14 @@ PaddlePaddle C++ 预测库针对不同的 `CPU `和 `CUDA` 版本提供了不同
``` ```
paddle_inference_install_dir paddle_inference_install_dir
├── paddle # paddle核心库和头文件 ├── paddle # paddle 核心库和头文件
├── third_party # 第三方依赖库和头文件 ├── third_party # 第三方依赖库和头文件
└── version.txt # 版本和编译信息 └── version.txt # 版本和编译信息
``` ```
**注意**:需要将 `Paddle预测库` 的路径(`D:\projects\paddle_inference_install_dir\paddle\lib`)添加到系统环境变量 `Path` 中。 **注意**:需要将 `Paddle 预测库` 的路径(`D:\projects\paddle_inference_install_dir\paddle\lib`)添加到系统环境变量 `Path` 中。
<a name='1.2'></a>
### 1.2 安装配置 OpenCV ### 1.2 安装配置 OpenCV
1. 在 OpenCV 官网下载适用于 Windows 平台的 3.4.6 版本,[下载地址](https://sourceforge.net/projects/opencvlibrary/files/3.4.6/opencv-3.4.6-vc14_vc15.exe/download) 1. 在 OpenCV 官网下载适用于 Windows 平台的 3.4.6 版本,[下载地址](https://sourceforge.net/projects/opencvlibrary/files/3.4.6/opencv-3.4.6-vc14_vc15.exe/download)
...@@ -44,7 +57,6 @@ paddle_inference_install_dir ...@@ -44,7 +57,6 @@ paddle_inference_install_dir
* 新建,将 OpenCV 路径填入并保存,如 `D:\projects\opencv\build\x64\vc14\bin` * 新建,将 OpenCV 路径填入并保存,如 `D:\projects\opencv\build\x64\vc14\bin`
<a name="2"></a> <a name="2"></a>
## 2. 使用 Visual Studio 2019 编译 ## 2. 使用 Visual Studio 2019 编译
1. 打开 Visual Studio 2019 Community,点击 `继续但无需代码` 1. 打开 Visual Studio 2019 Community,点击 `继续但无需代码`
...@@ -59,7 +71,7 @@ paddle_inference_install_dir ...@@ -59,7 +71,7 @@ paddle_inference_install_dir
![step2.2](../../images/inference_deployment/vs2019_step3.png) ![step2.2](../../images/inference_deployment/vs2019_step3.png)
3. 点击:`项目`->`CMake设置` 3. 点击:`项目`->`CMake 设置`
![step3](../../images/inference_deployment/vs2019_step4.png) ![step3](../../images/inference_deployment/vs2019_step4.png)
...@@ -69,10 +81,10 @@ paddle_inference_install_dir ...@@ -69,10 +81,10 @@ paddle_inference_install_dir
| ----------------------------- | ------------------ | ----------- | | ----------------------------- | ------------------ | ----------- |
| CMAKE_BACKWARDS_COMPATIBILITY | 3.17 | [√] | | CMAKE_BACKWARDS_COMPATIBILITY | 3.17 | [√] |
| CMAKE_BUILD_TYPE | RelWithDebInfo | [√] | | CMAKE_BUILD_TYPE | RelWithDebInfo | [√] |
| CUDA_LIB | CUDA的库路径 | [√] | | CUDA_LIB | CUDA 的库路径 | [√] |
| CUDNN_LIB | CUDNN的库路径 | [√] | | CUDNN_LIB | CUDNN 的库路径 | [√] |
| OpenCV_DIR | OpenCV的安装路径 | [√] | | OpenCV_DIR | OpenCV 的安装路径 | [√] |
| PADDLE_LIB | Paddle预测库的路径 | [√] | | PADDLE_LIB | Paddle 预测库的路径 | [√] |
| WITH_GPU | [√] | [√] | | WITH_GPU | [√] | [√] |
| WITH_MKL | [√] | [√] | | WITH_MKL | [√] | [√] |
| WITH_STATIC_LIB | [√] | [√] | | WITH_STATIC_LIB | [√] | [√] |
...@@ -83,16 +95,16 @@ paddle_inference_install_dir ...@@ -83,16 +95,16 @@ paddle_inference_install_dir
**注意** **注意**
* `CMAKE_BACKWARDS_COMPATIBILITY` 的值请根据自己 `cmake` 版本设置,`cmake` 版本可以通过命令:`cmake --version` 查询; * `CMAKE_BACKWARDS_COMPATIBILITY` 的值请根据自己 `cmake` 版本设置,`cmake` 版本可以通过命令:`cmake --version` 查询;
* `CUDA_LIB``CUDNN_LIB` 的值仅需在使用**GPU版本**预测库时指定,其中CUDA库版本尽量对齐,**使用9.0、10.0版本,不使用9.2、10.1等版本CUDA库** * `CUDA_LIB``CUDNN_LIB` 的值仅需在使用 **GPU 版本**预测库时指定,其中 CUDA 库版本尽量对齐,**使用 9.0、10.0 版本,不使用 9.2、10.1 等版本 CUDA 库**
* 在设置 `CUDA_LIB``CUDNN_LIB``OPENCV_DIR``PADDLE_LIB` 时,点击 `浏览`,分别设置相应的路径; * 在设置 `CUDA_LIB``CUDNN_LIB``OPENCV_DIR``PADDLE_LIB` 时,点击 `浏览`,分别设置相应的路径;
* `CUDA_LIB``CUDNN_LIB`:该路径取决于CUDA与CUDNN的安装位置。 * `CUDA_LIB``CUDNN_LIB`:该路径取决于 CUDA 与 CUDNN 的安装位置。
* `OpenCV_DIR`:该路径下需要有`.cmake`文件,一般为`opencv/build/` * `OpenCV_DIR`:该路径下需要有`.cmake`文件,一般为`opencv/build/`
* `PADDLE_LIB`:该路径下需要有`CMakeCache.txt`文件,一般为`paddle_inference_install_dir/` * `PADDLE_LIB`:该路径下需要有`CMakeCache.txt`文件,一般为`paddle_inference_install_dir/`
* 在使用 `CPU` 版预测库时,请不要勾选 `WITH_GPU` - `保存到 JSON` * 在使用 `CPU` 版预测库时,请不要勾选 `WITH_GPU` - `保存到 JSON`
![step4](../../images/inference_deployment/vs2019_step5.png) ![step4](../../images/inference_deployment/vs2019_step5.png)
设置完成后,点击上图中 `保存并生成CMake缓存以加载变量` 设置完成后,点击上图中 `保存并生成 CMake 缓存以加载变量`
5. 点击`生成`->`全部生成` 5. 点击`生成`->`全部生成`
...@@ -100,8 +112,10 @@ paddle_inference_install_dir ...@@ -100,8 +112,10 @@ paddle_inference_install_dir
在编译完成后,会生成可执行文件 `clas_system.exe`。并且,如未设置 `DCONFIG_LIB``DCLS_LIB`,则会在 `.\lib\` 目录下生成 `config lib` 和 `cls lib` 两个静态链接库文件(`libconfig.a`、`libcls.a`)。类似地,你也可以仅编译生成 `config lib` 和 `cls lib` 两个静态链接库文件,只需打开路径为 `D:\projects\PaddleClas\deploy\cpp\lib\CMakeList.txt` 的 `CMake` 文件并进行编译即可,具体参考[2. 使用 Visual Studio 2019 编译](#2),完成编译后,同样可在 `.\lib\` 目录下生成静态链接库文件,静态链接库文件可用于二次开发。 在编译完成后,会生成可执行文件 `clas_system.exe`。并且,如未设置 `DCONFIG_LIB``DCLS_LIB`,则会在 `.\lib\` 目录下生成 `config lib` 和 `cls lib` 两个静态链接库文件(`libconfig.a`、`libcls.a`)。类似地,你也可以仅编译生成 `config lib` 和 `cls lib` 两个静态链接库文件,只需打开路径为 `D:\projects\PaddleClas\deploy\cpp\lib\CMakeList.txt` 的 `CMake` 文件并进行编译即可,具体参考[2. 使用 Visual Studio 2019 编译](#2),完成编译后,同样可在 `.\lib\` 目录下生成静态链接库文件,静态链接库文件可用于二次开发。
<a name='3'></a>
## 3. 预测 ## 3. 预测
<a name='3.1'></a>
### 3.1 准备 inference model ### 3.1 准备 inference model
首先需要准备 inference model,关于将模型导出为 inference model 的具体步骤,可以参考 [模型导出](./export_model.md) 文档。假设导出的预测模型文件放在 `./inference` 目录下,则目录结构如下。 首先需要准备 inference model,关于将模型导出为 inference model 的具体步骤,可以参考 [模型导出](./export_model.md) 文档。假设导出的预测模型文件放在 `./inference` 目录下,则目录结构如下。
...@@ -114,16 +128,17 @@ inference/ ...@@ -114,16 +128,17 @@ inference/
**注意**:上述文件中,`cls_infer.pdmodel` 文件存储了模型网络结构信息,`cls_infer.pdiparams` 文件存储了模型参数权重信息。在运行预测时,注意两个文件的路径需要分别设置为配置文件 `tools/config.txt` 中的字段 `cls_model_path``cls_params_path` 的值。 **注意**:上述文件中,`cls_infer.pdmodel` 文件存储了模型网络结构信息,`cls_infer.pdiparams` 文件存储了模型参数权重信息。在运行预测时,注意两个文件的路径需要分别设置为配置文件 `tools/config.txt` 中的字段 `cls_model_path``cls_params_path` 的值。
<a name='3.2'></a>
### 3.2 运行预测 ### 3.2 运行预测
首先修改 `tools/config.txt` 中对应字段: 首先修改 `tools/config.txt` 中对应字段:
* use_gpu:是否使用GPU; * use_gpu:是否使用 GPU;
* gpu_id:使用的GPU卡号; * gpu_id:使用的 GPU 卡号;
* gpu_mem:显存; * gpu_mem:显存;
* cpu_math_library_num_threads:底层科学计算库所用线程的数量; * cpu_math_library_num_threads:底层科学计算库所用线程的数量;
* use_mkldnn:是否使用MKLDNN加速; * use_mkldnn:是否使用 MKLDNN 加速;
* use_tensorrt: 是否使用tensorRT进行加速; * use_tensorrt: 是否使用 tensorRT 进行加速;
* use_fp16:是否使用半精度浮点数进行计算,该选项仅在use_tensorrt为true时有效; * use_fp16:是否使用半精度浮点数进行计算,该选项仅在 use_tensorrt 为 true 时有效;
* cls_model_path:预测模型结构文件路径; * cls_model_path:预测模型结构文件路径;
* cls_params_path:预测模型参数文件路径; * cls_params_path:预测模型参数文件路径;
* resize_short_size:预处理时图像缩放大小; * resize_short_size:预处理时图像缩放大小;
...@@ -143,8 +158,8 @@ cd D:\projects\PaddleClas\deploy\cpp\out\build\x64-Release ...@@ -143,8 +158,8 @@ cd D:\projects\PaddleClas\deploy\cpp\out\build\x64-Release
上述命令中,第一个参数(`D:\projects\PaddleClas\deploy\cpp\tools\config.txt`)为配置文件路径,第二个参数(`.\docs\ILSVRC2012_val_00008306.JPEG`)为需要预测的图片路径。 上述命令中,第一个参数(`D:\projects\PaddleClas\deploy\cpp\tools\config.txt`)为配置文件路径,第二个参数(`.\docs\ILSVRC2012_val_00008306.JPEG`)为需要预测的图片路径。
注意,需要在配置文件中正确设置预测参数,包括所用模型文件的路径(`cls_model_path``cls_params_path`)。 注意,需要在配置文件中正确设置预测参数,包括所用模型文件的路径(`cls_model_path``cls_params_path`)。
<a name='3.3'></a>
### 4. 注意事项 ### 3.3 注意事项
* 在 Windows 下的终端中执行文件 exe 时,可能会发生乱码的现象,此时需要在终端中输入 `CHCP 65001`,将终端的编码方式由 GBK 编码(默认)改为 UTF-8 编码,更加具体的解释可以参考这篇博客:[https://blog.csdn.net/qq_35038153/article/details/78430359](https://blog.csdn.net/qq_35038153/article/details/78430359) * 在 Windows 下的终端中执行文件 exe 时,可能会发生乱码的现象,此时需要在终端中输入 `CHCP 65001`,将终端的编码方式由 GBK 编码(默认)改为 UTF-8 编码,更加具体的解释可以参考这篇博客:[https://blog.csdn.net/qq_35038153/article/details/78430359](https://blog.csdn.net/qq_35038153/article/details/78430359)
* 如果需要使用 CPU 预测,PaddlePaddle 在 Windows 上仅支持 avx 的 CPU 预测,目前不支持 noavx 的 CPU 预测; * 如果需要使用 CPU 预测,PaddlePaddle 在 Windows 上仅支持 avx 的 CPU 预测,目前不支持 noavx 的 CPU 预测;
* 在使用生成的 `clas_system.exe` 进行预测时,如提示 `由于找不到paddle_fluid.dll,无法继续执行代码。重新安装程序可能会解决此问题`,请检查是否将 Paddle 预测库路径添加到系统环境变量,详见[1.1 下载 PaddlePaddle C++ 预测库 paddle_inference_install_dir](#1.1) * 在使用生成的 `clas_system.exe` 进行预测时,如提示 `由于找不到 paddle_fluid.dll,无法继续执行代码。重新安装程序可能会解决此问题`,请检查是否将 Paddle 预测库路径添加到系统环境变量,详见[1.1 下载 PaddlePaddle C++ 预测库 paddle_inference_install_dir](#1.1)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册