提交 217ab059 编写于 作者: C cuicheng01

Update docs

上级 125cfa3b
此差异已折叠。
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# 知识蒸馏
## 一、模型压缩方法简介
近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。
在数据量足够大的情况下,通过合理构建网络模型的方式增加其参数量,可以显著改善模型性能,但是这又带来了模型复杂度急剧提升的问题。大模型在实际场景中使用的成本较高。
深度神经网络一般有较多的参数冗余,目前有几种主要的方法对模型进行压缩,减小其参数量。如裁剪、量化、知识蒸馏等,其中知识蒸馏是指使用教师模型(teacher model)去指导学生模型(student model)学习特定任务,保证小模型在参数量不变的情况下,得到比较大的性能提升,甚至获得与大模型相似的精度指标[1]。PaddleClas融合已有的蒸馏方法[2,3],提供了一种简单的半监督标签知识蒸馏方案(SSLD,Simple Semi-supervised Label Distillation),基于ImageNet1k分类数据集,在ResNet_vd以及MobileNet系列上的精度均有超过3%的绝对精度提升,具体指标如下图所示。
![](../../../images/distillation/distillation_perform_s.jpg)
## 二、SSLD 蒸馏策略
### 2.1 简介
SSLD的流程图如下图所示。
![](../../../images/distillation/ppcls_distillation.png)
首先,我们从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%`)。
* 改进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%`)。
* 无需数据集的真值标签,很容易扩展训练集。SSLD的loss在计算过程中,仅涉及到教师和学生模型对于相同图片的处理结果(经过softmax激活函数处理之后的soft label),因此即使图片数据不包含真值标签,也可以用来进行训练并提升模型性能。该蒸馏方案的无标签蒸馏策略也大大提升了学生模型的性能上限(`77.1%->78.5%`)。
* ImageNet1k蒸馏finetune。我们仅使用ImageNet1k数据,使用蒸馏方法对上述模型进行finetune,最终仍然可以获得0.4%的性能提升(`78.5%->78.9%`)。
### 2.2 数据选择
* SSLD蒸馏方案的一大特色就是无需使用图像的真值标签,因此可以任意扩展数据集的大小,考虑到计算资源的限制,我们在这里仅基于ImageNet22k数据集对蒸馏任务的训练集进行扩充。在SSLD蒸馏任务中,我们使用了`Top-k per class`的数据采样方案[3]。具体步骤如下。
* 训练集去重。我们首先基于SIFT特征相似度匹配的方式对ImageNet22k数据集与ImageNet1k验证集进行去重,防止添加的ImageNet22k训练集中包含ImageNet1k验证集图像,最终去除了4511张相似图片。部分过滤的相似图片如下所示。
![](../../../images/distillation/22k_1k_val_compare_w_sift.png)
* 大数据集soft label获取,对于去重后的ImageNet22k数据集,我们使用`ResNeXt101_32x16d_wsl`模型进行预测,得到每张图片的soft label。
* Top-k数据选择,ImageNet1k数据共有1000类,对于每一类,找出属于该类并且得分最高的k张图片,最终得到一个数据量不超过`1000*k`的数据集(某些类上得到的图片数量可能少于k张)。
* 将该数据集与ImageNet1k的训练集融合组成最终蒸馏模型所使用的数据集,数据量为500万。
## 三、实验
* PaddleClas的蒸馏策略为`大数据集训练+ImageNet1k蒸馏finetune`的策略。选择合适的教师模型,首先在挑选得到的500万数据集上进行训练,然后在ImageNet1k训练集上进行finetune,最终得到蒸馏后的学生模型。
### 3.1 教师模型的选择
为了验证教师模型和学生模型的模型大小差异和教师模型的模型精度对蒸馏结果的影响,我们做了几组实验验证。训练策略统一为:`cosine_decay_warmup,lr=1.3, epoch=120, bs=2048`,学生模型均为从头训练。
|Teacher Model | Teacher Top1 | Student Model | Student Top1|
|- |:-: |:-: | :-: |
| ResNeXt101_32x16d_wsl | 84.2% | MobileNetV3_large_x1_0 | 75.78% |
| ResNet50_vd | 79.12% | MobileNetV3_large_x1_0 | 75.60% |
| ResNet50_vd | 82.35% | MobileNetV3_large_x1_0 | 76.00% |
从表中可以看出
> 教师模型结构相同时,其精度越高,最终的蒸馏效果也会更好一些。
>
> 教师模型与学生模型的模型大小差异不宜过大,否则反而会影响蒸馏结果的精度。
因此最终在蒸馏实验中,对于ResNet系列学生模型,我们使用`ResNeXt101_32x16d_wsl`作为教师模型;对于MobileNet系列学生模型,我们使用蒸馏得到的`ResNet50_vd`作为教师模型。
### 3.2 大数据蒸馏
基于PaddleClas的蒸馏策略为`大数据集训练+imagenet1k finetune`的策略。
针对从ImageNet22k挑选出的400万数据,融合imagenet1k训练集,组成共500万的训练集进行训练,具体地,在不同模型上的训练超参及效果如下。
|Student Model | num_epoch | l2_ecay | batch size/gpu cards | base lr | learning rate decay | top1 acc |
| - |:-: |:-: | :-: |:-: |:-: |:-: |
| MobileNetV1 | 360 | 3e-5 | 4096/8 | 1.6 | cosine_decay_warmup | 77.65% |
| MobileNetV2 | 360 | 1e-5 | 3072/8 | 0.54 | cosine_decay_warmup | 76.34% |
| MobileNetV3_large_x1_0 | 360 | 1e-5 | 5760/24 | 3.65625 | cosine_decay_warmup | 78.54% |
| MobileNetV3_small_x1_0 | 360 | 1e-5 | 5760/24 | 3.65625 | cosine_decay_warmup | 70.11% |
| ResNet50_vd | 360 | 7e-5 | 1024/32 | 0.4 | cosine_decay_warmup | 82.07% |
| ResNet101_vd | 360 | 7e-5 | 1024/32 | 0.4 | cosine_decay_warmup | 83.41% |
| Res2Net200_vd_26w_4s | 360 | 4e-5 | 1024/32 | 0.4 | cosine_decay_warmup | 84.82% |
### 3.3 ImageNet1k训练集finetune
对于在大数据集上训练的模型,其学习到的特征可能与ImageNet1k数据特征有偏,因此在这里使用ImageNet1k数据集对模型进行finetune。finetune的超参和finetune的精度收益如下。
|Student Model | num_epoch | l2_ecay | batch size/gpu cards | base lr | learning rate decay | top1 acc |
| - |:-: |:-: | :-: |:-: |:-: |:-: |
| MobileNetV1 | 30 | 3e-5 | 4096/8 | 0.016 | cosine_decay_warmup | 77.89% |
| MobileNetV2 | 30 | 1e-5 | 3072/8 | 0.0054 | cosine_decay_warmup | 76.73% |
| MobileNetV3_large_x1_0 | 30 | 1e-5 | 2048/8 | 0.008 | cosine_decay_warmup | 78.96% |
| MobileNetV3_small_x1_0 | 30 | 1e-5 | 6400/32 | 0.025 | cosine_decay_warmup | 71.28% |
| ResNet50_vd | 60 | 7e-5 | 1024/32 | 0.004 | cosine_decay_warmup | 82.39% |
| ResNet101_vd | 30 | 7e-5 | 1024/32 | 0.004 | cosine_decay_warmup | 83.73% |
| Res2Net200_vd_26w_4s | 360 | 4e-5 | 1024/32 | 0.004 | cosine_decay_warmup | 85.13% |
### 3.4 数据增广以及基于Fix策略的微调
* 基于前文所述的实验结论,我们在训练的过程中加入自动增广(AutoAugment)[4],同时进一步减小了l2_decay(4e-5->2e-5),最终ResNet50_vd经过SSLD蒸馏策略,在ImageNet1k上的精度可以达到82.99%,相比之前不加数据增广的蒸馏策略再次增加了0.6%。
* 对于图像分类任务,在测试的时候,测试尺度为训练尺度的1.15倍左右时,往往在不需要重新训练模型的情况下,模型的精度指标就可以进一步提升[5],对于82.99%的ResNet50_vd在320x320的尺度下测试,精度可达83.7%,我们进一步使用Fix策略,即在320x320的尺度下进行训练,使用与预测时相同的数据预处理方法,同时固定除FC层以外的所有参数,最终在320x320的预测尺度下,精度可以达到**84.0%**
### 3.5 实验过程中的一些问题
* 在预测过程中,batch norm的平均值与方差是通过加载预训练模型得到(设其模式为test mode)。在训练过程中,batch norm是通过统计当前batch的信息(设其模式为train mode),与历史保存信息进行滑动平均计算得到,在蒸馏任务中,我们发现通过train mode,即教师模型的bn实时变化的模式,去指导学生模型,比通过test mode蒸馏,得到的学生模型性能更好一些,下面是一组实验结果。因此我们在该蒸馏方案中,均使用train mode去得到教师模型的soft label。
|Teacher Model | Teacher Top1 | Student Model | Student Top1|
|- |:-: |:-: | :-: |
| ResNet50_vd | 82.35% | MobileNetV3_large_x1_0 | 76.00% |
| ResNet50_vd | 82.35% | MobileNetV3_large_x1_0 | 75.84% |
## 四、蒸馏模型的应用
### 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]`的中间层学习率倍数设置能够带来更大的精度收益。
* 对于MoblileNetV3_large_x1_0,由于其包含15个block,我们设置每3个block共享一个学习率倍数参数,因此需要共5个学习率倍数的参数,最终发现在分类和检测任务中,`[0.25,0.25,0.5,0.5,0.75]`的中间层学习率倍数能够带来更大的精度收益。
* 适当的l2 decay。不同分类模型在训练的时候一般都会根据模型设置不同的l2 decay,大模型为了防止过拟合,往往会设置更大的l2 decay,如ResNet50等模型,一般设置为`1e-4`;而如MobileNet系列模型,在训练时往往都会设置为`1e-5~4e-5`,防止模型过度欠拟合,在蒸馏时亦是如此。在将蒸馏模型应用到目标检测任务中时,我们发现也需要调节backbone甚至特定任务模型模型的l2 decay,和预训练蒸馏时的l2 decay尽可能保持一致。以Faster RCNN MobiletNetV3 FPN为例,我们发现仅修改该参数,在COCO2017数据集上就可以带来最多0.5%左右的精度(mAP)提升(默认Faster RCNN l2 decay为1e-4,我们修改为1e-5~4e-5均有0.3%~0.5%的提升)。
### 4.2 迁移学习finetune
* 为验证迁移学习的效果,我们在10个小的数据集上验证其效果。在这里为了保证实验的可对比性,我们均使用ImageNet1k数据集训练的标准预处理过程,对于蒸馏模型我们也添加了蒸馏模型中间层学习率的搜索。
* 对于ResNet50_vd,baseline为Top1 Acc 79.12%的预训练模型基于grid search搜索得到的最佳精度,对比实验则为基于该精度对预训练和中间层学习率进一步搜索得到的最佳精度。下面给出10个数据集上所有baseline和蒸馏模型的精度对比。
| Dataset | Model | Baseline Top1 Acc | Distillation Model Finetune |
|- |:-: |:-: | :-: |
| Oxford102 flowers | ResNete50_vd | 97.18% | 97.41% |
| caltech-101 | ResNete50_vd | 92.57% | 93.21% |
| Oxford-IIIT-Pets | ResNete50_vd | 94.30% | 94.76% |
| DTD | ResNete50_vd | 76.48% | 77.71% |
| fgvc-aircraft-2013b | ResNete50_vd | 88.98% | 90.00% |
| Stanford-Cars | ResNete50_vd | 92.65% | 92.76% |
| SUN397 | ResNete50_vd | 64.02% | 68.36% |
| cifar100 | ResNete50_vd | 86.50% | 87.58% |
| cifar10 | ResNete50_vd | 97.72% | 97.94% |
| Food-101 | ResNete50_vd | 89.58% | 89.99% |
* 可以看出在上面10个数据集上,结合适当的中间层学习率倍数设置,蒸馏模型平均能够带来1%以上的精度提升。
### 4.3 目标检测
我们基于两阶段目标检测Faster/Cascade RCNN模型验证蒸馏得到的预训练模型的效果。
* ResNet50_vd
设置训练与评测的尺度均为640x640,最终COCO上检测指标如下。
| Model | train/test scale | pretrain top1 acc | feature map lr | coco mAP |
|- |:-: |:-: | :-: | :-: |
| Faster RCNN R50_vd FPN | 640/640 | 79.12% | [1.0,1.0,1.0,1.0,1.0] | 34.8% |
| Faster RCNN R50_vd FPN | 640/640 | 79.12% | [0.05,0.05,0.1,0.1,0.15] | 34.3% |
| Faster RCNN R50_vd FPN | 640/640 | 82.18% | [0.05,0.05,0.1,0.1,0.15] | 36.3% |
在这里可以看出,对于未蒸馏模型,过度调整中间层学习率反而降低最终检测模型的性能指标。基于该蒸馏模型,我们也提供了领先的服务端实用目标检测方案,详细的配置与训练代码均已开源,可以参考[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/master/configs/rcnn_enhance)
## 五、SSLD实战
本节将基于ImageNet-1K的数据集详细介绍SSLD蒸馏实验,如果想快速体验此方法,可以参考[**30分钟玩转PaddleClas(进阶版)**](../../tutorials/quick_start_professional.md)中基于CIFAR100的SSLD蒸馏实验。
### 5.1 参数配置
实战部分提供了SSLD蒸馏的示例,在`ppcls/configs/ImageNet/Distillation/mv3_large_x1_0_distill_mv3_small_x1_0.yaml`中提供了`MobileNetV3_large_x1_0`蒸馏`MobileNetV3_small_x1_0`的配置文件,用户可以在`tools/train.sh`里直接替换配置文件的路径即可使用。
```yaml
Arch:
name: "DistillationModel"
# if not null, its lengths should be same as models
pretrained_list:
# if not null, its lengths should be same as models
freeze_params_list:
- True
- False
models:
- Teacher:
name: MobileNetV3_large_x1_0
pretrained: True
use_ssld: True
- Student:
name: MobileNetV3_small_x1_0
pretrained: False
infer_model_name: "Student"
```
在参数配置中,`freeze_params_list`中需要指定模型是否需要冻结参数,`models`中需要指定Teacher模型和Student模型,其中Teacher模型需要加载预训练模型。用户可以直接在此处更改模型。
### 5.2 启动命令
当用户配置完训练环境后,类似于训练其他分类任务,只需要将`tools/train.sh`中的配置文件替换成为相应的蒸馏配置文件即可。
其中`train.sh`中的内容如下:
```bash
python -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \
--log_dir=mv3_large_x1_0_distill_mv3_small_x1_0 \
tools/train.py \
-c ./ppcls/configs/ImageNet/Distillation/mv3_large_x1_0_distill_mv3_small_x1_0.yaml
```
运行`train.sh`
```bash
sh tools/train.sh
```
### 5.3 注意事项
* 用户在使用SSLD蒸馏之前,首先需要在目标数据集上训练一个教师模型,该教师模型用于指导学生模型在该数据集上的训练。
* 如果学生模型没有加载预训练模型,训练的其他超参数可以参考该学生模型在ImageNet-1k上训练的超参数,如果学生模型加载了预训练模型,学习率可以调整到原来的1/10或者1/100。
* 在SSLD蒸馏的过程中,学生模型只学习soft-label导致训练目标变的更加复杂,建议可以适当的调小`l2_decay`的值来获得更高的验证集准确率。
* 若用户准备添加无标签的训练数据,只需要将新的训练数据放置在原本训练数据的路径下,生成新的数据list即可,另外,新生成的数据list需要将无标签的数据添加伪标签(只是为了统一读数据)。
> 如果您觉得此文档对您有帮助,欢迎star我们的项目:[https://github.com/PaddlePaddle/PaddleClas](https://github.com/PaddlePaddle/PaddleClas)
## 参考文献
[1] Hinton G, Vinyals O, Dean J. Distilling the knowledge in a neural network[J]. arXiv preprint arXiv:1503.02531, 2015.
[2] Bagherinezhad H, Horton M, Rastegari M, et al. Label refinery: Improving imagenet classification through label progression[J]. arXiv preprint arXiv:1805.02641, 2018.
[3] Yalniz I Z, Jégou H, Chen K, et al. Billion-scale semi-supervised learning for image classification[J]. arXiv preprint arXiv:1905.00546, 2019.
[4] 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.
[5] Touvron H, Vedaldi A, Douze M, et al. Fixing the train-test resolution discrepancy[C]//Advances in Neural Information Processing Systems. 2019: 8250-8260.
知识蒸馏
================================
.. toctree::
:maxdepth: 3
distillation.md
图像增广
================================
.. toctree::
:maxdepth: 3
ImageAugment.md
高阶使用
================================
.. toctree::
:maxdepth: 1
image_augmentation/index
distillation/index
multilabel/index
多标签分类
================================
.. toctree::
:maxdepth: 3
multilabel.md
\ No newline at end of file
# 多标签分类quick start
基于[NUS-WIDE-SCENE](https://lms.comp.nus.edu.sg/wp-content/uploads/2019/research/nuswide/NUS-WIDE.html)数据集,体验多标签分类的训练、评估、预测的过程,该数据集是NUS-WIDE数据集的一个子集。请事先参考[安装指南](install.md)配置运行环境和克隆PaddleClas代码。
## 一、数据和模型准备
* 进入PaddleClas目录。
```
cd path_to_PaddleClas
```
* 创建并进入`dataset/NUS-WIDE-SCENE`目录,下载并解压NUS-WIDE-SCENE数据集。
```shell
mkdir dataset/NUS-WIDE-SCENE
cd dataset/NUS-WIDE-SCENE
wget https://paddle-imagenet-models-name.bj.bcebos.com/data/NUS-SCENE-dataset.tar
tar -xf NUS-SCENE-dataset.tar
```
* 返回`PaddleClas`根目录
```
cd ../../
```
## 二、模型训练
```shell
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ./ppcls/configs/quick_start/professional/MobileNetV1_multilabel.yaml
```
训练10epoch之后,验证集最好的正确率应该在0.95左右。
## 三、模型评估
```bash
python3 tools/eval.py \
-c ./ppcls/configs/quick_start/professional/MobileNetV1_multilabel.yaml \
-o Arch.pretrained="./output/MobileNetV1/best_model"
```
## 四、模型预测
```bash
python3 tools/infer.py \
-c ./ppcls/configs/quick_start/professional/MobileNetV1_multilabel.yaml \
-o Arch.pretrained="./output/MobileNetV1/best_model"
```
得到类似下面的输出:
```
[{'class_ids': [6, 13, 17, 23, 26, 30], 'scores': [0.95683, 0.5567, 0.55211, 0.99088, 0.5943, 0.78767], 'file_name': './deploy/images/0517_2715693311.jpg', 'label_names': []}]
```
## 五、基于预测引擎预测
### 5.1 导出inference model
```bash
python3 tools/export_model.py \
-c ./ppcls/configs/quick_start/professional/MobileNetV1_multilabel.yaml \
-o Arch.pretrained="./output/MobileNetV1/best_model"
```
inference model的路径默认在当前路径下`./inference`
### 5.2 基于预测引擎预测
首先进入deploy目录下:
```bash
cd ./deploy
```
通过预测引擎推理预测:
```
python3 python/predict_cls.py \
-c configs/inference_multilabel_cls.yaml
```
得到类似下面的输出:
```
0517_2715693311.jpg: class id(s): [6, 13, 17, 23, 26, 30], score(s): [0.96, 0.56, 0.55, 0.99, 0.59, 0.79], label_name(s): []
```
# 动漫人物识别
自七十年代以来,人脸识别已经成为了计算机视觉和生物识别领域研究最多的主题之一。近年来,传统的人脸识别方法已经被基于卷积神经网络(CNN)的深度学习方法代替。目前,人脸识别技术广泛应用于安防、商业、金融、智慧自助终端、娱乐等各个领域。而在行业应用强烈需求的推动下,动漫媒体越来越受到关注,动漫人物的人脸识别也成为一个新的研究领域。
## 1 算法介绍
算法整体流程,详见[特征学习](./feature_learning.md)整体流程。值得注意的是,本流程没有使用`Neck`模块。
具体配置信息详见[配置文件](../../../ppcls/configs/Cartoonface/ResNet50_icartoon.yaml)
具体模块如下所示,
### 1.1 数据增强
- 图像`Resize`到224
- 随机水平翻转
- Normalize:归一化到0~1
### 1.2 Backbone的具体设置
采用ResNet50作为backbone。并采用大模型进行蒸馏
### 1.3 Metric Learning相关Loss设置
在动漫人物识别中,只使用了`CELoss`
## 2 实验结果
本方法使用iCartoonFace[1]数据集进行验证。该数据集由 5013 个动漫角色的 389678 张图像组成,并带有 ID、边界框、姿势和其他辅助属性。 iCartoonFace 是目前图像识别领域规模最大的卡通媒体数据集,而且质量高、注释丰富、内容全面,其中包含相似图像、有遮挡的图像以及外观有变化的图像。
与其他数据集相比,iCartoonFace无论在图像数量还是实体数量上,均具有明显领先的优势。其中训练集: 5013类,389678张图像; 验证集: query2500张,gallery20000张。
![icartoon](../../images/icartoon1.png)
值得注意的是,相比于人脸识别任务,动漫人物头像的配饰、道具、发型等因素可以显著提升识别的准确率,因此在原数据集标注框的基础上,长、宽各expand为之前的2倍,并做截断处理,得到了目前训练所有的数据集。
在此数据集上,此方法Recall1 达到83.24%。
## 3 参考文献
[1] Cartoon Face Recognition: A Benchmark Dataset. 2020. [下载地址](https://github.com/luxiangju-PersonAI/iCartoonFace)
# 特征学习
此部分主要是针对特征学习的训练模式进行说明,即`RecModel`的训练模式。主要是为了支持车辆识别(车辆细分类、ReID)、Logo识别、动漫人物识别、商品识别等特征学习的应用。与在`ImageNet`上训练普通的分类网络不同的是,此特征学习部分,主要有以下特征
- 支持对`backbone`的输出进行截断,即支持提取任意中间层的特征信息
- 支持在`backbone`的feature输出层后,添加可配置的网络层,即`Neck`部分
- 支持`ArcFace Loss``metric learning` 相关loss函数,提升特征学习能力
## 1 整体流程
![](../../images/recognition/rec_pipeline.png)
特征学习的整体结构如上图所示,主要包括:数据增强、Backbone的设置、Neck、Metric Learning等几大部分。其中`Neck`部分为自由添加的网络层,如添加的embedding层等,当然也可以不用此模块。训练时,利用`Metric Learning`部分的Loss对模型进行优化。预测时,一般来说,默认以`Neck`部分的输出作为特征输出。
针对不同的应用,可以根据需要,对每一部分自由选择。每一部分的具体配置,如数据增强、Backbone、Neck、Metric Learning相关Loss等设置,详见具体应用:[车辆识别](./vehicle_recognition.md)[Logo识别](./logo_recognition.md)[动漫人物识别](./cartoon_character_recognition.md)[商品识别](./product_recognition.md)
## 2 配置文件说明
配置文件说明详见[yaml配置文件说明文档](../tutorials/config.md)。其中模型结构配置,详见文档中**识别模型结构配置**部分。
## 3 预训练模型
以下为各应用在不同数据集下的预训练模型
- 车辆细分类:[CompCars](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/vehicle_cls_ResNet50_CompCars_v1.2_pretrained.pdparams)
- 车辆ReID:[VERI-Wild](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/vehicle_reid_ResNet50_VERIWild_v1.1_pretrained.pdparams)
- 动漫人物识别:[iCartoon](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/cartoon_rec_ResNet50_iCartoon_v1.0_pretrained.pdparams)
- Logo识别:[Logo3K](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/logo_rec_ResNet50_Logo3K_v1.1_pretrained.pdparams)
- 商品识别: [Inshop](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/product_ResNet50_vd_Inshop_pretrained_v1.1.pdparams)[Aliproduct](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/product_ResNet50_vd_Aliproduct_v1.0_pretrained.pdparams)
应用拓展
================================
.. toctree::
:maxdepth: 2
transfer_learning.md
object_detection.md
\ No newline at end of file
# Logo识别
Logo识别技术,是现实生活中应用很广的一个领域,比如一张照片中是否出现了Adidas或者Nike的商标Logo,或者一个杯子上是否出现了星巴克或者可口可乐的商标Logo。通常Logo类别数量较多时,往往采用检测+识别两阶段方式,检测模块负责检测出潜在的Logo区域,根据检测区域抠图后输入识别模块进行识别。识别模块多采用检索的方式,根据查询图片和底库图片进行相似度排序获得预测类别。此文档主要对Logo图片的特征提取部分进行相关介绍。
## 1 算法介绍
算法整体流程,详见[特征学习](./feature_learning.md)整体流程。
整体设置详见: [ResNet50_ReID.yaml](../../../ppcls/configs/Logo/ResNet50_ReID.yaml)
具体模块如下所示
### 1.1数据增强
与普通训练分类不同,此部分主要使用如下图像增强方式:
- 图像`Resize`到224。对于Logo而言,使用的图像,直接为检测器crop之后的图像,因此直接resize到224
- [AugMix](https://arxiv.org/abs/1912.02781v1):模拟Logo图像形变变化等实际场景
- [RandomErasing](https://arxiv.org/pdf/1708.04896v2.pdf):模拟遮挡等实际情况
### 1.2 Backbone的具体设置
使用`ResNet50`作为backbone,同时做了如下修改:
- last stage stride=1, 保持最后输出特征图尺寸14x14。计算量增加较小,但显著提高模型特征提取能力
具体代码:[ResNet50_last_stage_stride1](../../../ppcls/arch/backbone/variant_models/resnet_variant.py)
### 1.3 Neck部分
为了降低inferecne时计算特征距离的复杂度,添加一个embedding 卷积层,特征维度为512。
### 1.4 Metric Learning相关Loss的设置
在Logo识别中,使用了[Pairwise Cosface + CircleMargin](https://arxiv.org/abs/2002.10857) 联合训练,其中权重比例为1:1
具体代码详见:[PairwiseCosface](../../../ppcls/loss/pairwisecosface.py)[CircleMargin](../../../ppcls/arch/gears/circlemargin.py)
## 2 实验结果
<img src="../../images/logo/logodet3k.jpg" style="zoom:50%;" />
使用LogoDet-3K[1]数据集进行实验,此数据集是具有完整标注的Logo数据集,有3000个标识类别,约20万个高质量的人工标注的标识对象和158652张图片。
由于原始的数据集中,图像包含标注的检测框,在识别阶段只考虑检测器抠图后的logo区域,因此采用原始的标注框抠出Logo区域图像构成训练集,排除背景在识别阶段的影响。对数据集进行划分,产生155427张训练集,覆盖3000个logo类别(同时作为测试时gallery图库),3225张测试集,用于作为查询集。抠图后的训练集可[在此下载](https://arxiv.org/abs/2008.05359)
在此数据集上,recall1 达到89.8%。
## 3 参考文献
[1] LogoDet-3K: A Large-Scale Image Dataset for Logo Detection[J]. arXiv preprint arXiv:2008.05359, 2020.
# 主体检测
主体检测技术是目前应用非常广泛的一种检测技术,它指的是检测出图片中一个或者多个主体的坐标位置,然后将图像中的对应区域裁剪下来,进行识别,从而完成整个识别过程。主体检测是识别任务的前序步骤,可以有效提升识别精度。
本部分主要从数据集、模型训练2个方面对该部分内容进行介绍。
## 1. 数据集
在PaddleClas的识别任务中,训练主体检测模型时主要用到了以下几个数据集。
| 数据集 | 数据量 | 主体检测任务中使用的数据量 | 场景 | 数据集地址 |
| ------------ | ------------- | -------| ------- | -------- |
| Objects365 | 170W | 6k | 通用场景 | [地址](https://www.objects365.org/overview.html) |
| COCO2017 | 12W | 5k | 通用场景 | [地址](https://cocodataset.org/) |
| iCartoonFace | 2k | 2k | 动漫人脸检测 | [地址](https://github.com/luxiangju-PersonAI/iCartoonFace) |
| LogoDet-3k | 3k | 2k | Logo检测 | [地址](https://github.com/Wangjing1551/LogoDet-3K-Dataset) |
| RPC | 3k | 3k | 商品检测 | [地址](https://rpc-dataset.github.io/) |
在实际训练的过程中,将所有数据集混合在一起。由于是主体检测,这里将所有标注出的检测框对应的类别都修改为"前景"的类别,最终融合的数据集中只包含1个类别,即前景。
## 2. 模型选择
目标检测方法种类繁多,比较常用的有两阶段检测器(如FasterRCNN系列等);单阶段检测器(如YOLO、SSD等);anchor-free检测器(如FCOS等)。
PP-YOLO由[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection)提出,从骨干网络、数据增广、正则化策略、损失函数、后处理等多个角度对yolov3模型进行深度优化,最终在"速度-精度"方面达到了业界领先的水平。具体地,优化的策略如下。
- 更优的骨干网络: ResNet50vd-DCN
- 更大的训练batch size: 8 GPUs,每GPU batch_size=24,对应调整学习率和迭代轮数
- [Drop Block](https://arxiv.org/abs/1810.12890)
- [Exponential Moving Average](https://www.investopedia.com/terms/e/ema.asp)
- [IoU Loss](https://arxiv.org/pdf/1902.09630.pdf)
- [Grid Sensitive](https://arxiv.org/abs/2004.10934)
- [Matrix NMS](https://arxiv.org/pdf/2003.10152.pdf)
- [CoordConv](https://arxiv.org/abs/1807.03247)
- [Spatial Pyramid Pooling](https://arxiv.org/abs/1406.4729)
- 更优的预训练模型
更多关于PP-YOLO的详细介绍可以参考:[PP-YOLO 模型](https://github.com/PaddlePaddle/PaddleDetection/blob/release%2F2.1/configs/ppyolo/README_cn.md)
在主体检测任务中,为了保证检测效果,我们使用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),更换为自定义的主体检测数据集,进行训练,最终得到检测模型。
主体检测模型的inference模型下载地址为:[链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar)
## 3. 模型训练
本节主要介绍怎样基于PaddleDetection,基于自己的数据集,训练主体检测模型。
### 3.1 环境准备
下载PaddleDetection代码,安装requirements。
```shell
cd <path/to/clone/PaddleDetection>
git clone https://github.com/PaddlePaddle/PaddleDetection.git
cd PaddleDetection
# 安装其他依赖
pip install -r requirements.txt
```
更多安装教程,请参考: [安装文档](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/docs/tutorials/INSTALL_cn.md)
### 3.2 数据准备
对于自定义数据集,首先需要将自己的数据集修改为COCO格式,可以参考[自定义检测数据集教程](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/static/docs/tutorials/Custom_DataSet.md)制作COCO格式的数据集。
主体检测任务中,所有的检测框均属于前景,在这里需要将标注文件中,检测框的`category_id`修改为1,同时将整个标注文件中的`categories`映射表修改为下面的格式,即整个类别映射表中只包含`前景`类别。
```json
[{u'id': 1, u'name': u'foreground', u'supercategory': u'foreground'}]
```
### 3.3 配置文件改动和说明
我们使用 `configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml`配置进行训练,配置文件摘要如下:
<div align='center'>
<img src='../../images/det/PaddleDetection_config.png' width='400'/>
</div>
从上图看到 `ppyolov2_r50vd_dcn_365e_coco.yml` 配置需要依赖其他的配置文件,这些配置文件的含义如下:
```
coco_detection.yml:主要说明了训练数据和验证数据的路径
runtime.yml:主要说明了公共的运行参数,比如是否使用GPU、每多少个epoch存储checkpoint等
optimizer_365e.yml:主要说明了学习率和优化器的配置
ppyolov2_r50vd_dcn.yml:主要说明模型和主干网络的情况
ppyolov2_reader.yml:主要说明数据读取器配置,如batch size,并发加载子进程数等,同时包含读取后预处理操作,如resize、数据增强等等
```
在主体检测任务中,需要将`datasets/coco_detection.yml`中的`num_classes`参数修改为1(只有1个前景类别),同时将训练集和测试集的路径修改为自定义数据集的路径。
此外,也可以根据实际情况,修改上述文件,比如,如果显存溢出,可以将batch size和学习率等比缩小等。
### 3.4 启动训练
PaddleDetection提供了单卡/多卡训练模式,满足用户多种训练需求。
* GPU 单卡训练
```bash
# windows和Mac下不需要执行该命令
export CUDA_VISIBLE_DEVICES=0
python tools/train.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml
```
* GPU多卡训练
```bash
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
```
--eval:表示边训练边验证。
* (**推荐**)模型微调
如果希望加载PaddleClas中已经训练好的主体检测模型,在自己的数据集上进行模型微调,可以使用下面的命令进行训练。
```bash
export CUDA_VISIBLE_DEVICES=0
# 指定pretrain_weights参数,加载通用的主体检测预训练模型
python tools/train.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml -o pretrain_weights=https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/ppyolov2_r50vd_dcn_mainbody_v1.0_pretrained.pdparams
```
* 模型恢复训练
在日常训练过程中,有的用户由于一些原因导致训练中断,可以使用-r的命令恢复训练:
```bash
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
```
注意:如果遇到 "`Out of memory error`" 问题, 尝试在 `ppyolov2_reader.yml` 文件中调小`batch_size`
### 3.5 模型预测与调试
使用下面的命令完成PaddleDetection的预测过程。
```bash
export CUDA_VISIBLE_DEVICES=0
python tools/infer.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml --infer_img=your_image_path.jpg --output_dir=infer_output/ --draw_threshold=0.5 -o weights=output/ppyolov2_r50vd_dcn_365e_coco/model_final
```
`--draw_threshold` 是个可选参数. 根据 [NMS](https://ieeexplore.ieee.org/document/1699659) 的计算,不同阈值会产生不同的结果 `keep_top_k`表示设置输出目标的最大数量,默认值为100,用户可以根据自己的实际情况进行设定。
### 3.6 模型导出与预测部署。
执行导出模型脚本:
```bash
python tools/export_model.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml --output_dir=./inference -o weights=output/ppyolov2_r50vd_dcn_365e_coco/model_final.pdparams
```
预测模型会导出到`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`文件,用于后续主体检测的预测部署。
更多模型导出教程,请参考:[EXPORT_MODEL](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/deploy/EXPORT_MODEL.md)
最终,目录`inference/ppyolov2_r50vd_dcn_365e_coco`中包含`inference.pdiparams`, `inference.pdiparams.info` 以及 `inference.pdmodel` 文件,其中`inference.pdiparams`为保存的inference模型权重文件,`inference.pdmodel`为保存的inference模型结构文件。
导出模型之后,在主体检测与识别任务中,就可以将检测模型的路径更改为该inference模型路径,完成预测。
以商品识别为例,其配置文件为[inference_product.yaml](../../../deploy/configs/inference_product.yaml),修改其中的`Global.det_inference_model_dir`字段为导出的主体检测inference模型目录,参考[图像识别快速开始教程](../tutorials/quick_start_recognition.md),即可完成商品检测与识别过程。
### FAQ
#### Q:可以使用其他的主体检测模型结构吗?
* A:可以的,但是目前的检测预处理过程仅适配yolo系列的预处理,因此在使用的时候,建议优先使用yolo系列的模型进行训练,如果希望使用faster rcnn等其他系列的模型,需要按照PaddleDetection的数据预处理,修改下预处理逻辑,这块如果您有需求或者有问题的话,欢迎提issue或者在群里反馈。
#### Q:可以修改主体检测的预测尺度吗?
* A:可以的,但是需要注意2个地方
* PaddleClas中提供的主体检测模型是基于640x640的分辨率去训练的,因此预测的时候也是默认使用640x640的分辨率进行预测,使用其他分辨率预测的话,精度会有所降低。
* 在模型导出的时候,建议也修改下模型导出的分辨率,保持模型导出、模型预测的分辨率一致。
# 通用目标检测
## 服务器端实用目标检测方案
### 简介
* 近年来,学术界和工业界广泛关注图像中目标检测任务。基于SSLD蒸馏方案训练得到的ResNet50_vd预训练模型(ImageNet1k验证集上Top1 Acc为82.39%),结合PaddleDetection中的丰富算子,飞桨提供了一种面向服务器端实用的目标检测方案PSS-DET(Practical Server Side Detection)。基于COCO2017目标检测数据集,V100单卡预测速度为为61FPS时,COCO mAP可达41.6%;预测速度为20FPS时,COCO mAP可达47.8%。
### 消融实验
* 我们以标准的Faster RCNN ResNet50_vd FPN为例,下表给出了PSS-DET不同的模块的速度与精度收益。
| Trick | Train scale | Test scale | COCO mAP | Infer speed/FPS |
|- |:-: |:-: | :-: | :-: |
| `baseline` | 640x640 | 640x640 | 36.4% | 43.589 |
| +`test proposal=pre/post topk 500/300` | 640x640 | 640x640 | 36.2% | 52.512 |
| +`fpn channel=64` | 640x640 | 640x640 | 35.1% | 67.450 |
| +`ssld pretrain` | 640x640 | 640x640 | 36.3% | 67.450 |
| +`ciou loss` | 640x640 | 640x640 | 37.1% | 67.450 |
| +`DCNv2` | 640x640 | 640x640 | 39.4% | 60.345 |
| +`3x, multi-scale training` | 640x640 | 640x640 | 41.0% | 60.345 |
| +`auto augment` | 640x640 | 640x640 | 41.4% | 60.345 |
| +`libra sampling` | 640x640 | 640x640 | 41.6% | 60.345 |
基于该实验结论,我们结合Cascade RCNN,使用更大的训练与评估尺度(1000x1500),最终在单卡V100上速度为20FPS,COCO mAP达47.8%。下图给出了目前类似速度的目标检测方法的速度与精度指标。
![pssdet](../../images/det/pssdet.png)
**注意**
> 这里为了更方便地对比,我们将V100的预测耗时乘以1.2倍,近似转化为Titan V的预测耗时。
更加详细的代码、配置与预训练模型的地址可以参考[PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/master/configs/rcnn_server_side_det)
## 移动端实用目标检测方案
* 目前正在更新中,敬请期待!
\ No newline at end of file
# 商品识别
商品识别技术,是现如今应用非常广的一个领域。拍照购物的方式已经被很多人所采纳,无人结算台已经走入各大超市,无人超市更是如火如荼,这背后都是以商品识别技术作为支撑。商品识别技术大概是"商品检测+商品识别"这样的流程,商品检测模块负责检测出潜在的商品区域,商品识别模型负责将商品检测模块检测出的主体进行识别。识别模块多采用检索的方式,根据查询图片和底库图片进行相似度排序获得预测类别。此文档主要对商品图片的特征提取部分进行相关介绍。
## 1 算法介绍
算法整体流程,详见[特征学习](./feature_learning.md)整体流程。
整体设置详见: [ResNet50_vd_Aliproduct.yaml](../../../ppcls/configs/Products/ResNet50_vd_Aliproduct.yaml)
具体细节如下所示。
### 1.1数据增强
- 图像`RandomCrop`到224x224
- 图像`RandomFlip`
- Normlize:图像归一化
### 1.2 Backbone的具体设置
具体是用`ResNet50_vd`作为backbone,使用ImageNet预训练模型
### 1.3 Neck部分
加入一个512维的embedding FC层,没有做BatchNorm和激活。
### 1.4 Metric Learning相关Loss的设置
目前使用了[CELoss](../../../ppcls/loss/celoss.py)训练, 为了获得更加鲁棒的特征,后续会使用其他Loss参与训练,敬请期待。
## 2 实验结果
<img src="../../images/product/aliproduct.png" style="zoom:50%;" />
此方案在Aliproduct[1]数据集上进行实验。此数据集是天池竞赛开源的一个数据集,也是目前开源的最大的商品数据集,其有5万多个标识类别,约250万训练图片。
在此数据上,单模型Top 1 Acc:85.67%。
## 3 参考文献
[1] Weakly Supervised Learning with Side Information for Noisy Labeled Images. ECCV, 2020.
# 图像分类迁移学习
迁移学习是机器学习领域的一个重要分支,广泛应用于文本、图像等各种领域,此处我们主要介绍的是图像分类领域的迁移学习,也就是我们常说的域迁移,比如将 ImageNet 分类模型迁移到我们自己场景的图像分类任务上,如花卉分类。
## 一、 超参搜索
ImageNet 作为业界常用的图像分类数据被大家广泛使用,已经总结出一系列经验性的超参,使用这些超参往往能够得到不错的训练精度,而这些经验性的参数在迁移到自己的业务中时,有时效果不佳。有两种常用的超参搜索方法可以用于获得更好的模型超参。
### 1.1 网格搜索
网格搜索,即穷举搜索,通过查找搜索空间内所有的点,确定最优值。方法简单有效,但当搜索空间较大时,需要消耗大量的计算资源。
### 1.2 贝叶斯搜索
贝叶斯搜索,即贝叶斯优化,在搜索空间中随机选取超参数点,采用高斯过程,即根据上一个超参数点的结果,更新当前的先验信息,计算前面n个超参数点的后验概率分布,得到搜索空间中每一个超参数点的期望均值和方差,其中期望均值越大表示接近最优指标的可能性越大,方差越大表示不确定性越大。通常将选择期望均值大的超参数点称为`exporitation`,选择方差大的超参数点称为`exploration`。在贝叶斯优化中通过定义`acquisition function`权衡期望均值和方差。贝叶斯搜索认为当前选择的超参数点是处于最大值可能出现的位置。
------
基于上述两种搜索方案,我们在8个开源数据集上将固定一组参数实验以及两种搜索方案做了对比实验,参照[1]的实验方案,我们对4个超参数进行搜索,搜索空间及实验结果如下所示:
- 固定参数:
```
初始学习率lr=0.003,l2 decay=1e-4,label smoothing=False,mixup=False
```
- 超参搜索空间:
```
初始学习率lr: [0.1, 0.03, 0.01, 0.003, 0.001, 0.0003, 0.0001]
L2 decay: [1e-3, 3e-4, 1e-4, 3e-5, 1e-5, 3e-6, 1e-6]
Label smoothing: [False, True]
Mixup: [False, True]
```
网格搜索的搜索次数为196次,而贝叶斯搜索通过设置最大迭代次数(`max_iter`)和是否重复搜索(`de_duplication`)来确定搜索次数。我们设计了系列实验,baseline为ImageNet1k校验集Top1 Acc为79.12%的ResNet50_vd预训练模型,并固定超参,在新数据集上finetune得到的模型。下表给出了固定参数、网格搜索以及贝叶斯搜索的精度与搜索次数对比。
- 精度与搜索次数对比:
| 数据集 | 固定参数 | 网格搜索 | 网格搜索次数 | 贝叶斯搜索 | 贝叶斯搜索次数|
| ------------------ | -------- | -------- | -------- | -------- | ---------- |
| Oxford-IIIT-Pets | 93.64% | 94.55% | 196 | 94.04% | 20 |
| Oxford-102-Flowers | 96.08% | 97.69% | 196 | 97.49% | 20 |
| Food101 | 87.07% | 87.52% | 196 | 87.33% | 23 |
| SUN397 | 63.27% | 64.84% | 196 | 64.55% | 20 |
| Caltech101 | 91.71% | 92.54% | 196 | 92.16% | 14 |
| DTD | 76.87% | 77.53% | 196 | 77.47% | 13 |
| Stanford Cars | 85.14% | 92.72% | 196 | 92.72% | 25 |
| FGVC Aircraft | 80.32% | 88.45% | 196 | 88.36% | 20 |
- 上述实验验证了贝叶斯搜索相比网格搜索,在减少搜索次数10倍左右条件下,精度只下降0%~0.4%。
- 当搜索空间进一步扩大时,例如将是否进行AutoAugment,RandAugment,Cutout, Cutmix以及Dropout这些正则化策略作为选择时,贝叶斯搜索能够在获取较优精度的前提下,有效地降低搜索次数。
## 二、 大规模分类模型
在实际应用中,由于训练数据的匮乏,往往将ImageNet1k数据集训练的分类模型作为预训练模型,进行图像分类的迁移学习。为了进一步助力解决实际问题,基于ResNet50_vd, 百度开源了自研的大规模分类预训练模型,其中训练数据为10万个类别,4300万张图片。10万类预训练模型的下载地址:[**下载地址**](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet50_vd_10w_pretrained.pdparams)
我们在6个自有采集的数据集上进行迁移学习实验,采用一组固定参数以及网格搜索方式,其中训练轮数设置为20epochs,选用ResNet50_vd模型,ImageNet预训练精度为79.12%。实验数据集参数以及模型精度的对比结果如下:
固定参数:
```
初始学习率lr=0.001,l2 decay=1e-4,label smoothing=False,mixup=False
```
| 数据集 | 数据统计 | **ImageNet预训练模型 <br />固定参数Top-1/参数搜索Top-1** | **大规模分类预训练模型<br />固定参数Top-1/参数搜索Top-1** |
| --------------- | ----------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------- |
| 花卉 | class:102<br />train:5789<br />valid:2396 | 0.7779/0.9883 | 0.9892/0.9954 |
| 手绘简笔画 | Class:18<br />train:1007<br />valid:432 | 0.8795/0.9196 | 0.9107/0.9219 |
| 植物叶子 | class:6<br />train:5256<br />valid:2278 | 0.8212/0.8482 | 0.8385/0.8659 |
| 集装箱车辆 | Class:115<br />train:4879<br />valid:2094 | 0.6230/0.9556 | 0.9524/0.9702 |
| 椅子 | class:5<br />train:169<br />valid:78 | 0.8557/0.9688 | 0.9077/0.9792 |
| 地质 | class:4<br />train:671<br />valid:296 | 0.5719/0.8094 | 0.6781/0.8219 |
- 通过上述的实验验证了当使用一组固定参数时,相比于ImageNet预训练模型,使用大规模分类模型作为预训练模型在大多数情况下能够提升模型在新的数据集上得效果,通过参数搜索可以进一步提升精度。
## 参考文献
[1] Kornblith, Simon, Jonathon Shlens, and Quoc V. Le. "Do better imagenet models transfer better?." *Proceedings of the IEEE conference on computer vision and pattern recognition*. 2019.
[2] Kolesnikov, Alexander, et al. "Large Scale Learning of General Visual Representations for Transfer." *arXiv preprint arXiv:1912.11370* (2019).
# 车辆识别
此部分主要包含两部分:车辆细粒度分类、车辆ReID。
细粒度分类,是对属于某一类基础类别的图像进行子类别的细粉,如各种鸟、各种花、各种矿石之间。顾名思义,车辆细粒度分类是对车辆的不同子类别进行分类。
ReID,也就是 Re-identification,其定义是利用算法,在图像库中找到要搜索的目标的技术,所以它是属于图像检索的一个子问题。而车辆ReID就是给定一张车辆图像,找出同一摄像头不同的拍摄图像,或者不同摄像头下拍摄的同一车辆图像的过程。在此过程中,如何提取鲁棒特征,尤为重要。
此文档中,使用同一套训练方案对两个细方向分别做了尝试。
## 1 算法介绍
算法整体流程,详见[特征学习](./feature_learning.md)整体流程。
车辆ReID整体设置详见: [ResNet50_ReID.yaml](../../../ppcls/configs/Vehicle/ResNet50_ReID.yaml)
车辆细分类整体设置详见:[ResNet50.yaml](../../../ppcls/configs/Vehicle/ResNet50.yaml)
具体细节如下所示。
### 1.1数据增强
与普通训练分类不同,此部分主要使用如下图像增强方式:
- 图像`Resize`到224。尤其对于ReID而言,车辆图像已经是由检测器检测后crop出的车辆图像,因此若再使用crop图像增强,会丢失更多的车辆信息
- [AugMix](https://arxiv.org/abs/1912.02781v1):模拟光照变化、摄像头位置变化等实际场景
- [RandomErasing](https://arxiv.org/pdf/1708.04896v2.pdf):模拟遮挡等实际情况
### 1.2 Backbone的具体设置
使用`ResNet50`作为backbone,同时做了如下修改:
- last stage stride=1, 保持最后输出特征图尺寸14x14。计算量增加较小,但显著提高模型特征提取能力
具体代码:[ResNet50_last_stage_stride1](../../../ppcls/arch/backbone/variant_models/resnet_variant.py)
### 1.3 Neck部分
为了降低inferecne时计算特征距离的复杂度,添加一个embedding 卷积层,特征维度为512。
### 1.4 Metric Learning相关Loss的设置
车辆ReID及细粒度分类中,使用了[SupConLoss](../../../ppcls/loss/supconloss.py) + [ArcLoss](../../../ppcls/arch/gears/arcmargin.py),其中权重比例为1:1
## 2 实验结果
### 2.1 车辆ReID
<img src="../../images/recognition/vehicle/cars.JPG" style="zoom:50%;" />
此方法在VERI-Wild数据集上进行了实验。此数据集是在一个大型闭路电视监控系统,在无约束的场景下,一个月内(30*24小时)中捕获的。该系统由174个摄像头组成,其摄像机分布在200多平方公里的大型区域。原始车辆图像集包含1200万个车辆图像,经过数据清理和标注,采集了416314张40671个不同的车辆图像。[具体详见论文](https://github.com/PKU-IMRE/VERI-Wild)
| **Methods** | **Small** | | |
| :--------------------------: | :-------: | :-------: | :-------: |
| | mAP | Top1 | Top5 |
| Strong baesline(Resnet50)[1] | 76.61 | 90.83 | 97.29 |
| HPGN(Resnet50+PGN)[2] | 80.42 | 91.37 | - |
| GLAMOR(Resnet50+PGN)[3] | 77.15 | 92.13 | 97.43 |
| PVEN(Resnet50)[4] | 79.8 | 94.01 | 98.06 |
| SAVER(VAE+Resnet50)[5] | 80.9 | 93.78 | 97.93 |
| PaddleClas baseline | 80.57 | **93.81** | **98.06** |
### 2.2 车辆细分类
车辆细分类中,使用[CompCars](http://mmlab.ie.cuhk.edu.hk/datasets/comp_cars/index.html)作为训练数据集。
![](../../images/recognition/vehicle/CompCars.png)
数据集中图像主要来自网络和监控数据,其中网络数据包含163个汽车制造商、1716个汽车型号的汽车。共**136,726**张全车图像,**27,618**张部分车图像。其中网络汽车数据包含bounding box、视角、5个属性(最大速度、排量、车门数、车座数、汽车类型)。监控数据包含**50,000**张前视角图像。
值得注意的是,此数据集中需要根据自己的需要生成不同的label,如本demo中,将不同年份生产的相同型号的车辆视为同一类,因此,类别总数为:431类。
| **Methods** | Top1 Acc |
| :-----------------------------: | :--------: |
| ResNet101-swp[6] | 97.6% |
| Fine-Tuning DARTS[7] | 95.9% |
| Resnet50 + COOC[8] | 95.6% |
| A3M[9] | 95.4% |
| PaddleClas baseline (ResNet50) | **97.37**% |
## 3 参考文献
[1] Bag of Tricks and a Strong Baseline for Deep Person Re-Identification.CVPR workshop 2019.
[2] Exploring Spatial Significance via Hybrid Pyramidal Graph Network for Vehicle Re-identification. In arXiv preprint arXiv:2005.14684
[3] GLAMORous: Vehicle Re-Id in Heterogeneous Cameras Networks with Global and Local Attention. In arXiv preprint arXiv:2002.02256
[4] Parsing-based view-aware embedding network for vehicle re-identification. CVPR 2020.
[5] The Devil is in the Details: Self-Supervised Attention for Vehicle Re-Identification. In ECCV 2020.
[6] Deep CNNs With Spatially Weighted Pooling for Fine-Grained Car Recognition. IEEE Transactions on Intelligent Transportation Systems, 2017.
[7] Fine-Tuning DARTS for Image Classification. 2020.
[8] Fine-Grained Vehicle Classification with Unsupervised Parts Co-occurrence Learning. 2018
[9] Attribute-Aware Attention Model for Fine-grained Representation Learning. 2019.
### 赛事支持
PaddleClas的建设源于百度实际视觉业务应用的淬炼和视觉前沿能力的探索,助力多个视觉重点赛事取得领先成绩,并且持续推进更多的前沿视觉问题的解决和落地应用。
* 2018年Kaggle Open Images V4图像目标检测挑战赛冠军
* 2019年Kaggle Open Images V5图像目标检测挑战赛亚军
* 技术报告可以参考:[https://arxiv.org/pdf/1911.07171.pdf](https://arxiv.org/pdf/1911.07171.pdf)
* 详细文档与开源的模型可以参考:[OIDV5目标检测github地址](https://github.com/PaddlePaddle/PaddleDetection/blob/master/docs/featured_model/OIDV5_BASELINE_MODEL.md)
* 2019年Kaggle地标检索挑战赛亚军
* 技术报告可以参考:[https://arxiv.org/abs/1906.03990](https://arxiv.org/abs/1906.03990)
* 详细文档与开源的模型可以参考:[2019地标检索和识别github地址](https://github.com/PaddlePaddle/Research/tree/master/CV/landmark)
* 2019年Kaggle地标识别挑战赛亚军
* 技术报告可以参考:[https://arxiv.org/abs/1906.03990](https://arxiv.org/abs/1906.03990)
* 详细文档与开源的模型可以参考:[2019地标检索和识别github地址](https://github.com/PaddlePaddle/Research/tree/master/CV/landmark)
* 首届多媒体信息识别技术竞赛中印刷文本OCR、人脸识别和地标识别三项任务A级证书
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import recommonmark
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Project information -----------------------------------------------------
project = 'PaddleClas'
copyright = '2020, paddlepaddle'
author = 'paddlepaddle'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.mathjax',
'sphinx.ext.githubpages',
'sphinx.ext.napoleon',
'recommonmark',
'sphinx_markdown_tables',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# md file can also be parased
source_suffix = ['.rst', '.md']
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'zh_CN'
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd: # only import and set the theme if we're building docs locally
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# otherwise, readthedocs.org uses their theme by default, so no need to specify it
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_logo = '../images/logo.png'
# 使用VisualDL可视化训练过程
## 前言
VisualDL是飞桨可视化分析工具,以丰富的图表呈现训练参数变化趋势、模型结构、数据样本、高维数据分布等。可帮助用户更清晰直观地理解深度学习模型训练过程及模型结构,进而实现高效的模型优化。更多细节请查看[VisualDL](https://github.com/PaddlePaddle/VisualDL/)
## 在PaddleClas中使用VisualDL
现在PaddleClas支持在训练阶段使用VisualDL查看训练过程中学习率(learning rate)、损失值(loss)以及准确率(accuracy)的变化情况。
### 设置config文件并启动训练
在PaddleClas中使用VisualDL,只需在训练配置文件(config文件)中设置字段 `Global.use_visualdl``True`
```yaml
# config.yaml
Global:
...
use_visualdl: True
...
```
PaddleClas 会将 VisualDL 的日志保存在 `Global.output_dir` 字段指定目录下的 `vdl/` 子目录下,然后正常启动训练即可:
```shell
python3 tools/train.py -c config.yaml
```
### 启动VisualDL
在启动训练程序后,可以在新的终端session中启动VisualDL服务:
```shell
visualdl --logdir ./output/vdl/
```
上述命令中,参数`--logdir`用于指定保存 VisualDL 日志的目录,VisualDL将遍历并且迭代寻找指定目录的子目录,将所有实验结果进行可视化。也同样可以使用下述参数设定VisualDL服务的ip及端口号:
* `--host`:设定IP,默认为127.0.0.1
* `--port`:设定端口,默认为8040
更多参数信息,请查看[VisualDL](https://github.com/PaddlePaddle/VisualDL/blob/develop/README_CN.md#2-%E5%90%AF%E5%8A%A8%E9%9D%A2%E6%9D%BF)
在启动VisualDL后,即可在浏览器中查看训练过程,输入地址`127.0.0.1:8840`
<div align="center">
<img src="../../images/VisualDL/train_loss.png" width="400">
</div>
# 代码结构概览
* 正在持续更新中!!!
实用工具
================================
.. toctree::
:maxdepth: 1
paddle_inference.md
paddle_mobile_inference.md
paddle_quantization.md
multi_machine_training.md
paddle_hub.md
paddle_serving.md
# 多机训练
分布式训练的高性能,是飞桨的核心优势技术之一,在分类任务上,分布式训练可以达到几乎线性的加速比。
[Fleet](https://github.com/PaddlePaddle/Fleet) 是用于 PaddlePaddle 分布式训练的高层 API,基于这套接口用户可以很容易切换到分布式训练程序。
为了可以同时支持单机训练和多机训练,[PaddleClas](https://github.com/PaddlePaddle/PaddleClas) 采用 Fleet API 接口,更多的分布式训练可以参考 [Fleet API设计文档](https://github.com/PaddlePaddle/Fleet/blob/develop/README.md)
# Paddle Hub
[PaddleHub](https://github.com/PaddlePaddle/PaddleHub) 是飞桨生态的预训练模型应用工具,开发者可以便捷地使用高质量的预训练模型结合 Fine-tune API 快速完成模型迁移到部署的全流程工作。
PaddleHub 收录了 [PaddleClas](https://github.com/PaddlePaddle/PaddleClas) 的所有预训练模型,更多使用细节请查看 [PaddleHub官网](https://www.paddlepaddle.org.cn/hub)
# Paddle-Lite
## 一、简介
[Paddle-Lite](https://github.com/PaddlePaddle/Paddle-Lite) 是飞桨推出的一套功能完善、易用性强且性能卓越的轻量化推理引擎。
轻量化体现在使用较少比特数用于表示神经网络的权重和激活,能够大大降低模型的体积,解决终端设备存储空间有限的问题,推理性能也整体优于其他框架。
[PaddleClas](https://github.com/PaddlePaddle/PaddleClas) 使用 Paddle-Lite 进行了[移动端模型的性能评估](../models/Mobile.md),本部分以`ImageNet1k`数据集的`MobileNetV1`模型为例,介绍怎样使用`Paddle-Lite`,在移动端(基于骁龙855的安卓开发平台)对进行模型速度评估。
## 二、评估步骤
### 2.1 导出inference模型
* 首先需要将训练过程中保存的模型存储为用于预测部署的固化模型,可以使用`tools/export_model.py`导出inference模型,具体使用方法如下。
```shell
python tools/export_model.py -m MobileNetV1 -p pretrained/MobileNetV1_pretrained/ -o inference/MobileNetV1
```
最终在`inference/MobileNetV1`文件夹下会保存得到`model``parmas`文件。
### 2.2 benchmark二进制文件下载
* 使用adb(Android Debug Bridge)工具可以连接Android手机与PC端,并进行开发调试等。安装好adb,并确保PC端和手机连接成功后,使用以下命令可以查看手机的ARM版本,并基于此选择合适的预编译库。
```shell
adb shell getprop ro.product.cpu.abi
```
* 下载benchmark_bin文件
```shell
wget -c https://paddle-inference-dist.bj.bcebos.com/PaddleLite/benchmark_0/benchmark_bin_v8
```
如果查看的ARM版本为v7,则需要下载v7版本的benchmark_bin文件,下载命令如下。
```shell
wget -c https://paddle-inference-dist.bj.bcebos.com/PaddleLite/benchmark_0/benchmark_bin_v7
```
### 2.3 模型速度benchmark
PC端和手机连接成功后,使用下面的命令开始模型评估。
```
sh deploy/lite/benchmark/benchmark.sh ./benchmark_bin_v8 ./inference result_armv8.txt true
```
其中`./benchmark_bin_v8`为benchmark二进制文件路径,`./inference`为所有需要评测的模型的路径,`result_armv8.txt`为保存的结果文件,最后的参数`true`表示在评估之后会首先进行模型优化。最终在当前文件夹下会输出`result_armv8.txt`的评估结果文件,具体信息如下。
```
PaddleLite Benchmark
Threads=1 Warmup=10 Repeats=30
MobileNetV1 min = 30.89100 max = 30.73600 average = 30.79750
Threads=2 Warmup=10 Repeats=30
MobileNetV1 min = 18.26600 max = 18.14000 average = 18.21637
Threads=4 Warmup=10 Repeats=30
MobileNetV1 min = 10.03200 max = 9.94300 average = 9.97627
```
这里给出了不同线程数下的模型预测速度,单位为FPS,以线程数为1为例,MobileNetV1在骁龙855上的平均速度为`30.79750FPS`
### 2.4 模型优化与速度评估
* 在2.3节中提到了在模型评估之前对其进行优化,在这里也可以首先对模型进行优化,再直接加载优化后的模型进行速度评估。
* Paddle-Lite 提供了多种策略来自动优化原始的训练模型,其中包括量化、子图融合、混合调度、Kernel优选等等方法。为了使优化过程更加方便易用,Paddle-Lite提供了opt 工具来自动完成优化步骤,输出一个轻量的、最优的可执行模型。可以在[Paddle-Lite模型优化工具页面](https://paddle-lite.readthedocs.io/zh/latest/user_guides/model_optimize_tool.html)下载。在这里以`MacOS`开发环境为例,下载[opt_mac](https://paddlelite-data.bj.bcebos.com/model_optimize_tool/opt_mac)模型优化工具,并使用下面的命令对模型进行优化。
```shell
model_file="../MobileNetV1/model"
param_file="../MobileNetV1/params"
opt_models_dir="./opt_models"
mkdir ${opt_models_dir}
./opt_mac --model_file=${model_file} \
--param_file=${param_file} \
--valid_targets=arm \
--optimize_out_type=naive_buffer \
--prefer_int8_kernel=false \
--optimize_out=${opt_models_dir}/MobileNetV1
```
其中`model_file``param_file`分别是导出的inference模型结构文件与参数文件地址,转换成功后,会在`opt_models`文件夹下生成`MobileNetV1.nb`文件。
使用benchmark_bin文件加载优化后的模型进行评估,具体的命令如下。
```shell
bash benchmark.sh ./benchmark_bin_v8 ./opt_models result_armv8.txt
```
最终`result_armv8.txt`中结果如下。
```
PaddleLite Benchmark
Threads=1 Warmup=10 Repeats=30
MobileNetV1_lite min = 30.89500 max = 30.78500 average = 30.84173
Threads=2 Warmup=10 Repeats=30
MobileNetV1_lite min = 18.25300 max = 18.11000 average = 18.18017
Threads=4 Warmup=10 Repeats=30
MobileNetV1_lite min = 10.00600 max = 9.90000 average = 9.96177
```
以线程数为1为例,MobileNetV1在骁龙855上的平均速度为`30.84173FPS`
更加具体的参数解释与Paddle-Lite使用方法可以参考 [Paddle-Lite 文档](https://paddle-lite.readthedocs.io/zh/latest/)
# 模型量化
模型量化是 [PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim) 的特色功能之一,支持动态和静态两种量化训练方式,对权重全局量化和 Channel-Wise 量化,同时以兼容 Paddle-Lite 的格式保存模型。
[PaddleClas](https://github.com/PaddlePaddle/PaddleClas) 使用该量化工具,量化了78.9%的mobilenet_v3_large_x1_0的蒸馏模型, 量化后SD855上预测速度从19.308ms加速到14.395ms,存储大小从21M减小到10M, top1识别准确率75.9%。
具体的训练方法可以参见 [PaddleSlim 量化训练](../../../deploy/slim/quant/README.md)
# 模型服务化部署
## 一、简介
[Paddle Serving](https://github.com/PaddlePaddle/Serving) 旨在帮助深度学习开发者轻易部署在线预测服务,支持一键部署工业级的服务能力、客户端和服务端之间高并发和高效通信、并支持多种编程语言开发客户端。
该部分以HTTP预测服务部署为例,介绍怎样在PaddleClas中使用PaddleServing部署模型服务。
## 二、Serving安装
Serving官网推荐使用docker安装并部署Serving环境。首先需要拉取docker环境并创建基于Serving的docker。
```shell
nvidia-docker pull hub.baidubce.com/paddlepaddle/serving:0.2.0-gpu
nvidia-docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:0.2.0-gpu
nvidia-docker exec -it test bash
```
进入docker后,需要安装Serving相关的python包。
```shell
pip install paddlepaddle-gpu
pip install paddle-serving-client
pip install paddle-serving-server-gpu
```
* 如果安装速度太慢,可以通过`-i https://pypi.tuna.tsinghua.edu.cn/simple`更换源,加速安装过程。
* 如果希望部署CPU服务,可以安装serving-server的cpu版本,安装命令如下。
```shell
pip install paddle-serving-server
```
### 三、导出模型
使用`tools/export_serving_model.py`脚本导出Serving模型,以`ResNet50_vd`为例,使用方法如下。
```shell
python tools/export_serving_model.py -m ResNet50_vd -p ./pretrained/ResNet50_vd_pretrained/ -o serving
```
最终在serving文件夹下会生成`ppcls_client_conf``ppcls_model`两个文件夹,分别存储了client配置、模型参数与结构文件。
### 四、服务部署与请求
* 使用下面的方式启动Serving服务。
```shell
python tools/serving/image_service_gpu.py serving/ppcls_model workdir 9292
```
其中`serving/ppcls_model`为刚才保存的Serving模型地址,`workdir`为为工作目录,`9292`为服务的端口号。
* 使用下面的脚本向Serving服务发送识别请求,并返回结果。
```
python tools/serving/image_http_client.py 9292 ./docs/images/logo.png
```
`9292`为发送请求的端口号,需要与服务启动时的端口号保持一致,`./docs/images/logo.png`为待识别的图像文件。最终返回Top1识别结果的类别ID以及概率值。
* 更多的服务部署类型,如`RPC预测服务`等,可以参考Serving的github官网:[https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imagenet](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imagenet)
# 图像分类昆仑模型介绍(持续更新中)
## 前言
* 本文档介绍了目前昆仑支持的模型以及如何在昆仑设备上训练这些模型。支持昆仑的PaddlePaddle安装参考install_kunlun(https://github.com/PaddlePaddle/FluidDoc/blob/develop/doc/paddle/install/install_Kunlun_zh.md)
## 昆仑训练
* 数据来源和预训练模型参考[quick_start](../tutorials/quick_start_new_user.md)。昆仑训练效果与CPU/GPU对齐。
### ResNet50
* 命令:
```python3.7 tools/static/train.py -c configs/quick_start/ResNet50_vd_finetune_kunlun.yaml -o use_gpu=False -o use_xpu=True -o is_distributed=False```
与cpu/gpu训练的区别是加上-o use_xpu=True, 表示执行在昆仑设备上。
### MobileNetV3
* 命令:
```python3.7 tools/static/train.py -c configs/quick_start/MobileNetV3_large_x1_0_finetune.yaml -o use_gpu=False -o use_xpu=True -o is_distributed=False```
### HRNet
* 命令:
```python3.7 tools/static/train.py -c configs/quick_start/HRNet_W18_C_finetune.yaml -o is_distributed=False -o use_cpu=False -o use_xpu=True -o use_gpu=False```
### VGG16/19
* 命令:
```python3.7 tools/static/train.py -c configs/quick_start/VGG16_finetune_kunlun.yaml -o use_gpu=False -o use_cpu=False -o use_xpu=True -o is_distributed=False```
```python3.7 tools/static/train.py -c configs/quick_start/VGG19_finetune_kunlun.yaml -o use_gpu=False -o use_cpu=False -o use_xpu=True -o is_distributed=False```
# 使用DALI加速训练
## 前言
[NVIDIA数据加载库](https://docs.nvidia.com/deeplearning/dali/user-guide/docs/index.html)(The NVIDIA Data Loading Library,DALI)是用于数据加载和预处理的开源库,用于加速深度学习训练、推理过程,它可以直接构建飞桨Paddle的DataLoader数据读取器。
由于深度学习程序在训练阶段依赖大量数据,这些数据需要经过加载、预处理等操作后,才能送入训练程序,而这些操作通常在CPU完成,因此限制了训练速度进一步提高,特别是在batch_size较大时,数据读取可能成为训练速度的瓶颈。DALI可以基于GPU的高并行特性实现数据加载及预处理操作,可以进一步提高训练速度。
## 安装DALI
目前DALI仅支持Linux x64平台,且CUDA版本大于等于10.2。
* 对于CUDA 10:
pip install --extra-index-url https://developer.download.nvidia.com/compute/redist nvidia-dali-cuda100
* 对于CUDA 11.0:
pip install --extra-index-url https://developer.download.nvidia.com/compute/redist nvidia-dali-cuda110
关于更多DALI安装的信息,可以参考[DALI官方](https://docs.nvidia.com/deeplearning/dali/user-guide/docs/installation.html)
## 使用DALI
PaddleClas支持在静态图训练方式中使用DALI加速,由于DALI仅支持GPU训练,因此需要设置GPU,且DALI需要占用GPU显存,需要为DALI预留显存。使用DALI训练只需在训练配置文件中设置字段`use_dali=True`,或通过以下命令启动训练即可:
```shell
# 设置用于训练的GPU卡号
export CUDA_VISIBLE_DEVICES="0"
# 设置用于神经网络训练的显存大小,可根据具体情况设置,一般可设置为0.8或0.7,剩余显存则预留DALI使用
export FLAGS_fraction_of_gpu_memory_to_use=0.80
python ppcls/static/train.py -c ./ppcls/configs/ImageNet/ResNet/ResNet50.yaml -o use_dali=True
```
也可以使用多卡训练:
```shell
# 设置用于训练的GPU卡号
export CUDA_VISIBLE_DEVICES="0,1,2,3,4,5,6,7"
# 设置用于神经网络训练的显存大小,可根据具体情况设置,一般可设置为0.8或0.7,剩余显存则预留DALI使用
export FLAGS_fraction_of_gpu_memory_to_use=0.80
python -m paddle.distributed.launch \
--gpus="0,1,2,3,4,5,6,7" \
ppcls/static/train.py \
-c ./ppcls/configs/ImageNet/ResNet/ResNet50.yaml \
-o use_dali=True
```
## 使用FP16训练
在上述基础上,使用FP16半精度训练,可以进一步提高速度,可以参考下面的配置与运行命令。
```shell
export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
export FLAGS_fraction_of_gpu_memory_to_use=0.8
python -m paddle.distributed.launch \
--gpus="0,1,2,3,4,5,6,7" \
ppcls/static/train.py \
-c ./ppcls/configs/ImageNet/ResNet/ResNet50_fp16.yaml
```
此差异已折叠。
# 图像分类FAQ(持续更新)
## 前言
* 本文档收集了大家在使用PaddleClas或者学习图像分类时遇到的一些问题,旨在为图像分类任务的开发者提供一些参考,如果问题欢迎帮忙补充和修正,不胜感激。
## 目录
* [【精选】图像分类30个问题及PaddleClas常见使用问题](./faq.md)
* [2020 FAQ第一季](./faq_series/faq_2020_s1.md)(最近更新2020.12.31)
* [2021 FAQ第一季](./faq_series/faq_2021_s1.md)(最近更新2021.02.03)
# 特征图可视化指南
## 一、概述
特征图是输入图片在卷积网络中的特征表达,对特征图的研究可以有利于我们对于模型的理解与设计,所以基于动态图我们使用本工具来可视化特征图。
## 二、准备工作
首先需要选定研究的模型,本文设定ResNet50作为研究模型,将resnet.py从[模型库](../../../ppcls/arch/architecture/)拷贝到当前目录下,并下载预训练模型[预训练模型](../../zh_CN/models/models_intro), 复制resnet50的模型链接,使用下列命令下载并解压预训练模型。
```bash
wget The Link for Pretrained Model
tar -xf Downloaded Pretrained Model
```
以resnet50为例:
```bash
wget https://paddle-imagenet-models-name.bj.bcebos.com/ResNet50_pretrained.tar
tar -xf ResNet50_pretrained.tar
```
## 三、修改模型
找到我们所需要的特征图位置,设置self.fm将其fetch出来,本文以resnet50中的stem层之后的特征图为例。
在fm_vis.py中修改模型的名字。
在ResNet50的__init__函数中定义self.fm
```python
self.fm = None
```
在ResNet50的forward函数中指定特征图
```python
def forward(self, inputs):
y = self.conv(inputs)
self.fm = y
y = self.pool2d_max(y)
for bottleneck_block in self.bottleneck_block_list:
y = bottleneck_block(y)
y = self.avg_pool(y)
y = fluid.layers.reshape(y, shape=[-1, self.pool2d_avg_output])
y = self.out(y)
return y, self.fm
```
执行函数
```bash
python tools/feature_maps_visualization/fm_vis.py -i the image you want to test \
-c channel_num -p pretrained model \
--show whether to show \
--interpolation interpolation method\
--save_path where to save \
--use_gpu whether to use gpu
```
参数说明:
+ `-i`:待预测的图片文件路径,如 `./test.jpeg`
+ `-c`:特征图维度,如 `./resnet50_vd/model`
+ `-p`:权重文件路径,如 `./ResNet50_pretrained/`
+ `--interpolation`: 图像插值方式, 默认值 1
+ `--save_path`:保存路径,如:`./tools/`
+ `--use_gpu`:是否使用 GPU 预测,默认值:True
## 四、结果
* 输入图片:
![](../../../docs/images/feature_maps/feature_visualization_input.jpg)
* 运行下面的特征图可视化脚本
```
python tools/feature_maps_visualization/fm_vis.py \
-i ./docs/images/feature_maps/feature_visualization_input.jpg \
-c 5 \
-p pretrained/ResNet50_pretrained/ \
--show=True \
--interpolation=1 \
--save_path="./output.png" \
--use_gpu=False \
--load_static_weights=True
```
* 输出特征图保存为`output.png`,如下所示。
![](../../../docs/images/feature_maps/feature_visualization_output.jpg)
欢迎使用PaddleClas图像分类库!
================================
.. toctree::
:maxdepth: 1
tutorials/index
models/index
advanced_tutorials/index
application/index
extension/index
competition_support.md
model_zoo.md
update_history.md
faq.md
:math:`PaddlePaddle2020`
# 基于Python预测引擎推理
inference 模型(`paddle.jit.save`保存的模型)
一般是模型训练,把模型结构和模型参数保存在文件中的固化模型,多用于预测部署场景。
训练过程中保存的模型是checkpoints模型,保存的只有模型的参数,多用于恢复训练等。
与checkpoints模型相比,inference 模型会额外保存模型的结构信息,在预测部署、加速推理上性能优越,灵活方便,适合于实际系统集成。
接下来首先介绍如何将训练的模型转换成inference模型,然后依次介绍主体检测模型、特征提取模型在CPU、GPU上的预测方法,
之后介绍主体检测、特征提取、特征检索串联的预测方法,最后介绍图像分类的预测方法。
- [一、训练模型转inference模型](#训练模型转inference模型)
- [1.1 特征提取模型转inference模型](#特征提取模型转inference模型)
- [1.2 分类模型转inference模型](#分类模型转inference模型)
- [二、主体检测模型推理](#主体检测模型推理)
- [三、特征提取模型推理](#特征提取模型推理)
- [四、主体检测、特征提取和向量检索串联](#主体检测、特征提取和向量检索串联)
- [五、图像分类模型推理](#图像分类模型推理)
<a name="训练模型转inference模型"></a>
## 一、训练模型转inference模型
<a name="特征提取模型转inference模型"></a>
### 1.1 特征提取模型转inference模型
以下命令请在PaddleClas的根目录执行。以商品识别特征提取模型模型为例,首先下载预训练模型:
```shell script
wget -P ./product_pretrain/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/product_ResNet50_vd_Aliproduct_v1.0_pretrained.pdparams
```
上述模型是ResNet50_vd在AliProduct上训练的模型,训练使用的配置文件为ppcls/configs/Products/ResNet50_vd_Aliproduct.yaml
将训练好的模型转换成inference模型只需要运行如下命令:
``` shell script
# -c 后面设置训练算法的yml配置文件
# -o 配置可选参数
# Global.pretrained_model 参数设置待转换的训练模型地址,不用添加文件后缀 .pdmodel,.pdopt或.pdparams。
# Global.save_inference_dir参数设置转换的模型将保存的地址。
python3.7 tools/export_model.py -c ppcls/configs/Products/ResNet50_vd_Aliproduct.yaml -o Global.pretrained_model=./product_pretrain/product_ResNet50_vd_Aliproduct_v1.0_pretrained -o Global.save_inference_dir=./deploy/models/product_ResNet50_vd_aliproduct_v1.0_infer
```
这里也可以使用自己训练的模型。转inference模型时,使用的配置文件和训练时使用的配置文件相同。另外,还需要设置配置文件中的`Global.pretrained_model`参数,其指向训练中保存的模型参数文件。
转换成功后,在模型保存目录下有三个文件:
```
├── product_ResNet50_vd_aliproduct_v1.0_infer
│ ├── inference.pdiparams # 识别inference模型的参数文件
│ ├── inference.pdiparams.info # 识别inference模型的参数信息,可忽略
│ └── inference.pdmodel # 识别inference模型的program文件
```
<a name="分类模型转inference模型"></a>
### 1.2 分类模型转inference模型
下载预训练模型:
``` shell script
wget -P ./cls_pretrain/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/ResNet50_vd_pretrained.pdparams
```
上述模型是使用ResNet50_vd在ImageNet上训练的模型,使用的配置文件为`ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml`
转inference模型与特征提取模型的方式相同,如下:
```
# -c 后面设置训练算法的yml配置文件
# -o 配置可选参数
# Global.pretrained_model 参数设置待转换的训练模型地址,不用添加文件后缀 .pdmodel,.pdopt或.pdparams。
# Global.save_inference_dir参数设置转换的模型将保存的地址。
python3.7 tools/export_model.py -c ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml -o Global.pretrained_model=./cls_pretrain/ResNet50_vd_pretrained -o Global.save_inference_dir=./deploy/models/class_ResNet50_vd_ImageNet_infer
```
转换成功后,在目录下有三个文件:
```
├── class_ResNet50_vd_ImageNet_infer
│ ├── inference.pdiparams # 识别inference模型的参数文件
│ ├── inference.pdiparams.info # 识别inference模型的参数信息,可忽略
│ └── inference.pdmodel # 识别inference模型的program文件
```
<a name="主体检测模型推理"></a>
## 二、主体检测模型推理
下面介绍主体检测模型推理,以下命令请进入PaddleClas的deploy目录执行:
```shell script
cd deploy
```
使用PaddleClas提供的主体检测Inference模型进行推理,可以执行:
```shell script
mkdir -p models
cd models
# 下载通用检测inference模型并解压
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar && tar -xf ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar
cd ..
# 用下载的inference模型进行预测
python3.7 python/predict_det.py -c configs/inference_det.yaml
```
输入的图像如下所示。
[](../images/recognition/product_demo/wangzai.jpg)
最终输出结果如下:
```text
[{'class_id': 0, 'score': 0.4762245, 'bbox': array([305.55115, 226.05322, 776.61084, 930.42395], dtype=float32), 'label_name': 'foreground'}]
```
检测的可视化结果如下:
[](../images/recognition/product_demo/wangzai_det_result.jpg)
如果想要修改图像,可以在`configs/inference_det.yaml`中,修改infer_imgs的值,或使用-o Global.infer_imgs修改,
例如,要使用`images/anmuxi.jpg`可以运行:
```shell script
python3.7 python/predict_det.py -c configs/inference_det.yaml -o Global.infer_imgs=images/anmuxi.jpg
```
如果想使用CPU进行预测,可以将配置文件中`use_gpu`选项设置为`False`,或者执行命令:
```shell script
python3.7 python/predict_det.py -c configs/inference_det.yaml -o Global.use_gpu=False
```
<a name="特征提取模型推理"></a>
## 三、特征提取模型推理
下面以商品特征提取为例,介绍特征提取模型推理。其他应用可以参考图像识别快速开始中的[模型地址](./tutorials/quick_start_recognition.md#2-%E5%9B%BE%E5%83%8F%E8%AF%86%E5%88%AB%E4%BD%93%E9%AA%8C)
将链接替换为相应模型的链接。以下命令请进入PaddleClas的deploy目录执行:
```shell script
cd deploy
```
使用PaddleClas提供的商品特征提取Inference模型进行推理,可以执行:
```shell script
mkdir -p models
cd models
# 下载商品特征提取inference模型并解压
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/product_ResNet50_vd_aliproduct_v1.0_infer.tar && tar -xf product_ResNet50_vd_aliproduct_v1.0_infer.tar
cd ..
# 用下载的inference模型进行预测
python3.7 python/predict_rec.py -c configs/inference_rec.yaml
```
预测可以得到一个512特征向量,直接在命令行输出显示。
如果想要修改图像,可以在configs/inference_det.yaml中,修改infer_imgs的值,或使用-o Global.infer_imgs修改,
例如,要使用`images/anmuxi.jpg`可以运行:
```shell script
python3.7 python/predict_rec.py -c configs/inference_rec.yaml -o Global.infer_imgs=images/anmuxi.jpg
```
如果想使用CPU进行预测,可以将配置文件中use_gpu选项设置为False,或者执行命令:
```
python3.7 python/predict_rec.py -c configs/inference_rec.yaml -o Global.use_gpu=False
```
<a name="主体检测、特征提取和向量检索串联"></a>
## 四、主体检测、特征提取和向量检索串联
主体检测、特征提取和向量检索的串联预测,可以参考[图像识别快速体验](./tutorials/quick_start_recognition.md)
<a name="图像分类模型推理"></a>
## 五、图像分类模型推理
下面介绍图像分类模型推理,以下命令请进入PaddleClas的deploy目录执行:
```shell script
cd deploy
```
使用PaddleClas提供的商品特征提取Inference模型进行推理,首先请下载预训练模型并导出inference模型,具体参见[2. 分类模型转inference模型](#分类模型转inference模型)
导出inference模型后,可以使用下面的命令预测:
```shell script
python3.7 python/predict_cls.py -c configs/inference_cls.yaml
```
如果想要修改图像,可以在configs/inference_det.yaml中,修改infer_imgs的值,或使用-o Global.infer_imgs修改,
例如,要使用`images/ILSVRC2012_val_00010010.jpeg`可以运行:
```shell script
python3.7 python/predict_cls.py -c configs/inference_cls.yaml -o Global.infer_imgs=images/ILSVRC2012_val_00010010.jpeg
```
如果想使用CPU进行预测,可以将配置文件中use_gpu选项设置为False,或者执行命令:
```
python3.7 python/predict_cls.py -c configs/inference_cls.yaml -o Global.use_gpu=False
```
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
......@@ -2,26 +2,13 @@
## 概述
基于ImageNet1k分类数据集,PaddleClas支持的29种系列分类网络结构以及对应的134个图像分类预训练模型如下所示,训练技巧、每个系列网络结构的简单介绍和性能评估将在相应章节展现。
基于ImageNet1k分类数据集,PaddleClas支持的36种系列分类网络结构以及对应的175个图像分类预训练模型如下所示,训练技巧、每个系列网络结构的简单介绍和性能评估将在相应章节展现。
## 评估环境
* CPU的评估环境基于骁龙855(SD855)。
* GPU评估环境基于V100和TensorRT,评估脚本如下。
* Intel CPU的评估环境基于Intel(R) Xeon(R) Gold 6148。
* GPU评估环境基于V100和TensorRT。
```shell
#!/usr/bin/env bash
export PYTHONPATH=$PWD:$PYTHONPATH
python tools/infer/predict.py \
--model_file='pretrained/infer/model' \
--params_file='pretrained/infer/params' \
--enable_benchmark=True \
--model_name=ResNet50_vd \
--use_tensorrt=True \
--use_fp16=False \
--batch_size=1
```
![](../../images/models/T4_benchmark/t4.fp32.bs4.main_fps_top1.png)
......@@ -34,6 +21,7 @@ python tools/infer/predict.py \
## 预训练模型列表及下载地址
- ResNet及其Vd系列
- ResNet系列<sup>[[1](#ref1)]</sup>([论文地址](http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html))
- [ResNet18](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet18_pretrained.pdparams)
......@@ -52,12 +40,23 @@ python tools/infer/predict.py \
- [ResNet152_vd](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet152_vd_pretrained.pdparams)
- [ResNet200_vd](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet200_vd_pretrained.pdparams)
- [ResNet50_vd_ssld](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet50_vd_ssld_pretrained.pdparams)
- [ResNet50_vd_ssld_v2](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet50_vd_ssld_v2_pretrained.pdparams)
- [Fix_ResNet50_vd_ssld_v2](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/Fix_ResNet50_vd_ssld_v2_pretrained.pdparams)
- [ResNet101_vd_ssld](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet101_vd_ssld_pretrained.pdparams)
- 移动端系列
- 轻量级模型系列
- PP-LCNet系列<sup>[[28](#28)]</sup>([论文地址](https://arxiv.org/pdf/2109.15099.pdf))
- [PPLCNet_x0_25](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x0_25_pretrained.pdparams)
- [PPLCNet_x0_35](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x0_35_pretrained.pdparams)
- [PPLCNet_x0_5](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x0_5_pretrained.pdparams)
- [PPLCNet_x0_75](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x0_75_pretrained.pdparams)
- [PPLCNet_x1_0](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x1_0_pretrained.pdparams)
- [PPLCNet_x1_5](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x1_5_pretrained.pdparams)
- [PPLCNet_x2_0](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x2_0_pretrained.pdparams)
- [PPLCNet_x2_5](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x2_5_pretrained.pdparams)
- [PPLCNet_x0_5_ssld](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x0_5__ssld_pretrained.pdparams)
- [PPLCNet_x1_0_ssld](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x1_0_ssld_pretrained.pdparams)
- [PPLCNet_x2_5_ssld](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/PPLCNet_x2_5__ssld_pretrained.pdparams)
- MobileNetV3系列<sup>[[3](#ref3)]</sup>([论文地址](https://arxiv.org/abs/1905.02244))
- [MobileNetV3_large_x0_35](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/MobileNetV3_large_x0_35_pretrained.pdparams)
- [MobileNetV3_large_x0_5](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/MobileNetV3_large_x0_5_pretrained.pdparams)
......@@ -99,7 +98,17 @@ python tools/infer/predict.py \
- [GhostNet_x1_0](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/GhostNet_x1_0_pretrained.pdparams)
- [GhostNet_x1_3](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/GhostNet_x1_3_pretrained.pdparams)
- [GhostNet_x1_3_ssld](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/GhostNet_x1_3_ssld_pretrained.pdparams)
- MixNet系列<sup>[[29](#ref29)]</sup>([论文地址](https://arxiv.org/pdf/1907.09595.pdf))
- [MixNet_S](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/MixNet_S_pretrained.pdparams)
- [MixNet_M](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/MixNet_M_pretrained.pdparams)
- [MixNet_L](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/MixNet_L_pretrained.pdparams)
- ReXNet系列<sup>[[30](#ref30)]</sup>([论文地址](https://arxiv.org/pdf/2007.00992.pdf))
- [ReXNet_1_0](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ReXNet_1_0_pretrained.pdparams)
- [ReXNet_1_3](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ReXNet_1_3_pretrained.pdparams)
- [ReXNet_1_5](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ReXNet_1_5_pretrained.pdparams)
- [ReXNet_2_0](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ReXNet_2_0_pretrained.pdparams)
- [ReXNet_3_0](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ReXNet_3_0_pretrained.pdparams)
- SEResNeXt与Res2Net系列
- ResNeXt系列<sup>[[7](#ref7)]</sup>([论文地址](https://arxiv.org/abs/1611.05431))
......@@ -217,9 +226,38 @@ python tools/infer/predict.py \
- [SwinTransformer_large_patch4_window12_384_22kto1k](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_large_patch4_window12_384_22kto1k_pretrained.pdparams)
- [SwinTransformer_large_patch4_window7_224_22k](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_large_patch4_window7_224_22k_pretrained.pdparams)
- [SwinTransformer_large_patch4_window7_224_22kto1k](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/SwinTransformer_large_patch4_window7_224_22kto1k_pretrained.pdparams)
- ViT系列<sup>[[31](#ref31)]</sup>([论文地址](https://arxiv.org/pdf/2010.11929.pdf))
- [ViT_small_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_small_patch16_224_pretrained.pdparams)
- [ViT_base_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_base_patch16_224_pretrained.pdparams)
- [ViT_base_patch16_384](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_base_patch16_384_pretrained.pdparams)
- [ViT_base_patch32_384](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_base_patch32_384_pretrained.pdparams)
- [ViT_large_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch16_224_pretrained.pdparams)
- [ViT_large_patch16_384](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch16_384_pretrained.pdparams)
- [ViT_large_patch32_384](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch32_384_pretrained.pdparams)
- DeiT系列<sup>[[32](#ref32)]</sup>([论文地址](https://arxiv.org/pdf/2012.12877.pdf))
- [DeiT_tiny_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_tiny_patch16_224_pretrained.pdparams)
- [DeiT_small_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_small_patch16_224_pretrained.pdparams)
- [DeiT_base_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_base_patch16_224_pretrained.pdparams)
- [DeiT_base_patch16_384](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_base_patch16_384_pretrained.pdparams)
- [DeiT_tiny_distilled_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_tiny_distilled_patch16_224_pretrained.pdparams)
- [DeiT_small_distilled_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_small_distilled_patch16_224_pretrained.pdparams)
- [DeiT_base_distilled_patch16_224](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_base_distilled_patch16_224_pretrained.pdparams)
- [DeiT_base_distilled_patch16_384](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_base_distilled_patch16_384_pretrained.pdparams)
- LeViT系列<sup>[[33](#ref33)]</sup>([论文地址](https://arxiv.org/pdf/2104.01136.pdf))
- [LeViT_128S](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/LeViT_128S_pretrained.pdparams)
- [LeViT_128](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/LeViT_128_pretrained.pdparams)
- [LeViT_192](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/LeViT_192_pretrained.pdparams)
- [LeViT_256](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/LeViT_256_pretrained.pdparams)
- [LeViT_384](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/LeViT_384_pretrained.pdparams)
- Twins系列<sup>[[34](#ref43)]</sup>([论文地址](https://arxiv.org/pdf/2104.13840.pdf))
- [pcpvt_small](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/pcpvt_small_pretrained.pdparams)
- [pcpvt_base](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/pcpvt_base_pretrained.pdparams)
- [pcpvt_large](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/pcpvt_large_pretrained.pdparams)
- [alt_gvt_small](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/alt_gvt_small_pretrained.pdparams)
- [alt_gvt_base](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/alt_gvt_base_pretrained.pdparams)
- [alt_gvt_large](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/alt_gvt_large_pretrained.pdparams)
- TNT系列<sup>[[35](#ref35)]</sup>([论文地址](https://arxiv.org/pdf/2103.00112.pdf))
- [TNT_small](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/TNT_small_pretrained.pdparams)
- 其他模型
- AlexNet系列<sup>[[18](#ref18)]</sup>([论文地址](https://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf))
......@@ -234,6 +272,40 @@ python tools/infer/predict.py \
- [VGG19](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/VGG19_pretrained.pdparams)
- DarkNet系列<sup>[[21](#ref21)]</sup>([论文地址](https://arxiv.org/abs/1506.02640))
- [DarkNet53](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DarkNet53_pretrained.pdparams)
- RepVGG系列<sup>[[36](#ref36)]</sup>([论文地址](https://arxiv.org/pdf/2101.03697.pdf))
- [RepVGG_A0](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_A0_pretrained.pdparams)
- [RepVGG_A1](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_A1_pretrained.pdparams)
- [RepVGG_A2](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_A2_pretrained.pdparams)
- [RepVGG_B0](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_B0_pretrained.pdparams)
- [RepVGG_B1s](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_B1_pretrained.pdparams)
- [RepVGG_B2](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_B2_pretrained.pdparams)
- [RepVGG_B1g2](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_B1g2_pretrained.pdparams)
- [RepVGG_B1g4](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_B1g4_pretrained.pdparams)
- [RepVGG_B2g4](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_B2g4_pretrained.pdparams)
- [RepVGG_B3g4](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RepVGG_B3g4_pretrained.pdparams)
- HarDNet系列<sup>[[37](#ref37)]</sup>([论文地址](https://arxiv.org/pdf/1909.00948.pdf))
- [HarDNet39_ds](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/HarDNet39_ds_pretrained.pdparams)
- [HarDNet68_ds](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/HarDNet68_ds_pretrained.pdparams)
- [HarDNet68](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/HarDNet68_pretrained.pdparams)
- [HarDNet85](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/HarDNet85_pretrained.pdparams)
- DLA系列<sup>[[38](#ref38)]</sup>([论文地址](https://arxiv.org/pdf/1707.06484.pdf))
- [DLA102](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA102_pretrained.pdparams)
- [DLA102x2](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA102x2_pretrained.pdparams)
- [DLA102x](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA102x_pretrained.pdparams)
- [DLA169](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA169_pretrained.pdparams)
- [DLA34](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA34_pretrained.pdparams)
- [DLA46_c](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA46_c_pretrained.pdparams)
- [DLA60](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA60_pretrained.pdparams)
- [DLA60x_c](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA60x_c_pretrained.pdparams)
- [DLA60x](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DLA60x_pretrained.pdparams)
- RedNet系列<sup>[[39](#ref39)]</sup>([论文地址](https://arxiv.org/pdf/2103.06255.pdf))
- [RedNet26](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RedNet26_pretrained.pdparams)
- [RedNet38](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RedNet38_pretrained.pdparams)
- [RedNet50](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RedNet50_pretrained.pdparams)
- [RedNet101](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RedNet101_pretrained.pdparams)
- [RedNet152](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/RedNet152_pretrained.pdparams)
**注意**:以上模型中EfficientNetB1-B7的预训练模型转自[pytorch版EfficientNet](https://github.com/lukemelas/EfficientNet-PyTorch),ResNeXt101_wsl系列预训练模型转自[官方repo](https://github.com/facebookresearch/WSL-Images),剩余预训练模型均基于飞桨训练得到的,并在configs里给出了相应的训练超参数。
......@@ -297,3 +369,28 @@ python tools/infer/predict.py \
<a name="ref26">[26]</a> C.Szegedy, V.Vanhoucke, S.Ioffe, J.Shlens, and Z.Wojna. Rethinking the inception architecture for computer vision. arXiv preprint arXiv:1512.00567, 2015.
<a name="ref27">[27]</a> Ze Liu, Yutong Lin, Yue Cao, Han Hu, Yixuan Wei, Zheng Zhang, Stephen Lin and Baining Guo. Swin Transformer: Hierarchical Vision Transformer using Shifted Windows.
<a name="ref28">[28]</a>Cheng Cui, Tingquan Gao, Shengyu Wei, Yuning Du, Ruoyu Guo, Shuilong Dong, Bin Lu, Ying Zhou, Xueying Lv, Qiwen Liu, Xiaoguang Hu, Dianhai Yu, Yanjun Ma. PP-LCNet: A Lightweight CPU Convolutional Neural Network.
<a name="ref29">[29]</a>Mingxing Tan, Quoc V. Le. MixConv: Mixed Depthwise Convolutional Kernels.
<a name="ref30">[30]</a>Dongyoon Han, Sangdoo Yun, Byeongho Heo, YoungJoon Yoo. Rethinking Channel Dimensions for Efficient Model Design.
<a name="ref31">[31]</a>Alexey Dosovitskiy, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani, Matthias Minderer, Georg Heigold, Sylvain Gelly, Jakob Uszkoreit, Neil Houlsby. AN IMAGE IS WORTH 16X16 WORDS:
TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE.
<a name="ref32">[32]</a>Hugo Touvron, Matthieu Cord, Matthijs Douze, Francisco Massa, Alexandre Sablayrolles, Herve Jegou. Training data-efficient image transformers & distillation through attention.
<a name="ref33">[33]</a>Benjamin Graham, Alaaeldin El-Nouby, Hugo Touvron, Pierre Stock, Armand Joulin, Herve Jegou, Matthijs Douze. LeViT: a Vision Transformer in ConvNet’s Clothing for Faster Inference.
<a name="ref34">[34]</a>Xiangxiang Chu, Zhi Tian, Yuqing Wang, Bo Zhang, Haibing Ren, Xiaolin Wei, Huaxia Xia, Chunhua Shen. Twins: Revisiting the Design of Spatial Attention in Vision Transformers.
<a name="ref35">[35]</a>Kai Han, An Xiao, Enhua Wu, Jianyuan Guo, Chunjing Xu, Yunhe Wang. Transformer in Transformer.
<a name="ref36">[36]</a>Xiaohan Ding, Xiangyu Zhang, Ningning Ma, Jungong Han, Guiguang Ding, Jian Sun. RepVGG: Making VGG-style ConvNets Great Again.
<a name="ref37">[37]</a>Ping Chao, Chao-Yang Kao, Yu-Shan Ruan, Chien-Hsiang Huang, Youn-Long Lin. HarDNet: A Low Memory Traffic Network.
<a name="ref38">[38]</a>Fisher Yu, Dequan Wang, Evan Shelhamer, Trevor Darrell. Deep Layer Aggregation.
<a name="ref39">[39]</a>Duo Lim Jie Hu, Changhu Wang, Xiangtai Li, Qi She, Lei Zhu, Tong Zhang, Qifeng Chen. Involution: Inverting the Inherence of Convolution for Visual Recognition.
\ No newline at end of file
## 识别效果展示
- 商品识别
<div align="center">
<img src="../images/recognition/more_demo_images/output_product/channelhandle_5.jpg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_product/cliniqueblush_1.jpg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_product/daoxiangcunjinzhubing_10.jpg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_product/gannidress_10.jpg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_product/gbyingerche_15.jpg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_product/lafiolewine_03.jpg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_product/taochunqiu_8.jpg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_product/weiduomeinaiyougege_10.jpg" width = "400" />
</div>
- 动漫人物识别
<div align="center">
<img src="../images/recognition/more_demo_images/output_cartoon/labixiaoxin-005.jpeg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_cartoon/liuchuanfeng-010.jpeg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_cartoon/zhangchulan-007.jpeg" width = "400" />
</div>
- logo识别
<div align="center">
<img src="../images/recognition/more_demo_images/output_logo/cctv_4.jpg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_logo/mangguo_8.jpeg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_logo/zhongshiyou-007.jpg" width = "400" />
</div>
- 车辆识别
<div align="center">
<img src="../images/recognition/more_demo_images/output_vehicle/audia5-115.jpeg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_vehicle/bentian-yage-101.jpeg" width = "400" />
</div>
<div align="center">
<img src="../images/recognition/more_demo_images/output_vehicle/bmw-m340-107.jpeg" width = "400" />
</div>
[更多效果图](https://github.com/PaddlePaddle/PaddleClas/tree/release/2.2/docs/images/recognition/more_demo_images)
# 配置说明
---
## 简介
本文档介绍了PaddleClas配置文件(`ppcls/configs/*.yaml`)中各参数的含义,以便您更快地自定义或修改超参数配置。
## 配置详解
### 1.分类模型
此处以`ResNet50_vd``ImageNet-1k`上的训练配置为例,详解各个参数的意义。[配置路径](../../../ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml)
#### 1.1 全局配置(Global)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| checkpoints | 断点模型路径,用于恢复训练 | null | str |
| pretrained_model | 预训练模型路径 | null | str |
| output_dir | 保存模型路径 | "./output/" | str |
| save_interval | 每隔多少个epoch保存模型 | 1 | int |
| eval_during_train| 是否在训练时进行评估 | True | bool |
| 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" |
**注**`pretrained_model`也可以填写存放预训练模型的http地址。
#### 1.2 结构(Arch)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | 模型结构名字 | ResNet50 | PaddleClas提供的模型结构 |
| class_num | 分类数 | 1000 | int |
| pretrained | 预训练模型 | False | bool, str |
**注**:此处的pretrained可以设置为`True`或者`False`,也可以设置权重的路径。另外当`Global.pretrained_model`也设置相应路径时,此处的`pretrained`失效。
#### 1.3 损失函数(Loss)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| CELoss | 交叉熵损失函数 | —— | —— |
| CELoss.weight | CELoss的在整个Loss中的权重 | 1.0 | float |
| CELoss.epsilon | CELoss中label_smooth的epsilon值 | 0.1 | float,0-1之间 |
#### 1.4 优化器(Optimizer)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | 优化器方法名 | "Momentum" | "RmsProp"等其他优化器 |
| momentum | momentum值 | 0.9 | float |
| lr.name | 学习率下降方式 | "Cosine" | "Linear"、"Piecewise"等其他下降方式 |
| lr.learning_rate | 学习率初始值 | 0.1 | float |
| lr.warmup_epoch | warmup轮数 | 0 | int,如5 |
| regularizer.name | 正则化方法名 | "L2" | ["L1", "L2"] |
| regularizer.coeff | 正则化系数 | 0.00007 | float |
**注**`lr.name`不同时,新增的参数可能也不同,如当`lr.name=Piecewise`时,需要添加如下参数:
```
lr:
name: Piecewise
learning_rate: 0.1
decay_epochs: [30, 60, 90]
values: [0.1, 0.01, 0.001, 0.0001]
```
添加方法及参数请查看[learning_rate.py](../../../ppcls/optimizer/learning_rate.py)
#### 1.5数据读取模块(DataLoader)
##### 1.5.1 dataset
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | 读取数据的类的名字 | ImageNetDataset | VeriWild等其他读取数据类的名字 |
| image_root | 数据集存放的路径 | ./dataset/ILSVRC2012/ | str |
| cls_label_path | 数据集标签list | ./dataset/ILSVRC2012/train_list.txt | str |
| transform_ops | 单张图片的数据预处理 | —— | —— |
| batch_transform_ops | batch图片的数据预处理 | —— | —— |
transform_ops中参数的意义:
| 功能名字 | 参数名字 | 具体含义 |
|:---:|:---:|:---:|
| DecodeImage | to_rgb | 数据转RGB |
| | channel_first | 按CHW排列的图片数据 |
| RandCropImage | size | 随机裁剪 |
| RandFlipImage | | 随机翻转 |
| NormalizeImage | scale | 归一化scale值 |
| | mean | 归一化均值 |
| | std | 归一化方差 |
| | order | 归一化顺序 |
| CropImage | size | 裁剪大小 |
| ResizeImage | resize_short | 按短边调整大小 |
batch_transform_ops中参数的含义:
| 功能名字 | 参数名字 | 具体含义 |
|:---:|:---:|:---:|
| MixupOperator | alpha | Mixup参数值,该值越大增强越强 |
##### 1.5.2 sampler
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | sampler类型 | DistributedBatchSampler | DistributedRandomIdentitySampler等其他Sampler |
| batch_size | 批大小 | 64 | int |
| drop_last | 是否丢掉最后不够batch-size的数据 | False | bool |
| shuffle | 数据是否做shuffle | True | bool |
##### 1.5.3 loader
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| num_workers | 数据读取线程数 | 4 | int |
| use_shared_memory | 是否使用共享内存 | True | bool |
#### 1.6 评估指标(Metric)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| TopkAcc | TopkAcc | [1, 5] | list, int |
#### 1.7 预测(Infer)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| 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 |
**注**:Infer模块的`transforms`的解释参考数据读取模块中的dataset中`transform_ops`的解释。
### 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)。这里只介绍与分类模型有区别的参数。
#### 2.1 结构(Arch)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| name | 模型结构名字 | DistillationModel | —— |
| class_num | 分类数 | 1000 | int |
| freeze_params_list | 冻结参数列表 | [True, False] | list |
| models | 模型列表 | [Teacher, Student] | list |
| Teacher.name | 教师模型的名字 | MobileNetV3_large_x1_0 | PaddleClas中的模型 |
| Teacher.pretrained | 教师模型预训练权重 | True | 布尔值或者预训练权重路径 |
| Teacher.use_ssld | 教师模型预训练权重是否是ssld权重 | True | 布尔值 |
| infer_model_name | 被infer模型的类型 | Student | Teacher |
**注**
1.list在yaml中体现如下:
```
freeze_params_list:
- True
- False
```
2.Student的参数情况类似,不再赘述。
#### 2.2 损失函数(Loss)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| DistillationCELoss | 蒸馏的交叉熵损失函数 | —— | —— |
| 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"] | —— |
#### 2.3 评估指标(Metric)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| DistillationTopkAcc | DistillationTopkAcc | 包含model_key和topk两个参数 | —— |
| DistillationTopkAcc.model_key | 被评估的模型 | "Student" | "Teacher" |
| DistillationTopkAcc.topk | Topk的值 | [1, 5] | list, int |
**注**`DistillationTopkAcc`与普通`TopkAcc`含义相同,只是只用在蒸馏任务中。
### 3. 识别模型
**注**:此处以`ResNet50``LogoDet-3k`上的训练配置为例,详解各个参数的意义。[配置路径](../../../ppcls/configs/Logo/ResNet50_ReID.yaml)。这里只介绍与分类模型有区别的参数。
#### 3.1 结构(Arch)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
| :---------------: | :-----------------------: | :--------: | :----------------------------------------------------------: |
| 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保持一致 |
| Head.class_num | 类别数 | 3000 | int |
| Head.margin | CircleMargin中的margin值 | 0.35 | float |
| Head.scale | CircleMargin中的scale值 | 64 | int |
**注**
1.在PaddleClas中,`Neck`部分是Backbone与embedding层的连接部分,`Head`部分是embedding层与分类层的连接部分。
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.2 评估指标(Metric)
| 参数名字 | 具体含义 | 默认值 | 可选值 |
|:---:|:---:|:---:|:---:|
| Recallk| 召回率 | [1, 5] | list, int |
| mAP| 平均检索精度 | None | None |
# 数据说明
---
## 1.简介
本文档介绍ImageNet1k和flowers102数据准备过程。
## 2.数据集准备
数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注|
:------:|:---------------:|:---------------------:|:-----------:|:-----------:
[flowers102](https://www.robots.ox.ac.uk/~vgg/data/flowers/102/)|1k | 6k | 102 |
[ImageNet1k](http://www.image-net.org/challenges/LSVRC/2012/)|1.2M| 50k | 1000 |
* 数据格式
按照如下结构组织数据,其中`train_list.txt``val_list.txt`的格式形如:
```shell
# 每一行采用"空格"分隔图像路径与标注
# 下面是train_list.txt中的格式样例
train/n01440764/n01440764_10026.JPEG 0
...
# 下面是val_list.txt中的格式样例
val/ILSVRC2012_val_00000001.JPEG 65
...
```
### ImageNet1k
从官方下载数据后,按如下组织数据
```bash
PaddleClas/dataset/ILSVRC2012/
|_ train/
| |_ n01440764
| | |_ n01440764_10026.JPEG
| | |_ ...
| |_ ...
| |
| |_ n15075141
| |_ ...
| |_ n15075141_9993.JPEG
|_ val/
| |_ ILSVRC2012_val_00000001.JPEG
| |_ ...
| |_ ILSVRC2012_val_00050000.JPEG
|_ train_list.txt
|_ val_list.txt
```
### Flowers102
[VGG官方网站](https://www.robots.ox.ac.uk/~vgg/data/flowers/102/)下载后的数据,解压后包括
```shell
jpg/
setid.mat
imagelabels.mat
```
将以上文件放置在PaddleClas/dataset/flowers102/下
通过运行generate_flowers102_list.py生成train_list.txt和val_list.txt
```bash
python generate_flowers102_list.py jpg train > train_list.txt
python generate_flowers102_list.py jpg valid > val_list.txt
```
按照如下结构组织数据:
```bash
PaddleClas/dataset/flowers102/
|_ jpg/
| |_ image_03601.jpg
| |_ ...
| |_ image_02355.jpg
|_ train_list.txt
|_ val_list.txt
```
# 开始使用
---
请参考[安装指南](./install.md)配置运行环境,并根据[快速开始](./quick_start_new_user.md)文档准备flower102数据集,本章节下面所有的实验均以flower102数据集为例。
PaddleClas目前支持的训练/评估环境如下:
```shell
└── CPU/单卡GPU
   ├── Linux
   └── Windows
└── 多卡GPU
└── Linux
```
## 1. 基于CPU/单卡GPU上的训练与评估
在基于CPU/单卡GPU上训练与评估,推荐使用`tools/train.py``tools/eval.py`脚本。关于Linux平台多卡GPU环境下的训练与评估,请参考[2. 基于Linux+GPU的模型训练与评估](#2)
<a name="1.1"></a>
### 1.1 模型训练
准备好配置文件之后,可以使用下面的方式启动训练。
```
python3 tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Arch.pretrained=False \
-o Global.device=gpu
```
其中,`-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)信息:
```
...
[Train][Epoch 3/20][Avg]CELoss: 6.46287, loss: 6.46287
...
[Eval][Epoch 3][Avg]CELoss: 5.94309, loss: 5.94309, top1: 0.01961, top5: 0.07941
...
```
* 如果训练过程中没有使用mixup或者cutmix的数据增广,那么除了上述信息外,日志中也会打印出top-1与top-k(默认为5)的信息:
```
...
[Train][Epoch 3/20][Avg]CELoss: 6.12570, loss: 6.12570, top1: 0.01765, top5: 0.06961
...
[Eval][Epoch 3][Avg]CELoss: 5.40727, loss: 5.40727, top1: 0.07549, top5: 0.20980
...
```
训练期间也可以通过VisualDL实时观察loss变化,详见[VisualDL](../extension/VisualDL.md)
### 1.2 模型微调
根据自己的数据集路径设置好配置文件后,可以通过加载预训练模型的方式进行微调,如下所示。
```
python3 tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Arch.pretrained=True \
-o Global.device=gpu
```
其中`Arch.pretrained`设置为`True`表示加载ImageNet的预训练模型,此外,`Arch.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。
我们也提供了大量基于`ImageNet-1k`数据集的预训练模型,模型列表及下载地址详见[模型库概览](../models/models_intro.md)
<a name="1.3"></a>
### 1.3 模型恢复训练
如果训练任务因为其他原因被终止,也可以加载断点权重文件,继续训练:
```
python3 tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Global.checkpoints="./output/MobileNetV3_large_x1_0/epoch_5" \
-o Global.device=gpu
```
其中配置文件不需要做任何修改,只需要在继续训练时设置`Global.checkpoints`参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。
**注意**
* `-o Global.checkpoints`参数无需包含断点权重文件的后缀名,上述训练命令会在训练过程中生成如下所示的断点权重文件,若想从断点`5`继续训练,则`Global.checkpoints`参数只需设置为`"../output/MobileNetV3_large_x1_0/epoch_5"`,PaddleClas会自动补充后缀名。output目录下的文件结构如下所示:
```shell
output
├── MobileNetV3_large_x1_0
│   ├── best_model.pdopt
│   ├── best_model.pdparams
│   ├── best_model.pdstates
│   ├── epoch_1.pdopt
│   ├── epoch_1.pdparams
│   ├── epoch_1.pdstates
.
.
.
```
<a name="1.4"></a>
### 1.4 模型评估
可以通过以下命令进行模型评估。
```bash
python3 tools/eval.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-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`参数更新配置,如上所示。
可配置的部分评估参数说明如下:
* `Arch.name`:模型名称
* `Global.pretrained_model`:待评估的模型预训练模型文件路径
**注意:** 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[1.3 模型恢复训练](#1.3)
<a name="2"></a>
## 2. 基于Linux+GPU的模型训练与评估
如果机器环境为Linux+GPU,那么推荐使用`paddle.distributed.launch`启动模型训练脚本(`tools/train.py`)、评估脚本(`tools/eval.py`),可以更方便地启动多卡训练与评估。
### 2.1 模型训练
参考如下方式启动模型训练,`paddle.distributed.launch`通过设置`gpus`指定GPU运行卡号:
```bash
# PaddleClas通过launch方式启动多卡多进程训练
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml
```
输出日志信息的格式同上,详见[1.1 模型训练](#1.1)
### 2.2 模型微调
根据自己的数据集配置好配置文件之后,可以加载预训练模型进行微调,如下所示。
```
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Arch.pretrained=True
```
其中`Arch.pretrained``True``False`,当然也可以设置加载预训练权重文件的路径,使用时需要换成自己的预训练模型权重文件路径,也可以直接在配置文件中修改该路径。
30分钟玩转PaddleClas[尝鲜版](./quick_start_new_user.md)[进阶版](./quick_start_professional.md)中包含大量模型微调的示例,可以参考该章节在特定的数据集上进行模型微调。
<a name="model_resume"></a>
### 2.3 模型恢复训练
如果训练任务因为其他原因被终止,也可以加载断点权重文件继续训练。
```
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Global.checkpoints="./output/MobileNetV3_large_x1_0/epoch_5" \
-o Global.device=gpu
```
其中配置文件不需要做任何修改,只需要在训练时设置`Global.checkpoints`参数即可,该参数表示加载的断点权重文件路径,使用该参数会同时加载保存的模型参数权重和学习率、优化器等信息,详见[1.3 模型恢复训练](#1.3)
### 2.4 模型评估
可以通过以下命令进行模型评估。
```bash
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \
tools/eval.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model
```
参数说明详见[1.4 模型评估](#1.4)
<a name="model_infer"></a>
## 3. 使用预训练模型进行模型预测
模型训练完成之后,可以加载训练得到的预训练模型,进行模型预测。在模型库的 `tools/infer/infer.py` 中提供了完整的示例,只需执行下述命令即可完成模型预测:
```python
python3 tools/infer.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Infer.infer_imgs=dataset/flowers102/jpg/image_00001.jpg \
-o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model
```
参数说明:
+ `Infer.infer_imgs`:待预测的图片文件路径或者批量预测时的图片文件夹。
+ `Global.pretrained_model`:模型权重文件路径,如 `./output/MobileNetV3_large_x1_0/best_model`
<a name="model_inference"></a>
## 4. 使用inference模型进行模型推理
通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。接下来介绍如何用预测引擎进行推理:
首先,对训练好的模型进行转换:
```bash
python3 tools/export_model.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Global.pretrained_model=output/MobileNetV3_large_x1_0/best_model
```
其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[1.3 模型恢复训练](#1.3))。
上述命令将生成模型结构文件(`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理:
进入deploy目录下:
```bash
cd deploy
```
执行命令进行预测,由于默认class_id_map_file是ImageNet数据集的映射文件,所以此处需要置None。
```bash
python3 python/predict_cls.py \
-c configs/inference_cls.yaml \
-o Global.infer_imgs=../dataset/flowers102/jpg/image_00001.jpg \
-o Global.inference_model_dir=../inference/ \
-o PostProcess.Topk.class_id_map_file=None
其中:
+ `Global.infer_imgs`:待预测的图片文件路径。
+ `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`
**注意**: 如果使用`Transformer`系列模型,如`DeiT_***_384`, `ViT_***_384`等,请注意模型的输入数据尺寸,需要设置参数`resize_short=384`, `resize=384`
* 如果你希望提升评测模型速度,使用gpu评测时,建议开启TensorRT加速预测,使用cpu评测时,建议开启MKL-DNN加速预测。
# 开始使用
---
首先,请参考[安装指南](./install.md)配置运行环境。
PaddleClas图像检索部分目前支持的训练/评估环境如下:
```shell
└── CPU/单卡GPU
   ├── Linux
   └── Windows
```
## 目录
* [1. 数据准备与处理](#数据准备与处理)
* [2. 基于单卡GPU上的训练与评估](#基于单卡GPU上的训练与评估)
* [2.1 模型训练](#模型训练)
* [2.2 模型恢复训练](#模型恢复训练)
* [2.3 模型评估](#模型评估)
* [3. 导出inference模型](#导出inference模型)
<a name="数据的准备与处理"></a>
## 1. 数据的准备与处理
* 进入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)
```shell
# linux or mac
cd dataset
# 将下载后的数据拷贝到此目录
cp {数据存放的路径}/CUB_200_2011.tgz .
# 解压
tar -xzvf CUB_200_2011.tgz
#进入CUB_200_2011目录
cd CUB_200_2011
```
该数据集在用作图像检索任务时,通常将前100类当做训练集,后100类当做测试集,所以此处需要将下载的数据集做一些后处理,来更好的适应PaddleClas的图像检索训练。
```shell
#新建train和test目录
mkdir train && mkdir test
#将数据分成训练集和测试集,前100类作为训练集,后100类作为测试集
ls images | awk -F "." '{if(int($1)<101)print "mv images/"$0" train/"int($1)}' | sh
ls images | awk -F "." '{if(int($1)>100)print "mv images/"$0" test/"int($1)}' | sh
#生成train_list和test_list
tree -r -i -f train | grep jpg | awk -F "/" '{print $0" "int($2) " "NR}' > train_list.txt
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`目录下应有如下结构:
```
├── 1
│   ├── Black_Footed_Albatross_0001_796111.jpg
│   ├── Black_Footed_Albatross_0002_55.jpg
...
├── 10
│   ├── Red_Winged_Blackbird_0001_3695.jpg
│   ├── Red_Winged_Blackbird_0005_5636.jpg
...
```
`train_list.txt`应为:
```
train/99/Ovenbird_0137_92639.jpg 99 1
train/99/Ovenbird_0136_92859.jpg 99 2
train/99/Ovenbird_0135_93168.jpg 99 3
train/99/Ovenbird_0131_92559.jpg 99 4
train/99/Ovenbird_0130_92452.jpg 99 5
...
```
其中,分隔符为空格" ", 三列数据的含义分别是训练数据的路径、训练数据的label信息、训练数据的unique id。
测试集格式与训练集格式相同。
**注意**
* 当gallery dataset和query dataset相同时,为了去掉检索得到的第一个数据(检索图片本身无须评估),每个数据需要对应一个unique id,用于后续评测mAP、recall@1等指标。关于gallery dataset与query dataset的解析请参考[图像检索数据集介绍](#图像检索数据集介绍), 关于mAP、recall@1等评测指标请参考[图像检索评价指标](#图像检索评价指标)
返回`PaddleClas`根目录
```shell
# linux or mac
cd ../../
```
<a name="基于单卡GPU上的训练与评估"></a>
## 2. 基于单卡GPU上的训练与评估
在基于单卡GPU上训练与评估,推荐使用`tools/train.py``tools/eval.py`脚本。
<a name="模型训练"></a>
### 2.1 模型训练
准备好配置文件之后,可以使用下面的方式启动图像检索任务的训练。PaddleClas训练图像检索任务的方法是度量学习,关于度量学习的解析请参考[度量学习](#度量学习)
```
python3 tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \
-o Arch.Backbone.pretrained=True \
-o Global.device=gpu
```
其中,`-c`用于指定配置文件的路径,`-o`用于指定需要修改或者添加的参数,其中`-o Arch.Backbone.pretrained=True`表示Backbone部分使用预训练模型,此外,`Arch.Backbone.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。`-o Global.device=gpu`表示使用GPU进行训练。如果希望使用CPU进行训练,则需要将`Global.device`设置为`cpu`
更详细的训练配置,也可以直接修改模型对应的配置文件。具体配置参数参考[配置文档](config_description.md)
运行上述命令,可以看到输出日志,示例如下:
```
...
[Train][Epoch 1/50][Avg]CELoss: 6.59110, TripletLossV2: 0.54044, loss: 7.13154
...
[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的名字。
在训练Loss部分,此处使用了[CELoss](../../../ppcls/loss/celoss.py)[TripletLossV2](../../../ppcls/loss/triplet.py),配置文件如下:
```
Loss:
Train:
- CELoss:
weight: 1.0
- TripletLossV2:
weight: 1.0
margin: 0.5
```
最终的总Loss是所有Loss的加权和,其中weight定义了特定Loss在最终总Loss的权重。如果想替换其他Loss,也可以在配置文件中更改Loss字段,目前支持的Loss请参考[Loss](../../../ppcls/loss)
<a name="模型恢复训练"></a>
### 2.2 模型恢复训练
如果训练任务因为其他原因被终止,也可以加载断点权重文件,继续训练:
```
python3 tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \
-o Global.checkpoints="./output/RecModel/epoch_5" \
-o Global.device=gpu
```
其中配置文件不需要做任何修改,只需要在继续训练时设置`Global.checkpoints`参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。
**注意**
* `-o Global.checkpoints`参数无需包含断点权重文件的后缀名,上述训练命令会在训练过程中生成如下所示的断点权重文件,若想从断点`5`继续训练,则`Global.checkpoints`参数只需设置为`"./output/RecModel/epoch_5"`,PaddleClas会自动补充后缀名。
```shell
output/
└── RecModel
├── best_model.pdopt
├── best_model.pdparams
├── best_model.pdstates
├── epoch_1.pdopt
├── epoch_1.pdparams
├── epoch_1.pdstates
.
.
.
```
<a name="模型评估"></a>
### 2.3 模型评估
可以通过以下命令进行模型评估。
```bash
python3 tools/eval.py \
-c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \
-o Global.pretrained_model=./output/RecModel/best_model
```
上述命令将使用`./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`中添加相关的指标。
**注意:**
* 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[2.2 模型恢复训练](#模型恢复训练)
* Metric learning任务一般不评测TopkAcc。
<a name="导出inference模型"></a>
## 3. 导出inference模型
通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。对训练好的模型进行转换:
```bash
python3 tools/export_model.py \
-c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \
-o Global.pretrained_model=output/RecModel/best_model \
-o Global.save_inference_dir=./inference
```
其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[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预测引擎预测推理](https://github.com/PaddlePaddle/PaddleClas/blob/develop/docs/zh_CN/inference.md)
## 基础知识
图像检索指的是给定一个包含特定实例(例如特定目标、场景、物品等)的查询图像,图像检索旨在从数据库图像中找到包含相同实例的图像。不同于图像分类,图像检索解决的是一个开集问题,训练集中可能不包含被识别的图像的类别。图像检索的整体流程为:首先将图像中表示为一个合适的特征向量,其次,对这些图像的特征向量用欧式距离或余弦距离进行最近邻搜索以找到底库中相似的图像,最后,可以使用一些后处理技术对检索结果进行微调,确定被识别图像的类别等信息。所以,决定一个图像检索算法性能的关键在于图像对应的特征向量的好坏。
<a name="度量学习"></a>
- 度量学习(Metric Learning)
度量学习研究如何在一个特定的任务上学习一个距离函数,使得该距离函数能够帮助基于近邻的算法 (kNN、k-means等) 取得较好的性能。深度度量学习 (Deep Metric Learning )是度量学习的一种方法,它的目标是学习一个从原始特征到低维稠密的向量空间 (嵌入空间,embedding space) 的映射,使得同类对象在嵌入空间上使用常用的距离函数 (欧氏距离、cosine距离等) 计算的距离比较近,而不同类的对象之间的距离则比较远。深度度量学习在计算机视觉领域取得了非常多的成功的应用,比如人脸识别、商品识别、图像检索、行人重识别等。
<a name="图像检索数据集介绍"></a>
- 图像检索数据集介绍
- 训练集合(train dataset):用来训练模型,使模型能够学习该集合的图像特征。
- 底库数据集合(gallery dataset):用来提供图像检索任务中的底库数据,该集合可与训练集或测试集相同,也可以不同,当与训练集相同时,测试集的类别体系应与训练集的类别体系相同。
- 测试集合(query dataset):用来测试模型的好坏,通常要对测试集的每一张测试图片进行特征提取,之后和底库数据的特征进行距离匹配,得到识别结果,后根据识别结果计算整个测试集的指标。
<a name="图像检索评价指标"></a>
- 图像检索评价指标
<a name="召回率"></a>
- 召回率(recall):表示预测为正例且标签为正例的个数 / 标签为正例的个数
- recall@1:检索的top-1中预测正例且标签为正例的个数 / 标签为正例的个数
- recall@5:检索的top-5中所有预测正例且标签为正例的个数 / 标签为正例的个数
<a name="平均检索精度"></a>
- 平均检索精度(mAP)
- AP: AP指的是不同召回率上的正确率的平均值
- mAP: 测试集中所有图片对应的AP的的平均值
# 图像分类
---
图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题,也是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在很多领域有广泛应用,包括安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等。
一般来说,图像分类通过手工特征或特征学习方法对整个图像进行全部描述,然后使用分类器判别物体类别,因此如何提取图像的特征至关重要。在深度学习算法之前使用较多的是基于词袋(Bag of Words)模型的物体分类方法。而基于深度学习的图像分类方法,可以通过有监督或无监督的方式学习层次化的特征描述,从而取代了手工设计或选择图像特征的工作。深度学习模型中的卷积神经网络(Convolution Neural Network, CNN)近年来在图像领域取得了惊人的成绩,CNN直接利用图像像素信息作为输入,最大程度上保留了输入图像的所有信息,通过卷积操作进行特征的提取和高层抽象,模型输出直接是图像识别的结果。这种基于"输入-输出"直接端到端的学习方法取得了非常好的效果,得到了广泛的应用。
图像分类是计算机视觉里很基础但又重要的一个领域,其研究成果一直影响着计算机视觉甚至深度学习的发展,图像分类有很多子领域,如多标签分类、细粒度分类等,此处只对单标签图像分类做一个简述。
## 一、数据集介绍
### 1.1 ImageNet-1k
ImageNet项目是一个大型视觉数据库,用于视觉目标识别软件研究。该项目已手动注释了1400多万张图像,以指出图片中的对象,并在至少100万张图像中提供了边框。ImageNet-1k是ImageNet数据集的子集,其包含1000个类别。训练集包含1281167个图像数据,验证集包含50000个图像数据。2010年以来,ImageNet项目每年举办一次图像分类竞赛,即ImageNet大规模视觉识别挑战赛(ILSVRC)。挑战赛使用的数据集即为ImageNet-1k。到目前为止,ImageNet-1k已经成为计算机视觉领域发展的最重要的数据集之一,其促进了整个计算机视觉的发展,很多计算机视觉下游任务的初始化模型都是基于该数据集训练得到的权重。
### 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张。由于这两个数据集规模较小,因此可以让研究人员快速尝试不同的算法。这两个数据集也是图像分类领域测试模型好坏的常用数据集。
## 二、图像分类的流程
将准备好的训练数据做相应的数据预处理后经过图像分类模型,模型的输出与真实标签做交叉熵损失函数,该损失函数描述了模型的收敛方向,遍历所有的图片数据输入模型,对最终损失函数通过某些优化器做相应的梯度下降,将梯度信息回传到模型中,更新模型的权重,如此循环往复遍历多次数据,即可得到一个图像分类的模型。
### 2.1 数据及其预处理
数据的质量及数量往往可以决定一个模型的好坏。在图像分类领域,数据包括图像及标签。在大部分情形下,带有标签的数据比较匮乏,所以数量很难达到使模型饱和的程度,为了可以使模型学习更多的图像特征,图像数据在进入模型之前要经过很多图像变换或者数据增强,来保证输入图像数据的多样性,从而保证模型有更好的泛化能力。PaddleClas提供了训练ImageNet-1k的标准图像变换,也提供了8中数据增强的方法,相关代码可以[数据处理](../../../ppcls/data/preprocess),配置文件可以参考[数据增强配置文件](../../../ppcls/configs/ImageNet/DataAugment)
### 2.2 模型准备
在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了35个系列共164个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](../ImageNet_models_cn.md)
### 2.3 模型训练
在准备好数据、模型后,便可以开始迭代模型并更新模型的参数。经过多次迭代最终可以得到训练好的模型来做图像分类任务。图像分类的训练过程需要很多经验,涉及很多超参数的设置,PaddleClas提供了一些列的[训练调优方法](../models/Tricks.md),可以快速助你获得高精度的模型。
### 2.4 模型评估
当训练得到一个模型之后,如何确定模型的好坏,需要将模型在验证集上进行评估。评估指标一般是Top1-Acc或者Top5-Acc,该指标越高往往代表模型性能越好。
## 三、主要算法简介
- LeNet:Yan LeCun等人于上个世纪九十年代第一次将卷积神经网络应用到图像分类任务上,创造性的提出了LeNet,在手写数字识别任务上取得了巨大的成功。
- AlexNet:Alex Krizhevsky等人在2012年提出了AlexNet,并应用于ImageNet上,获得了2012年ImageNet分类比赛的冠军,从此,掀起了深度学习的热潮。
- VGG:Simonyan和Zisserman于2014年提出了VGG网络结构,该网络结构使用了更小的卷积核堆叠整个网络,在ImageNet分类上取得了更好的性能,也为之后的网络结构设计提供了新的思路。
- GoogLeNet:Christian Szegedy等人在2014年提出了GoogLeNet,该网络使用了多分支结构和全局平均池化层(GAP),在保持模型精度的同时,模型存储和计算量大大缩减。该网络取得了2014年ImageNet分类比赛的冠军。
- ResNet:Kaiming He等人在2015年提出了ResNet,通过引入残差模块加深了网络的深度,最终该网络将ImageNet分类的识别错误率降低到了3.6\%,首次超出正常人眼的识别精度。
- DenseNet:Huang Gao等人在2017年提出了DenseNet,该网络设计了一种更稠密连接的block,在更小的参数量上获得了更高的性能。
- EfficientNet:Mingxing Tan等人在2019年提出了EfficientNet,该网络平衡了网络的宽度、网络的深度、以及输入图片的分辨率,在同样FLOPS与参数量的情况下,精度达到了state-of-the-art的效果。
关于更多的算法介绍,请参考[算法介绍](../models)
初级使用
================================
.. toctree::
:maxdepth: 1
install.md
quick_start_new_user.md
quick_start_professional.md
data.md
getting_started.md
config.md
# 安装说明
---
本章将介绍如何安装PaddleClas及其依赖项。
## 1. 安装PaddlePaddle
运行PaddleClas需要`PaddlePaddle 2.1`或更高版本。可以参考下面的步骤安装PaddlePaddle。
### 1.1 环境要求
- python 3.x
- cuda >= 10.1 (如果使用paddlepaddle-gpu)
- cudnn >= 7.6.4 (如果使用paddlepaddle-gpu)
- nccl >= 2.1.2 (如果使用分布式训练/评估)
- gcc >= 8.2
建议使用我们提供的docker运行PaddleClas,有关docker、nvidia-docker使用请参考[链接](https://www.runoob.com/docker/docker-tutorial.html)
在cuda10.1时,建议显卡驱动版本大于等于418.39;在使用cuda10.2时,建议显卡驱动版本大于440.33,更多cuda版本与要求的显卡驱动版本可以参考[链接](https://docs.nvidia.com/deploy/cuda-compatibility/index.html)
如果不使用docker,可以直接跳过1.2部分内容,从1.3部分开始执行。
### 1.2 (建议)准备docker环境。第一次使用这个镜像,会自动下载该镜像,请耐心等待。
```
# 切换到工作目录下
cd /home/Projects
# 首次运行需创建一个docker容器,再次运行时不需要运行当前命令
# 创建一个名字为ppcls的docker容器,并将当前目录映射到容器的/paddle目录下
如果您希望在CPU环境下使用docker,使用docker而不是nvidia-docker创建docker,设置docker容器共享内存shm-size为8G,建议设置8G以上
sudo docker run --name ppcls -v $PWD:/paddle --shm-size=8G --network=host -it paddlepaddle/paddle:2.1.0 /bin/bash
如果希望使用GPU版本的容器,请运行以下命令创建容器。
sudo nvidia-docker run --name ppcls -v $PWD:/paddle --shm-size=8G --network=host -it paddlepaddle/paddle:2.1.0-gpu-cuda10.2-cudnn7 /bin/bash
```
您也可以访问[DockerHub](https://hub.docker.com/r/paddlepaddle/paddle/tags/)获取与您机器适配的镜像。
```
# ctrl+P+Q可退出docker 容器,重新进入docker 容器使用如下命令
sudo docker exec -it ppcls /bin/bash
```
### 1.3 通过pip安装PaddlePaddle
运行下面的命令,通过pip安装最新GPU版本PaddlePaddle
```bash
pip3 install paddlepaddle-gpu --upgrade -i https://mirror.baidu.com/pypi/simple
```
如果希望在CPU环境中使用PaddlePaddle,可以运行下面的命令安装PaddlePaddle。
```bash
pip3 install paddlepaddle --upgrade -i https://mirror.baidu.com/pypi/simple
```
**注意:**
* 如果先安装了CPU版本的paddlepaddle,之后想切换到GPU版本,那么需要首先卸载CPU版本的paddle,再安装GPU版本的paddle,否则容易导致使用的paddle版本混乱。
* 您也可以从源码编译安装PaddlePaddle,请参照[PaddlePaddle 安装文档](http://www.paddlepaddle.org.cn/install/quick)中的说明进行操作。
### 1.4 验证是否安装成功
使用以下命令可以验证PaddlePaddle是否安装成功。
```python
import paddle
paddle.utils.run_check()
```
查看PaddlePaddle版本的命令如下:
```bash
python3 -c "import paddle; print(paddle.__version__)"
```
注意:
- 从源码编译的PaddlePaddle版本号为0.0.0,请确保使用了PaddlePaddle 2.0及之后的源码编译。
- PaddleClas基于PaddlePaddle高性能的分布式训练能力,若您从源码编译,请确保打开编译选项,**WITH_DISTRIBUTE=ON**。具体编译选项参考[编译选项表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/install/Tables.html#id3)
- 在docker中运行时,为保证docker容器有足够的共享内存用于Paddle的数据读取加速,在创建docker容器时,请设置参数`--shm_size=8g`,条件允许的话可以设置为更大的值。
-
## 2. 安装PaddleClas
### 2.1 克隆PaddleClas模型库
```bash
git clone https://github.com/PaddlePaddle/PaddleClas.git -b release/2.2
```
如果从github上网速太慢,可以从gitee下载,下载命令如下:
```bash
git clone https://gitee.com/paddlepaddle/PaddleClas.git -b release/2.2
```
### 2.2 安装Python依赖库
Python依赖库在`requirements.txt`中给出,可通过如下命令安装:
```bash
pip3 install --upgrade -r requirements.txt -i https://mirror.baidu.com/pypi/simple
```
# PaddleClas代码解析与社区贡献指南
## 1. 整体代码结构解析
### 1.1 前言
有用户对PaddleClas的代码做了非常详细的解读,可以参考下面的三篇文档。本部分内容大部分也是来自该系列文档,在此感谢[FutureSI](https://aistudio.baidu.com/aistudio/personalcenter/thirdview/76563)的贡献与解读。
* [PaddleClas 分类套件源码解析(一)](https://aistudio.baidu.com/aistudio/projectdetail/1308952)
* [PaddleClas 分类套件源码解析(二)](https://aistudio.baidu.com/aistudio/projectdetail/1315501)
* [PaddleClas 分类套件源码解析(三)](https://aistudio.baidu.com/aistudio/projectdetail/1339544)
### 1.2 代码解析
#### 1.2.1 整体代码和目录概览
* PaddleClas主要代码和目录结构如下
<div align="center">
<img src="../../images/quick_start/community/code_framework.png" width = "800" />
</div>
* configs 文件夹下存放训练脚本和验证脚本的yaml配置文件,文件按模型类别存放。
* dataset 文件夹下存放数据集和用于处理数据集的脚本。脚本负责将数据集处理为适合Dataloader处理的格式。
* docs 文件夹下存放中英文文档。
* deploy 文件夹存放的是部署工具,支持 Cpp inference、Hub Serveing、Paddle Lite、Slim量化等多种部署方式。
* ppcls 文件夹下存放PaddleClas框架主体。模型结构脚本、数据增强脚本、优化脚本等DL程序的标准流程代码都在这里。
* tools 文件夹下存放用于模型下载、训练、预测的脚本。
* requirements.txt 文件用于安装 PaddleClas 的依赖项。使用pip进行升级安装使用。
#### 1.2.2 训练模块定义
深度学习模型训练流程框图如下。
<div align="center">
<img src="../../images/quick_start/community/train_framework.png" width = "800" />
</div>
具体地,深度学习模型训练过程中,主要包含以下几个核心模块。
* 数据:对于有监督任务来说,训练数据一般包含原始数据及其标注。在基于单标签的图像分类任务中,原始数据指的是图像数据,而标注则是该图像数据所属的类比。PaddleClas中,训练时需要提供标签文件,形式如下,每一行包含一条训练样本,分别表示图片路径和类别标签,用分隔符隔开(默认为空格)。
```
train/n01440764/n01440764_10026.JPEG 0
train/n01440764/n01440764_10027.JPEG 0
```
在代码`ppcls/data/reader.py`中,包含`CommonDataset`类,继承自`paddle.io.Dataset`,该数据集类可以通过一个键值进行索引并获取指定样本。
对于读入的数据,需要通过数据转换,将原始的图像数据进行转换。训练时,标准的数据预处理包含:`DecodeImage`, `RandCropImage`, `RandFlipImage`, `NormalizeImage`, `ToCHWImage`。在配置文件中体现如下,数据预处理主要包含在`transforms`字段中,以列表形式呈现,会按照顺序对数据依次做这些转换。
```yaml
DataLoader:
Train:
dataset:
name: ImageNetDataset
image_root: ./dataset/ILSVRC2012/
cls_label_path: ./dataset/ILSVRC2012/train_list.txt
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
```
PaddleClas中也包含了`AutoAugment`, `RandAugment`等数据增广方法,也可以通过在配置文件中配置,从而添加到训练过程的数据预处理中。每个数据转换的方法均以类实现,方便迁移和复用,更多的数据处理具体实现过程可以参考`ppcls/data/preprocess/ops/`下的代码。
对于组成一个batch的数据,也可以使用mixup或者cutmix等方法进行数据增广。PaddleClas中集成了`MixupOperator`, `CutmixOperator`, `FmixOperator`等基于batch的数据增广方法,可以在配置文件中配置mix参数进行配置,更加具体的实现可以参考`ppcls/data/preprocess/batch_ops/batch_operators.py`
图像分类中,数据后处理主要为`argmax`操作,在此不再赘述。
* 模型结构
在配置文件中,模型结构定义如下
```yaml
Arch:
name: ResNet50
pretrained: False
use_ssld: False
```
`Arch.name`表示模型名称,`Arch.pretrained`表示是否添加预训练模型。所有的模型名称均在`ppcls/arch/backbone/__init__.py`中定义。
对应的,在`ppcls/arch/__init__.py`中,通过`build_model`方法创建模型对象。
```python
def build_model(config):
config = copy.deepcopy(config)
model_type = config.pop("name")
mod = importlib.import_module(__name__)
arch = getattr(mod, model_type)(**config)
return arch
```
* 损失函数
PaddleClas中,包含了`CELoss`, `JSDivLoss`, `TripletLoss`, `CenterLoss`等损失函数,均定义在`ppcls/loss`中。
`ppcls/loss/__init__.py`文件中,使用`CombinedLoss`来构建及合并损失函数,不同训练策略中所需要的损失函数与计算方法不同,PaddleClas在构建损失函数过程中,主要考虑了以下几个因素。
1. 是否使用label smooth
2. 是否使用mixup或者cutmix
3. 是否使用蒸馏方法进行训练
4. 是否是训练metric learning
用户可以在配置文件中指定损失函数的类型及权重,如在训练中添加TripletLossV2,配置文件如下:
```yaml
Loss:
Train:
- CELoss:
weight: 1.0
- TripletLossV2:
weight: 1.0
margin: 0.5
```
* 优化器和学习率衰减、权重衰减策略
图像分类任务中,`Momentum`是一种比较常用的优化器,PaddleClas中提供了`Momentum``RMSProp`两种优化器策略。
权重衰减策略是一种比较常用的正则化方法,主要用于防止模型过拟合。PaddleClas中提供了`L1Decay``L2Decay`两种权重衰减策略。
学习率衰减是图像分类任务中必不可少的精度提升训练方法,PaddleClas目前支持`Cosine`, `Piecewise`, `Linear`等学习率衰减策略。
在配置文件中,优化器、权重衰减策略、学习率衰减策略可以通过以下的字段进行配置。
```yaml
Optimizer:
name: Momentum
momentum: 0.9
lr:
name: Piecewise
learning_rate: 0.1
decay_epochs: [30, 60, 90]
values: [0.1, 0.01, 0.001, 0.0001]
regularizer:
name: 'L2'
coeff: 0.0001
```
`ppcls/optimizer/__init__.py`中使用`build_optimizer`创建优化器和学习率对象。
```python
def build_optimizer(config, epochs, step_each_epoch, parameters):
config = copy.deepcopy(config)
# step1 build lr
lr = build_lr_scheduler(config.pop('lr'), epochs, step_each_epoch)
logger.debug("build lr ({}) success..".format(lr))
# step2 build regularization
if 'regularizer' in config and config['regularizer'] is not None:
reg_config = config.pop('regularizer')
reg_name = reg_config.pop('name') + 'Decay'
reg = getattr(paddle.regularizer, reg_name)(**reg_config)
else:
reg = None
logger.debug("build regularizer ({}) success..".format(reg))
# step3 build optimizer
optim_name = config.pop('name')
if 'clip_norm' in config:
clip_norm = config.pop('clip_norm')
grad_clip = paddle.nn.ClipGradByNorm(clip_norm=clip_norm)
else:
grad_clip = None
optim = getattr(optimizer, optim_name)(learning_rate=lr,
weight_decay=reg,
grad_clip=grad_clip,
**config)(parameters=parameters)
logger.debug("build optimizer ({}) success..".format(optim))
return optim, lr
```
不同优化器和权重衰减策略均以类的形式实现具体实现可以参考文件`ppcls/optimizer/optimizer.py`不同的学习率衰减策略可以参考文件`ppcls/optimizer/learning_rate.py`
* 训练时评估与模型存储
模型在训练的时候可以设置模型保存的间隔也可以选择每隔若干个epoch对验证集进行评估从而可以保存在验证集上精度最佳的模型配置文件中可以通过下面的字段进行配置
```yaml
Global:
save_interval: 1 # 模型保存的epoch间隔
eval_during_train: True # 是否进行训练时评估
eval_interval: 1 # 评估的epoch间隔
```
模型存储是通过 Paddle 框架的 `paddle.save()` 函数实现的,存储的是模型的 persistable 版本,便于继续训练。具体实现如下
```python
ef save_model(program, model_path, epoch_id, prefix='ppcls'):
model_path = os.path.join(model_path, str(epoch_id))
_mkdir_if_not_exist(model_path)
model_prefix = os.path.join(model_path, prefix)
paddle.static.save(program, model_prefix)
logger.info(
logger.coloring("Already save model in {}".format(model_path), "HEADER"))
```
在保存的时候有两点需要注意:
1. 只在0号节点上保存模型。否则多卡训练的时候,如果所有节点都保存模型到相同的路径,则多个节点写文件时可能会发生写文件冲突,导致最终保存的模型无法被正确加载。
2. 优化器参数也需要存储,方便后续的加载断点进行训练。
1.2.3 预测部署代码和方式。
* 如果希望在服务端使用cpp进行部署,可以参考[cpp inference预测教程](../../../deploy/cpp_infer/readme.md)。
* 如果希望将分类模型部署为服务,可以参考[hub serving预测部署教程](../../../deploy/hubserving/readme.md)。
* 如果希望将对分类模型进行量化,可以参考[Paddle Slim量化教程](../../../deploy/slim/quant/README.md)。
* 如果希望在移动端使用分类模型进行预测,可以参考[PaddleLite预测部署教程](../../../deploy/lite/readme.md)。
## 2. 如何贡献代码
### 2.1 PaddleClas分支说明
PaddleClas未来将维护2种分支,分别为:
* release/x.x系列分支:为稳定的发行版本分支,会适时打tag发布版本,适配Paddle的release版本。当前最新的分支为release/2.0分支,是当前默认分支,适配Paddle v2.0.0。随着版本迭代,release/x.x系列分支会越来越多,默认维护最新版本的release分支,前1个版本分支会修复bug,其他的分支不再维护。
* develop分支:为开发分支,适配Paddle的develop版本,主要用于开发新功能。如果有同学需要进行二次开发,请选择develop分支。为了保证develop分支能在需要的时候拉出release/x.x分支,develop分支的代码只能使用Paddle最新release分支中有效的api。也就是说,如果Paddle develop分支中开发了新的api,但尚未出现在release分支代码中,那么请不要在PaddleClas中使用。除此之外,对于不涉及api的性能优化、参数调整、策略更新等,都可以正常进行开发。
PaddleClas的历史分支,未来将不再维护。考虑到一些同学可能仍在使用,这些分支还会继续保留:
* release/static分支:这个分支曾用于静态图的开发与测试,目前兼容>=1.7版本的Paddle。如果有特殊需求,要适配旧版本的Paddle,那还可以使用这个分支,但除了修复bug外不再更新代码。
* dygraph-dev分支:这个分支将不再维护,也不再接受新的代码,请使用的同学尽快迁移到develop分支。
PaddleClas欢迎大家向repo中积极贡献代码,下面给出一些贡献代码的基本流程。
### 2.2 PaddleClas代码提交流程与规范
#### 2.2.1 fork和clone代码
* 跳转到[PaddleClas GitHub首页](https://github.com/PaddlePaddle/PaddleClas),然后单击 Fork 按钮,生成自己目录下的仓库,比如 `https://github.com/USERNAME/PaddleClas`。
<div align="center">
<img src="../../images/quick_start/community/001_fork.png" width = "600" />
</div>
* 将远程仓库clone到本地
```shell
# 拉取develop分支的代码
git clone https://github.com/USERNAME/PaddleClas.git -b develop
cd PaddleClas
```
clone的地址可以从下面获取
<div align="center">
<img src="../../images/quick_start/community/002_clone.png" width = "600" />
</div>
#### 2.2.2 和远程仓库建立连接
首先通过`git remote -v`查看当前远程仓库的信息。
```
origin https://github.com/USERNAME/PaddleClas.git (fetch)
origin https://github.com/USERNAME/PaddleClas.git (push)
```
只有clone的远程仓库的信息,也就是自己用户名下的 PaddleClas,接下来我们创建一个原始 PaddleClas 仓库的远程主机,命名为 upstream。
```shell
git remote add upstream https://github.com/PaddlePaddle/PaddleClas.git
```
使用`git remote -v`查看当前远程仓库的信息,输出如下,发现包括了origin和upstream 2个远程仓库。
```
origin https://github.com/USERNAME/PaddleClas.git (fetch)
origin https://github.com/USERNAME/PaddleClas.git (push)
upstream https://github.com/PaddlePaddle/PaddleClas.git (fetch)
upstream https://github.com/PaddlePaddle/PaddleClas.git (push)
```
这主要是为了后续在提交pull request(PR)时,始终保持本地仓库最新。
#### 2.2.3 创建本地分支
可以基于当前分支创建新的本地分支,命令如下。
```shell
git checkout -b new_branch
```
也可以基于远程或者上游的分支创建新的分支,命令如下。
```shell
# 基于用户远程仓库(origin)的develop创建new_branch分支
git checkout -b new_branch origin/develop
# 基于上游远程仓库(upstream)的develop创建new_branch分支
# 如果需要从upstream创建新的分支,需要首先使用git fetch upstream获取上游代码
git checkout -b new_branch upstream/develop
```
最终会显示切换到新的分支,输出信息如下
```
Branch new_branch set up to track remote branch develop from upstream.
Switched to a new branch 'new_branch'
```
#### 2.2.4 使用pre-commit勾子
Paddle 开发人员使用 pre-commit 工具来管理 Git 预提交钩子。 它可以帮助我们格式化源代码(C++,Python),在提交(commit)前自动检查一些基本事宜(如每个文件只有一个 EOL,Git 中不要添加大文件等)。
pre-commit测试是 Travis-CI 中单元测试的一部分,不满足钩子的 PR 不能被提交到 PaddleClas,首先安装并在当前目录运行它:
```shell
pip install pre-commit
pre-commit install
```
* **注意**
1. Paddle 使用 clang-format 来调整 C/C++ 源代码格式,请确保 `clang-format` 版本在 3.8 以上。
2. 通过pip install pre-commit和conda install -c conda-forge pre-commit安装的yapf稍有不同的,PaddleClas 开发人员使用的是`pip install pre-commit`。
#### 2.2.5 修改与提交代码
可以通过`git status`查看改动的文件。
对PaddleClas的`README.md`做了一些修改,希望提交上去。则可以通过以下步骤
```shell
git add README.md
pre-commit
```
重复上述步骤,直到pre-comit格式检查不报错。如下所示。
<div align="center">
<img src="../../images/quick_start/community/003_precommit_pass.png" width = "600" />
</div>
使用下面的命令完成提交。
```shell
git commit -m "your commit info"
```
#### 2.2.6 保持本地仓库最新
获取 upstream 的最新代码并更新当前分支。这里的upstream来自于2.2节的`和远程仓库建立连接`部分。
```shell
git fetch upstream
# 如果是希望提交到其他分支,则需要从upstream的其他分支pull代码,这里是develop
git pull upstream develop
```
#### 2.2.7 push到远程仓库
```shell
git push origin new_branch
```
#### 2.2.7 提交Pull Request
点击new pull request,选择本地分支和目标分支,如下图所示。在PR的描述说明中,填写该PR所完成的功能。接下来等待review,如果有需要修改的地方,参照上述步骤更新 origin 中的对应分支即可。
<div align="center">
<img src="../../images/quick_start/community/004_create_pr.png" width = "600" />
</div>
#### 2.2.8 签署CLA协议和通过单元测试
* 签署CLA
在首次向PaddlePaddle提交Pull Request时,您需要您签署一次CLA(Contributor License Agreement)协议,以保证您的代码可以被合入,具体签署方式如下:
1. 请您查看PR中的Check部分,找到license/cla,并点击右侧detail,进入CLA网站
2. 点击CLA网站中的“Sign in with GitHub to agree”,点击完成后将会跳转回您的Pull Request页面
#### 2.2.9 删除分支
* 删除远程分支
在 PR 被 merge 进主仓库后,我们可以在 PR 的页面删除远程仓库的分支。
也可以使用 `git push origin :分支名` 删除远程分支,如:
```shell
git push origin :new_branch
```
* 删除本地分支
```shell
# 切换到develop分支,否则无法删除当前分支
git checkout develop
# 删除new_branch分支
git branch -D new_branch
```
#### 2.2.10 提交代码的一些约定
为了使官方维护人员在评审代码时更好地专注于代码本身,请您每次提交代码时,遵守以下约定:
1)请保证Travis-CI 中单元测试能顺利通过。如果没过,说明提交的代码存在问题,官方维护人员一般不做评审。
2)提交PUll Request前:
请注意commit的数量。
原因:如果仅仅修改一个文件但提交了十几个commit,每个commit只做了少量的修改,这会给评审人带来很大困扰。评审人需要逐一查看每个commit才能知道做了哪些修改,且不排除commit之间的修改存在相互覆盖的情况。
建议:每次提交时,保持尽量少的commit,可以通过git commit --amend补充上次的commit。对已经Push到远程仓库的多个commit,可以参考[squash commits after push](https://stackoverflow.com/questions/5667884/how-to-squash-commits-in-git-after-they-have-been-pushed)。
请注意每个commit的名称:应能反映当前commit的内容,不能太随意。
3)如果解决了某个Issue的问题,请在该PUll Request的第一个评论框中加上:fix #issue_number,这样当该PUll Request被合并后,会自动关闭对应的Issue。关键词包括:close, closes, closed, fix, fixes, fixed, resolve, resolves, resolved,请选择合适的词汇。详细可参考[Closing issues via commit messages](https://help.github.com/articles/closing-issues-via-commit-messages)。
此外,在回复评审人意见时,请您遵守以下约定:
1)官方维护人员的每一个review意见都希望得到回复,这样会更好地提升开源社区的贡献。
- 对评审意见同意且按其修改完的,给个简单的Done即可;
- 对评审意见不同意的,请给出您自己的反驳理由。
2)如果评审意见比较多,
- 请给出总体的修改情况。
- 请采用`start a review`进行回复,而非直接回复的方式。原因是每个回复都会发送一封邮件,会造成邮件灾难。
## 3. 总结
* 开源社区依赖于众多开发者与用户的贡献和反馈,在这里感谢与期待大家向PaddleClas提出宝贵的意见与pull request,希望我们可以一起打造一个领先实用全面的图像分类代码仓库!
## 4. 参考文献
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)
# 30分钟玩转PaddleClas(尝鲜版)
此教程主要针对初级用户,即深度学习相关理论知识处于入门阶段,具有一定的python基础,能够阅读简单代码的用户。此内容主要包括利用PaddleClas进行网络训练及模型预测。
## 一、基础知识
图像分类顾名思义就是一个模式分类问题,是计算机视觉中最基础的任务,它的目标是将不同的图像,划分到不同的类别。以下会对整个模型训练过程中需要了解到的一些概念做简单的解释,希望能够对初次体验PaddleClas的你有所帮助:
- train/val/test dataset分别代表模型的训练集、验证集和测试集
- 训练集(train dataset):用来训练模型,使模型能够识别不同类型的特征
- 验证集(val dataset):训练过程中的测试集,方便训练过程中查看模型训练程度
- 测试集(test dataset):训练模型结束后,用于评价模型结果的测试集
- 预训练模型
使用在某个较大的数据集训练好的预训练模型,即被预置了参数的权重,可以帮助模型在新的数据集上更快收敛。尤其是对一些训练数据比较稀缺的任务,在神经网络参数十分庞大的情况下,仅仅依靠任务自身的训练数据可能无法训练充分,加载预训练模型的方法可以认为是让模型基于一个更好的初始状态进行学习,从而能够达到更好的性能。
- 迭代轮数(epoch)
模型训练迭代的总轮数,模型对训练集全部样本过一遍即为一个epoch。当测试错误率和训练错误率相差较小时,可认为当前迭代轮数合适;当测试错误率先变小后变大时,则说明迭代轮数过大,需要减小迭代轮数,否则容易出现过拟合。
- 损失函数(Loss Function)
训练过程中,衡量模型输出(预测值)与真实值之间的差异
- 准确率(Acc)
表示预测正确的样本数占总数据的比例
- Top1 Acc:预测结果中概率最大的所在分类正确,则判定为正确
- Top5 Acc:预测结果中概率排名前5中有分类正确,则判定为正确
## 二、环境安装与配置
具体安装步骤可详看[安装文档](install.md)
## 三、数据的准备与处理
* 进入PaddleClas目录。
```bash
# linux or mac, $path_to_PaddleClas表示PaddleClas的根目录,用户需要根据自己的真实目录修改
cd $path_to_PaddleClas
```
* 进入`dataset/flowers102`目录,下载并解压flowers102数据集.
```shell
# linux or mac
cd dataset/flowers102
# 如果希望从浏览器中直接下载,可以复制该链接并访问,然后下载解压即可
wget https://paddle-imagenet-models-name.bj.bcebos.com/data/flowers102.zip
# 解压
unzip flowers102.zip
```
没有安装`wget`命令或者windows中下载的话,需要将地址拷贝到浏览器中下载,并进行解压到PaddleClas的根目录即可。
解压完成后,在文件夹下已经生成用于训练和测试的三个`.txt`文件:`train_list.txt`(训练集,1020张图)、`val_list.txt`(验证集,1020张图)、`train_extra_list.txt`(更大的训练集,7169张图)。文件中每行格式:**图像相对路径** **图像的label_id**(注意:中间有空格)。
此时flowers102数据集存放在**dataset/flowers102/jpg** 文件夹中,图像示例如下:
<div align="center">
<img src="../../images/quick_start/Examples-Flower-102.png" width = "800" />
</div>
* 返回`PaddleClas`根目录
```shell
# linux or mac
cd ../../
# windoes直接打开PaddleClas根目录即可
```
## 四、模型训练
### 使用CPU进行模型训练
由于使用CPU来进行模型训练,计算速度较慢,因此,此处以ShuffleNetV2_x0_25为例。此模型计算量较小,在CPU上计算速度较快。但是也因为模型较小,训练好的模型精度也不会太高。
#### 不使用预训练模型
```shell
# windows在cmd中进入PaddleClas根目录,执行此命令
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml
```
- `-c` 参数是指定训练的配置文件路径,训练的具体超参数可查看`yaml`文件
- `yaml``Global.device` 参数设置为`cpu`,即使用CPU进行训练(若不设置,此参数默认为`True`
- `yaml`文件中`epochs`参数设置为20,说明对整个数据集进行20个epoch迭代,预计训练20分钟左右(不同CPU,训练时间略有不同),此时训练模型不充分。若提高训练模型精度,请将此参数设大,如**40**,训练时间也会相应延长
#### 使用预训练模型
```shell
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml -o Arch.pretrained=True
```
- `-o` 参数可以选择为True或False,也可以是预训练模型存放路径,当选择为True时,预训练权重会自动下载到本地。注意:若为预训练模型路径,则不要加上:`.pdparams`
可以使用将使用与不使用预训练模型训练进行对比,观察loss的下降情况。
### 使用GPU进行模型训练
由于GPU训练速度更快,可以使用更复杂模型,因此以ResNet50_vd为例。与ShuffleNetV2_x0_25相比,此模型计算量较大, 训练好的模型精度也会更高。
首先要设置环境变量,使用0号GPU进行训练
- linux 或者 mac
```shell
export CUDA_VISIBLE_DEVICES=0
```
- windows
```shell
set CUDA_VISIBLE_DEVICES=0
```
#### 不使用预训练模型
```shell
python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml
```
训练完成后,验证集的`Top1 Acc`曲线如下所示,最高准确率为0.2735。训练精度曲线下图所示
<div align="center">
<img src="../../images/quick_start/r50_vd_acc.png" width = "800" />
</div>
#### 使用预训练模型进行训练
基于ImageNet1k分类预训练模型进行微调,训练脚本如下所示
```shell
python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.pretrained=True
```
**注**
- 此训练脚本使用GPU,如使用CPU可按照上文中[使用CPU进行模型训练](#使用CPU进行模型训练)所示,进行修改
验证集的`Top1 Acc`曲线如下所示,最高准确率为0.9402,加载预训练模型之后,flowers102数据集精度大幅提升,绝对精度涨幅超过65%。
<div align="center">
<img src="../../images/quick_start/r50_vd_pretrained_acc.png" width = "800" />
</div>
## 五、模型预测
训练完成后预测代码如下
```shell
cd $path_to_PaddleClas
python3 tools/infer.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml -o Infer.infer_imgs=dataset/flowers102/jpg/image_00001.jpg -o Global.pretrained_model=output/ShuffleNetV2_x0_25/best_model
```
`-i`输入为单张图像路径,运行成功后,示例结果如下:
`[{'class_ids': [76, 65, 34, 9, 69], 'scores': [0.91762, 0.01801, 0.00833, 0.0071, 0.00669], 'file_name': 'dataset/flowers102/jpg/image_00001.jpg', 'label_names': []}]`
`-i`输入为图像集所在目录,运行成功后,示例结果如下:
```txt
[{'class_ids': [76, 65, 34, 9, 69], 'scores': [0.91762, 0.01801, 0.00833, 0.0071, 0.00669], 'file_name': 'dataset/flowers102/jpg/image_00001.jpg', 'label_names': []}, {'class_ids': [76, 69, 34, 28, 9], 'scores': [0.77122, 0.06295, 0.02537, 0.02531, 0.0251], 'file_name': 'dataset/flowers102/jpg/image_00002.jpg', 'label_names': []}, {'class_ids': [99, 76, 81, 85, 16], 'scores': [0.26374, 0.20423, 0.07818, 0.06042, 0.05499], 'file_name': 'dataset/flowers102/jpg/image_00003.jpg', 'label_names': []}, {'class_ids': [9, 37, 34, 24, 76], 'scores': [0.17784, 0.16651, 0.14539, 0.12096, 0.04816], 'file_name': 'dataset/flowers102/jpg/image_00004.jpg', 'label_names': []}, {'class_ids': [76, 66, 91, 16, 13], 'scores': [0.95494, 0.00688, 0.00596, 0.00352, 0.00308], 'file_name': 'dataset/flowers102/jpg/image_00005.jpg', 'label_names': []}, {'class_ids': [76, 66, 34, 8, 43], 'scores': [0.44425, 0.07487, 0.05609, 0.05609, 0.03667], 'file_name': 'dataset/flowers102/jpg/image_00006.jpg', 'label_names': []}, {'class_ids': [86, 93, 81, 22, 21], 'scores': [0.44714, 0.13582, 0.07997, 0.0514, 0.03497], 'file_name': 'dataset/flowers102/jpg/image_00007.jpg', 'label_names': []}, {'class_ids': [13, 76, 81, 18, 97], 'scores': [0.26771, 0.1734, 0.06576, 0.0451, 0.03986], 'file_name': 'dataset/flowers102/jpg/image_00008.jpg', 'label_names': []}, {'class_ids': [34, 76, 8, 5, 9], 'scores': [0.67224, 0.31896, 0.00241, 0.00227, 0.00102], 'file_name': 'dataset/flowers102/jpg/image_00009.jpg', 'label_names': []}, {'class_ids': [76, 34, 69, 65, 66], 'scores': [0.95185, 0.01101, 0.00875, 0.00452, 0.00406], 'file_name': 'dataset/flowers102/jpg/image_00010.jpg', 'label_names': []}]
```
其中,列表的长度为batch_size的大小。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# DLA系列
## 概述
DLA (Deep Layer Aggregation)。 视觉识别需要丰富的表示形式,其范围从低到高,范围从小到大,分辨率从精细到粗糙。即使卷积网络中的要素深度很深,仅靠隔离层还是不够的:将这些表示法进行复合和聚合可改善对内容和位置的推断。尽管已合并了残差连接以组合各层,但是这些连接本身是“浅”的,并且只能通过简单的一步操作来融合。作者通过更深层的聚合来增强标准体系结构,以更好地融合各层的信息。Deep Layer Aggregation 结构迭代地和分层地合并了特征层次结构,以使网络具有更高的准确性和更少的参数。跨体系结构和任务的实验表明,与现有的分支和合并方案相比,Deep Layer Aggregation 可提高识别和分辨率。[论文地址](https://arxiv.org/abs/1707.06484)
## 精度、FLOPS和参数量
| Model | Params (M) | FLOPs (G) | Top-1 (%) | Top-5 (%) |
|:-----------------:|:----------:|:---------:|:---------:|:---------:|
| DLA34 | 15.8 | 3.1 | 76.03 | 92.98 |
| DLA46_c | 1.3 | 0.5 | 63.21 | 85.30 |
| DLA46x_c | 1.1 | 0.5 | 64.36 | 86.01 |
| DLA60 | 22.0 | 4.2 | 76.10 | 92.92 |
| DLA60x | 17.4 | 3.5 | 77.53 | 93.78 |
| DLA60x_c | 1.3 | 0.6 | 66.45 | 87.54 |
| DLA102 | 33.3 | 7.2 | 78.93 | 94.52 |
| DLA102x | 26.4 | 5.9 | 78.10 | 94.00 |
| DLA102x2 | 41.4 | 9.3 | 78.85 | 94.45 |
| DLA169 | 53.5 | 11.6 | 78.09 | 94.09 |
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册