提交 d76c53a2 编写于 作者: S sibo2rr

modify documentation according to the standard format

上级 eb9d0088
文件已添加
文件已添加
文件已添加
......@@ -2,7 +2,7 @@
---
图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题,也是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在很多领域有广泛应用,包括安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等。
一般来说,图像分类通过手工特征或特征学习方法对整个图像进行全部描述,然后使用分类器判别物体类别,因此如何提取图像的特征至关重要。在深度学习算法之前使用较多的是基于词袋(Bag of Words)模型的物体分类方法。而基于深度学习的图像分类方法,可以通过有监督或无监督的方式学习层次化的特征描述,从而取代了手工设计或选择图像特征的工作。深度学习模型中的卷积神经网络(Convolution Neural Network, CNN)近年来在图像领域取得了惊人的成绩,CNN直接利用图像像素信息作为输入,最大程度上保留了输入图像的所有信息,通过卷积操作进行特征的提取和高层抽象,模型输出直接是图像识别的结果。这种基于"输入-输出"直接端到端的学习方法取得了非常好的效果,得到了广泛的应用。
一般来说,图像分类通过手工特征或特征学习方法对整个图像进行全部描述,然后使用分类器判别物体类别,因此如何提取图像的特征至关重要。在深度学习算法之前使用较多的是基于词袋 (Bag of Words) 模型的物体分类方法。而基于深度学习的图像分类方法,可以通过有监督或无监督的方式学习层次化的特征描述,从而取代了手工设计或选择图像特征的工作。深度学习模型中的卷积神经网络 (Convolution Neural Network, CNN) 近年来在图像领域取得了惊人的成绩,CNN 直接利用图像像素信息作为输入,最大程度上保留了输入图像的所有信息,通过卷积操作进行特征的提取和高层抽象,模型输出直接是图像识别的结果。这种基于“输入-输出”直接端到端的学习方法取得了非常好的效果,得到了广泛的应用。
图像分类是计算机视觉里很基础但又重要的一个领域,其研究成果一直影响着计算机视觉甚至深度学习的发展,图像分类有很多子领域,如多标签分类、细粒度分类等,此处只对单标签图像分类做一个简述。
......@@ -10,73 +10,74 @@
## 目录
- [数据集介绍](#1)
- [1. 数据集介绍](#1)
- [1.1 ImageNet-1k](#1.1)
- [1.2 CIFAR-10/CIFAR-100](#1.2)
- [图像分类的流程](#2)
- [2. 图像分类的流程](#2)
- [2.1 数据及其预处理](#2.1)
- [2.2 模型准备](#2.2)
- [2.3 模型训练](#2.3)
- [2.3 模型评估](#2.4)
- [使用方法介绍](#3)
- [3.1 基于CPU/单卡GPU上的训练与评估](#3.1)
- [3. 使用方法介绍](#3)
- [3.1 基于 CPU /单卡 GPU 上的训练与评估](#3.1)
- [3.1.1 模型训练](#3.1.1)
- [3.1.2 模型微调](#3.1.2)
- [3.1.3 模型恢复训练](#3.1.3)
- [3.1.4 模型评估](#3.1.4)
- [3.2 基于Linux+多卡GPU的模型训练与评估](#3.2)
- [3.2 基于 Linux + 多卡 GPU 的模型训练与评估](#3.2)
- [3.2.1 模型训练](#3.2.1)
- [3.2.2 模型微调](#3.2.2)
- [3.2.3 模型恢复训练](#3.2.3)
- [3.2.4 模型评估](#3.2.4)
- [3.3 使用预训练模型进行模型预测](#3.3)
- [3.4 使用inference模型进行模型推理](#3.4)
- [3.4 使用 inference 模型进行模型推理](#3.4)
<a name="1"></a>
## 一、数据集介绍
## 1. 数据集介绍
<a name="1.1"></a>
### 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>
### 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>
## 二、图像分类的流程
## 2. 图像分类的流程
将准备好的训练数据做相应的数据预处理后经过图像分类模型,模型的输出与真实标签做交叉熵损失函数,该损失函数描述了模型的收敛方向,遍历所有的图片数据输入模型,对最终损失函数通过某些优化器做相应的梯度下降,将梯度信息回传到模型中,更新模型的权重,如此循环往复遍历多次数据,即可得到一个图像分类的模型。
<a name="2.1"></a>
### 2.1 数据及其预处理
数据的质量及数量往往可以决定一个模型的好坏。在图像分类领域,数据包括图像及标签。在大部分情形下,带有标签的数据比较匮乏,所以数量很难达到使模型饱和的程度,为了可以使模型学习更多的图像特征,图像数据在进入模型之前要经过很多图像变换或者数据增强,来保证输入图像数据的多样性,从而保证模型有更好的泛化能力。PaddleClas提供了训练ImageNet-1k的标准图像变换,也提供了多种数据增强的方法,相关代码可以[数据处理](../../../ppcls/data/preprocess),配置文件可以参考[数据增强配置文件](../../../ppcls/configs/ImageNet/DataAugment), 相关数据增强算法详见数据[增强介绍文档](../algorithm_introduction/DataAugmentation.md)
数据的质量及数量往往可以决定一个模型的好坏。在图像分类领域,数据包括图像及标签。在大部分情形下,带有标签的数据比较匮乏,所以数量很难达到使模型饱和的程度,为了可以使模型学习更多的图像特征,图像数据在进入模型之前要经过很多图像变换或者数据增强,来保证输入图像数据的多样性,从而保证模型有更好的泛化能力。PaddleClas 提供了训练 ImageNet-1k 的标准图像变换,也提供了多种数据增强的方法,相关代码可以查看[数据处理](../../../ppcls/data/preprocess),配置文件可以参考[数据增强配置文件](../../../ppcls/configs/ImageNet/DataAugment), 相关数据增强算法详见[增强介绍文档](../algorithm_introduction/DataAugmentation.md)
<a name="2.2"></a>
### 2.2 模型准备
在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了35个系列共164个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](../algorithm_introduction/ImageNet_models.md)
在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas 提供了 35 个系列共 164 个 ImageNet 预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](../algorithm_introduction/ImageNet_models.md)
<a name="2.3"></a>
### 2.3 模型训练
在准备好数据、模型后,便可以开始迭代模型并更新模型的参数。经过多次迭代最终可以得到训练好的模型来做图像分类任务。图像分类的训练过程需要很多经验,涉及很多超参数的设置,PaddleClas提供了一些列的[训练调优方法](./train_strategy.md),可以快速助你获得高精度的模型。
在准备好数据、模型后,便可以开始迭代模型并更新模型的参数。经过多次迭代最终可以得到训练好的模型来做图像分类任务。图像分类的训练过程需要很多经验,涉及很多超参数的设置,PaddleClas 提供了一些列的[训练调优方法](./train_strategy.md),可以快速助你获得高精度的模型。
<a name="2.4"></a>
### 2.4 模型评估
当训练得到一个模型之后,如何确定模型的好坏,需要将模型在验证集上进行评估。评估指标一般是Top1-Acc或者Top5-Acc,该指标越高往往代表模型性能越好。
当训练得到一个模型之后,如何确定模型的好坏,需要将模型在验证集上进行评估。评估指标一般是 Top1-Acc 或者 Top5-Acc,该指标越高往往代表模型性能越好。
<a name="3"></a>
## 三、使用方法介绍
## 3. 使用方法介绍
请参考[安装指南](../installation/install_paddleclas.md)配置运行环境,并根据[快速开始](../quick_start/quick_start_classification_new_user.md)文档准备flower102数据集,本章节下面所有的实验均以flower102数据集为例。
请参考[安装指南](../installation/install_paddleclas.md)配置运行环境,并根据[快速开始](../quick_start/quick_start_classification_new_user.md)文档准备 flower102 数据集,本章节下面所有的实验均以 flower102 数据集为例。
PaddleClas目前支持的训练/评估环境如下:
PaddleClas 目前支持的训练/评估环境如下:
```shell
└── CPU/单卡GPU
   ├── Linux
......@@ -89,7 +90,7 @@ PaddleClas目前支持的训练/评估环境如下:
<a name="3.1"></a>
### 3.1 基于CPU/单卡GPU上的训练与评估
在基于CPU/单卡GPU上训练与评估,推荐使用`tools/train.py``tools/eval.py`脚本。关于Linux平台多卡GPU环境下的训练与评估,请参考[3.2. 基于Linux+GPU的模型训练与评估](#3.2)
在基于 CPU/单卡 GPU 上训练与评估,推荐使用 `tools/train.py``tools/eval.py` 脚本。关于 Linux 平台多卡 GPU 环境下的训练与评估,请参考 [3.2. 基于Linux+GPU的模型训练与评估](#3.2)
<a name="3.1.1"></a>
......@@ -104,13 +105,13 @@ python3 tools/train.py \
-o Global.device=gpu
```
其中,`-c`用于指定配置文件的路径,`-o`用于指定需要修改或者添加的参数,其中`-o Arch.pretrained=False`表示不使用预训练模型,`-o Global.device=gpu`表示使用GPU进行训练。如果希望使用CPU进行训练,则需要将`Global.device`设置为`cpu`
其中,`-c` 用于指定配置文件的路径,`-o` 用于指定需要修改或者添加的参数,其中 `-o Arch.pretrained=False` 表示不使用预训练模型,`-o Global.device=gpu` 表示使用 GPU 进行训练。如果希望使用 CPU 进行训练,则需要将 `Global.device` 设置为 `cpu`
更详细的训练配置,也可以直接修改模型对应的配置文件。具体配置参数参考[配置文档](config_description.md)
运行上述命令,可以看到输出日志,示例如下:
* 如果在训练中使用了mixup或者cutmix的数据增广方式,那么日志中将不会打印top-1与top-k(默认为5)信息:
* 如果在训练中使用了 mixup 或者 cutmix 的数据增广方式,那么日志中将不会打印 top-1 与 top-k(默认为5)信息:
```
...
[Train][Epoch 3/20][Avg]CELoss: 6.46287, loss: 6.46287
......@@ -119,7 +120,7 @@ python3 tools/train.py \
...
```
* 如果训练过程中没有使用mixup或者cutmix的数据增广,那么除了上述信息外,日志中也会打印出top-1与top-k(默认为5)的信息:
* 如果训练过程中没有使用 mixup 或者 cutmix 的数据增广,那么除了上述信息外,日志中也会打印出 top-1 与top-k(默认为5)的信息:
```
...
......@@ -129,7 +130,7 @@ python3 tools/train.py \
...
```
训练期间也可以通过VisualDL实时观察loss变化,详见[VisualDL](../others/VisualDL.md)
训练期间也可以通过 VisualDL 实时观察 loss 变化,详见 [VisualDL](../others/VisualDL.md)
<a name="3.1.2"></a>
#### 3.1.2 模型微调
......@@ -143,9 +144,9 @@ python3 tools/train.py \
-o Global.device=gpu
```
其中`Arch.pretrained`设置为`True`表示加载ImageNet的预训练模型,此外,`Arch.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。
其中 `Arch.pretrained` 设置为 `True` 表示加载 ImageNet 的预训练模型,此外,`Arch.pretrained` 也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。
我们也提供了大量基于`ImageNet-1k`数据集的预训练模型,模型列表及下载地址详见[模型库概览](../algorithm_introduction/ImageNet_models.md)
我们也提供了大量基于 `ImageNet-1k` 数据集的预训练模型,模型列表及下载地址详见[模型库概览](../algorithm_introduction/ImageNet_models.md)
<a name="3.1.3"></a>
......@@ -160,11 +161,11 @@ python3 tools/train.py \
-o Global.device=gpu
```
其中配置文件不需要做任何修改,只需要在继续训练时设置`Global.checkpoints`参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。
其中配置文件不需要做任何修改,只需要在继续训练时设置 `Global.checkpoints` 参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。
**注意**
* `-o Global.checkpoints`参数无需包含断点权重文件的后缀名,上述训练命令会在训练过程中生成如下所示的断点权重文件,若想从断点`5`继续训练,则`Global.checkpoints`参数只需设置为`"../output/MobileNetV3_large_x1_0/epoch_5"`,PaddleClas会自动补充后缀名。output目录下的文件结构如下所示:
* `-o Global.checkpoints` 参数无需包含断点权重文件的后缀名,上述训练命令会在训练过程中生成如下所示的断点权重文件,若想从断点 `5` 继续训练,则 `Global.checkpoints` 参数只需设置为 `"../output/MobileNetV3_large_x1_0/epoch_5"`,PaddleClas 会自动补充后缀名。output 目录下的文件结构如下所示:
```shell
output
......@@ -192,24 +193,25 @@ python3 tools/eval.py \
-o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model
```
上述命令将使用`./configs/quick_start/MobileNetV3_large_x1_0.yaml`作为配置文件,对上述训练得到的模型`./output/MobileNetV3_large_x1_0/best_model`进行评估。你也可以通过更改配置文件中的参数来设置评估,也可以通过`-o`参数更新配置,如上所示。
上述命令将使用 `./configs/quick_start/MobileNetV3_large_x1_0.yaml` 作为配置文件,对上述训练得到的模型 `./output/MobileNetV3_large_x1_0/best_model` 进行评估。你也可以通过更改配置文件中的参数来设置评估,也可以通过 `-o` 参数更新配置,如上所示。
可配置的部分评估参数说明如下:
* `Arch.name`:模型名称
* `Global.pretrained_model`:待评估的模型预训练模型文件路径
**注意:** 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[3.1.3 模型恢复训练](#3.1.3)
**注意:** 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas 会自动补齐 `.pdparams` 的后缀,如 [3.1.3 模型恢复训练](#3.1.3)
<a name="3.2"></a>
### 3.2 基于Linux+多卡GPU的模型训练与评估
### 3.2 基于 Linux + 多卡 GPU 的模型训练与评估
如果机器环境为Linux+GPU,那么推荐使用`paddle.distributed.launch`启动模型训练脚本(`tools/train.py`)、评估脚本(`tools/eval.py`,可以更方便地启动多卡训练与评估。
如果机器环境为 Linux + GPU,那么推荐使用 `paddle.distributed.launch` 启动模型训练脚本(`tools/train.py`)、评估脚本(`tools/eval.py`),可以更方便地启动多卡训练与评估。
<a name="3.2.1"></a>
#### 3.2.1 模型训练
参考如下方式启动模型训练,`paddle.distributed.launch`通过设置`gpus`指定GPU运行卡号:
参考如下方式启动模型训练,`paddle.distributed.launch` 通过设置 `gpus` 指定 GPU 运行卡号:
```bash
# PaddleClas通过launch方式启动多卡多进程训练
......@@ -221,7 +223,7 @@ python3 -m paddle.distributed.launch \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml
```
输出日志信息的格式同上,详见[3.1.1 模型训练](#3.1.1)
输出日志信息的格式同上,详见 [3.1.1 模型训练](#3.1.1)
<a name="3.2.2"></a>
#### 3.2.2 模型微调
......@@ -237,12 +239,12 @@ python3 -m paddle.distributed.launch \
-o Arch.pretrained=True
```
其中`Arch.pretrained``True``False`,当然也可以设置加载预训练权重文件的路径,使用时需要换成自己的预训练模型权重文件路径,也可以直接在配置文件中修改该路径。
30分钟玩转PaddleClas[尝鲜版](../quick_start/quick_start_classification_new_user.md)[进阶版](../quick_start/quick_start_classification_professional.md)中包含大量模型微调的示例,可以参考该章节在特定的数据集上进行模型微调。
其中 `Arch.pretrained``True``False`,当然也可以设置加载预训练权重文件的路径,使用时需要换成自己的预训练模型权重文件路径,也可以直接在配置文件中修改该路径。
30 分钟玩转 PaddleClas [尝鲜版](../quick_start/quick_start_classification_new_user.md)[进阶版](../quick_start/quick_start_classification_professional.md)中包含大量模型微调的示例,可以参考该章节在特定的数据集上进行模型微调。
<a name="3.2.3"></a>
#### 3.2.3 模型恢复训练
如果训练任务因为其他原因被终止,也可以加载断点权重文件继续训练。
......@@ -258,9 +260,10 @@ python3 -m paddle.distributed.launch \
-o Global.device=gpu
```
其中配置文件不需要做任何修改,只需要在训练时设置`Global.checkpoints`参数即可,该参数表示加载的断点权重文件路径,使用该参数会同时加载保存的模型参数权重和学习率、优化器等信息,详见[3.1.3 模型恢复训练](#3.1.3)
其中配置文件不需要做任何修改,只需要在训练时设置 `Global.checkpoints` 参数即可,该参数表示加载的断点权重文件路径,使用该参数会同时加载保存的模型参数权重和学习率、优化器等信息,详见 [3.1.3 模型恢复训练](#3.1.3)
<a name="3.2.4"></a>
#### 3.2.4 模型评估
可以通过以下命令进行模型评估。
......@@ -273,7 +276,7 @@ python3 -m paddle.distributed.launch \
-o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model
```
参数说明详见[3.1.4 模型评估](#3.1.4)
参数说明详见 [3.1.4 模型评估](#3.1.4)
<a name="3.3"></a>
......@@ -294,9 +297,9 @@ python3 tools/infer.py \
<a name="3.4"></a>
### 3.4 使用inference模型进行模型推理
### 3.4 使用 inference 模型进行模型推理
通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。接下来介绍如何用预测引擎进行推理:
通过导出 inference 模型,PaddlePaddle 支持使用预测引擎进行预测推理。接下来介绍如何用预测引擎进行推理:
首先,对训练好的模型进行转换:
```bash
......@@ -306,9 +309,9 @@ python3 tools/export_model.py \
```
其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[3.1.3 模型恢复训练](#3.1.3))。
其中,`Global.pretrained_model` 用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如 [3.1.3 模型恢复训练](#3.1.3))。
上述命令将生成模型结构文件`inference.pdmodel`)和模型权重文件(`inference.pdiparams`,然后可以使用预测引擎进行推理:
上述命令将生成模型结构文件(`inference.pdmodel`) 和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理:
进入deploy目录下:
......@@ -316,7 +319,7 @@ python3 tools/export_model.py \
cd deploy
```
执行命令进行预测,由于默认class_id_map_file是ImageNet数据集的映射文件,所以此处需要置None。
执行命令进行预测,由于默认 `class_id_map_file` 是 ImageNet 数据集的映射文件,所以此处需要置 None。
```bash
python3 python/predict_cls.py \
......@@ -328,13 +331,13 @@ python3 python/predict_cls.py \
```
其中:
+ `Global.infer_imgs`:待预测的图片文件路径。
+ `Global.inference_model_dir`:inference模型结构文件路径,如 `../inference/inference.pdmodel`
+ `Global.inference_model_dir`:inference 模型结构文件路径,如 `../inference/inference.pdmodel`
+ `Global.use_tensorrt`:是否使用 TesorRT 预测引擎,默认值:`False`
+ `Global.use_gpu`:是否使用 GPU 预测,默认值:`True`
+ `Global.enable_mkldnn`:是否启用`MKL-DNN`加速,默认为`False`。注意`enable_mkldnn``use_gpu`同时为`True`时,将忽略`enable_mkldnn`,而使用GPU运行。
+ `Global.use_fp16`:是否启用`FP16`,默认为`False`
+ `Global.enable_mkldnn`:是否启用 `MKL-DNN` 加速,默认为 `False`。注意 `enable_mkldnn``use_gpu` 同时为 `True` 时,将忽略 `enable_mkldnn`,而使用 GPU 运行。
+ `Global.use_fp16`:是否启用 `FP16`,默认为 `False`
注意: 如果使用`Transformer`系列模型,如`DeiT_***_384`, `ViT_***_384`等,请注意模型的输入数据尺寸,需要设置参数`resize_short=384`, `resize=384`
注意: 如果使用 `Transformer` 系列模型,如 `DeiT_***_384`, `ViT_***_384` 等,请注意模型的输入数据尺寸,需要设置参数 `resize_short=384`, `resize=384`
如果你希望提升评测模型速度,使用gpu评测时,建议开启TensorRT加速预测,使用cpu评测时,建议开启MKLDNN加速预测。
如果你希望提升评测模型速度,使用 GPU 评测时,建议开启 TensorRT 加速预测,使用 CPU 评测时,建议开启MKLDNN 加速预测。
......@@ -4,7 +4,7 @@
## 简介
本文档介绍了PaddleClas配置文件(`ppcls/configs/*.yaml`)中各参数的含义,以便您更快地自定义或修改超参数配置。
本文档介绍了 PaddleClas 配置文件(`ppcls/configs/*.yaml`)中各参数的含义,以便您更快地自定义或修改超参数配置。
......@@ -12,28 +12,29 @@
### 目录
- [分类模型](#1)
- [1. 分类模型](#1)
- [1.1 全局配置(Global)](#1.1)
- [1.2 结构(Arch)](#1.2)
- [1.3 损失函数(Loss)](#1.3)
- [1.3 损失函数(Loss)](#1.3)
- [1.4 优化器(Optimizer)](#1.4)
- [1.5数据读取模块(DataLoader)](#1.5)
- [1.5数据读取模块(DataLoader)](#1.5)
- [1.5.1 dataset](#1.5.1)
- [1.5.1 sampler](#1.5.2)
- [1.5.1 loader](#1.5.3)
- [1.6 评估指标(Metric)](#1.6)
- [蒸馏模型](#2)
- [1.6 评估指标(Metric)](#1.6)
- [2. 蒸馏模型](#2)
- [2.1 结构(Arch)](#2.1)
- [2.2 损失函数(Loss)](#2.2)
- [2.3 评估指标(Metric)](#2.3)
- [识别模型](#3)
- [2.2 损失函数(Loss)](#2.2)
- [2.3 评估指标(Metric)](#2.3)
- [3. 识别模型](#3)
- [3.1 结构(Arch)](#3.1)
- [3.2 评估指标(Metric)](#3.2)
- [3.2 评估指标(Metric)](#3.2)
<a name="1"></a>
### 1.分类模型
此处以`ResNet50_vd``ImageNet-1k`上的训练配置为例,详解各个参数的意义。[配置路径](../../../ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml)
此处以 `ResNet50_vd``ImageNet-1k` 上的训练配置为例,详解各个参数的意义。[配置路径](../../../ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml)
<a name="1.1"></a>
#### 1.1 全局配置(Global)
......@@ -43,30 +44,30 @@
| checkpoints | 断点模型路径,用于恢复训练 | null | str |
| pretrained_model | 预训练模型路径 | null | str |
| output_dir | 保存模型路径 | "./output/" | str |
| save_interval | 每隔多少个epoch保存模型 | 1 | int |
| save_interval | 每隔多少个 epoch 保存模型 | 1 | int |
| eval_during_train| 是否在训练时进行评估 | True | bool |
| eval_interval | 每隔多少个epoch进行模型评估 | 1 | int |
| eval_interval | 每隔多少个 epoch 进行模型评估 | 1 | int |
| epochs | 训练总epoch数 | | int |
| print_batch_step | 每隔多少个mini-batch打印输出 | 10 | int |
| use_visualdl | 是否是用visualdl可视化训练过程 | False | bool |
| image_shape | 图片大小 | [3,224,224] | list, shape: (3,) |
| save_inference_dir | inference模型的保存路径 | "./inference" | str |
| eval_mode | eval的模式 | "classification" | "retrieval" |
| print_batch_step | 每隔多少个 mini-batch 打印输出 | 10 | int |
| use_visualdl | 是否是用 visualdl 可视化训练过程 | False | bool |
| image_shape | 图片大小 | [3, 224, 224] | list, shape: (3,) |
| save_inference_dir | inference 模型的保存路径 | "./inference" | str |
| eval_mode | eval 的模式 | "classification" | "retrieval" |
| to_static | 是否改为静态图模式 | False | True |
| ues_dali | 是否使用dali库进行图像预处理 | False | True |
| ues_dali | 是否使用 dali 库进行图像预处理 | False | True |
**注**`pretrained_model`也可以填写存放预训练模型的http地址。
**注**`pretrained_model` 也可以填写存放预训练模型的 http 地址。
<a name="1.2"></a>
#### 1.2 结构(Arch)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | 模型结构名字 | ResNet50 | PaddleClas提供的模型结构 |
| name | 模型结构名字 | ResNet50 | PaddleClas 提供的模型结构 |
| class_num | 分类数 | 1000 | int |
| pretrained | 预训练模型 | False | bool str |
| pretrained | 预训练模型 | False | bool, str |
**注**:此处的pretrained可以设置为`True`或者`False`,也可以设置权重的路径。另外当`Global.pretrained_model`也设置相应路径时,此处的`pretrained`失效。
**注**:此处的pretrained可以设置为 `True` 或者 `False`,也可以设置权重的路径。另外当 `Global.pretrained_model` 也设置相应路径时,此处的 `pretrained` 失效。
<a name="1.3"></a>
#### 1.3 损失函数(Loss)
......@@ -74,8 +75,8 @@
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| CELoss | 交叉熵损失函数 | —— | —— |
| CELoss.weight | CELoss的在整个Loss中的权重 | 1.0 | float |
| CELoss.epsilon | CELoss中label_smooth的epsilon值 | 0.1 | float,0-1之间 |
| CELoss.weight | CELoss 在整个 Loss 中的权重 | 1.0 | float |
| CELoss.epsilon | CELoss 中 label_smooth 的 epsilon 值 | 0.1 | float, 0-1 之间 |
<a name="1.4"></a>
#### 1.4 优化器(Optimizer)
......@@ -83,14 +84,14 @@
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | 优化器方法名 | "Momentum" | "RmsProp"等其他优化器 |
| momentum | momentum值 | 0.9 | float |
| momentum | momentum 值 | 0.9 | float |
| lr.name | 学习率下降方式 | "Cosine" | "Linear"、"Piecewise"等其他下降方式 |
| lr.learning_rate | 学习率初始值 | 0.1 | float |
| lr.warmup_epoch | warmup轮数 | 0 | int,如5 |
| lr.warmup_epoch | warmup 轮数 | 0 | int,如5 |
| regularizer.name | 正则化方法名 | "L2" | ["L1", "L2"] |
| regularizer.coeff | 正则化系数 | 0.00007 | float |
**注**`lr.name`不同时,新增的参数可能也不同,如当`lr.name=Piecewise`时,需要添加如下参数:
**注**`lr.name` 不同时,新增的参数可能也不同,如当 `lr.name=Piecewise` 时,需要添加如下参数:
```
lr:
......@@ -100,53 +101,53 @@
values: [0.1, 0.01, 0.001, 0.0001]
```
添加方法及参数请查看[learning_rate.py](../../../ppcls/optimizer/learning_rate.py)
添加方法及参数请查看 [learning_rate.py](../../../ppcls/optimizer/learning_rate.py)
<a name="1.5"></a>
#### 1.5数据读取模块(DataLoader)
#### 1.5数据读取模块(DataLoader)
<a name="1.5.1"></a>
##### 1.5.1 dataset
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | 读取数据的类的名字 | ImageNetDataset | VeriWild等其他读取数据类的名字 |
| name | 读取数据的类的名字 | ImageNetDataset | VeriWild 等其他读取数据类的名字 |
| image_root | 数据集存放的路径 | ./dataset/ILSVRC2012/ | str |
| cls_label_path | 数据集标签list | ./dataset/ILSVRC2012/train_list.txt | str |
| cls_label_path | 数据集标签 list | ./dataset/ILSVRC2012/train_list.txt | str |
| transform_ops | 单张图片的数据预处理 | —— | —— |
| batch_transform_ops | batch图片的数据预处理 | —— | —— |
| batch_transform_ops | batch 图片的数据预处理 | —— | —— |
transform_ops中参数的意义:
transform_ops 中参数的意义:
| 功能名字 | 参数名字 | 具体含义 |
|:---:|:---:|:---:|
| DecodeImage | to_rgb | 数据转RGB |
| | channel_first | 按CHW排列的图片数据 |
| DecodeImage | to_rgb | 数据转 RGB |
| | channel_first | 按 CHW 排列的图片数据 |
| RandCropImage | size | 随机裁剪 |
| RandFlipImage | | 随机翻转 |
| NormalizeImage | scale | 归一化scale值 |
| NormalizeImage | scale | 归一化 scale 值 |
| | mean | 归一化均值 |
| | std | 归一化方差 |
| | order | 归一化顺序 |
| CropImage | size | 裁剪大小 |
| ResizeImage | resize_short | 按短边调整大小 |
batch_transform_ops中参数的含义:
batch_transform_ops 中参数的含义:
| 功能名字 | 参数名字 | 具体含义 |
|:---:|:---:|:---:|
| MixupOperator | alpha | Mixup参数值,该值越大增强越强 |
| MixupOperator | alpha | Mixup 参数值,该值越大增强越强 |
<a name="1.5.2"></a>
##### 1.5.2 sampler
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | sampler类型 | DistributedBatchSampler | DistributedRandomIdentitySampler等其他Sampler |
| name | sampler 类型 | DistributedBatchSampler | DistributedRandomIdentitySampler 等其他 Sampler |
| batch_size | 批大小 | 64 | int |
| drop_last | 是否丢掉最后不够batch-size的数据 | False | bool |
| shuffle | 数据是否做shuffle | True | bool |
| drop_last | 是否丢掉最后不够 batch-size 的数据 | False | bool |
| shuffle | 数据是否做 shuffle | True | bool |
<a name="1.5.3"></a>
##### 1.5.3 loader
......@@ -157,7 +158,7 @@ batch_transform_ops中参数的含义:
| use_shared_memory | 是否使用共享内存 | True | bool |
<a name="1.6"></a>
#### 1.6 评估指标(Metric)
#### 1.6 评估指标(Metric)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
......@@ -168,18 +169,18 @@ batch_transform_ops中参数的含义:
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| infer_imgs | 被infer的图像的地址 | docs/images/whl/demo.jpg | str |
| infer_imgs | 被 infer 的图像的地址 | docs/images/whl/demo.jpg | str |
| batch_size | 批大小 | 10 | int |
| PostProcess.name | 后处理名字 | Topk | str |
| PostProcess.topk | topk的值 | 5 | int |
| PostProcess.class_id_map_file | class id和名字的映射文件 | ppcls/utils/imagenet1k_label_list.txt | str |
| PostProcess.topk | topk 的值 | 5 | int |
| PostProcess.class_id_map_file | class id 和名字的映射文件 | ppcls/utils/imagenet1k_label_list.txt | str |
**注**:Infer模块的`transforms`的解释参考数据读取模块中的dataset中`transform_ops`的解释。
**注**:Infer 模块的 `transforms` 的解释参考数据读取模块中的 dataset 中 `transform_ops` 的解释。
<a name="2"></a>
### 2.蒸馏模型
**注**:此处以`MobileNetV3_large_x1_0``ImageNet-1k`上蒸馏`MobileNetV3_small_x1_0`的训练配置为例,详解各个参数的意义。[配置路径](../../../ppcls/configs/ImageNet/Distillation/mv3_large_x1_0_distill_mv3_small_x1_0.yaml)。这里只介绍与分类模型有区别的参数。
**注**:此处以 `MobileNetV3_large_x1_0``ImageNet-1k` 上蒸馏 `MobileNetV3_small_x1_0` 的训练配置为例,详解各个参数的意义。[配置路径](../../../ppcls/configs/ImageNet/Distillation/mv3_large_x1_0_distill_mv3_small_x1_0.yaml)。这里只介绍与分类模型有区别的参数。
<a name="2.1"></a>
#### 2.1 结构(Arch)
......@@ -190,48 +191,49 @@ batch_transform_ops中参数的含义:
| class_num | 分类数 | 1000 | int |
| freeze_params_list | 冻结参数列表 | [True, False] | list |
| models | 模型列表 | [Teacher, Student] | list |
| Teacher.name | 教师模型的名字 | MobileNetV3_large_x1_0 | PaddleClas中的模型 |
| Teacher.name | 教师模型的名字 | MobileNetV3_large_x1_0 | PaddleClas 中的模型 |
| Teacher.pretrained | 教师模型预训练权重 | True | 布尔值或者预训练权重路径 |
| Teacher.use_ssld | 教师模型预训练权重是否是ssld权重 | True | 布尔值 |
| infer_model_name | 被infer模型的类型 | Student | Teacher |
| Teacher.use_ssld | 教师模型预训练权重是否是 ssld 权重 | True | 布尔值 |
| infer_model_name | 被 infer 模型的类型 | Student | Teacher |
**注**
1.list在yaml中体现如下:
1.list 在 yaml 中体现如下:
```
freeze_params_list:
- True
- False
```
2.Student的参数情况类似,不再赘述。
2.Student 的参数情况类似,不再赘述。
<a name="2.2"></a>
#### 2.2 损失函数(Loss)
#### 2.2 损失函数(Loss)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| DistillationCELoss | 蒸馏的交叉熵损失函数 | —— | —— |
| DistillationCELoss.weight | Loss权重 | 1.0 | float |
| DistillationCELoss.weight | Loss 权重 | 1.0 | float |
| DistillationCELoss.model_name_pairs | ["Student", "Teacher"] | —— | —— |
| DistillationGTCELoss.weight | 蒸馏的模型与真实Label的交叉熵损失函数 | —— | —— |
| DistillationGTCELos.weight | Loss权重 | 1.0 | float |
| DistillationCELoss.model_names | 与真实label作交叉熵的模型名字 | ["Student"] | —— |
| DistillationGTCELoss.weight | 蒸馏的模型与真实 Label 的交叉熵损失函数 | —— | —— |
| DistillationGTCELos.weight | Loss 权重 | 1.0 | float |
| DistillationCELoss.model_names | 与真实 label 作交叉熵的模型名字 | ["Student"] | —— |
<a name="2.3"></a>
#### 2.3 评估指标(Metric)
#### 2.3 评估指标(Metric)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| DistillationTopkAcc | DistillationTopkAcc | 包含model_key和topk两个参数 | —— |
| DistillationTopkAcc | DistillationTopkAcc | 包含 model_key 和 topk 两个参数 | —— |
| DistillationTopkAcc.model_key | 被评估的模型 | "Student" | "Teacher" |
| DistillationTopkAcc.topk | Topk的值 | [1, 5] | list, int |
| DistillationTopkAcc.topk | Topk 的值 | [1, 5] | list, int |
**注**`DistillationTopkAcc`与普通`TopkAcc`含义相同,只是只用在蒸馏任务中。
**注**`DistillationTopkAcc` 与普通 `TopkAcc` 含义相同,只是只用在蒸馏任务中。
<a name="3"></a>
### 3. 识别模型
**注**:此处以`ResNet50``LogoDet-3k`上的训练配置为例,详解各个参数的意义。[配置路径](../../../ppcls/configs/Logo/ResNet50_ReID.yaml)。这里只介绍与分类模型有区别的参数。
**注**:此处以 `ResNet50``LogoDet-3k` 上的训练配置为例,详解各个参数的意义。[配置路径](../../../ppcls/configs/Logo/ResNet50_ReID.yaml)。这里只介绍与分类模型有区别的参数。
<a name="3.1"></a>
#### 3.1 结构(Arch)
......@@ -239,30 +241,30 @@ batch_transform_ops中参数的含义:
| 参数名字 | 具体含义 | 默认值 | 可选值 |
| :---------------: | :-----------------------: | :--------: | :----------------------------------------------------------: |
| name | 模型结构 | "RecModel" | ["RecModel"] |
| infer_output_key | inference时的输出值 | “feature” | ["feature", "logits"] |
| infer_add_softmax | infercne是否添加softmax | False | [True, False] |
| Backbone.name | Backbone的名字 | ResNet50_last_stage_stride1 | PaddleClas提供的其他backbone |
| Backbone.pretrained | Backbone预训练模型 | True | 布尔值或者预训练模型路径 |
| BackboneStopLayer.name | Backbone中的输出层名字 | True | Backbone中的特征输出层的`full_name` |
| Neck.name | 网络Neck部分名字 | VehicleNeck | 需传入字典结构,Neck网络层的具体输入参数 |
| Neck.in_channels | 输入Neck部分的维度大小 | 2048 | 与BackboneStopLayer.name层的大小相同 |
| Neck.out_channels | 输出Neck部分的维度大小,即特征维度大小 | 512 | int |
| Head.name | 网络Head部分名字 | CircleMargin | Arcmargin等 |
| Head.embedding_size | 特征维度大小 | 512 | 与Neck.out_channels保持一致 |
| infer_output_key | inference 时的输出值 | “feature” | ["feature", "logits"] |
| infer_add_softmax | infercne 是否添加 softmax | False | [True, False] |
| Backbone.name | Backbone 的名字 | ResNet50_last_stage_stride1 | PaddleClas 提供的其他 backbone |
| Backbone.pretrained | Backbone 预训练模型 | True | 布尔值或者预训练模型路径 |
| BackboneStopLayer.name | Backbone 中的输出层名字 | True | Backbone中的特征输出层的 `full_name` |
| Neck.name | 网络 Neck 部分名字 | VehicleNeck | 需传入字典结构,Neck 网络层的具体输入参数 |
| Neck.in_channels | 输入 Neck 部分的维度大小 | 2048 | 与BackboneStopLayer.name层的大小相同 |
| Neck.out_channels | 输出 Neck 部分的维度大小,即特征维度大小 | 512 | int |
| Head.name | 网络 Head 部分名字 | CircleMargin | Arcmargin 等 |
| Head.embedding_size | 特征维度大小 | 512 | 与 Neck.out_channels 保持一致 |
| Head.class_num | 类别数 | 3000 | int |
| Head.margin | CircleMargin中的margin值 | 0.35 | float |
| Head.scale | CircleMargin中的scale值 | 64 | int |
| Head.margin | CircleMargin 中的 margin 值 | 0.35 | float |
| Head.scale | CircleMargin 中的 scale 值 | 64 | int |
**注**
1.PaddleClas中,`Neck`部分是Backbone与embedding层的连接部分,`Head`部分是embedding层与分类层的连接部分。
1. PaddleClas 中,`Neck` 部分是 Backbone 与 embedding 层的连接部分,`Head` 部分是 embedding 层与分类层的连接部分。
2.`BackboneStopLayer.name`的获取方式可以通过将模型可视化后获取,可视化方式可以参考[Netron](https://github.com/lutzroeder/netron)或者[visualdl](https://github.com/PaddlePaddle/VisualDL)
2.`BackboneStopLayer.name` 的获取方式可以通过将模型可视化后获取,可视化方式可以参考 [Netron](https://github.com/lutzroeder/netron) 或者 [visualdl](https://github.com/PaddlePaddle/VisualDL)
3.调用`tools/export_model.py`会将模型的权重转为inference model,其中`infer_add_softmax`参数会控制是否在其后增加`Softmax`激活函数,代码中默认为`True`(分类任务中最后的输出层会接`Softmax`激活函数),识别任务中特征层无须接激活函数,此处要设置为`False`
3.调用 `tools/export_model.py` 会将模型的权重转为 inference model,其中 `infer_add_softmax` 参数会控制是否在其后增加 `Softmax` 激活函数,代码中默认为 `True`(分类任务中最后的输出层会接`Softmax`激活函数),识别任务中特征层无须接激活函数,此处要设置为 `False`
<a name="3.2"></a>
#### 3.2 评估指标(Metric)
#### 3.2 评估指标(Metric)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
......
# 图像识别
---
PaddleClas中,图像识别,是指给定一张查询图像,系统能够识别该查询图像类别。广义上,图像分类也是图像识别的一种。但是与普通图像识别不同的是,图像分类只能判别出模型已经学习的类别,如果需要添加新的类别,分类模型只能重新训练。PaddleClas中的图像识别,**对于陌生类别,只需要更新相应的检索库**,就能够正确的识别出查询图像的类别,而无需重新训练模型,这大大增加了识别系统的可用性,同时降低了更新模型的需求,方便用户部署应用。
PaddleClas 中,图像识别,是指给定一张查询图像,系统能够识别该查询图像类别。广义上,图像分类也是图像识别的一种。但是与普通图像识别不同的是,图像分类只能判别出模型已经学习的类别,如果需要添加新的类别,分类模型只能重新训练。PaddleClas 中的图像识别,**对于陌生类别,只需要更新相应的检索库**,就能够正确的识别出查询图像的类别,而无需重新训练模型,这大大增加了识别系统的可用性,同时降低了更新模型的需求,方便用户部署应用。
对于一张待查询图片,PaddleClas中的图像识别流程主要分为三部分:
对于一张待查询图片,PaddleClas 中的图像识别流程主要分为三部分:
1. 主体检测:对于给定一个查询图像,主体检测器首先检测出图像的物体,从而去掉无用背景信息,提高识别精度。
2. 特征提取:对主体检测的各个候选区域,通过特征模型,进行特征提取
......@@ -19,47 +19,47 @@
## 目录
- [主体检测](#主体检测)
- [特征模型训练](#特征模型训练)
- [2.1. 特征模型数据准备与处理](#特征模型数据准备与处理)
- [2. 特征模型基于单卡GPU上的训练与评估](#特征模型基于单卡GPU上的训练与评估)
- [2.1 特征模型训练](#特征模型训练)
- [2.2 特征模型恢复训练](#特征模型恢复训练)
- [2.3 特征模型评估](#特征模型评估)
- [3. 特征模型导出inference模型](#特征模型导出inference模型)
- [特征检索](#特征检索)
- [基础知识](#基础知识)
- [1. 主体检测](#1)
- [2. 特征模型训练](#2)
- [2.1. 特征模型数据准备与处理](#2.1)
- [2. 2特征模型基于单卡 GPU 上的训练与评估](#2.2)
- [2.2.1 特征模型训练](#2.2.2)
- [2.2.2 特征模型恢复训练](#2.2.2)
- [2.2.3 特征模型评估](#2.2.3)
- [2.3 特征模型导出 inference 模型](#2.3)
- [3. 特征检索](#3)
- [4. 基础知识](#4)
<a name="主体检测"></a>
<a name="1"></a>
## 一、主体检测
## 1. 主体检测
主体检测训练过程基于 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/develop) ,唯一的区别在于,主体检测任务中,所有的检测框均属于前景,在这里需要将标注文件中,检测框的 `category_id` 修改为1,同时将整个标注文件中的 `categories` 映射表修改为下面的格式,即整个类别映射表中只包含`前景`类别。
主体检测训练过程基于 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/develop),唯一的区别在于,主体检测任务中,所有的检测框均属于前景,在这里需要将标注文件中,检测框的 `category_id` 修改为 1,同时将整个标注文件中的 `categories` 映射表修改为下面的格式,即整个类别映射表中只包含 `前景` 类别。
```json
[{u'id': 1, u'name': u'foreground', u'supercategory': u'foreground'}]
```
关于主体检测训练方法可以参考: [PaddleDetection训练教程](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/docs/tutorials/GETTING_STARTED_cn.md#4-%E8%AE%AD%E7%BB%83)
关于主体检测训练方法可以参考: [PaddleDetection 训练教程](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/docs/tutorials/GETTING_STARTED_cn.md#4-%E8%AE%AD%E7%BB%83)
更多关于 PaddleClas 中提供的主体检测的模型介绍与下载请参考:[主体检测教程](../image_recognition_pipeline/mainbody_detection.md)
<a name="特征模型训练"></a>
<a name="2"></a>
## 二、特征模型训练
## 2. 特征模型训练
<a name="特征模型数据准备与处理"></a>
<a name="2.1"></a>
### 2.1 特征模型数据的准备与处理
* 进入PaddleClas目录。
* 进入 `PaddleClas` 目录。
```bash
## linux or mac, $path_to_PaddleClas表示PaddleClas的根目录,用户需要根据自己的真实目录修改
cd $path_to_PaddleClas
```
* 进入`dataset`目录,为了快速体验PaddleClas图像检索模块,此处使用的数据集为[CUB_200_2011](http://vision.ucsd.edu/sites/default/files/WelinderEtal10_CUB-200.pdf),其是一个包含200类鸟的细粒度鸟类数据集。首先,下载CUB_200_2011数据集,下载方式请参考[官网](http://www.vision.caltech.edu/visipedia/CUB-200-2011.html)
* 进入 `dataset` 目录,为了快速体验PaddleClas图像检索模块,此处使用的数据集为 [CUB_200_2011](http://vision.ucsd.edu/sites/default/files/WelinderEtal10_CUB-200.pdf),其是一个包含200类鸟的细粒度鸟类数据集。首先,下载 CUB_200_2011 数据集,下载方式请参考[官网](http://www.vision.caltech.edu/visipedia/CUB-200-2011.html)
```shell
# linux or mac
......@@ -75,7 +75,7 @@ tar -xzvf CUB_200_2011.tgz
cd CUB_200_2011
```
该数据集在用作图像检索任务时,通常将前100类当做训练集,后100类当做测试集,所以此处需要将下载的数据集做一些后处理,来更好的适应PaddleClas的图像检索训练。
该数据集在用作图像检索任务时,通常将前 100 类当做训练集,后 100 类当做测试集,所以此处需要将下载的数据集做一些后处理,来更好的适应 PaddleClas 的图像检索训练。
```shell
#新建train和test目录
......@@ -90,9 +90,9 @@ tree -r -i -f train | grep jpg | awk -F "/" '{print $0" "int($2) " "NR}' > train
tree -r -i -f test | grep jpg | awk -F "/" '{print $0" "int($2) " "NR}' > test_list.txt
```
至此,现在已经得到`CUB_200_2011`的训练集(`train`目录)、测试集(`test`目录)、`train_list.txt``test_list.txt`
至此,现在已经得到 `CUB_200_2011` 的训练集(`train` 目录)、测试集(`test` 目录)、`train_list.txt``test_list.txt`
数据处理完毕后,`CUB_200_2011`中的`train`目录下应有如下结构:
数据处理完毕后,`CUB_200_2011` 中的 `train` 目录下应有如下结构:
```
├── 1
......@@ -105,7 +105,7 @@ tree -r -i -f test | grep jpg | awk -F "/" '{print $0" "int($2) " "NR}' > test_l
...
```
`train_list.txt`应为:
`train_list.txt` 应为:
```
train/99/Ovenbird_0137_92639.jpg 99 1
......@@ -115,32 +115,32 @@ train/99/Ovenbird_0131_92559.jpg 99 4
train/99/Ovenbird_0130_92452.jpg 99 5
...
```
其中,分隔符为空格" ", 三列数据的含义分别是训练数据的路径、训练数据的label信息、训练数据的unique id。
其中,分隔符为空格" ", 三列数据的含义分别是训练数据的路径、训练数据的 label 信息、训练数据的 unique id。
测试集格式与训练集格式相同。
**注意**
*gallery dataset和query dataset相同时,为了去掉检索得到的第一个数据(检索图片本身无须评估),每个数据需要对应一个unique id,用于后续评测mAP、recall@1等指标。关于gallery dataset与query dataset的解析请参考[图像检索数据集介绍](#图像检索数据集介绍), 关于mAP、recall@1等评测指标请参考[图像检索评价指标](#图像检索评价指标)
* gallery dataset 和 query dataset 相同时,为了去掉检索得到的第一个数据(检索图片本身无须评估),每个数据需要对应一个 unique id,用于后续评测 mAP、recall@1 等指标。关于 gallery dataset 与 query dataset 的解析请参考[图像检索数据集介绍](#图像检索数据集介绍), 关于 mAP、recall@1 等评测指标请参考[图像检索评价指标](#图像检索评价指标)
返回`PaddleClas`根目录
返回 `PaddleClas` 根目录
```shell
# linux or mac
cd ../../
```
<a name="特征模型基于单卡GPU上的训练与评估"></a>
<a name="2.2"></a>
### 2.2 特征模型GPU上的训练与评估
### 2.2 特征模型 GPU 上的训练与评估
在基于单卡GPU上训练与评估,推荐使用`tools/train.py``tools/eval.py`脚本。
在基于单卡 GPU 上训练与评估,推荐使用 `tools/train.py``tools/eval.py` 脚本。
<a name="特征模型训练"></a>
<a name="2.2.1"></a>
#### 2.2.1 特征模型训练
准备好配置文件之后,可以使用下面的方式启动图像检索任务的训练。PaddleClas训练图像检索任务的方法是度量学习,关于度量学习的解析请参考[度量学习](#度量学习)
准备好配置文件之后,可以使用下面的方式启动图像检索任务的训练。PaddleClas 训练图像检索任务的方法是度量学习,关于度量学习的解析请参考[度量学习](#度量学习)
```shell
# 单卡GPU
......@@ -156,7 +156,7 @@ python3 -m paddle.distributed.launch tools/train.py \
-o Global.device=gpu
```
其中,`-c`用于指定配置文件的路径,`-o`用于指定需要修改或者添加的参数,其中`-o Arch.Backbone.pretrained=True`表示Backbone部分使用预训练模型,此外,`Arch.Backbone.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。`-o Global.device=gpu`表示使用GPU进行训练。如果希望使用CPU进行训练,则需要将`Global.device`设置为`cpu`
其中,`-c` 用于指定配置文件的路径,`-o` 用于指定需要修改或者添加的参数,其中 `-o Arch.Backbone.pretrained=True` 表示 Backbone 部分使用预训练模型,此外,`Arch.Backbone.pretrained` 也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。`-o Global.device=gpu` 表示使用 GPU 进行训练。如果希望使用 CPU 进行训练,则需要将 `Global.device` 设置为 `cpu`
更详细的训练配置,也可以直接修改模型对应的配置文件。具体配置参数参考[配置文档](config_description.md)
......@@ -169,9 +169,9 @@ python3 -m paddle.distributed.launch tools/train.py \
[Eval][Epoch 1][Avg]recall1: 0.46962, recall5: 0.75608, mAP: 0.21238
...
```
此处配置文件的Backbone是MobileNetV1,如果想使用其他Backbone,可以重写参数`Arch.Backbone.name`,比如命令中增加`-o Arch.Backbone.name={其他Backbone}`。此外,由于不同模型`Neck`部分的输入维度不同,更换Backbone后可能需要改写此处的输入大小,改写方式类似替换Backbone的名字。
此处配置文件的 Backbone 是 MobileNetV1,如果想使用其他 Backbone,可以重写参数 `Arch.Backbone.name`,比如命令中增加 `-o Arch.Backbone.name={其他Backbone}`。此外,由于不同模型`Neck`部分的输入维度不同,更换 Backbone 后可能需要改写此处的输入大小,改写方式类似替换 Backbone 的名字。
在训练Loss部分,此处使用了[CELoss](../../../ppcls/loss/celoss.py)[TripletLossV2](../../../ppcls/loss/triplet.py),配置文件如下:
在训练 Loss 部分,此处使用了 [CELoss](../../../ppcls/loss/celoss.py)[TripletLossV2](../../../ppcls/loss/triplet.py),配置文件如下:
```
Loss:
......@@ -183,9 +183,9 @@ Loss:
margin: 0.5
```
最终的总Loss是所有Loss的加权和,其中weight定义了特定Loss在最终总Loss的权重。如果想替换其他Loss,也可以在配置文件中更改Loss字段,目前支持的Loss请参考[Loss](../../../ppcls/loss)
最终的总 Loss 是所有 Loss 的加权和,其中 weight 定义了特定 Loss 在最终总 Loss 的权重。如果想替换其他 Loss,也可以在配置文件中更改 Loss 字段,目前支持的 Loss 请参考 [Loss](../../../ppcls/loss)
<a name="特征模型恢复训练"></a>
<a name="2.2.2"></a>
#### 2.2.2 特征模型恢复训练
......@@ -205,11 +205,11 @@ python3 -m paddle.distributed.launch tools/train.py \
-o Global.device=gpu
```
其中配置文件不需要做任何修改,只需要在继续训练时设置`Global.checkpoints`参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。
其中配置文件不需要做任何修改,只需要在继续训练时设置 `Global.checkpoints` 参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。
**注意**
* `-o Global.checkpoints`参数无需包含断点权重文件的后缀名,上述训练命令会在训练过程中生成如下所示的断点权重文件,若想从断点`5`继续训练,则`Global.checkpoints`参数只需设置为`"./output/RecModel/epoch_5"`,PaddleClas会自动补充后缀名。
* `-o Global.checkpoints` 参数无需包含断点权重文件的后缀名,上述训练命令会在训练过程中生成如下所示的断点权重文件,若想从断点 `5` 继续训练,则 `Global.checkpoints` 参数只需设置为 `"./output/RecModel/epoch_5"` ,PaddleClas 会自动补充后缀名。
```shell
output/
......@@ -225,7 +225,7 @@ python3 -m paddle.distributed.launch tools/train.py \
.
```
<a name="特征模型评估"></a>
<a name="2.2.3"></a>
#### 2.2.3 特征模型评估
......@@ -243,24 +243,24 @@ python3 -m paddle.distributed.launch tools/eval.py \
-o Global.pretrained_model=./output/RecModel/best_model
```
上述命令将使用`./configs/quick_start/MobileNetV1_retrieval.yaml`作为配置文件,对上述训练得到的模型`./output/RecModel/best_model`进行评估。你也可以通过更改配置文件中的参数来设置评估,也可以通过`-o`参数更新配置,如上所示。
上述命令将使用 `./configs/quick_start/MobileNetV1_retrieval.yaml` 作为配置文件,对上述训练得到的模型 `./output/RecModel/best_model` 进行评估。你也可以通过更改配置文件中的参数来设置评估,也可以通过 `-o` 参数更新配置,如上所示。
可配置的部分评估参数说明如下:
* `Arch.name`:模型名称
* `Global.pretrained_model`:待评估的模型的预训练模型文件路径,不同于`Global.Backbone.pretrained`,此处的预训练模型是整个模型的权重,而`Global.Backbone.pretrained`只是Backbone部分的权重。当需要做模型评估时,需要加载整个模型的权重。
* `Metric.Eval`:待评估的指标,默认评估recall@1、recall@5、mAP。当你不准备评测某一项指标时,可以将对应的试标从配置文件中删除;当你想增加某一项评测指标时,也可以参考[Metric](../../../ppcls/metric/metrics.py)部分在配置文件`Metric.Eval`中添加相关的指标。
* `Global.pretrained_model`:待评估的模型的预训练模型文件路径,不同于 `Global.Backbone.pretrained`,此处的预训练模型是整个模型的权重,而 `Global.Backbone.pretrained` 只是 Backbone 部分的权重。当需要做模型评估时,需要加载整个模型的权重。
* `Metric.Eval`:待评估的指标,默认评估 recall@1、recall@5、mAP。当你不准备评测某一项指标时,可以将对应的试标从配置文件中删除;当你想增加某一项评测指标时,也可以参考 [Metric](../../../ppcls/metric/metrics.py) 部分在配置文件 `Metric.Eval` 中添加相关的指标。
**注意:**
* 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[2.2.2 特征模型恢复训练](#特征模型恢复训练)
* 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐 `.pdparams` 的后缀,如 [2.2.2 特征模型恢复训练](#2.2.2)
* Metric learning任务一般不评测TopkAcc。
* Metric learning 任务一般不评测 TopkAcc。
<a name="特征模型导出inference模型"></a>
<a name="2.3"></a>
### 2.3 特征模型导出inference模型
### 2.3 特征模型导出 inference 模型
通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。对训练好的模型进行转换:
通过导出 inference 模型,PaddlePaddle 支持使用预测引擎进行预测推理。对训练好的模型进行转换:
```bash
python3 tools/export_model.py \
......@@ -269,15 +269,15 @@ python3 tools/export_model.py \
-o Global.save_inference_dir=./inference
```
其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[2.2.2 特征模型恢复训练](#特征模型恢复训练))。当执行后,会在当前目录下生成`./inference`目录,目录下包含`inference.pdiparams``inference.pdiparams.info``inference.pdmodel`文件。`Global.save_inference_dir`可以指定导出inference模型的路径。此处保存的inference模型在embedding特征层做了截断,即模型最终的输出为n维embedding特征。
其中,`Global.pretrained_model` 用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[2.2.2 特征模型恢复训练](#2.2.2))。当执行后,会在当前目录下生成 `./inference` 目录,目录下包含 `inference.pdiparams``inference.pdiparams.info``inference.pdmodel` 文件。`Global.save_inference_dir` 可以指定导出 inference 模型的路径。此处保存的 inference 模型在 embedding 特征层做了截断,即模型最终的输出为 n 维 embedding 特征。
上述命令将生成模型结构文件`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理。使用inference模型推理的流程可以参考[基于Python预测引擎预测推理](../inference_deployment/python_deploy.md)
上述命令将生成模型结构文件(`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理。使用 inference 模型推理的流程可以参考[基于Python预测引擎预测推理](../inference_deployment/python_deploy.md)
<a name="特征检索"></a>
<a name="3"></a>
## 三、特征检索
## 3. 特征检索
PaddleClas图像检索部分目前支持的环境如下:
PaddleClas 图像检索部分目前支持的环境如下:
```shell
└── CPU/单卡GPU
......@@ -286,13 +286,13 @@ PaddleClas图像检索部分目前支持的环境如下:
└── Windows
```
此部分使用了[Faiss](https://github.com/facebookresearch/faiss)作为检索库,其是一个高效的特征检索及聚类的库。此库中集成了多种相似度检索算法,以满足不同的检索场景。在PaddleClas中,支持三种检索算法:
此部分使用了 [Faiss](https://github.com/facebookresearch/faiss) 作为检索库,其是一个高效的特征检索及聚类的库。此库中集成了多种相似度检索算法,以满足不同的检索场景。在 PaddleClas 中,支持三种检索算法:
- **HNSW32**: 一种图索引方法。检索精度较高,速度较快。但是特征库只支持添加图像功能,不支持删除图像特征功能。(默认方法)
- **IVF**:倒排索引检索方法。速度较快,但是精度略低。特征库支持增加、删除图像特功能。
- **FLAT**: 暴力检索算法。精度最高,但是数据量大时,检索速度较慢。特征库支持增加、删除图像特征功能。
详细介绍请参考[Faiss](https://github.com/facebookresearch/faiss)官方文档。
详细介绍请参考 [Faiss](https://github.com/facebookresearch/faiss) 官方文档。
具体安装方法如下:
......@@ -300,38 +300,38 @@ PaddleClas图像检索部分目前支持的环境如下:
pip install faiss-cpu==1.7.1post2
```
若使用时,不能正常引用,则`uninstall` 之后,重新`install`,尤其是`windows`下。
若使用时,不能正常引用,则 `uninstall` 之后,重新 `install`,尤其是 `windows` 下。
<a name="基础知识"></a>
<a name="4"></a>
## 四、基础知识
## 4. 基础知识
图像检索指的是给定一个包含特定实例(例如特定目标、场景、物品等)的查询图像,图像检索旨在从数据库图像中找到包含相同实例的图像。不同于图像分类,图像检索解决的是一个开集问题,训练集中可能不包含被识别的图像的类别。图像检索的整体流程为:首先将图像中表示为一个合适的特征向量,其次,对这些图像的特征向量用欧式距离或余弦距离进行最近邻搜索以找到底库中相似的图像,最后,可以使用一些后处理技术对检索结果进行微调,确定被识别图像的类别等信息。所以,决定一个图像检索算法性能的关键在于图像对应的特征向量的好坏。
<a name="度量学习"></a>
- 度量学习(Metric Learning)
度量学习研究如何在一个特定的任务上学习一个距离函数,使得该距离函数能够帮助基于近邻的算法 (kNN、k-means等) 取得较好的性能。深度度量学习 (Deep Metric Learning )是度量学习的一种方法,它的目标是学习一个从原始特征到低维稠密的向量空间 (嵌入空间,embedding space) 的映射,使得同类对象在嵌入空间上使用常用的距离函数 (欧氏距离、cosine距离等) 计算的距离比较近,而不同类的对象之间的距离则比较远。深度度量学习在计算机视觉领域取得了非常多的成功的应用,比如人脸识别、商品识别、图像检索、行人重识别等。更详细的介绍请参考[此文档](../algorithm_introduction/metric_learning.md)
度量学习研究如何在一个特定的任务上学习一个距离函数,使得该距离函数能够帮助基于近邻的算法 (kNN、k-means 等) 取得较好的性能。深度度量学习(Deep Metric Learning)是度量学习的一种方法,它的目标是学习一个从原始特征到低维稠密的向量空间(嵌入空间,embedding space)的映射,使得同类对象在嵌入空间上使用常用的距离函数(欧氏距离、cosine 距离等)计算的距离比较近,而不同类的对象之间的距离则比较远。深度度量学习在计算机视觉领域取得了非常多的成功的应用,比如人脸识别、商品识别、图像检索、行人重识别等。更详细的介绍请参考[此文档](../algorithm_introduction/metric_learning.md)
<a name="图像检索数据集介绍"></a>
- 图像检索数据集介绍
- 训练集合(train dataset):用来训练模型,使模型能够学习该集合的图像特征。
- 底库数据集合(gallery dataset):用来提供图像检索任务中的底库数据,该集合可与训练集或测试集相同,也可以不同,当与训练集相同时,测试集的类别体系应与训练集的类别体系相同。
- 测试集合(query dataset):用来测试模型的好坏,通常要对测试集的每一张测试图片进行特征提取,之后和底库数据的特征进行距离匹配,得到识别结果,后根据识别结果计算整个测试集的指标。
- 训练集合(train dataset):用来训练模型,使模型能够学习该集合的图像特征。
- 底库数据集合(gallery dataset):用来提供图像检索任务中的底库数据,该集合可与训练集或测试集相同,也可以不同,当与训练集相同时,测试集的类别体系应与训练集的类别体系相同。
- 测试集合(query dataset):用来测试模型的好坏,通常要对测试集的每一张测试图片进行特征提取,之后和底库数据的特征进行距离匹配,得到识别结果,后根据识别结果计算整个测试集的指标。
<a name="图像检索评价指标"></a>
- 图像检索评价指标
<a name="召回率"></a>
- 召回率(recall):表示预测为正例且标签为正例的个数 / 标签为正例的个数
- 召回率(recall):表示预测为正例且标签为正例的个数 / 标签为正例的个数
- recall@1:检索的top-1中预测正例且标签为正例的个数 / 标签为正例的个数
- recall@5:检索的top-5中所有预测正例且标签为正例的个数 / 标签为正例的个数
- recall@1:检索的 top-1 中预测正例且标签为正例的个数 / 标签为正例的个数
- recall@5:检索的 top-5 中所有预测正例且标签为正例的个数 / 标签为正例的个数
<a name="平均检索精度"></a>
- 平均检索精度(mAP)
- AP: AP指的是不同召回率上的正确率的平均值
- mAP: 测试集中所有图片对应的AP的的平均值
- AP: AP 指的是不同召回率上的正确率的平均值
- mAP: 测试集中所有图片对应的 AP 的平均值
# 训练技巧
## 目录
- [1. 优化器的选择](#1)
- [2. 学习率以及学习率下降策略的选择](#2)
- [2.1 学习率的概念](#2.1)
- [2. 2 学习率下降策略](#2.2)
- [2.3 warmup 策略](#2.3)
- [3. batch_size 的选择](#3)
- [4. weight_decay 的选择](#4)
- [5. label_smoothing 的选择](#5)
- [6.针对小模型更改图片的 crop 面积与拉伸变换程度](#6)
- [7.使用数据增广方式提升精度](#7)
- [8. 通过 train_acc 和 test_acc 确定调优策略](#8)
- [9.通过已有的预训练模型提升自己的数据集的精度](#9)
<a name="1"></a>
## 1.优化器的选择
自深度学习发展以来,就有很多关于优化器的研究者工作,优化器的目的是为了让损失函数尽可能的小,从而找到合适的参数来完成某项任务。目前业界主要用到的优化器有SGD、RMSProp、Adam、AdaDelt等,其中由于带momentum的SGD优化器广泛应用于学术界和工业界,所以我们发布的模型也大都使用该优化器来实现损失函数的梯度下降。带momentum的SGD优化器有两个劣势,其一是收敛速度慢,其二是初始学习率的设置需要依靠大量的经验,然而如果初始学习率设置得当并且迭代轮数充足,该优化器也会在众多的优化器中脱颖而出,使得其在验证集上获得更高的准确率。一些自适应学习率的优化器如Adam、RMSProp等,收敛速度往往比较快,但是最终的收敛精度会稍差一些。如果追求更快的收敛速度,我们推荐使用这些自适应学习率的优化器,如果追求更高的收敛精度,我们推荐使用带momentum的SGD优化器。
自深度学习发展以来,就有很多关于优化器的研究者工作,优化器的目的是为了让损失函数尽可能的小,从而找到合适的参数来完成某项任务。目前业界主要用到的优化器有 SGD、RMSProp、Adam、AdaDelt 等,其中由于带 momentum 的 SGD 优化器广泛应用于学术界和工业界,所以我们发布的模型也大都使用该优化器来实现损失函数的梯度下降。带 momentum 的 SGD 优化器有两个劣势,其一是收敛速度慢,其二是初始学习率的设置需要依靠大量的经验,然而如果初始学习率设置得当并且迭代轮数充足,该优化器也会在众多的优化器中脱颖而出,使得其在验证集上获得更高的准确率。一些自适应学习率的优化器如 Adam、RMSProp 等,收敛速度往往比较快,但是最终的收敛精度会稍差一些。如果追求更快的收敛速度,我们推荐使用这些自适应学习率的优化器,如果追求更高的收敛精度,我们推荐使用带 momentum 的 SGD 优化器。
<a name="2"></a>
## 2.学习率以及学习率下降策略的选择
学习率的选择往往和优化器以及数据和任务有关系。这里主要介绍以momentum+SGD作为优化器训练ImageNet-1k的学习率以及学习率下降的选择。
学习率的选择往往和优化器以及数据和任务有关系。这里主要介绍以 momentum+SGD 作为优化器训练 ImageNet-1k 的学习率以及学习率下降的选择。
### 学习率的概念:
<a name="2.1"></a>
### 2.1 学习率的概念:
学习率是通过损失函数的梯度调整网络权重的超参数的速度。学习率越低,损失函数的变化速度就越慢。虽然使用低学习率可以确保不会错过任何局部极小值,但也意味着将花费更长的时间来进行收敛,特别是在被困在高原区域的情况下。
### 学习率下降策略:
在整个训练过程中,我们不能使用同样的学习率来更新权重,否则无法到达最优点,所以需要在训练过程中调整学习率的大小。在训练初始阶段,由于权重处于随机初始化的状态,损失函数相对容易进行梯度下降,所以可以设置一个较大的学习率。在训练后期,由于权重参数已经接近最优值,较大的学习率无法进一步寻找最优值,所以需要设置一个较小的学习率。在训练整个过程中,很多研究者使用的学习率下降方式是piecewise_decay,即阶梯式下降学习率,如在ResNet50标准的训练中,我们设置的初始学习率是0.1,每30epoch学习率下降到原来的1/10,一共迭代120epoch。除了piecewise_decay,很多研究者也提出了学习率的其他下降方式,如polynomial_decay(多项式下降)、exponential_decay(指数下降),cosine_decay(余弦下降)等,其中cosine_decay无需调整超参数,鲁棒性也比较高,所以成为现在提高模型精度首选的学习率下降方式。Cosine_decay和piecewise_decay的学习率变化曲线如下图所示,容易观察到,在整个训练过程中,cosine_decay都保持着较大的学习率,所以其收敛较为缓慢,但是最终的收敛效果较peicewise_decay更好一些。
<a name="2.2"></a>
### 2.2 学习率下降策略:
在整个训练过程中,我们不能使用同样的学习率来更新权重,否则无法到达最优点,所以需要在训练过程中调整学习率的大小。在训练初始阶段,由于权重处于随机初始化的状态,损失函数相对容易进行梯度下降,所以可以设置一个较大的学习率。在训练后期,由于权重参数已经接近最优值,较大的学习率无法进一步寻找最优值,所以需要设置一个较小的学习率。在训练整个过程中,很多研究者使用的学习率下降方式是 piecewise_decay,即阶梯式下降学习率,如在 ResNet50 标准的训练中,我们设置的初始学习率是 0.1,每 30 epoch 学习率下降到原来的 1/10,一共迭代 120 epoch。除了 piecewise_decay,很多研究者也提出了学习率的其他下降方式,如polynomial_decay(多项式下降)、exponential_decay(指数下降)、cosine_decay(余弦下降)等,其中cosine_decay 无需调整超参数,鲁棒性也比较高,所以成为现在提高模型精度首选的学习率下降方式。Cosine_decay 和 piecewise_decay 的学习率变化曲线如下图所示,容易观察到,在整个训练过程中,cosine_decay 都保持着较大的学习率,所以其收敛较为缓慢,但是最终的收敛效果较 peicewise_decay 更好一些。
![](../../images/models/lr_decay.jpeg)
另外,从图中我们也可以看到,cosine_decay里学习率小的轮数较少,这样会影响到最终的精度,所以为了使得cosine_decay发挥更好的效果,建议迭代更多的轮数,如200轮。
另外,从图中我们也可以看到,cosine_decay 里学习率小的轮数较少,这样会影响到最终的精度,所以为了使得cosine_decay 发挥更好的效果,建议迭代更多的轮数,如 200 轮。
### warmup策略
如果使用较大的batch_size训练神经网络时,我们建议您使用warmup策略。Warmup策略顾名思义就是让学习率先预热一下,在训练初期我们不直接使用最大的学习率,而是用一个逐渐增大的学习率去训练网络,当学习率增大到最高点时,再使用学习率下降策略中提到的学习率下降方式衰减学习率的值。实验表明,在batch_size较大时,warmup可以稳定提升模型的精度。在训练MobileNetV3等batch_size较大的实验中,我们默认将warmup中的epoch设置为5,即先用5epoch将学习率从0增加到最大值,再去做相应的学习率衰减。
<a name="2.3"></a>
### 2.3 warmup 策略
如果使用较大的 batch_size 训练神经网络时,我们建议您使用 warmup 策略。Warmup 策略顾名思义就是让学习率先预热一下,在训练初期我们不直接使用最大的学习率,而是用一个逐渐增大的学习率去训练网络,当学习率增大到最高点时,再使用学习率下降策略中提到的学习率下降方式衰减学习率的值。实验表明,在 batch_size 较大时,warmup 可以稳定提升模型的精度。在训练 MobileNetV3 等 batch_size 较大的实验中,我们默认将warmup 中的 epoch 设置为 5,即先用 5 epoch 将学习率从 0 增加到最大值,再去做相应的学习率衰减。
<a name="3"></a>
## 3.batch_size的选择
batch_size是训练神经网络中的一个重要的超参数,该值决定了一次将多少数据送入神经网络参与训练。在论文[1]中,作者通过实验发现,当batch_size的值与学习率的值呈线性关系时,收敛精度几乎不受影响。在训练ImageNet数据时,大部分的神经网络选择的初始学习率为0.1,batch_size是256,所以根据实际的模型大小和显存情况,可以将学习率设置为0.1\*k,batch_size设置为256\*k。
batch_size 是训练神经网络中的一个重要的超参数,该值决定了一次将多少数据送入神经网络参与训练。在论文[1]中,作者通过实验发现,当 batch_size 的值与学习率的值呈线性关系时,收敛精度几乎不受影响。在训练 ImageNet 数据时,大部分的神经网络选择的初始学习率为 0.1,batch_size 是 256,所以根据实际的模型大小和显存情况,可以将学习率设置为 0.1\*k, batch_size 设置为 256\*k。
<a name="4"></a>
## 4.weight_decay的选择
过拟合是机器学习中常见的一个名词,简单理解即为模型在训练数据上表现很好,但在测试数据上表现较差,在卷积神经网络中,同样存在过拟合的问题,为了避免过拟合,很多正则方式被提出,其中,weight_decay是其中一个广泛使用的避免过拟合的方式。Weight_decay等价于在最终的损失函数后添加L2正则化,L2正则化使得网络的权重倾向于选择更小的值,最终整个网络中的参数值更趋向于0,模型的泛化性能相应提高。在各大深度学习框架的实现中,该值表达的含义是L2正则前的系数,在paddle框架中,该值的名称是l2_decay,所以以下都称其为l2_decay。该系数越大,表示加入的正则越强,模型越趋于欠拟合状态。在训练ImageNet的任务中,大多数的网络将该参数值设置为1e-4,在一些小的网络如MobileNet系列网络中,为了避免网络欠拟合,该值设置为1e-5~4e-5之间。当然,该值的设置也和具体的数据集有关系,当任务的数据集较大时,网络本身趋向于欠拟合状态,可以将该值适当减小,当任务的数据集较小时,网络本身趋向于过拟合状态,可以将该值适当增大。下表展示了MobileNetV1_x0_25在ImageNet-1k上使用不同l2_decay的精度情况。由于MobileNetV1_x0_25是一个比较小的网络,所以l2_decay过大会使网络趋向于欠拟合状态,所以在该网络中,相对1e-4,3e-5是更好的选择。
过拟合是机器学习中常见的一个名词,简单理解即为模型在训练数据上表现很好,但在测试数据上表现较差,在卷积神经网络中,同样存在过拟合的问题,为了避免过拟合,很多正则方式被提出,其中,weight_decay 是其中一个广泛使用的避免过拟合的方式。Weight_decay 等价于在最终的损失函数后添加 L2 正则化,L2 正则化使得网络的权重倾向于选择更小的值,最终整个网络中的参数值更趋向于 0,模型的泛化性能相应提高。在各大深度学习框架的实现中,该值表达的含义是 L2 正则前的系数,在 paddle 框架中,该值的名称是 l2_decay,所以以下都称其为 l2_decay。该系数越大,表示加入的正则越强,模型越趋于欠拟合状态。在训练 ImageNet 的任务中,大多数的网络将该参数值设置为 1e-4,在一些小的网络如 MobileNet 系列网络中,为了避免网络欠拟合,该值设置为1e-5~4e-5 之间。当然,该值的设置也和具体的数据集有关系,当任务的数据集较大时,网络本身趋向于欠拟合状态,可以将该值适当减小,当任务的数据集较小时,网络本身趋向于过拟合状态,可以将该值适当增大。下表展示了 MobileNetV1_x0_25 在 ImageNet-1k 上使用不同 l2_decay 的精度情况。由于 MobileNetV1_x0_25 是一个比较小的网络,所以 l2_decay 过大会使网络趋向于欠拟合状态,所以在该网络中,相对 1e-4, 3e-5 是更好的选择。
| 模型 | L2_decay | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| MobileNetV1_x0_25 | 1e-4 | 43.79%/67.61% | 50.41%/74.70% |
| MobileNetV1_x0_25 | 3e-5 | 47.38%/70.83% | 51.45%/75.45% |
另外,该值的设置也和训练过程中是否使用其他正则化有关系。如果训练过程中的数据预处理比较复杂,相当于训练任务变的更难,可以将该值适当减小,下表展示了在ImageNet-1k上,ResNet50在使用randaugment预处理方式后使用不同l2_decay的精度。容易观察到,在任务变难后,使用更小的l2_decay有助于模型精度的提升。
另外,该值的设置也和训练过程中是否使用其他正则化有关系。如果训练过程中的数据预处理比较复杂,相当于训练任务变的更难,可以将该值适当减小,下表展示了在 ImageNet-1k上, ResNet50 在使用 randaugment 预处理方式后使用不同 l2_decay 的精度。容易观察到,在任务变难后,使用更小的 l2_decay 有助于模型精度的提升。
| 模型 | L2_decay | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| ResNet50 | 1e-4 | 75.13%/90.42% | 77.65%/93.79% |
| ResNet50 | 7e-5 | 75.56%/90.55% | 78.04%/93.74% |
综上所述,l2_decay可以根据具体的任务和模型去做相应的调整,通常简单的任务或者较大的模型,推荐使用较大的l2_decay,复杂的任务或者较小的模型,推荐使用较小的l2_decay。
综上所述,l2_decay 可以根据具体的任务和模型去做相应的调整,通常简单的任务或者较大的模型,推荐使用较大的 l2_decay,复杂的任务或者较小的模型,推荐使用较小的 l2_decay。
## 5.label_smoothing的选择
Label_smoothing是深度学习中的一种正则化方法,其全称是 Label Smoothing Regularization(LSR),即标签平滑正则化。在传统的分类任务计算损失函数时,是将真实的one hot标签与神经网络的输出做相应的交叉熵计算,而label_smoothing是将真实的one hot标签做一个标签平滑的处理,使得网络学习的标签不再是一个hard label,而是一个有概率值的soft label,其中在类别对应的位置的概率最大,其他位置概率是一个非常小的数。具体的计算方式参见论文[2]。在label_smoothing里,有一个epsilon的参数值,该值描述了将标签软化的程度,该值越大,经过label smoothing后的标签向量的标签概率值越小,标签越平滑,反之,标签越趋向于hard label,在训练ImageNet-1k的实验里通常将该值设置为0.1。
在训练ImageNet-1k的实验中,我们发现,ResNet50大小级别及其以上的模型在使用label_smooting后,精度有稳定的提升。下表展示了ResNet50_vd在使用label_smoothing前后的精度指标。
<a name="5"></a>
## 5.label_smoothing 的选择
Label_smoothing 是深度学习中的一种正则化方法,其全称是 Label Smoothing Regularization(LSR),即标签平滑正则化。在传统的分类任务计算损失函数时,是将真实的 one hot 标签与神经网络的输出做相应的交叉熵计算,而 label_smoothing 是将真实的 one hot 标签做一个标签平滑的处理,使得网络学习的标签不再是一个 hard label,而是一个有概率值的 soft label,其中在类别对应的位置的概率最大,其他位置概率是一个非常小的数。具体的计算方式参见论文[2]。在 label_smoothing 里,有一个 epsilon 的参数值,该值描述了将标签软化的程度,该值越大,经过 label smoothing 后的标签向量的标签概率值越小,标签越平滑,反之,标签越趋向于 hard label,在训练 ImageNet-1k 的实验里通常将该值设置为 0.1。
在训练 ImageNet-1k 的实验中,我们发现,ResNet50 大小级别及其以上的模型在使用 label_smooting 后,精度有稳定的提升。下表展示了 ResNet50_vd 在使用 label_smoothing 前后的精度指标。
| 模型 | Use_label_smoothing | Test acc1 |
|:--:|:--:|:--:|
| ResNet50_vd | 0 | 77.9% |
| ResNet50_vd | 1 | 78.4% |
同时,由于label_smoohing相当于一种正则方式,在相对较小的模型上,精度提升不明显甚至会有所下降,下表展示了ResNet18在ImageNet-1k上使用label_smoothing前后的精度指标。可以明显看到,在使用label_smoothing后,精度有所下降。
同时,由于 label_smoohing 相当于一种正则方式,在相对较小的模型上,精度提升不明显甚至会有所下降,下表展示了 ResNet18 在 ImageNet-1k 上使用 label_smoothing 前后的精度指标。可以明显看到,在使用label_smoothing 后,精度有所下降。
| 模型 | Use_label_smoohing | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| ResNet18 | 0 | 69.81%/87.70% | 70.98%/89.92% |
| ResNet18 | 1 | 68.00%/86.56% | 70.81%/89.89% |
综上所述,较大的模型使用 label_smoohing 可以有效提升模型的精度,较小的模型使用 label_smoohing 可能会降低模型的精度,所以在决定是否使用 label_smoohing 前,需要评估模型的大小和任务的难易程度。
综上所述,较大的模型使用label_smoohing可以有效提升模型的精度,较小的模型使用label_smoohing可能会降低模型的精度,所以在决定是否使用label_smoohing前,需要评估模型的大小和任务的难易程度。
<a name="6"></a>
## 6.针对小模型更改图片的crop面积与拉伸变换程度
ImageNet-1k数据的标准预处理中,random_crop函数中定义了scale和ratio两个值,两个值分别确定了图片crop的大小和图片的拉伸程度,其中scale的默认取值范围是0.08-1(lower_scale-upper_scale),ratio的默认取值范围是3/4-4/3(lower_ratio-upper_ratio)。在非常小的网络训练中,此类数据增强会使得网络欠拟合,导致精度有所下降。为了提升网络的精度,可以使其数据增强变的更弱,即增大图片的crop区域或者减弱图片的拉伸变换程度。我们可以分别通过增大lower_scale的值或缩小lower_ratio与upper_scale的差距来实现更弱的图片变换。下表列出了使用不同lower_scale训练MobileNetV2_x0_25的精度,可以看到,增大图片的crop区域面积后训练精度和验证精度均有提升。
## 6.针对小模型更改图片的 crop 面积与拉伸变换程度
ImageNet-1k 数据的标准预处理中,random_crop 函数中定义了 scale 和 ratio 两个值,两个值分别确定了图片 crop 的大小和图片的拉伸程度,其中 scale 的默认取值范围是 0.08-1(lower_scale-upper_scale), ratio 的默认取值范围是 3/4-4/3(lower_ratio-upper_ratio)。在非常小的网络训练中,此类数据增强会使得网络欠拟合,导致精度有所下降。为了提升网络的精度,可以使其数据增强变的更弱,即增大图片的 crop 区域或者减弱图片的拉伸变换程度。我们可以分别通过增大 lower_scale 的值或缩小 lower_ratio 与 upper_scale 的差距来实现更弱的图片变换。下表列出了使用不同 lower_scale 训练 MobileNetV2_x0_25 的精度,可以看到,增大图片的 crop 区域面积后训练精度和验证精度均有提升。
| 模型 | Scale取值范围 | Train_acc1/acc5 | Test_acc1/acc5 |
|:--:|:--:|:--:|:--:|
| MobileNetV2_x0_25 | [0.08,1] | 50.36%/72.98% | 52.35%/75.65% |
| MobileNetV2_x0_25 | [0.2,1] | 54.39%/77.08% | 53.18%/76.14% |
## 7.使用数据增广方式提升精度
一般来说,数据集的规模对性能影响至关重要,但是图片的标注往往比较昂贵,所以有标注的图片数量往往比较稀少,在这种情况下,数据的增广尤为重要。在训练ImageNet-1k的标准数据增广中,主要使用了random_crop与random_flip两种数据增广方式,然而,近些年,越来越多的数据增广方式被提出,如cutout、mixup、cutmix、AutoAugment等。实验表明,这些数据的增广方式可以有效提升模型的精度,下表列出了ResNet50在8种不同的数据增广方式的表现,可以看出,相比baseline,所有的数据增广方式均有收益,其中cutmix是目前最有效的数据增广。更多数据增广的介绍请参考[**数据增广章节**](../algorithm_introduction/DataAugmentation.md)
<a name="7"></a>
## 7. 使用数据增广方式提升精度
一般来说,数据集的规模对性能影响至关重要,但是图片的标注往往比较昂贵,所以有标注的图片数量往往比较稀少,在这种情况下,数据的增广尤为重要。在训练 ImageNet-1k 的标准数据增广中,主要使用了 random_crop 与 random_flip 两种数据增广方式,然而,近些年,越来越多的数据增广方式被提出,如 cutout、mixup、cutmix、AutoAugment 等。实验表明,这些数据的增广方式可以有效提升模型的精度,下表列出了 ResNet50 在 8 种不同的数据增广方式的表现,可以看出,相比 baseline,所有的数据增广方式均有收益,其中 cutmix 是目前最有效的数据增广。更多数据增广的介绍请参考[**数据增广章节**](../algorithm_introduction/DataAugmentation.md)
| 模型 | 数据增广方式 | Test top-1 |
|:--:|:--:|:--:|
......@@ -81,11 +116,17 @@ Label_smoothing是深度学习中的一种正则化方法,其全称是 Label S
| ResNet50 | Random-Erasing | 77.91% |
| ResNet50 | Hide-and-Seek | 77.43% |
## 8. 通过train_acc和test_acc确定调优策略
在训练网络的过程中,通常会打印每一个epoch的训练集准确率和验证集准确率,二者刻画了该模型在两个数据集上的表现。通常来说,训练集的准确率比验证集准确率微高或者二者相当是比较不错的状态。如果发现训练集的准确率比验证集高很多,说明在这个任务上已经过拟合,需要在训练过程中加入更多的正则,如增大l2_decay的值,加入更多的数据增广策略,加入label_smoothing策略等;如果发现训练集的准确率比验证集低一些,说明在这个任务上可能欠拟合,需要在训练过程中减弱正则效果,如减小l2_decay的值,减少数据增广方式,增大图片crop区域面积,减弱图片拉伸变换,去除label_smoothing等。
<a name="8"></a>
## 8. 通过 train_acc 和 test_acc 确定调优策略
在训练网络的过程中,通常会打印每一个 epoch 的训练集准确率和验证集准确率,二者刻画了该模型在两个数据集上的表现。通常来说,训练集的准确率比验证集准确率微高或者二者相当是比较不错的状态。如果发现训练集的准确率比验证集高很多,说明在这个任务上已经过拟合,需要在训练过程中加入更多的正则,如增大 l2_decay 的值,加入更多的数据增广策略,加入 label_smoothing 策略等;如果发现训练集的准确率比验证集低一些,说明在这个任务上可能欠拟合,需要在训练过程中减弱正则效果,如减小 l2_decay 的值,减少数据增广方式,增大图片 crop 区域面积,减弱图片拉伸变换,去除 label_smoothing 等。
<a name="9"></a>
## 9.通过已有的预训练模型提升自己的数据集的精度
在现阶段计算机视觉领域中,加载预训练模型来训练自己的任务已成为普遍的做法,相比从随机初始化开始训练,加载预训练模型往往可以提升特定任务的精度。一般来说,业界广泛使用的预训练模型是通过训练128万张图片1000类的ImageNet-1k数据集得到的,该预训练模型的fc层权重是是一个k\*1000的矩阵,其中k是fc层以前的神经元数,在加载预训练权重时,无需加载fc层的权重。在学习率方面,如果您的任务训练的数据集特别小(如小于1千张),我们建议你使用较小的初始学习率,如0.001(batch_size:256,下同),以免较大的学习率破坏预训练权重。如果您的训练数据集规模相对较大(大于10万),我们建议你尝试更大的初始学习率,如0.01或者更大。
在现阶段计算机视觉领域中,加载预训练模型来训练自己的任务已成为普遍的做法,相比从随机初始化开始训练,加载预训练模型往往可以提升特定任务的精度。一般来说,业界广泛使用的预训练模型是通过训练 128 万张图片 1000 类的 ImageNet-1k 数据集得到的,该预训练模型的 fc 层权重是一个 k\*1000 的矩阵,其中 k 是 fc 层以前的神经元数,在加载预训练权重时,无需加载 fc 层的权重。在学习率方面,如果您的任务训练的数据集特别小(如小于 1 千张),我们建议你使用较小的初始学习率,如 0.001(batch_size:256,下同),以免较大的学习率破坏预训练权重。如果您的训练数据集规模相对较大(大于 10 万),我们建议你尝试更大的初始学习率,如 0.01 或者更大。
> 如果您觉得此文档对您有帮助,欢迎star我们的项目:[https://github.com/PaddlePaddle/PaddleClas](https://github.com/PaddlePaddle/PaddleClas)
......
......@@ -94,7 +94,7 @@ cd ../../
<a name="4.1"></a>
### 4.1 使用CPU进行模型训练
由于使用CPU来进行模型训练,计算速度较慢,因此,此处以 ShuffleNetV2_x0_25 为例。此模型计算量较小,在 CPU 上计算速度较快。但是也因为模型较小,训练好的模型精度也不会太高。
由于使用 CPU 来进行模型训练,计算速度较慢,因此,此处以 ShuffleNetV2_x0_25 为例。此模型计算量较小,在 CPU 上计算速度较快。但是也因为模型较小,训练好的模型精度也不会太高。
<a name="4.1.1"></a>
#### 4.1.1 不使用预训练模型进行训练
......@@ -104,7 +104,7 @@ cd ../../
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml
```
- `-c` 参数是指定训练的配置文件路径,训练的具体超参数可查看`yaml`文件
- `-c` 参数是指定训练的配置文件路径,训练的具体超参数可查看 `yaml` 文件
- `yaml``Global.device` 参数设置为`cpu`,即使用CPU进行训练(若不设置,此参数默认为`True`
- `yaml`文件中`epochs`参数设置为20,说明对整个数据集进行20个epoch迭代,预计训练20分钟左右(不同CPU,训练时间略有不同),此时训练模型不充分。若提高训练模型精度,请将此参数设大,如**40**,训练时间也会相应延长
......
......@@ -90,7 +90,7 @@ inference model 的路径默认在当前路径下 `./inference`
<a name="5.2"></a>
### 5.2 基于预测引擎预测
首先进入 deploy 目录下:
首先进入 `deploy` 目录下:
```bash
cd ./deploy
......
......@@ -22,7 +22,7 @@
## 1. 环境配置
* 安装:请先参考[Paddle安装教程](../installation/install_paddle.md) 以及 [PaddleClas安装教程](../installation/install_paddleclas.md) 配置 PaddleClas 运行环境。
* 安装:请先参考 [Paddle安装教程](../installation/install_paddle.md) 以及 [PaddleClas安装教程](../installation/install_paddleclas.md) 配置 PaddleClas 运行环境。
* 进入 `deploy` 运行目录。本部分所有内容与命令均需要在 `deploy` 目录下运行,可以通过下面的命令进入 `deploy` 目录。
......@@ -172,9 +172,9 @@ python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.u
[{'bbox': [244, 49, 509, 964], 'rec_docs': '农夫山泉-饮用天然水', 'rec_scores': 0.7585664}]
```
其中bbox表示检测出的主体所在位置,rec_docs表示索引库中与检测框最为相似的类别,rec_scores表示对应的置信度。
其中 `bbox` 表示检测出的主体所在位置,`rec_docs` 表示索引库中与检测框最为相似的类别,`rec_scores` 表示对应的置信度。
检测的可视化结果也保存在`output`文件夹下,对于本张图像,识别结果可视化如下所示。
检测的可视化结果也保存在 `output` 文件夹下,对于本张图像,识别结果可视化如下所示。
<div align="center">
<img src="../../images/recognition/drink_data_demo/output/nongfu_spring.jpeg" width = "400" />
......@@ -209,7 +209,7 @@ Inference: 150.06470680236816 ms per batch image
...
```
所有图像的识别结果可视化图像也保存在 `output`文件夹内。
所有图像的识别结果可视化图像也保存在 `output` 文件夹内。
更多地,可以通过修改 `Global.rec_inference_model_dir` 字段来更改识别 inference 模型的路径,通过修改 `IndexProcess.index_dir` 字段来更改索引库索引的路径。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册