提交 4579d796 编写于 作者: C cuicheng01

Merge new docs to release/2.3

上级 44389ef7
# 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)
# 一、数据增强分类实战
本节将基于ImageNet-1K的数据集详细介绍数据增强实验,如果想快速体验此方法,可以参考[**30分钟玩转PaddleClas(进阶版)**](../quick_start/quick_start_classification.md)中基于CIFAR100的数据增强实验。如果想了解相关算法的内容,请参考[数据增强算法介绍](../algorithm_introduction/DataAugmentation.md)
## 1.1 参数配置
由于不同的数据增强方式含有不同的超参数,为了便于理解和使用,我们在`configs/DataAugment`里分别列举了8种训练ResNet50的数据增强方式的参数配置文件,用户可以在`tools/run.sh`里直接替换配置文件的路径即可使用。此处分别挑选了图像变换、图像裁剪、图像混叠中的一个示例展示,其他参数配置用户可以自查配置文件。
### AutoAugment
`AotoAugment`的图像增广方式的配置如下。`AutoAugment`是在uint8的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`)之前。
```yaml
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- AutoAugment:
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
```
### RandAugment
`RandAugment`的图像增广方式的配置如下,其中用户需要指定其中的参数`num_layers``magnitude`,默认的数值分别是`2``5``RandAugment`是在uint8的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`)之前。
```yaml
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- RandAugment:
num_layers: 2
magnitude: 5
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
```
### TimmAutoAugment
`TimmAutoAugment`的图像增广方式的配置如下,其中用户需要指定其中的参数`config_str``interpolation``img_size`,默认的数值分别是`rand-m9-mstd0.5-inc1``bicubic``224``TimmAutoAugment`是在uint8的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`)之前。
```yaml
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- TimmAutoAugment:
config_str: rand-m9-mstd0.5-inc1
interpolation: bicubic
img_size: 224
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
```
### Cutout
`Cutout`的图像增广方式的配置如下,其中用户需要指定其中的参数`n_holes``length`,默认的数值分别是`1``112`。类似其他图像裁剪类的数据增强方式,`Cutout`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml
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: ''
- Cutout:
n_holes: 1
length: 112
```
### RandomErasing
`RandomErasing`的图像增广方式的配置如下,其中用户需要指定其中的参数`EPSILON``sl``sh``r1``attempt``use_log_aspect``mode`,默认的数值分别是`0.25``0.02``1.0/3.0``0.3``10``True``pixel`。类似其他图像裁剪类的数据增强方式,`RandomErasing`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml
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: ''
- RandomErasing:
EPSILON: 0.25
sl: 0.02
sh: 1.0/3.0
r1: 0.3
attempt: 10
use_log_aspect: True
mode: pixel
```
### HideAndSeek
`HideAndSeek`的图像增广方式的配置如下。类似其他图像裁剪类的数据增强方式,`HideAndSeek`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml
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: ''
- HideAndSeek:
```
### GridMask
`GridMask`的图像增广方式的配置如下,其中用户需要指定其中的参数`d1``d2``rotate``ratio``mode`, 默认的数值分别是`96``224``1``0.5``0`。类似其他图像裁剪类的数据增强方式,`GridMask`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml
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: ''
- GridMask:
d1: 96
d2: 224
rotate: 1
ratio: 0.5
mode: 0
```
### Mixup
`Mixup`的图像增广方式的配置如下,其中用户需要指定其中的参数`alpha`,默认的数值是`0.2`。类似其他图像混合类的数据增强方式,`Mixup`是在图像做完数据处理后将每个batch内的数据做图像混叠,将混叠后的图像和标签输入网络中训练,所以其是在图像数据处理(图像变换、图像裁剪)后操作。
```yaml
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: ''
batch_transform_ops:
- MixupOperator:
alpha: 0.2
```
### Cutmix
`Cutmix`的图像增广方式的配置如下,其中用户需要指定其中的参数`alpha`,默认的数值是`0.2`。类似其他图像混合类的数据增强方式,`Cutmix`是在图像做完数据处理后将每个batch内的数据做图像混叠,将混叠后的图像和标签输入网络中训练,所以其是在图像数据处理(图像变换、图像裁剪)后操作。
```yaml
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: ''
batch_transform_ops:
- CutmixOperator:
alpha: 0.2
```
### Mixup与Cutmix同时使用
`Mixup``与Cutmix`同时使用的配置如下,其中用户需要指定额外的参数`prob`,该参数控制不同数据增强的概率,默认为`0.5`
```yaml
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: ''
- OpSampler:
MixupOperator:
alpha: 0.8
prob: 0.5
CutmixOperator:
alpha: 1.0
prob: 0.5
```
## 1.2 启动命令
当用户配置完训练环境后,类似于训练其他分类任务,只需要将`tools/train.sh`中的配置文件替换成为相应的数据增强方式的配置文件即可。
其中`train.sh`中的内容如下:
```bash
python3 -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \
--log_dir=ResNet50_Cutout \
tools/train.py \
-c ./ppcls/configs/ImageNet/DataAugment/ResNet50_Cutout.yaml
```
运行`train.sh`
```bash
sh tools/train.sh
```
## 1.3 注意事项
* 由于图像混叠时需对label进行混叠,无法计算训练数据的准确率,所以在训练过程中没有打印训练准确率。
* 在使用数据增强后,由于训练数据更难,所以训练损失函数可能较大,训练集的准确率相对较低,但其有拥更好的泛化能力,所以验证集的准确率相对较高。
* 在使用数据增强后,模型可能会趋于欠拟合状态,建议可以适当的调小`l2_decay`的值来获得更高的验证集准确率。
* 几乎每一类图像增强均含有超参数,我们只提供了基于ImageNet-1k的超参数,其他数据集需要用户自己调试超参数,具体超参数的含义用户可以阅读相关的论文,调试方法也可以参考训练技巧的章节。
## 二、实验结果
基于PaddleClas,在ImageNet1k数据集上的分类精度如下。
| 模型 | 初始学习率策略 | l2 decay | batch size | epoch | 数据变化策略 | Top1 Acc | 论文中结论 |
|-------------|------------------|--------------|------------|-------|----------------|------------|----|
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | 标准变换 | 0.7731 | - |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | AutoAugment | 0.7795 | 0.7763 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | mixup | 0.7828 | 0.7790 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | cutmix | 0.7839 | 0.7860 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | cutout | 0.7801 | - |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | gridmask | 0.7785 | 0.7790 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | random-augment | 0.7770 | 0.7760 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | random erasing | 0.7791 | - |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | hide and seek | 0.7743 | 0.7720 |
**注意**
* 在这里的实验中,为了便于对比,我们将l2 decay固定设置为1e-4,在实际使用中,我们推荐尝试使用更小的l2 decay。结合数据增强,我们发现将l2 decay由1e-4减小为7e-5均能带来至少0.3~0.5%的精度提升。
* 我们目前尚未对不同策略进行组合并验证效果,这一块后续我们会开展更多的对比实验,敬请期待。
# PaddleClas代码解析
## 1. 整体代码结构解析
### 1.1 整体代码和目录概览
PaddleClas主要代码和目录结构如下
* benchmark: 文件夹下存放了一些shell脚本,主要是为了测试PaddleClas中不同模型的速度指标,如单卡训练速度指标、多卡训练速度指标等。
* dataset:文件夹下存放数据集和用于处理数据集的脚本。脚本负责将数据集处理为适合Dataloader处理的格式。
* deploy:部署核心代码,文件夹存放的是部署工具,支持 python/cpp inference、Hub Serveing、Paddle Lite、Slim离线量化等多种部署方式。
* ppcls:训练核心代码,文件夹下存放PaddleClas框架主体。配置文件、模型训练、评估、预测、动转静导出等具体代码实现均在这里。
* tools:训练、评估、预测、模型动转静导出的入口函数和脚本均在该文件下。
* requirements.txt 文件用于安装 PaddleClas 的依赖项。使用pip进行升级安装使用。
* tests:PaddleClas模型从训练到预测的全链路测试,验证各功能是否能够正常使用。
### 1.2 训练模块定义
深度学习模型训练过程中,主要包含以下几个核心模块。
* 数据:对于有监督任务来说,训练数据一般包含原始数据及其标注。在基于单标签的图像分类任务中,原始数据指的是图像数据,而标注则是该图像数据所属的类比。PaddleClas中,训练时需要提供标签文件,形式如下,每一行包含一条训练样本,分别表示图片路径和类别标签,用分隔符隔开(默认为空格)。
```
train/n01440764/n01440764_10026.JPEG 0
train/n01440764/n01440764_10027.JPEG 0
```
在代码`ppcls/data/dataloader/common_dataset.py`中,包含`CommonDataset`类,继承自`paddle.io.Dataset`,该数据集类可以通过一个键值进行索引并获取指定样本。`ImageNetDataset`, `LogoDataset`, `CommonDataset` 等数据集类都对这个类别
对于读入的数据,需要通过数据转换,将原始的图像数据进行转换。训练时,标准的数据预处理包含:`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
class_num: 1000
pretrained: False
use_ssld: False
```
`Arch.name` 表示模型名称, `Arch.pretrained` 表示是否添加预训练模型,`use_ssld` 表示是否使用基于 `SSLD` 知识蒸馏得到的预训练模型。所有的模型名称均在 `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``Adam``AdamW`等几种优化器策略。
权重衰减策略是一种比较常用的正则化方法,主要用于防止模型过拟合。 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()` 函数实现的,存储的是模型的动态图版本,以字典的形式存储,便于继续训练。具体实现如下
```python
def 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. 优化器参数也需要存储,方便后续的加载断点进行训练。
* 模型裁剪、量化训练
如果想对模型进行压缩训练,则通过下面字段进行配置
模型裁剪:
```yaml
Slim:
prune:
name: fpgm
pruned_ratio: 0.3
```
模型量化:
```yaml
Slim:
quant:
name: pact
```
训练方法详见模型[裁剪量化使用介绍](../advanced_tutorials/model_prune_quantization.md), 算法介绍详见[裁剪量化算法介绍](../algorithm_introduction/model_prune_quantization.md)
### 1.3 预测部署代码和方式
* 如果希望在服务端使用 cpp 进行部署,可以参考 [cpp inference 预测教程](../../../deploy/cpp_infer/readme.md)
* 如果希望将分类模型部署为服务,可以参考 [hub serving 预测部署教程](../../../deploy/hubserving/readme.md)
* 如果希望将对分类模型进行离线量化,可以参考 [模型量化裁剪教程](../advanced_tutorials/model_prune_quantization.md) 中离线量化部分。
* 如果希望在移动端使用分类模型进行预测,可以参考 [PaddleLite 预测部署教程](../../../deploy/lite/readme.md)
知识蒸馏
================================
.. toctree::
:maxdepth: 3
distillation.md
# PaddleClas 社区贡献指南
### 1.1 PaddleClas 分支说明
PaddleClas 未来将维护 2 种分支,分别为:
* release/x.x 系列分支:为稳定的发行版本分支,会适时打 tag 发布版本,适配 Paddle 的 release 版本。当前最新的分支为 release/2.3 分支,是当前默认分支,适配 Paddle v2.1.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 中积极贡献代码,下面给出一些贡献代码的基本流程。
### 1.2 PaddleClas 代码提交流程与规范
#### 1.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>
#### 1.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) 时,始终保持本地仓库最新。
#### 1.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'
```
#### 1.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`
#### 1.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"
```
#### 1.2.6 保持本地仓库最新
获取 upstream 的最新代码并更新当前分支。这里的 upstream 来自于 1.2 节的`和远程仓库建立连接`部分。
```shell
git fetch upstream
# 如果是希望提交到其他分支,则需要从upstream的其他分支pull代码,这里是develop
git pull upstream develop
```
#### 1.2.7 push到远程仓库
```shell
git push origin new_branch
```
#### 1.2.8 提交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>
#### 1.2.9 签署 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 页面
#### 1.2.10 删除分支
* 删除远程分支
在 PR 被 merge 进主仓库后,我们可以在 PR 的页面删除远程仓库的分支。
也可以使用 `git push origin :分支名` 删除远程分支,如:
```shell
git push origin :new_branch
```
* 删除本地分支
```shell
# 切换到develop分支,否则无法删除当前分支
git checkout develop
# 删除new_branch分支
git branch -D new_branch
```
#### 1.2.11 提交代码的一些约定
为了使官方维护人员在评审代码时更好地专注于代码本身,请您每次提交代码时,遵守以下约定:
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` 进行回复,而非直接回复的方式。原因是每个回复都会发送一封邮件,会造成邮件灾难。
## 2. 总结
* 开源社区依赖于众多开发者与用户的贡献和反馈,在这里感谢与期待大家向 PaddleClas 提出宝贵的意见与 Pull Request ,希望我们可以一起打造一个领先实用全面的图像识别代码仓库!
## 3. 参考文献
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)
图像增广
================================
.. toctree::
:maxdepth: 3
ImageAugment.md
高阶使用
================================
.. toctree::
:maxdepth: 1
image_augmentation/index
distillation/index
multilabel/index
# 知识蒸馏 # 知识蒸馏
## 一、模型压缩方法简介 ## 一、模型压缩与知识蒸馏方法简介
近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。 近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。
在数据量足够大的情况下,通过合理构建网络模型的方式增加其参数量,可以显著改善模型性能,但是这又带来了模型复杂度急剧提升的问题。大模型在实际场景中使用的成本较高。 在数据量足够大的情况下,通过合理构建网络模型的方式增加其参数量,可以显著改善模型性能,但是这又带来了模型复杂度急剧提升的问题。大模型在实际场景中使用的成本较高。
深度神经网络一般有较多的参数冗余,目前有几种主要的方法对模型进行压缩,减小其参数量。如裁剪、量化、知识蒸馏等,其中知识蒸馏是指使用教师模型(teacher model)去指导学生模型(student model)学习特定任务,保证小模型在参数量不变的情况下,得到比较大的性能提升,甚至获得与大模型相似的精度指标[1]。PaddleClas融合已有的蒸馏方法[2,3],提供了一种简单的半监督标签知识蒸馏方案(SSLD,Simple Semi-supervised Label Distillation),基于ImageNet1k分类数据集,在ResNet_vd以及MobileNet系列上的精度均有超过3%的绝对精度提升,具体指标如下图所示。 深度神经网络一般有较多的参数冗余,目前有几种主要的方法对模型进行压缩,减小其参数量。如裁剪、量化、知识蒸馏等,其中知识蒸馏是指使用教师模型 (teacher model) 去指导学生模型 (student model) 学习特定任务,保证小模型在参数量不变的情况下,得到比较大的性能提升,甚至获得与大模型相似的精度指标 [1]。 PaddleClas 融合已有的蒸馏方法 [2,3] ,提供了一种简单的半监督标签知识蒸馏方案 (SSLD,Simple Semi-supervised Label Distillation) ,基于 ImageNet1k 分类数据集,在 ResNet_vd 以及 MobileNet 系列上的精度均有超过 3% 的绝对精度提升,具体指标如下图所示。
![](../../../images/distillation/distillation_perform_s.jpg)
<div align="center">
<img src="../../images/distillation/distillation_perform_s.jpg" width = "600" />
</div>
## 二、SSLD 蒸馏策略 ## 二、SSLD 蒸馏策略
### 2.1 简介 ### 2.1 简介
SSLD的流程图如下图所示。 SSLD 的流程图如下图所示。
![](../../../images/distillation/ppcls_distillation.png) <div align="center">
<img src="../../images/distillation/ppcls_distillation.png" width = "600" />
</div>
首先,我们从ImageNet22k中挖掘出了近400万张图片,同时与ImageNet-1k训练集整合在一起,得到了一个新的包含500万张图片的数据集。然后,我们将学生模型与教师模型组合成一个新的网络,该网络分别输出学生模型和教师模型的预测分布,与此同时,固定教师模型整个网络的梯度,而学生模型可以做正常的反向传播。最后,我们将两个模型的logits经过softmax激活函数转换为soft label,并将二者的soft label做JS散度作为损失函数,用于蒸馏模型训练。下面以MobileNetV3(该模型直接训练,精度为75.3%)的知识蒸馏为例,介绍该方案的核心关键点(baseline为79.12%的ResNet50_vd模型蒸馏MobileNetV3,训练集为ImageNet1k训练集,loss为cross entropy loss,迭代轮数为120epoch,精度指标为75.6%)。 首先,我们从 ImageNet22k 中挖掘出了近400万张图片,同时与 ImageNet-1k 训练集整合在一起,得到了一个新的包含 500 万张图片的数据集。然后,我们将学生模型与教师模型组合成一个新的网络,该网络分别输出学生模型和教师模型的预测分布,与此同时,固定教师模型整个网络的梯度,而学生模型可以做正常的反向传播。最后,我们将两个模型的 logits 经过 softmax 激活函数转换为 soft label ,并将二者的 soft label 做 JS 散度作为损失函数,用于蒸馏模型训练。下面以 MobileNetV3 (该模型直接训练,精度为 75.3%) 的知识蒸馏为例,介绍该方案的核心关键点( baseline 为 79.12% 的 ResNet50_vd 模型蒸馏 MobileNetV3 ,训练集为 ImageNet1k 训练集, loss 为 cross entropy loss ,迭代轮数为 120epoch ,精度指标为 75.6% )。
* 教师模型的选择。在进行知识蒸馏时,如果教师模型与学生模型的结构差异太大,蒸馏得到的结果反而不会有太大收益。相同结构下,精度更高的教师模型对结果也有很大影响。相比于79.12%的ResNet50_vd教师模型,使用82.4%的ResNet50_vd教师模型可以带来0.4%的绝对精度收益(`75.6%->76.0%`)。 * 教师模型的选择。在进行知识蒸馏时,如果教师模型与学生模型的结构差异太大,蒸馏得到的结果反而不会有太大收益。相同结构下,精度更高的教师模型对结果也有很大影响。相比于 79.12% 的 ResNet50_vd 教师模型,使用 82.4% 的 ResNet50_vd 教师模型可以带来 0.4% 的绝对精度收益( `75.6%->76.0%` )。
* 改进loss计算方法。分类loss计算最常用的方法就是cross entropy loss,我们经过实验发现,在使用soft label进行训练时,相对于cross entropy loss,KL div loss对模型性能提升几乎无帮助,但是使用具有对称特性的JS div loss时,在多个蒸馏任务上相比cross entropy loss均有0.2%左右的收益(`76.0%->76.2%`),SSLD中也基于JS div loss展开实验。 * 改进 loss 计算方法。分类 loss 计算最常用的方法就是 cross entropy loss ,我们经过实验发现,在使用 soft label 进行训练时,相对于 cross entropy loss , KL div loss 对模型性能提升几乎无帮助,但是使用具有对称特性的 JS div loss 时,在多个蒸馏任务上相比 cross entropy loss 均有 0.2% 左右的收益( `76.0%->76.2%` ), SSLD 中也基于 JS div loss 展开实验。
* 更多的迭代轮数。蒸馏的baseline实验只迭代了120个epoch。实验发现,迭代轮数越多,蒸馏效果越好,最终我们迭代了360epoch,精度指标可以达到77.1%(`76.2%->77.1%`) * 更多的迭代轮数。蒸馏的 baseline 实验只迭代了 120 个 epoch 。实验发现,迭代轮数越多,蒸馏效果越好,最终我们迭代了 360epoch ,精度指标可以达到 77.1%(`76.2%->77.1%`)
* 无需数据集的真值标签,很容易扩展训练集。SSLD的loss在计算过程中,仅涉及到教师和学生模型对于相同图片的处理结果(经过softmax激活函数处理之后的soft label),因此即使图片数据不包含真值标签,也可以用来进行训练并提升模型性能。该蒸馏方案的无标签蒸馏策略也大大提升了学生模型的性能上限(`77.1%->78.5%`)。 * 无需数据集的真值标签,很容易扩展训练集。 SSLD 的 loss 在计算过程中,仅涉及到教师和学生模型对于相同图片的处理结果(经过 softmax 激活函数处理之后的 soft label ),因此即使图片数据不包含真值标签,也可以用来进行训练并提升模型性能。该蒸馏方案的无标签蒸馏策略也大大提升了学生模型的性能上限( `77.1%->78.5%` )。
* ImageNet1k蒸馏finetune。我们仅使用ImageNet1k数据,使用蒸馏方法对上述模型进行finetune,最终仍然可以获得0.4%的性能提升(`78.5%->78.9%`)。 * ImageNet1k 蒸馏 finetune 。 我们仅使用 ImageNet1k 数据,使用蒸馏方法对上述模型进行 finetune ,最终仍然可以获得 0.4% 的性能提升( `78.5%->78.9%` )。
### 2.2 数据选择 ### 2.2 数据选择
* SSLD 蒸馏方案的一大特色就是无需使用图像的真值标签,因此可以任意扩展数据集的大小,考虑到计算资源的限制,我们在这里仅基于 ImageNet22k 数据集对蒸馏任务的训练集进行扩充。在 SSLD 蒸馏任务中,我们使用了 `Top-k per class` 的数据采样方案 [3] 。具体步骤如下。
* 训练集去重。我们首先基于 SIFT 特征相似度匹配的方式对 ImageNet22k 数据集与 ImageNet1k 验证集进行去重,防止添加的 ImageNet22k 训练集中包含 ImageNet1k 验证集图像,最终去除了 4511 张相似图片。部分过滤的相似图片如下所示。
* SSLD蒸馏方案的一大特色就是无需使用图像的真值标签,因此可以任意扩展数据集的大小,考虑到计算资源的限制,我们在这里仅基于ImageNet22k数据集对蒸馏任务的训练集进行扩充。在SSLD蒸馏任务中,我们使用了`Top-k per class`的数据采样方案[3]。具体步骤如下。 <div align="center">
* 训练集去重。我们首先基于SIFT特征相似度匹配的方式对ImageNet22k数据集与ImageNet1k验证集进行去重,防止添加的ImageNet22k训练集中包含ImageNet1k验证集图像,最终去除了4511张相似图片。部分过滤的相似图片如下所示。 <img src="../../images/distillation/22k_1k_val_compare_w_sift.png" width = "600" />
</div>
![](../../../images/distillation/22k_1k_val_compare_w_sift.png)
* 大数据集soft label获取,对于去重后的ImageNet22k数据集,我们使用`ResNeXt101_32x16d_wsl`模型进行预测,得到每张图片的soft label * 大数据集 soft label 获取,对于去重后的 ImageNet22k 数据集,我们使用 `ResNeXt101_32x16d_wsl` 模型进行预测,得到每张图片的 soft label
* Top-k数据选择,ImageNet1k数据共有1000类,对于每一类,找出属于该类并且得分最高的k张图片,最终得到一个数据量不超过`1000*k`的数据集(某些类上得到的图片数量可能少于k张)。 * Top-k 数据选择, ImageNet1k 数据共有 1000 类,对于每一类,找出属于该类并且得分最高的 `k` 张图片,最终得到一个数据量不超过`1000*k`的数据集(某些类上得到的图片数量可能少于 `k` 张)。
* 将该数据集与ImageNet1k的训练集融合组成最终蒸馏模型所使用的数据集,数据量为500万。 * 将该数据集与 ImageNet1k 的训练集融合组成最终蒸馏模型所使用的数据集,数据量为 500 万。
## 三、实验 ## 三、实验
* PaddleClas的蒸馏策略为`大数据集训练+ImageNet1k蒸馏finetune`的策略。选择合适的教师模型,首先在挑选得到的500万数据集上进行训练,然后在ImageNet1k训练集上进行finetune,最终得到蒸馏后的学生模型。 * PaddleClas 的蒸馏策略为`大数据集训练 + ImageNet1k 蒸馏 finetune`的策略。选择合适的教师模型,首先在挑选得到的 500 万数据集上进行训练,然后在 ImageNet1k 训练集上进行 finetune,最终得到蒸馏后的学生模型。
### 3.1 教师模型的选择 ### 3.1 教师模型的选择
...@@ -70,13 +73,13 @@ SSLD的流程图如下图所示。 ...@@ -70,13 +73,13 @@ SSLD的流程图如下图所示。
> 教师模型与学生模型的模型大小差异不宜过大,否则反而会影响蒸馏结果的精度。 > 教师模型与学生模型的模型大小差异不宜过大,否则反而会影响蒸馏结果的精度。
因此最终在蒸馏实验中,对于ResNet系列学生模型,我们使用`ResNeXt101_32x16d_wsl`作为教师模型;对于MobileNet系列学生模型,我们使用蒸馏得到的`ResNet50_vd`作为教师模型。 因此最终在蒸馏实验中,对于ResNet系列学生模型,我们使用 `ResNeXt101_32x16d_wsl` 作为教师模型;对于 MobileNet 系列学生模型,我们使用蒸馏得到的 `ResNet50_vd` 作为教师模型。
### 3.2 大数据蒸馏 ### 3.2 大数据蒸馏
基于PaddleClas的蒸馏策略为`大数据集训练+imagenet1k finetune`的策略。 基于 PaddleClas 的蒸馏策略为`大数据集训练 + imagenet1k finetune` 的策略。
针对从ImageNet22k挑选出的400万数据,融合imagenet1k训练集,组成共500万的训练集进行训练,具体地,在不同模型上的训练超参及效果如下。 针对从 ImageNet22k 挑选出的 400 万数据,融合 imagenet1k 训练集,组成共 500 万的训练集进行训练,具体地,在不同模型上的训练超参及效果如下。
|Student Model | num_epoch | l2_ecay | batch size/gpu cards | base lr | learning rate decay | top1 acc | |Student Model | num_epoch | l2_ecay | batch size/gpu cards | base lr | learning rate decay | top1 acc |
...@@ -89,9 +92,9 @@ SSLD的流程图如下图所示。 ...@@ -89,9 +92,9 @@ SSLD的流程图如下图所示。
| ResNet101_vd | 360 | 7e-5 | 1024/32 | 0.4 | cosine_decay_warmup | 83.41% | | 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% | | Res2Net200_vd_26w_4s | 360 | 4e-5 | 1024/32 | 0.4 | cosine_decay_warmup | 84.82% |
### 3.3 ImageNet1k训练集finetune ### 3.3 ImageNet1k 训练集 finetune
对于在大数据集上训练的模型,其学习到的特征可能与ImageNet1k数据特征有偏,因此在这里使用ImageNet1k数据集对模型进行finetune。finetune的超参和finetune的精度收益如下。 对于在大数据集上训练的模型,其学习到的特征可能与 ImageNet1k 数据特征有偏,因此在这里使用 ImageNet1k 数据集对模型进行 finetune。 finetune 的超参和 finetune 的精度收益如下。
|Student Model | num_epoch | l2_ecay | batch size/gpu cards | base lr | learning rate decay | top1 acc | |Student Model | num_epoch | l2_ecay | batch size/gpu cards | base lr | learning rate decay | top1 acc |
...@@ -105,17 +108,17 @@ SSLD的流程图如下图所示。 ...@@ -105,17 +108,17 @@ SSLD的流程图如下图所示。
| Res2Net200_vd_26w_4s | 360 | 4e-5 | 1024/32 | 0.004 | cosine_decay_warmup | 85.13% | | Res2Net200_vd_26w_4s | 360 | 4e-5 | 1024/32 | 0.004 | cosine_decay_warmup | 85.13% |
### 3.4 数据增广以及基于Fix策略的微调 ### 3.4 数据增广以及基于 Fix 策略的微调
* 基于前文所述的实验结论,我们在训练的过程中加入自动增广(AutoAugment)[4],同时进一步减小了l2_decay(4e-5->2e-5),最终ResNet50_vd经过SSLD蒸馏策略,在ImageNet1k上的精度可以达到82.99%,相比之前不加数据增广的蒸馏策略再次增加了0.6% * 基于前文所述的实验结论,我们在训练的过程中加入自动增广 (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%** * 对于图像分类任务,在测试的时候,测试尺度为训练尺度的 1.15 倍左右时,往往在不需要重新训练模型的情况下,模型的精度指标就可以进一步提升 [5] ,对于 82.99% 的 ResNet50_vd 在 320x320 的尺度下测试,精度可达 83.7% ,我们进一步使用 Fix 策略,即在 320x320 的尺度下进行训练,使用与预测时相同的数据预处理方法,同时固定除 FC 层以外的所有参数,最终在 320x320 的预测尺度下,精度可以达到 **84.0%**
### 3.5 实验过程中的一些问题 ### 3.5 实验过程中的一些问题
* 在预测过程中,batch norm的平均值与方差是通过加载预训练模型得到(设其模式为test mode)。在训练过程中,batch norm是通过统计当前batch的信息(设其模式为train mode),与历史保存信息进行滑动平均计算得到,在蒸馏任务中,我们发现通过train mode,即教师模型的bn实时变化的模式,去指导学生模型,比通过test mode蒸馏,得到的学生模型性能更好一些,下面是一组实验结果。因此我们在该蒸馏方案中,均使用train mode去得到教师模型的soft label * 在预测过程中, batch norm 的平均值与方差是通过加载预训练模型得到(设其模式为 test mode )。在训练过程中, batch norm 是通过统计当前 batch 的信息(设其模式为 train mode ),与历史保存信息进行滑动平均计算得到,在蒸馏任务中,我们发现通过 train mode ,即教师模型的均值与方差实时变化的模式,去指导学生模型,比通过 test mode 蒸馏,得到的学生模型性能更好一些,下面是一组实验结果。因此我们在该蒸馏方案中,均使用 train mode 去得到教师模型的 soft label
|Teacher Model | Teacher Top1 | Student Model | Student Top1| |Teacher Model | Teacher Top1 | Student Model | Student Top1|
|- |:-: |:-: | :-: | |- |:-: |:-: | :-: |
...@@ -128,16 +131,16 @@ SSLD的流程图如下图所示。 ...@@ -128,16 +131,16 @@ SSLD的流程图如下图所示。
### 4.1 使用方法 ### 4.1 使用方法
* 中间层学习率调整。蒸馏得到的模型的中间层特征图更加精细化,因此将蒸馏模型预训练应用到其他任务中时,如果采取和之前相同的学习率,容易破坏中间层特征。而如果降低整体模型训练的学习率,则会带来训练收敛速度慢的问题。因此我们使用了中间层学习率调整的策略。具体地: * 中间层学习率调整。蒸馏得到的模型的中间层特征图更加精细化,因此将蒸馏模型预训练应用到其他任务中时,如果采取和之前相同的学习率,容易破坏中间层特征。而如果降低整体模型训练的学习率,则会带来训练收敛速度慢的问题。因此我们使用了中间层学习率调整的策略。具体地:
* 针对ResNet50_vd,我们设置一个学习率倍数列表,res block之前的3个conv2d卷积参数具有统一的学习率倍数,4个res block的conv2d分别有一个学习率参数,共需设置5个学习率倍数的超参。在实验中发现。用于迁移学习finetune分类模型时,`[0.1,0.1,0.2,0.2,0.3]`的中间层学习率倍数设置在绝大多数的任务中都性能更好;而在目标检测任务中,`[0.05,0.05,0.05,0.1,0.15]`的中间层学习率倍数设置能够带来更大的精度收益。 * 针对 ResNet50_vd ,我们设置一个学习率倍数列表, res block 之前的 3 个 conv2d 卷积参数具有统一的学习率倍数, 4 个 res block 的 conv2d 分别有一个学习率参数,共需设置 5 个学习率倍数的超参。在实验中发现。用于迁移学习finetune分类模型时, `[0.1,0.1,0.2,0.2,0.3]` 的中间层学习率倍数设置在绝大多数的任务中都性能更好;而在目标检测任务中, `[0.05,0.05,0.05,0.1,0.15]` 的中间层学习率倍数设置能够带来更大的精度收益。
* 对于MoblileNetV3_large_x1_0,由于其包含15个block,我们设置每3个block共享一个学习率倍数参数,因此需要共5个学习率倍数的参数,最终发现在分类和检测任务中,`[0.25,0.25,0.5,0.5,0.75]`的中间层学习率倍数能够带来更大的精度收益。 * 对于 MoblileNetV3_large_x1_0 ,由于其包含 15 个 block ,我们设置每 3 个 block 共享一个学习率倍数参数,因此需要共 5 个学习率倍数的参数,最终发现在分类和检测任务中, `[0.25,0.25,0.5,0.5,0.75]` 的中间层学习率倍数能够带来更大的精度收益。
* 适当的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%的提升)。 * 适当的 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 ### 4.2 迁移学习 finetune
* 为验证迁移学习的效果,我们在10个小的数据集上验证其效果。在这里为了保证实验的可对比性,我们均使用ImageNet1k数据集训练的标准预处理过程,对于蒸馏模型我们也添加了蒸馏模型中间层学习率的搜索。 * 为验证迁移学习的效果,我们在 10 个小的数据集上验证其效果。在这里为了保证实验的可对比性,我们均使用 ImageNet1k 数据集训练的标准预处理过程,对于蒸馏模型我们也添加了蒸馏模型中间层学习率的搜索。
* 对于ResNet50_vd,baseline为Top1 Acc 79.12%的预训练模型基于grid search搜索得到的最佳精度,对比实验则为基于该精度对预训练和中间层学习率进一步搜索得到的最佳精度。下面给出10个数据集上所有baseline和蒸馏模型的精度对比。 * 对于 ResNet50_vd , baseline 为 Top1 Acc 79.12% 的预训练模型基于 grid search 搜索得到的最佳精度,对比实验则为基于该精度对预训练和中间层学习率进一步搜索得到的最佳精度。下面给出 10 个数据集上所有 baseline 和蒸馏模型的精度对比。
| Dataset | Model | Baseline Top1 Acc | Distillation Model Finetune | | Dataset | Model | Baseline Top1 Acc | Distillation Model Finetune |
...@@ -153,16 +156,16 @@ SSLD的流程图如下图所示。 ...@@ -153,16 +156,16 @@ SSLD的流程图如下图所示。
| cifar10 | ResNete50_vd | 97.72% | 97.94% | | cifar10 | ResNete50_vd | 97.72% | 97.94% |
| Food-101 | ResNete50_vd | 89.58% | 89.99% | | Food-101 | ResNete50_vd | 89.58% | 89.99% |
* 可以看出在上面10个数据集上,结合适当的中间层学习率倍数设置,蒸馏模型平均能够带来1%以上的精度提升。 * 可以看出在上面 10 个数据集上,结合适当的中间层学习率倍数设置,蒸馏模型平均能够带来 1% 以上的精度提升。
### 4.3 目标检测 ### 4.3 目标检测
我们基于两阶段目标检测Faster/Cascade RCNN模型验证蒸馏得到的预训练模型的效果。 我们基于两阶段目标检测 Faster/Cascade RCNN 模型验证蒸馏得到的预训练模型的效果。
* ResNet50_vd * ResNet50_vd
设置训练与评测的尺度均为640x640,最终COCO上检测指标如下。 设置训练与评测的尺度均为 640x640 ,最终 COCO 上检测指标如下。
| Model | train/test scale | pretrain top1 acc | feature map lr | coco mAP | | Model | train/test scale | pretrain top1 acc | feature map lr | coco mAP |
|- |:-: |:-: | :-: | :-: | |- |:-: |:-: | :-: | :-: |
...@@ -170,16 +173,16 @@ SSLD的流程图如下图所示。 ...@@ -170,16 +173,16 @@ SSLD的流程图如下图所示。
| 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 | 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% | | 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) 在这里可以看出,对于未蒸馏模型,过度调整中间层学习率反而降低最终检测模型的性能指标。基于该蒸馏模型,我们也提供了领先的服务端实用目标检测方案,详细的配置与训练代码均已开源,可以参考 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/master/configs/rcnn_enhance)
## 五、SSLD实战 ## 五、SSLD实战
本节将基于ImageNet-1K的数据集详细介绍SSLD蒸馏实验,如果想快速体验此方法,可以参考[**30分钟玩转PaddleClas(进阶版)**](../../tutorials/quick_start_professional.md)中基于CIFAR100的SSLD蒸馏实验。 本节将基于 ImageNet-1K 的数据集详细介绍 SSLD 蒸馏实验,如果想快速体验此方法,可以参考 [**30分钟玩转PaddleClas(进阶版)**](../../tutorials/quick_start_professional.md) 中基于 CIFAR100 的 SSLD 蒸馏实验。
### 5.1 参数配置 ### 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`里直接替换配置文件的路径即可使用。 实战部分提供了 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 ```yaml
Arch: Arch:
...@@ -202,14 +205,14 @@ Arch: ...@@ -202,14 +205,14 @@ Arch:
infer_model_name: "Student" infer_model_name: "Student"
``` ```
在参数配置中,`freeze_params_list`中需要指定模型是否需要冻结参数,`models`中需要指定Teacher模型和Student模型,其中Teacher模型需要加载预训练模型。用户可以直接在此处更改模型。 在参数配置中,`freeze_params_list` 中需要指定模型是否需要冻结参数, `models` 中需要指定 Teacher 模型和 Student 模型,其中 Teacher 模型需要加载预训练模型。用户可以直接在此处更改模型。
### 5.2 启动命令 ### 5.2 启动命令
当用户配置完训练环境后,类似于训练其他分类任务,只需要将`tools/train.sh`中的配置文件替换成为相应的蒸馏配置文件即可。 当用户配置完训练环境后,类似于训练其他分类任务,只需要将 `tools/train.sh` 中的配置文件替换成为相应的蒸馏配置文件即可。
其中`train.sh`中的内容如下: 其中 `train.sh` 中的内容如下:
```bash ```bash
...@@ -220,7 +223,7 @@ python -m paddle.distributed.launch \ ...@@ -220,7 +223,7 @@ python -m paddle.distributed.launch \
-c ./ppcls/configs/ImageNet/Distillation/mv3_large_x1_0_distill_mv3_small_x1_0.yaml -c ./ppcls/configs/ImageNet/Distillation/mv3_large_x1_0_distill_mv3_small_x1_0.yaml
``` ```
运行`train.sh` 运行 `train.sh`
```bash ```bash
sh tools/train.sh sh tools/train.sh
...@@ -228,16 +231,13 @@ sh tools/train.sh ...@@ -228,16 +231,13 @@ sh tools/train.sh
### 5.3 注意事项 ### 5.3 注意事项
* 用户在使用SSLD蒸馏之前,首先需要在目标数据集上训练一个教师模型,该教师模型用于指导学生模型在该数据集上的训练。 * 用户在使用 SSLD 蒸馏之前,首先需要在目标数据集上训练一个教师模型,该教师模型用于指导学生模型在该数据集上的训练。
* 如果学生模型没有加载预训练模型,训练的其他超参数可以参考该学生模型在ImageNet-1k上训练的超参数,如果学生模型加载了预训练模型,学习率可以调整到原来的1/10或者1/100。
* 在SSLD蒸馏的过程中,学生模型只学习soft-label导致训练目标变的更加复杂,建议可以适当的调小`l2_decay`的值来获得更高的验证集准确率。
* 若用户准备添加无标签的训练数据,只需要将新的训练数据放置在原本训练数据的路径下,生成新的数据list即可,另外,新生成的数据list需要将无标签的数据添加伪标签(只是为了统一读数据) * 如果学生模型没有加载预训练模型,训练的其他超参数可以参考该学生模型在 ImageNet-1k 上训练的超参数,如果学生模型加载了预训练模型,学习率可以调整到原来的 1/10 或者 1/100
* 在 SSLD 蒸馏的过程中,学生模型只学习 soft-label 导致训练目标变的更加复杂,建议可以适当的调小 `l2_decay` 的值来获得更高的验证集准确率。
> 如果您觉得此文档对您有帮助,欢迎star我们的项目:[https://github.com/PaddlePaddle/PaddleClas](https://github.com/PaddlePaddle/PaddleClas) * 若用户准备添加无标签的训练数据,只需要将新的训练数据放置在原本训练数据的路径下,生成新的数据 list 即可,另外,新生成的数据 list 需要将无标签的数据添加伪标签(只是为了统一读数据)。
## 参考文献 ## 参考文献
......
## 模型量化、裁剪使用介绍
复杂的模型有利于提高模型的性能,但也导致模型中存在一定冗余。此部分提供精简模型的功能,包括两部分:模型量化(量化训练、离线量化)、模型剪枝。
其中模型量化将全精度缩减到定点数减少这种冗余,达到减少模型计算复杂度,提高模型推理性能的目的。
模型量化可以在基本不损失模型的精度的情况下,将FP32精度的模型参数转换为Int8精度,减小模型参数大小并加速计算,使用量化后的模型在移动端等部署时更具备速度优势。
模型剪枝将CNN中不重要的卷积核裁剪掉,减少模型参数量,从而降低模型计算复杂度。
本教程将介绍如何使用飞桨模型压缩库PaddleSlim做PaddleClas模型的压缩,即裁剪、量化功能。
[PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim) 集成了模型剪枝、量化(包括量化训练和离线量化)、蒸馏和神经网络搜索等多种业界常用且领先的模型压缩功能,如果您感兴趣,可以关注并了解。
在开始本教程之前,建议先了解[PaddleClas模型的训练方法](../models_training/classification.md)以及[PaddleSlim](https://paddleslim.readthedocs.io/zh_CN/latest/index.html),相关裁剪、量化方法可以参考[模型裁剪量化算法介绍文档](../algorithm_introduction/model_prune_quantization.md)
## 快速开始
当训练出一个模型后,如果希望进一步的压缩模型大小并加速预测,可使用量化或者剪枝的方法压缩模型。
模型压缩主要包括五个步骤:
1. 安装 PaddleSlim
2. 准备训练好的模型
3. 模型压缩
4. 导出量化推理模型
5. 量化模型预测部署
### 1. 安装PaddleSlim
* 可以通过pip install的方式进行安装。
```bash
pip install paddleslim -i https://pypi.tuna.tsinghua.edu.cn/simple
```
* 如果获取PaddleSlim的最新特性,可以从源码安装。
```bash
git clone https://github.com/PaddlePaddle/PaddleSlim.git
cd Paddleslim
python3.7 setup.py install
```
### 2. 准备训练好的模型
PaddleClas提供了一系列训练好的[模型](../models/models_intro.md),如果待量化的模型不在列表中,需要按照[常规训练](../models_training/classification.md)方法得到训练好的模型。
### 3. 模型裁剪、量化
进入PaddleClas根目录
```bash
cd PaddleClas
```
`slim`训练相关代码已经集成到`ppcls/engine/`下,离线量化代码位于`deploy/slim/quant_post_static.py`
#### 3.1 模型量化
量化训练包括离线量化训练和在线量化训练,在线量化训练效果更好,需加载预训练模型,在定义好量化策略后即可对模型进行量化。
##### 3.1.1 在线量化训练
训练指令如下:
* CPU/单卡GPU
以CPU为例,若使用GPU,则将命令中改成`cpu`改成`gpu`
```bash
python3.7 tools/train.py -c ppcls/configs/slim/ResNet50_vd_quantization.yaml -o Global.device=cpu
```
其中`yaml`文件解析详见[参考文档](../models_training/config_description.md)。为了保证精度,`yaml`文件中已经使用`pretrained model`.
* 单机多卡/多机多卡启动
```bash
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3.7 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ppcls/configs/slim/ResNet50_vd_quantization.yaml
```
##### 3.1.2 离线量化
**注意**:目前离线量化,必须使用已经训练好的模型,导出的`inference model`进行量化。一般模型导出`inference model`可参考[教程](../inference_deployment/export_model.md).
一般来说,离线量化损失模型精度较多。
生成`inference model`后,离线量化运行方式如下
```bash
python3.7 deploy/slim/quant_post_static.py -c ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml -o Global.save_inference_dir=./deploy/models/class_ResNet50_vd_ImageNet_infer
```
`Global.save_inference_dir``inference model`存放的目录。
执行成功后,在`Global.save_inference_dir`的目录下,生成`quant_post_static_model`文件夹,其中存储生成的离线量化模型,其可以直接进行预测部署,无需再重新导出模型。
#### 3.2 模型剪枝
训练指令如下:
- CPU/单卡GPU
以CPU为例,若使用GPU,则将命令中改成`cpu`改成`gpu`
```bash
python3.7 tools/train.py -c ppcls/configs/slim/ResNet50_vd_prune.yaml -o Global.device=cpu
```
- 单机单卡/单机多卡/多机多卡启动
```bash
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3.7 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ppcls/configs/slim/ResNet50_vd_prune.yaml
```
### 4. 导出模型
在得到在线量化训练、模型剪枝保存的模型后,可以将其导出为inference model,用于预测部署,以模型剪枝为例:
```bash
python3.7 tools/export.py \
-c ppcls/configs/slim/ResNet50_vd_prune.yaml \
-o Global.pretrained_model=./output/ResNet50_vd/best_model \
-o Global.save_inference_dir=./inference
```
### 5. 模型部署
上述步骤导出的模型可以直接使用inferecne 进行部署,参考[inference部署](../inference_deployment/)
也通过PaddleLite的opt模型转换工具,完成inference模型到移动端模型转换,用于移动端的模型部署。
移动端模型部署的可参考 [移动端模型部署](../../../deploy/lite/readme.md)
## 训练超参数建议
* 量化、裁剪训练时,建议加载常规训练得到的预训练模型,加速量化训练收敛。
* 量化训练时,建议初始学习率修改为常规训练的`1/20~1/10`,同时将训练epoch数修改为常规训练的`1/5~1/2`,学习率策略方面,加上Warmup,其他配置信息不建议修改。
* 裁剪训练时,建议超参数配置与普通训练一致。
多标签分类
================================
.. 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): []
```
# 一、数据增广 # 一、数据增
在图像分类任务中,图像数据的增广是一种常用的正则化方法,常用于数据量不足或者模型参数较多的场景。在本章节中,我们将对除 ImageNet 分类任务标准数据增广外的8种数据增广方式进行简单的介绍和对比,用户也可以将这些增广方法应用到自己的任务中,以获得模型精度的提升。这8种数据增广方式在ImageNet上的精度指标如下所示。 在图像分类任务中,图像数据的增广是一种常用的正则化方法,常用于数据量不足或者模型参数较多的场景。在本章节中,我们将对除 ImageNet 分类任务标准数据增强外的8种数据增强方式进行简单的介绍和对比,用户也可以将这些增广方法应用到自己的任务中,以获得模型精度的提升。这8种数据增强方式在ImageNet上的精度指标如下所示。
![](../../../images/image_aug/main_image_aug.png) ![](../../images/image_aug/main_image_aug.png)
# 二、常用数据增广方法 # 二、常用数据增方法
如果没有特殊说明,本章节中所有示例为 ImageNet 分类,并且假设最终输入网络的数据维度为:`[batch-size, 3, 224, 224]` 如果没有特殊说明,本章节中所有示例为 ImageNet 分类,并且假设最终输入网络的数据维度为:`[batch-size, 3, 224, 224]`
其中 ImageNet 分类训练阶段的标准数据增广方式分为以下几个步骤: 其中 ImageNet 分类训练阶段的标准数据增方式分为以下几个步骤:
1. 图像解码:简写为 `ImageDecode` 1. 图像解码:简写为 `ImageDecode`
2. 随机裁剪到长宽均为 224 的图像:简写为 `RandCrop` 2. 随机裁剪到长宽均为 224 的图像:简写为 `RandCrop`
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
增广后的可视化效果如下所示。 增广后的可视化效果如下所示。
![](../../../images/image_aug/image_aug_samples_s.jpg) ![](../../images/image_aug/image_aug_samples_s.jpg)
具体如下表所示: 具体如下表所示:
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
| **Process** | (N, 3, 224, 224)<br>float32 | (N, 3, 224, 224)<br>float32 | \- | \- | \- | \- | \- | \- | Y | Y | | **Process** | (N, 3, 224, 224)<br>float32 | (N, 3, 224, 224)<br>float32 | \- | \- | \- | \- | \- | \- | Y | Y |
PaddleClas中集成了上述所有的数据增广策略,每种数据增广策略的参考论文与参考开源代码均在下面的介绍中列出。下文将介绍这些策略的原理与使用方法,并以下图为例,对变换后的效果进行可视化。为了说明问题,本章节中将 `RandCrop` 替换为 `Resize` PaddleClas中集成了上述所有的数据增强策略,每种数据增强策略的参考论文与参考开源代码均在下面的介绍中列出。下文将介绍这些策略的原理与使用方法,并以下图为例,对变换后的效果进行可视化。为了说明问题,本章节中将 `RandCrop` 替换为 `Resize`
![][test_baseline] ![][test_baseline]
...@@ -53,6 +53,7 @@ PaddleClas中集成了上述所有的数据增广策略,每种数据增广策 ...@@ -53,6 +53,7 @@ PaddleClas中集成了上述所有的数据增广策略,每种数据增广策
+ AutoAugment + AutoAugment
+ RandAugment + RandAugment
+ TimmAutoAugment
## 3.1 AutoAugment ## 3.1 AutoAugment
...@@ -60,30 +61,9 @@ PaddleClas中集成了上述所有的数据增广策略,每种数据增广策 ...@@ -60,30 +61,9 @@ PaddleClas中集成了上述所有的数据增广策略,每种数据增广策
开源代码github地址:[https://github.com/DeepVoltaire/AutoAugment](https://github.com/DeepVoltaire/AutoAugment) 开源代码github地址:[https://github.com/DeepVoltaire/AutoAugment](https://github.com/DeepVoltaire/AutoAugment)
不同于常规的人工设计图像增广方式,AutoAugment 是在一系列图像增广子策略的搜索空间中通过搜索算法找到的适合特定数据集的图像增广方案。针对 ImageNet 数据集,最终搜索出来的数据增广方案包含 25 个子策略组合,每个子策略中都包含两种变换,针对每幅图像都随机的挑选一个子策略组合,然后以一定的概率来决定是否执行子策略中的每种变换。 不同于常规的人工设计图像增广方式,AutoAugment 是在一系列图像增广子策略的搜索空间中通过搜索算法找到的适合特定数据集的图像增广方案。针对 ImageNet 数据集,最终搜索出来的数据增方案包含 25 个子策略组合,每个子策略中都包含两种变换,针对每幅图像都随机的挑选一个子策略组合,然后以一定的概率来决定是否执行子策略中的每种变换。
PaddleClas中`AutoAugment`的使用方法如下所示。 经过AutoAugment数据增强后结果如下图所示。
```python
size = 224
decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
autoaugment_op = ImageNetPolicy()
ops = [decode_op, resize_op, autoaugment_op]
imgs_dir = "imgs_dir"
file_names = os.listdir(imgs_dir)
for file_name in file_names:
file_path = os.join(imgs_dir, file_name)
with open(file_path) as f:
data = f.read()
img = transform(data, ops)
```
结果如下图所示。
![][test_autoaugment] ![][test_autoaugment]
...@@ -96,31 +76,18 @@ for file_name in file_names: ...@@ -96,31 +76,18 @@ for file_name in file_names:
`AutoAugment` 的搜索方法比较暴力,直接在数据集上搜索针对该数据集的最优策略,其计算量很大。在 `RandAugment` 文章中作者发现,一方面,针对越大的模型,越大的数据集,使用 `AutoAugment` 方式搜索到的增广方式产生的收益也就越小;另一方面,这种搜索出的最优策略是针对该数据集的,其迁移能力较差,并不太适合迁移到其他数据集上。 `AutoAugment` 的搜索方法比较暴力,直接在数据集上搜索针对该数据集的最优策略,其计算量很大。在 `RandAugment` 文章中作者发现,一方面,针对越大的模型,越大的数据集,使用 `AutoAugment` 方式搜索到的增广方式产生的收益也就越小;另一方面,这种搜索出的最优策略是针对该数据集的,其迁移能力较差,并不太适合迁移到其他数据集上。
`RandAugment` 中,作者提出了一种随机增广的方式,不再像 `AutoAugment` 中那样使用特定的概率确定是否使用某种子策略,而是所有的子策略都会以同样的概率被选择到,论文中的实验也表明这种数据增广方式即使在大模型的训练中也具有很好的效果。 `RandAugment` 中,作者提出了一种随机增广的方式,不再像 `AutoAugment` 中那样使用特定的概率确定是否使用某种子策略,而是所有的子策略都会以同样的概率被选择到,论文中的实验也表明这种数据增强方式即使在大模型的训练中也具有很好的效果。
PaddleClas中`RandAugment`的使用方法如下所示。
```python
size = 224
decode_op = DecodeImage() 经过RandAugment数据增强后结果如下图所示。
resize_op = ResizeImage(size=(size, size))
randaugment_op = RandAugment()
ops = [decode_op, resize_op, randaugment_op] ![][test_randaugment]
imgs_dir = 图像路径 ## 3.3 TimmAutoAugment
fnames = os.listdir(imgs_dir)
for f in fnames:
data = open(os.path.join(imgs_dir, f)).read()
img = transform(data, ops)
```
结果如下图所示。 开源代码github地址:[https://github.com/rwightman/pytorch-image-models/blob/master/timm/data/auto_augment.py](https://github.com/rwightman/pytorch-image-models/blob/master/timm/data/auto_augment.py)
![][test_randaugment] `TimmAutoAugment`是开源作者对AutoAugment和RandAugment的改进,事实证明,其在很多视觉任务上有更好的表现,目前绝大多数VisionTransformer模型都是基于TimmAutoAugment去实现的。
# 四、图像裁剪类 # 四、图像裁剪类
...@@ -145,26 +112,7 @@ for f in fnames: ...@@ -145,26 +112,7 @@ for f in fnames:
Cutout 可以理解为 Dropout 的一种扩展操作,不同的是 Dropout 是对图像经过网络后生成的特征进行遮挡,而 Cutout 是直接对输入的图像进行遮挡,相对于Dropout对噪声的鲁棒性更好。作者在论文中也进行了说明,这样做法有以下两点优势:(1) 通过 Cutout 可以模拟真实场景中主体被部分遮挡时的分类场景;(2) 可以促进模型充分利用图像中更多的内容来进行分类,防止网络只关注显著性的图像区域,从而发生过拟合。 Cutout 可以理解为 Dropout 的一种扩展操作,不同的是 Dropout 是对图像经过网络后生成的特征进行遮挡,而 Cutout 是直接对输入的图像进行遮挡,相对于Dropout对噪声的鲁棒性更好。作者在论文中也进行了说明,这样做法有以下两点优势:(1) 通过 Cutout 可以模拟真实场景中主体被部分遮挡时的分类场景;(2) 可以促进模型充分利用图像中更多的内容来进行分类,防止网络只关注显著性的图像区域,从而发生过拟合。
PaddleClas中`Cutout`的使用方法如下所示。 经过RandAugment数据增强后结果如下图所示。
```python
size = 224
decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
cutout_op = Cutout(n_holes=1, length=112)
ops = [decode_op, resize_op, cutout_op]
imgs_dir = 图像路径
fnames = os.listdir(imgs_dir)
for f in fnames:
data = open(os.path.join(imgs_dir, f)).read()
img = transform(data, ops)
```
结果如下图所示。
![][test_cutout] ![][test_cutout]
...@@ -179,25 +127,7 @@ for f in fnames: ...@@ -179,25 +127,7 @@ for f in fnames:
PaddleClas中`RandomErasing`的使用方法如下所示。 PaddleClas中`RandomErasing`的使用方法如下所示。
```python 经过RandomErasing数据增强后结果如下图所示。
size = 224
decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
randomerasing_op = RandomErasing()
ops = [decode_op, resize_op, tochw_op, randomerasing_op]
imgs_dir = 图像路径
fnames = os.listdir(imgs_dir)
for f in fnames:
data = open(os.path.join(imgs_dir, f)).read()
img = transform(data, ops)
img = img.transpose((1, 2, 0))
```
结果如下图所示。
![][test_randomerassing] ![][test_randomerassing]
...@@ -217,25 +147,8 @@ for f in fnames: ...@@ -217,25 +147,8 @@ for f in fnames:
PaddleClas中`HideAndSeek`的使用方法如下所示。 PaddleClas中`HideAndSeek`的使用方法如下所示。
```python
size = 224
decode_op = DecodeImage() 经过HideAndSeek数据增强后结果如下图所示。
resize_op = ResizeImage(size=(size, size))
hide_and_seek_op = HideAndSeek()
ops = [decode_op, resize_op, tochw_op, hide_and_seek_op]
imgs_dir = 图像路径
fnames = os.listdir(imgs_dir)
for f in fnames:
data = open(os.path.join(imgs_dir, f)).read()
img = transform(data, ops)
img = img.transpose((1, 2, 0))
```
结果如下图所示。
![][test_hideandseek] ![][test_hideandseek]
...@@ -265,31 +178,7 @@ for f in fnames: ...@@ -265,31 +178,7 @@ for f in fnames:
论文中验证上述第二种方法的训练效果更好一些。 论文中验证上述第二种方法的训练效果更好一些。
经过GridMask数据增强后结果如下图所示。
PaddleClas中`GridMask`的使用方法如下所示。
```python
size = 224
decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
tochw_op = ToCHWImage()
gridmask_op = GridMask(d1=96, d2=224, rotate=1, ratio=0.6, mode=1, prob=0.8)
ops = [decode_op, resize_op, tochw_op, gridmask_op]
imgs_dir = 图像路径
fnames = os.listdir(imgs_dir)
for f in fnames:
data = open(os.path.join(imgs_dir, f)).read()
img = transform(data, ops)
img = img.transpose((1, 2, 0))
```
结果如下图所示。
![][test_gridmask] ![][test_gridmask]
...@@ -313,34 +202,8 @@ Mixup 是最先提出的图像混叠增广方案,其原理简单、方便实 ...@@ -313,34 +202,8 @@ Mixup 是最先提出的图像混叠增广方案,其原理简单、方便实
如下是 `imaug` 中的实现,需要指出的是,下述实现会出现对同一幅进行相加的情况,也就是最终得到的图和原图一样,随着 `batch-size` 的增加这种情况出现的概率也会逐渐减小。 如下是 `imaug` 中的实现,需要指出的是,下述实现会出现对同一幅进行相加的情况,也就是最终得到的图和原图一样,随着 `batch-size` 的增加这种情况出现的概率也会逐渐减小。
PaddleClas中`Mixup`的使用方法如下所示。
```python
size = 224 经过Mixup数据增强结果如下图所示。
decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
tochw_op = ToCHWImage()
hide_and_seek_op = HideAndSeek()
mixup_op = MixupOperator()
cutmix_op = CutmixOperator()
ops = [decode_op, resize_op, tochw_op]
imgs_dir = 图像路径
batch = []
fnames = os.listdir(imgs_dir)
for idx, f in enumerate(fnames):
data = open(os.path.join(imgs_dir, f)).read()
img = transform(data, ops)
batch.append( (img, idx) ) # fake label
new_batch = mixup_op(batch)
```
结果如下图所示。
![][test_mixup] ![][test_mixup]
...@@ -352,167 +215,11 @@ new_batch = mixup_op(batch) ...@@ -352,167 +215,11 @@ new_batch = mixup_op(batch)
`Mixup` 直接对两幅图进行相加不一样,`Cutmix` 是从一幅图中随机裁剪出一个 `ROI`,然后覆盖当前图像中对应的区域,代码实现如下所示: `Mixup` 直接对两幅图进行相加不一样,`Cutmix` 是从一幅图中随机裁剪出一个 `ROI`,然后覆盖当前图像中对应的区域,代码实现如下所示:
```python 经过Cutmix数据增强后结果如下图所示。
size = 224
decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
tochw_op = ToCHWImage()
hide_and_seek_op = HideAndSeek()
cutmix_op = CutmixOperator()
ops = [decode_op, resize_op, tochw_op]
imgs_dir = 图像路径
batch = []
fnames = os.listdir(imgs_dir)
for idx, f in enumerate(fnames):
data = open(os.path.join(imgs_dir, f)).read()
img = transform(data, ops)
batch.append( (img, idx) ) # fake label
new_batch = cutmix_op(batch)
```
结果如下图所示。
![][test_cutmix] ![][test_cutmix]
关于数据增强相关的实战部分实参考[数据增强实战](../advanced_tutorials/DataAugmentation.md)
# 六、实验
基于PaddleClas,在ImageNet1k数据集上的分类精度如下。
| 模型 | 初始学习率策略 | l2 decay | batch size | epoch | 数据变化策略 | Top1 Acc | 论文中结论 |
|-------------|------------------|--------------|------------|-------|----------------|------------|----|
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | 标准变换 | 0.7731 | - |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | AutoAugment | 0.7795 | 0.7763 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | mixup | 0.7828 | 0.7790 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | cutmix | 0.7839 | 0.7860 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | cutout | 0.7801 | - |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | gridmask | 0.7785 | 0.7790 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | random-augment | 0.7770 | 0.7760 |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | random erasing | 0.7791 | - |
| ResNet50 | 0.1/cosine_decay | 0.0001 | 256 | 300 | hide and seek | 0.7743 | 0.7720 |
**注意**
* 在这里的实验中,为了便于对比,我们将l2 decay固定设置为1e-4,在实际使用中,我们推荐尝试使用更小的l2 decay。结合数据增广,我们发现将l2 decay由1e-4减小为7e-5均能带来至少0.3~0.5%的精度提升。
* 我们目前尚未对不同策略进行组合并验证效果,这一块后续我们会开展更多的对比实验,敬请期待。
# 七、数据增广分类实战
本节将基于ImageNet-1K的数据集详细介绍数据增广实验,如果想快速体验此方法,可以参考[**30分钟玩转PaddleClas(进阶版)**](../../tutorials/quick_start_professional.md)中基于CIFAR100的数据增广实验。
## 7.1 参数配置
由于不同的数据增广方式含有不同的超参数,为了便于理解和使用,我们在`configs/DataAugment`里分别列举了8种训练ResNet50的数据增广方式的参数配置文件,用户可以在`tools/run.sh`里直接替换配置文件的路径即可使用。此处分别挑选了图像变换、图像裁剪、图像混叠中的一个示例展示,其他参数配置用户可以自查配置文件。
### RandAugment
`RandAugment`的图像增广方式的配置如下,其中用户需要指定其中的参数`num_layers``magnitude`,默认的数值分别是`2``5``RandAugment`是在uint8的数据格式上转换的,所以其处理过程应该放在归一化操作(`NormalizeImage`)之前。
```yaml
transform_ops:
- DecodeImage:
to_rgb: True
channel_first: False
- RandCropImage:
size: 224
- RandFlipImage:
flip_code: 1
- RandAugment:
num_layers: 2
magnitude: 5
- NormalizeImage:
scale: 1.0/255.0
mean: [0.485, 0.456, 0.406]
std: [0.229, 0.224, 0.225]
order: ''
```
### Cutout
`Cutout`的图像增广方式的配置如下,其中用户需要指定其中的参数`n_holes``length`,默认的数值分别是`1``112`。类似其他图像裁剪类的数据增广方式,`Cutout`既可以在uint8格式的数据上操作,也可以在归一化(`NormalizeImage`)后的数据上操作,此处给出的是在归一化后的操作。
```yaml
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: ''
- Cutout:
n_holes: 1
length: 112
```
### Mixup
`Mixup`的图像增广方式的配置如下,其中用户需要指定其中的参数`alpha`,默认的数值是`0.2`。类似其他图像混合类的数据增广方式,`Mixup`是在图像做完数据处理后将每个batch内的数据做图像混叠,将混叠后的图像和标签输入网络中训练,所以其是在图像数据处理(图像变换、图像裁剪)后操作。另外,在配置文件中,需要将`use_mix`参数设置为`True`
```yaml
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: ''
batch_transform_ops:
- MixupOperator:
alpha: 0.2
```
## 7.2 启动命令
当用户配置完训练环境后,类似于训练其他分类任务,只需要将`tools/train.sh`中的配置文件替换成为相应的数据增广方式的配置文件即可。
其中`train.sh`中的内容如下:
```bash
python3 -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \
--log_dir=ResNet50_Cutout \
tools/train.py \
-c ./ppcls/configs/ImageNet/DataAugment/ResNet50_Cutout.yaml
```
运行`train.sh`
```bash
sh tools/train.sh
```
## 7.3 注意事项
* 由于图像混叠时需对label进行混叠,无法计算训练数据的准确率,所以在训练过程中没有打印训练准确率。
* 在使用数据增广后,由于训练数据更难,所以训练损失函数可能较大,训练集的准确率相对较低,但其有拥更好的泛化能力,所以验证集的准确率相对较高。
* 在使用数据增广后,模型可能会趋于欠拟合状态,建议可以适当的调小`l2_decay`的值来获得更高的验证集准确率。
* 几乎每一类图像增广均含有超参数,我们只提供了基于ImageNet-1k的超参数,其他数据集需要用户自己调试超参数,具体超参数的含义用户可以阅读相关的论文,调试方法也可以参考训练技巧的章节。
> 如果您觉得此文档对您有帮助,欢迎star我们的项目:[https://github.com/PaddlePaddle/PaddleClas](https://github.com/PaddlePaddle/PaddleClas)
# 参考文献 # 参考文献
...@@ -536,14 +243,14 @@ sh tools/train.sh ...@@ -536,14 +243,14 @@ sh tools/train.sh
[test_baseline]: ../../../images/image_aug/test_baseline.jpeg [test_baseline]: ../../images/image_aug/test_baseline.jpeg
[test_autoaugment]: ../../../images/image_aug/test_autoaugment.jpeg [test_autoaugment]: ../../images/image_aug/test_autoaugment.jpeg
[test_cutout]: ../../../images/image_aug/test_cutout.jpeg [test_cutout]: ../../images/image_aug/test_cutout.jpeg
[test_gridmask]: ../../../images/image_aug/test_gridmask.jpeg [test_gridmask]: ../../images/image_aug/test_gridmask.jpeg
[gridmask-0]: ../../../images/image_aug/gridmask-0.png [gridmask-0]: ../../images/image_aug/gridmask-0.png
[test_hideandseek]: ../../../images/image_aug/test_hideandseek.jpeg [test_hideandseek]: ../../images/image_aug/test_hideandseek.jpeg
[test_randaugment]: ../../../images/image_aug/test_randaugment.jpeg [test_randaugment]: ../../images/image_aug/test_randaugment.jpeg
[test_randomerassing]: ../../../images/image_aug/test_randomerassing.jpeg [test_randomerassing]: ../../images/image_aug/test_randomerassing.jpeg
[hide_and_seek_mask_expanation]: ../../../images/image_aug/hide-and-seek-visual.png [hide_and_seek_mask_expanation]: ../../images/image_aug/hide-and-seek-visual.png
[test_mixup]: ../../../images/image_aug/test_mixup.png [test_mixup]: ../../images/image_aug/test_mixup.png
[test_cutmix]: ../../../images/image_aug/test_cutmix.png [test_cutmix]: ../../images/image_aug/test_cutmix.png
...@@ -7,24 +7,25 @@ ...@@ -7,24 +7,25 @@
### 模型库概览图 ### 模型库概览图
基于ImageNet1k分类数据集,PaddleClas支持35个系列分类网络结构以及对应的164个图像分类预训练模型,训练技巧、每个系列网络结构的简单介绍和性能评估将在相应章节展现,下面所有的速度指标评估环境如下: 基于ImageNet1k分类数据集,PaddleClas支持35个系列分类网络结构以及对应的164个图像分类预训练模型,训练技巧、每个系列网络结构的简单介绍和性能评估将在相应章节展现,下面所有的速度指标评估环境如下:
* CPU的评估环境基于骁龙855(SD855)。 * Arm CPU的评估环境基于骁龙855(SD855)。
* Intel CPU的评估环境基于Intel(R) Xeon(R) Gold 6148。
* GPU评估环境基于T4机器,在FP32+TensorRT配置下运行500次测得(去除前10次的warmup时间)。 * GPU评估环境基于T4机器,在FP32+TensorRT配置下运行500次测得(去除前10次的warmup时间)。
常见服务器端模型的精度指标与其预测耗时的变化曲线如下图所示。 常见服务器端模型的精度指标与其预测耗时的变化曲线如下图所示。
![](../images/models/T4_benchmark/t4.fp32.bs1.main_fps_top1.png) ![](../../images/models/T4_benchmark/t4.fp32.bs1.main_fps_top1.png)
常见移动端模型的精度指标与其预测耗时、模型存储大小的变化曲线如下图所示。 常见移动端模型的精度指标与其预测耗时、模型存储大小的变化曲线如下图所示。
![](../images/models/mobile_arm_storage.png) ![](../../images/models/mobile_arm_storage.png)
![](../images/models/mobile_arm_top1.png) ![](../../images/models/mobile_arm_top1.png)
<a name="SSLD知识蒸馏系列"></a> <a name="SSLD知识蒸馏系列"></a>
### SSLD知识蒸馏预训练模型 ### SSLD知识蒸馏预训练模型
基于SSLD知识蒸馏的预训练模型列表如下所示,更多关于SSLD知识蒸馏方案的介绍可以参考:[SSLD知识蒸馏文档](./advanced_tutorials/distillation/distillation.md) 基于SSLD知识蒸馏的预训练模型列表如下所示,更多关于SSLD知识蒸馏方案的介绍可以参考:[SSLD知识蒸馏文档](./knowledge_distillation.md)
* 服务器端知识蒸馏模型 * 服务器端知识蒸馏模型
...@@ -41,7 +42,7 @@ ...@@ -41,7 +42,7 @@
| SE_HRNet_W64_C_ssld | 0.848 | - | - | 31.697 | 94.995 | 57.83 | 128.97 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/SE_HRNet_W64_C_ssld_pretrained.pdparams) | | SE_HRNet_W64_C_ssld | 0.848 | - | - | 31.697 | 94.995 | 57.83 | 128.97 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/SE_HRNet_W64_C_ssld_pretrained.pdparams) |
* 端侧知识蒸馏模型 * 移动端知识蒸馏模型
| 模型 | Top-1 Acc | Reference<br>Top-1 Acc | Acc gain | SD855 time(ms)<br>bs=1 | Flops(G) | Params(M) | 模型大小(M) | 下载地址 | | 模型 | Top-1 Acc | Reference<br>Top-1 Acc | Acc gain | SD855 time(ms)<br>bs=1 | Flops(G) | Params(M) | 模型大小(M) | 下载地址 |
|---------------------|-----------|-----------|---------------|----------------|-----------|----------|-----------|-----------------------------------| |---------------------|-----------|-----------|---------------|----------------|-----------|----------|-----------|-----------------------------------|
...@@ -69,7 +70,7 @@ ...@@ -69,7 +70,7 @@
<a name="PP-LCNet系列"></a> <a name="PP-LCNet系列"></a>
### PP-LCNet系列 ### PP-LCNet系列
PP-LCNet系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[PP-LCNet系列模型文档](./models/PP-LCNet.md) PP-LCNet系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[PP-LCNet系列模型文档](../models/PP-LCNet.md)
| 模型 | Top-1 Acc | Top-5 Acc | Intel-Xeon-Gold-6148 time(ms)<br>bs=1 | FLOPs(M) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | Intel-Xeon-Gold-6148 time(ms)<br>bs=1 | FLOPs(M) | Params(M) | 下载地址 |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:| |:--:|:--:|:--:|:--:|:--:|:--:|:--:|
...@@ -86,7 +87,7 @@ PP-LCNet系列模型的精度、速度指标如下表所示,更多关于该系 ...@@ -86,7 +87,7 @@ PP-LCNet系列模型的精度、速度指标如下表所示,更多关于该系
<a name="ResNet及其Vd系列"></a> <a name="ResNet及其Vd系列"></a>
### ResNet及其Vd系列 ### ResNet及其Vd系列
ResNet及其Vd系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[ResNet及其Vd系列模型文档](./models/ResNet_and_vd.md) ResNet及其Vd系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[ResNet及其Vd系列模型文档](../models/ResNet_and_vd.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
|---------------------|-----------|-----------|-----------------------|----------------------|----------|-----------|----------------------------------------------------------------------------------------------| |---------------------|-----------|-----------|-----------------------|----------------------|----------|-----------|----------------------------------------------------------------------------------------------|
...@@ -110,7 +111,7 @@ ResNet及其Vd系列模型的精度、速度指标如下表所示,更多关于 ...@@ -110,7 +111,7 @@ ResNet及其Vd系列模型的精度、速度指标如下表所示,更多关于
<a name="移动端系列"></a> <a name="移动端系列"></a>
### 移动端系列 ### 移动端系列
移动端系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[移动端系列模型文档](./models/Mobile.md) 移动端系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[移动端系列模型文档](../models/Mobile.md)
| 模型 | Top-1 Acc | Top-5 Acc | SD855 time(ms)<br>bs=1 | Flops(G) | Params(M) | 模型大小(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | SD855 time(ms)<br>bs=1 | Flops(G) | Params(M) | 模型大小(M) | 下载地址 |
|----------------------------------|-----------|-----------|------------------------|----------|-----------|---------|-----------------------------------------------------------------------------------------------------------| |----------------------------------|-----------|-----------|------------------------|----------|-----------|---------|-----------------------------------------------------------------------------------------------------------|
...@@ -155,7 +156,7 @@ ResNet及其Vd系列模型的精度、速度指标如下表所示,更多关于 ...@@ -155,7 +156,7 @@ ResNet及其Vd系列模型的精度、速度指标如下表所示,更多关于
<a name="SEResNeXt与Res2Net系列"></a> <a name="SEResNeXt与Res2Net系列"></a>
### SEResNeXt与Res2Net系列 ### SEResNeXt与Res2Net系列
SEResNeXt与Res2Net系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[SEResNeXt与Res2Net系列模型文档](./models/SEResNext_and_Res2Net.md) SEResNeXt与Res2Net系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[SEResNeXt与Res2Net系列模型文档](../models/SEResNext_and_Res2Net.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
...@@ -190,7 +191,7 @@ SEResNeXt与Res2Net系列模型的精度、速度指标如下表所示,更多 ...@@ -190,7 +191,7 @@ SEResNeXt与Res2Net系列模型的精度、速度指标如下表所示,更多
<a name="DPN与DenseNet系列"></a> <a name="DPN与DenseNet系列"></a>
### DPN与DenseNet系列 ### DPN与DenseNet系列
DPN与DenseNet系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[DPN与DenseNet系列模型文档](./models/DPN_DenseNet.md) DPN与DenseNet系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[DPN与DenseNet系列模型文档](../models/DPN_DenseNet.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
...@@ -211,7 +212,7 @@ DPN与DenseNet系列模型的精度、速度指标如下表所示,更多关于 ...@@ -211,7 +212,7 @@ DPN与DenseNet系列模型的精度、速度指标如下表所示,更多关于
<a name="HRNet系列"></a> <a name="HRNet系列"></a>
### HRNet系列 ### HRNet系列
HRNet系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[HRNet系列模型文档](./models/HRNet.md) HRNet系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[HRNet系列模型文档](../models/HRNet.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
...@@ -231,7 +232,7 @@ HRNet系列模型的精度、速度指标如下表所示,更多关于该系列 ...@@ -231,7 +232,7 @@ HRNet系列模型的精度、速度指标如下表所示,更多关于该系列
<a name="Inception系列"></a> <a name="Inception系列"></a>
### Inception系列 ### Inception系列
Inception系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[Inception系列模型文档](./models/Inception.md) Inception系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[Inception系列模型文档](../models/Inception.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
|--------------------|-----------|-----------|-----------------------|----------------------|----------|-----------|---------------------------------------------------------------------------------------------| |--------------------|-----------|-----------|-----------------------|----------------------|----------|-----------|---------------------------------------------------------------------------------------------|
...@@ -248,7 +249,7 @@ Inception系列模型的精度、速度指标如下表所示,更多关于该 ...@@ -248,7 +249,7 @@ Inception系列模型的精度、速度指标如下表所示,更多关于该
<a name="EfficientNet与ResNeXt101_wsl系列"></a> <a name="EfficientNet与ResNeXt101_wsl系列"></a>
### EfficientNet与ResNeXt101_wsl系列 ### EfficientNet与ResNeXt101_wsl系列
EfficientNet与ResNeXt101_wsl系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[EfficientNet与ResNeXt101_wsl系列模型文档](./models/EfficientNet_and_ResNeXt101_wsl.md) EfficientNet与ResNeXt101_wsl系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[EfficientNet与ResNeXt101_wsl系列模型文档](../models/EfficientNet_and_ResNeXt101_wsl.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
...@@ -272,7 +273,7 @@ EfficientNet与ResNeXt101_wsl系列模型的精度、速度指标如下表所示 ...@@ -272,7 +273,7 @@ EfficientNet与ResNeXt101_wsl系列模型的精度、速度指标如下表所示
<a name="ResNeSt与RegNet系列"></a> <a name="ResNeSt与RegNet系列"></a>
### ResNeSt与RegNet系列 ### ResNeSt与RegNet系列
ResNeSt与RegNet系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[ResNeSt与RegNet系列模型文档](./models/ResNeSt_RegNet.md) ResNeSt与RegNet系列模型的精度、速度指标如下表所示,更多关于该系列的模型介绍可以参考:[ResNeSt与RegNet系列模型文档](../models/ResNeSt_RegNet.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
...@@ -285,7 +286,7 @@ ResNeSt与RegNet系列模型的精度、速度指标如下表所示,更多关 ...@@ -285,7 +286,7 @@ ResNeSt与RegNet系列模型的精度、速度指标如下表所示,更多关
<a name="ViT_and_DeiT系列"></a> <a name="ViT_and_DeiT系列"></a>
### ViT_and_DeiT系列 ### ViT_and_DeiT系列
ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列模型的精度、速度指标如下表所示. 更多关于该系列模型的介绍可以参考: [ViT_and_DeiT系列模型文档](./models/ViT_and_DeiT.md) ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列模型的精度、速度指标如下表所示. 更多关于该系列模型的介绍可以参考: [ViT_and_DeiT系列模型文档](../models/ViT_and_DeiT.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
...@@ -297,7 +298,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -297,7 +298,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
| ViT_large_<br/>patch16_224 | 0.8323 | 0.9650 | - | - | | 307 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch16_224_pretrained.pdparams) | | ViT_large_<br/>patch16_224 | 0.8323 | 0.9650 | - | - | | 307 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch16_224_pretrained.pdparams) |
| ViT_large_<br/>patch16_384 | 0.8513 | 0.9736 | - | - | | | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch16_384_pretrained.pdparams) | | ViT_large_<br/>patch16_384 | 0.8513 | 0.9736 | - | - | | | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch16_384_pretrained.pdparams) |
| ViT_large_<br/>patch32_384 | 0.8153 | 0.9608 | - | - | | | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch32_384_pretrained.pdparams) | | ViT_large_<br/>patch32_384 | 0.8153 | 0.9608 | - | - | | | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ViT_large_patch32_384_pretrained.pdparams) |
| | | | | | | | |
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
...@@ -310,13 +311,13 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -310,13 +311,13 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
| DeiT_small_<br>distilled_patch16_224 | 0.809 | 0.953 | - | - | | 22 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_small_distilled_patch16_224_pretrained.pdparams) | | DeiT_small_<br>distilled_patch16_224 | 0.809 | 0.953 | - | - | | 22 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_small_distilled_patch16_224_pretrained.pdparams) |
| DeiT_base_<br>distilled_patch16_224 | 0.831 | 0.964 | - | - | | 87 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_base_distilled_patch16_224_pretrained.pdparams) | | DeiT_base_<br>distilled_patch16_224 | 0.831 | 0.964 | - | - | | 87 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_base_distilled_patch16_224_pretrained.pdparams) |
| DeiT_base_<br>distilled_patch16_384 | 0.851 | 0.973 | - | - | | 88 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_base_distilled_patch16_384_pretrained.pdparams) | | DeiT_base_<br>distilled_patch16_384 | 0.851 | 0.973 | - | - | | 88 | [下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DeiT_base_distilled_patch16_384_pretrained.pdparams) |
| | | | | | | | |
<a name="RepVGG系列"></a> <a name="RepVGG系列"></a>
### RepVGG系列 ### RepVGG系列
关于RepVGG系列模型的精度、速度指标如下表所示,更多介绍可以参考:[RepVGG系列模型文档](./models/RepVGG.md) 关于RepVGG系列模型的精度、速度指标如下表所示,更多介绍可以参考:[RepVGG系列模型文档](../models/RepVGG.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
...@@ -336,7 +337,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -336,7 +337,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
### MixNet系列 ### MixNet系列
关于MixNet系列模型的精度、速度指标如下表所示,更多介绍可以参考:[MixNet系列模型文档](./models/MixNet.md) 关于MixNet系列模型的精度、速度指标如下表所示,更多介绍可以参考:[MixNet系列模型文档](../models/MixNet.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(M) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(M) | Params(M) | 下载地址 |
| -------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | -------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -348,7 +349,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -348,7 +349,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
### ReXNet系列 ### ReXNet系列
关于ReXNet系列模型的精度、速度指标如下表所示,更多介绍可以参考:[ReXNet系列模型文档](./models/ReXNet.md) 关于ReXNet系列模型的精度、速度指标如下表所示,更多介绍可以参考:[ReXNet系列模型文档](../models/ReXNet.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -362,7 +363,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -362,7 +363,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
### SwinTransformer系列 ### SwinTransformer系列
关于SwinTransformer系列模型的精度、速度指标如下表所示,更多介绍可以参考:[SwinTransformer系列模型文档](./models/SwinTransformer.md) 关于SwinTransformer系列模型的精度、速度指标如下表所示,更多介绍可以参考:[SwinTransformer系列模型文档](../models/SwinTransformer.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -380,7 +381,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -380,7 +381,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="LeViT系列"></a> <a name="LeViT系列"></a>
### LeViT系列 ### LeViT系列
关于LeViT系列模型的精度、速度指标如下表所示,更多介绍可以参考:[LeViT系列模型文档](./models/LeViT.md) 关于LeViT系列模型的精度、速度指标如下表所示,更多介绍可以参考:[LeViT系列模型文档](../models/LeViT.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(M) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(M) | Params(M) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -395,7 +396,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -395,7 +396,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="Twins系列"></a> <a name="Twins系列"></a>
### Twins系列 ### Twins系列
关于Twins系列模型的精度、速度指标如下表所示,更多介绍可以参考:[Twins系列模型文档](./models/Twins.md) 关于Twins系列模型的精度、速度指标如下表所示,更多介绍可以参考:[Twins系列模型文档](../models/Twins.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -411,7 +412,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -411,7 +412,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="HarDNet系列"></a> <a name="HarDNet系列"></a>
### HarDNet系列 ### HarDNet系列
关于HarDNet系列模型的精度、速度指标如下表所示,更多介绍可以参考:[HarDNet系列模型文档](./models/HarDNet.md) 关于HarDNet系列模型的精度、速度指标如下表所示,更多介绍可以参考:[HarDNet系列模型文档](../models/HarDNet.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -423,7 +424,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -423,7 +424,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="DLA系列"></a> <a name="DLA系列"></a>
### DLA系列 ### DLA系列
关于 DLA系列模型的精度、速度指标如下表所示,更多介绍可以参考:[DLA系列模型文档](./models/DLA.md) 关于 DLA系列模型的精度、速度指标如下表所示,更多介绍可以参考:[DLA系列模型文档](../models/DLA.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -440,7 +441,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -440,7 +441,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="RedNet系列"></a> <a name="RedNet系列"></a>
### RedNet系列 ### RedNet系列
关于RedNet系列模型的精度、速度指标如下表所示,更多介绍可以参考:[RedNet系列模型文档](./models/RedNet.md) 关于RedNet系列模型的精度、速度指标如下表所示,更多介绍可以参考:[RedNet系列模型文档](../models/RedNet.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -453,7 +454,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -453,7 +454,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="TNT系列"></a> <a name="TNT系列"></a>
### TNT系列 ### TNT系列
关于TNT系列模型的精度、速度指标如下表所示,更多介绍可以参考:[TNT系列模型文档](./models/TNT.md) 关于TNT系列模型的精度、速度指标如下表所示,更多介绍可以参考:[TNT系列模型文档](../models/TNT.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ | | ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
...@@ -465,7 +466,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列 ...@@ -465,7 +466,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
### 其他模型 ### 其他模型
关于AlexNet、SqueezeNet系列、VGG系列、DarkNet53等模型的精度、速度指标如下表所示,更多介绍可以参考:[其他模型文档](./models/Others.md) 关于AlexNet、SqueezeNet系列、VGG系列、DarkNet53等模型的精度、速度指标如下表所示,更多介绍可以参考:[其他模型文档](../models/Others.md)
| 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 | | 模型 | Top-1 Acc | Top-5 Acc | time(ms)<br>bs=1 | time(ms)<br>bs=4 | Flops(G) | Params(M) | 下载地址 |
......
...@@ -28,7 +28,7 @@ CIFAR-10数据集由10个类的60000个彩色图像组成,图像分辨率为32 ...@@ -28,7 +28,7 @@ CIFAR-10数据集由10个类的60000个彩色图像组成,图像分辨率为32
### 2.2 模型准备 ### 2.2 模型准备
在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了35个系列共164个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](../ImageNet_models_cn.md) 在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了36个系列共175个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](./ImageNet_models.md)
### 2.3 模型训练 ### 2.3 模型训练
......
# 知识蒸馏
## 1. 模型压缩和知识蒸馏方法简介
近年来,深度神经网络在计算机视觉、自然语言处理等领域被验证是一种极其有效的解决问题的方法。通过构建合适的神经网络,加以训练,最终网络模型的性能指标基本上都会超过传统算法。
在数据量足够大的情况下,通过合理构建网络模型的方式增加其参数量,可以显著改善模型性能,但是这又带来了模型复杂度急剧提升的问题。大模型在实际场景中使用的成本较高。
深度神经网络一般有较多的参数冗余,目前有几种主要的方法对模型进行压缩,减小其参数量。如裁剪、量化、知识蒸馏等,其中知识蒸馏是指使用教师模型(teacher model)去指导学生模型(student model)学习特定任务,保证小模型在参数量不变的情况下,得到比较大的性能提升,甚至获得与大模型相似的精度指标 [1]。
目前知识蒸馏的方法大致可以分为以下三种。
* Response based distillation:教师模型对学生模型的输出进行监督。
* Feature based distillation:教师模型对学生模型的中间层 feature map 进行监督。
* Relation based distillation:对于不同的样本,使用教师模型和学生模型同时计算样本之间 feature map 的相关性,使得学生模型和教师模型得到的相关性矩阵尽可能一致。
## 2. 知识蒸馏应用
知识蒸馏算法在模型轻量化过程任务中应用广泛,对于需要满足特定的精度的任务,通过使用知识蒸馏的方法,我们可以使用更小的模型便能达到要求的精度,从而减小了模型部署的成本。
此外,对于相同的模型结构,使用知识蒸馏训练得到的预训练模型精度往往更高,这些预训练模型往往也可以提升下游任务的模型精度。比如在图像分类任务中,基于知识蒸馏算法得到的精度更高的预训练模型,也能够在目标检测、图像分割、OCR、视频分类等任务中获得明显的精度收益。
## 3. 知识蒸馏算法介绍
### 3.1 Response based distillation
最早的知识蒸馏算法KD,由Hinton提出,训练的损失函数中除了 gt loss 之外,还引入了学生模型与教师模型输出的 KL 散度,最终精度超过单纯使用 gt loss 训练的精度。这里需要注意的是,在训练的时候,需要首先训练得到一个更大的教师模型,来指导学生模型的训练过程。
PaddleClas 中提出了一种简单使用的 SSLD 知识蒸馏算法 [6],在训练的时候去除了对 gt label 的依赖,结合大量无标注数据,最终蒸馏训练得到的预训练模型在 15 个模型上的精度提升平均高达 3%。
上述标准的蒸馏方法是通过一个大模型作为教师模型来指导学生模型提升效果,而后来又发展出 DML (Deep Mutual Learning) 互学习蒸馏方法 [7],即通过两个结构相同的模型互相学习。具体的。相比于 KD 等依赖于大的教师模型的知识蒸馏算法,DML 脱离了对大的教师模型的依赖,蒸馏训练的流程更加简单,模型产出效率也要更高一些。
### 3.2 Feature based distillation
Heo 等人提出了 OverHaul [8], 计算学生模型与教师模型的 feature map distance,作为蒸馏的 loss,在这里使用了学生模型、教师模型的转移,来保证二者的 feature map 可以正常地进行 distance 的计算。
基于 feature map distance 的知识蒸馏方法也能够和 `3.1章节` 中的基于 response 的知识蒸馏算法融合在一起,同时对学生模型的输出结果和中间层 feature map 进行监督。而对于 DML 方法来说,这种融合过程更为简单,因为不需要对学生和教师模型的 feature map 进行转换,便可以完成对齐 (alignment) 过程。PP-OCRv2 系统中便使用了这种方法,最终大幅提升了 OCR 文字识别模型的精度。
### 3.3 Relation based distillation

`3.1``3.2` 章节中的论文中主要是考虑到学生模型与教师模型的输出或者中间层 feature map,这些知识蒸馏算法只关注个体的输出结果,没有考虑到个体之间的输出关系。
Park 等人提出了 RKD [10],基于关系的知识蒸馏算法,RKD 中进一步考虑个体输出之间的关系,使用 2 种损失函数,二阶的距离损失(distance-wise)和三阶的角度损失(angle-wise)
本论文提出的算法关系知识蒸馏(RKD)迁移教师模型得到的输出结果间的结构化关系给学生模型,不同于之前的只关注个体输出结果,RKD 算法使用两种损失函数:二阶的距离损失 (distance-wise) 和三阶的角度损失 (angle-wise)。在最终计算蒸馏损失函数的时候,同时考虑KD loss 和 RKD loss。最终精度优于单独使用 KD loss 蒸馏得到的模型精度。
## 4. 参考文献
[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.
[6] Cui C, Guo R, Du Y, et al. Beyond Self-Supervision: A Simple Yet Effective Network Distillation Alternative to Improve Backbones[J]. arXiv preprint arXiv:2103.05959, 2021.
[7] Zhang Y, Xiang T, Hospedales T M, et al. Deep mutual learning[C]//Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2018: 4320-4328.
[8] Heo B, Kim J, Yun S, et al. A comprehensive overhaul of feature distillation[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision. 2019: 1921-1930.
[9] Du Y, Li C, Guo R, et al. PP-OCRv2: Bag of Tricks for Ultra Lightweight OCR System[J]. arXiv preprint arXiv:2109.03144, 2021.
[10] Park W, Kim D, Lu Y, et al. Relational knowledge distillation[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2019: 3967-3976.
## 模型裁剪、量化算法介绍
深度学习因其计算复杂度或参数冗余,在一些场景和设备上限制了相应的模型部署,需要借助模型压缩、优化加速、异构计算等方法突破瓶颈。模型压缩算法能够有效降低参数冗余,从而减少存储占用、通信带宽和计算复杂度,有助于深度学习的应用部署。其中模型量化、裁剪应用比较广泛。在PaddleClas中,主要应该应用以下两种算法。
- 量化方法:PACT量化
- 裁剪:FPGM裁剪
其中具体算法参数请参考[PaddeSlim](https://github.com/PaddlePaddle/PaddleSlim/)
### PACT量化方法
模型量化主要包括两个部分,一是对权重Weight量化,一是针对激活值Activation量化。同时对两部分进行量化,才能获得最大的计算效率收益。权重可以借助网络正则化等手段,让权重分布尽量紧凑,减少离群点、不均匀分布情况发生,而对于激活值还缺乏有效的手段。
**PACT量化(PArameterized Clipping acTivation**是一种新的量化方法,该方法通过在量化激活值之前去掉一些离群点,将模型量化带来的精度损失降到最低,甚至比原模型准确率更高。提出方法的背景是作者发现:“在运用权重量化方案来量化activation时,激活值的量化结果和全精度结果相差较大”。作者发现,activation的量化可能引起的误差很大(相较于weight基本在 0到1范围内,activation的值的范围是无限大的,这是RELU的结果),所以提出**截断式RELU** 的激活函数。该截断的上界,即$α$ 是可学习的参数,这保证了每层能够通过训练学习到不一样的量化范围,最大程度降低量化带来的舍入误差。其中量化的示意图如下图所示,**PACT**解决问题的方法是,不断裁剪激活值范围,使得激活值分布收窄,从而降低量化映射损失。**PACT**通过对激活数值做裁剪,从而减少激活分布中的离群点,使量化模型能够得到一个更合理的量化scale,降低量化损失。
<div align="center">
<img src="../../images/algorithm_introduction/quantization.jpg" width = "600" />
</div>
**PACT**量化公式如下:
<div align="center">
<img src="../../images/algorithm_introduction/quantization_formula.png" width = "800" height="100"/>
</div>
可以看出PACT思想是用上述量化代替*ReLU*函数,对大于零的部分进行一个截断操作,截断阈值为$a$。但是在*PaddleSlim*中对上述公式做了进一步的改进,其改进如下:
<div align="center">
<img src="../../images/algorithm_introduction/quantization_formula_slim.png" width = "550" height="120"/>
</div>
经过如上改进后,在激活值和待量化的OP(卷积,全连接等)之间插入*PACT*预处理,不只对大于0的分布进行截断,同时也对小于0的部分做同样的限制,从而更好地得到待量化的范围,降低量化损失。同时,截断阈值是一个可训练的参数,在量化训练过程中,模型会自动的找到一个合理的截断阈值,从而进一步降低量化精度损失。
算法具体参数请参考PaddleSlim中[参数介绍](https://github.com/PaddlePaddle/PaddleSlim/blob/release/2.0.0/docs/zh_cn/api_cn/dygraph/quanter/qat.rst#qat)
### FPGM裁剪
模型剪枝是减小模型大小,提升预测效率的一种非常重要的手段。在之前的网络剪枝文章中一般将网络filter的范数作为其重要性度量,**范数值较小的代表的filter越不重要**,将其从网络中裁剪掉,反之也就越重要。而**FPGM**认为之前的方法要依赖如下两点
- filter的范数偏差应该比较大,这样重要和非重要的filter才可以很好区分开
- 不重要的filter的范数应该足够的小
基于此,**FPGM**利用层中filter的几何中心特性,由于那些靠近中心的filter可以被其它的表达,因而可以将其剔除,从而避免了上面提到的两点剪枝条件,从信息的冗余度出发,而不是选择范数少的进行剪枝。下图展示了**FPGM**方法与之前方法的不同,具体细节请详看[论文](https://openaccess.thecvf.com/content_CVPR_2019/papers/He_Filter_Pruning_via_Geometric_Median_for_Deep_Convolutional_Neural_Networks_CVPR_2019_paper.pdf)
<div align="center">
<img src="../../images/algorithm_introduction/fpgm.png" width = "600" />
</div>
算法具体参数请参考PaddleSlim中[参数介绍](https://github.com/PaddlePaddle/PaddleSlim/blob/release/2.0.0/docs/zh_cn/api_cn/dygraph/pruners/fpgm_filter_pruner.rst#fpgmfilterpruner)
# 动漫人物识别
自七十年代以来,人脸识别已经成为了计算机视觉和生物识别领域研究最多的主题之一。近年来,传统的人脸识别方法已经被基于卷积神经网络(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.
# 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'
# 图像分类任务数据集说明 # 图像分类任务数据集说明
本文档将介绍 PaddleClas 所使用的数据集格式,以及图像分类任务的主要数据集,包括 ImageNet1k 和 flowers102 的介绍。 本文档将介绍 PaddleClas 所使用的图像分类任务数据集格式,以及图像分类领域的常见数据集介绍。
--- ---
...@@ -20,13 +20,19 @@ val/ILSVRC2012_val_00000001.JPEG 65 ...@@ -20,13 +20,19 @@ val/ILSVRC2012_val_00000001.JPEG 65
... ...
``` ```
## 2. ImageNet1k 数据集 ## 2. 图像分类任务常见数据集介绍
这里整理了常用的图像分类任务数据集,持续更新中,欢迎各位小伙伴补充完善~
### 2.1 ImageNet1k
[ImageNet](https://image-net.org/)项目是一个大型视觉数据库,用于视觉目标识别研究任务,该项目已手动标注了 1400 多万张图像。ImageNet-1k 是 ImageNet 数据集的子集,其包含 1000 个类别。训练集包含 1281167 个图像数据,验证集包含 50000 个图像数据。2010 年以来,ImageNet 项目每年举办一次图像分类竞赛,即 ImageNet 大规模视觉识别挑战赛(ILSVRC)。挑战赛使用的数据集即为 ImageNet-1k。到目前为止,ImageNet-1k 已经成为计算机视觉领域发展的最重要的数据集之一,其促进了整个计算机视觉的发展,很多计算机视觉下游任务的初始化模型都是基于该数据集训练得到的。
数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注| 数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注|
:------:|:---------------:|:---------------------:|:-----------:|:-----------: :------:|:---------------:|:---------------------:|:-----------:|:-----------:
[ImageNet1k](http://www.image-net.org/challenges/LSVRC/2012/)|1.2M| 50k | 1000 | [ImageNet1k](http://www.image-net.org/challenges/LSVRC/2012/)|1.2M| 50k | 1000 |
从官方下载数据后,按如下组织数据 从官方下载数据后,按如下格式组织数据,即可在 PaddleClas 中使用 ImageNet1k 数据集进行训练。
```bash ```bash
PaddleClas/dataset/ILSVRC2012/ PaddleClas/dataset/ILSVRC2012/
...@@ -47,7 +53,7 @@ PaddleClas/dataset/ILSVRC2012/ ...@@ -47,7 +53,7 @@ PaddleClas/dataset/ILSVRC2012/
|_ val_list.txt |_ val_list.txt
``` ```
## 3. Flowers102 数据集 ### 2.2 Flowers102
数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注| 数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注|
:------:|:---------------:|:---------------------:|:-----------:|:-----------: :------:|:---------------:|:---------------------:|:-----------:|:-----------:
...@@ -81,3 +87,21 @@ PaddleClas/dataset/flowers102/ ...@@ -81,3 +87,21 @@ PaddleClas/dataset/flowers102/
|_ train_list.txt |_ train_list.txt
|_ val_list.txt |_ val_list.txt
``` ```
### 2.3 CIFAR10 / CIFAR100
CIFAR-10 数据集由 10 个类的 60000 个彩色图像组成,图像分辨率为 32x32,每个类有 6000 个图像,其中训练集 5000 张,验证集 1000 张,10 个不同的类代表飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、轮船和卡车。CIFAR-100 数据集是CIFAR-10的扩展,由 100 个类的 60000 个彩色图像组成,图像分辨率为 32x32,每个类有 600 个图像,其中训练集 500 张,验证集 100 张。
数据集地址:http://www.cs.toronto.edu/~kriz/cifar.html
### 2.4 MNIST
MMNIST是一个非常有名的手写体数字识别数据集,在很多资料中,这个数据集都会被用作深度学习的入门样例。其包含 60000 张图片数据,50000 张作为训练集,10000 张作为验证集,每张图片的大小为 28 * 28。
数据集地址:http://yann.lecun.com/exdb/mnist/
### 2.5 NUS-WIDE
NUS-WIDE 是一个多分类数据集。该数据集包含 269648 张图片, 81 个类别, 每张图片被标记为该 81 个类别中的某一类或某几类。
数据集地址:https://lms.comp.nus.edu.sg/wp-content/uploads/2019/research/nuswide/NUS-WIDE.html
# 图像分类任务数据集说明
本文档将介绍 PaddleClas 所使用的图像识别任务数据集格式,以及图像识别领域的常见数据集介绍。
---
## 1. 数据集格式说明
与分类任务数据集不同,图像检索任务的数据集分为以下三部分:
* 训练集合(train dataset):用来训练模型,使模型能够学习该集合的图像特征。
* 底库数据集合(gallery dataset):用来提供图像检索任务中的底库数据,该集合可与训练集或测试集相同,也可以不同,当与训练集相同时,测试集的类别体系应与训练集的类别体系相同。
* 测试数据集合(query dataset):用来测试模型的好坏,通常要对测试集的每一张测试图片进行特征提取,之后和底库数据的特征进行距离匹配,得到识别结果,后根据识别结果计算整个测试集的指标。
训练集、底库数据集和测试数据集均使用 `txt` 文件指定,以 `CUB_200_2011` 数据集为例,训练数据集 `train_list.txt` 文件内容格式如下所示:
```shell
# 采用"空格"作为分隔符号
...
train/99/Ovenbird_0136_92859.jpg 99 2
...
train/99/Ovenbird_0128_93366.jpg 99 6
...
```
每行数据使用“空格”分割,三列数据的含义分别是训练数据的路径、训练数据的label信息、训练数据的unique id。
**注意**:当gallery dataset和query dataset相同时,为了去掉检索得到的第一个数据(检索图片本身无须评估),每个数据需要对应一个unique id,用于后续评测mAP、recall@1等指标。
## 2. 图像识别任务常见数据集介绍
这里整理了常用的图像识别任务数据集,持续更新中,欢迎各位小伙伴补充完善~
### 2.1 通用图像识别数据集
- SOP: SOP数据集是通用识别研究领域、MetricLearning技术研究方向常用的一个商品数据集, 其包含从eBay.com下载的22,634个产品的120,053张图片。其中, 训练集包含图片59551张, 类别数11318; 验证集包含图片60502张,类别数11316个。
地址: https://cvgl.stanford.edu/projects/lifted_struct/
- Cars196:
Cars数据集包含了196类汽车的16185张图像。数据被分成8144张训练图像和8041张测试图像,每个类大致以50-50的比例分割。级别通常是在制造,模型,年,例如2012特斯拉模型S或2012宝马M3双门跑车。
地址: https://ai.stanford.edu/~jkrause/cars/car_dataset.html
- CUB_200_2011: CUB_200_2011数据集是由加州理工学院在2010年提出的细粒度数据集,也是目前细粒度分类识别研究的基准图像数据集。该数据集共有11788张鸟类图像,包含200类鸟类子类,其中训练数据集有5994张图像,测试集有5794张图像,每张图像均提供了图像类标记信息,图像中鸟的bounding box,鸟的关键part信息,以及鸟类的属性信息,数据集如下图所示。
地址: http://www.vision.caltech.edu/visipedia/CUB-200-2011.html
- In-shop Clothes: In-shop Clothes 是DeepFashion数据集的4个子集之一, 它是一个卖家秀图片集,每个商品id,有多张不同角度的卖家秀,放在同一个文件夹内。该数据集共包含7982件商品,共52712张图像,每张图片都有463中属性,Bbox,landmarks,以及店铺描述。
地址: http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion.html
### 2.2 垂类图像识别数据集
#### 2.2.1 动漫人物识别
+ iCartoonFace: iCartoonFace是由爱奇艺开放的目前全球最大的手工标注卡通人物检测数据集与识别数据集,它包含超过5013个卡通人物、389678张高质量实景图片。相比于其他数据集,它具有大规模、高质量、多样性丰富、挑战难度大等特点,是目前研究动漫人物识别最常用的数据集之一。
地址: http://challenge.ai.iqiyi.com/detail?raceId=5def69ace9fcf68aef76a75d
+ Manga109: Manga109是2020.5月发布的一个用于研究卡通人物检测和识别的数据集,其包含21142张图片,官方不允许用于商用。该数据集旗下的子集Manga109-s,可以供工业使用, 主要用于文本检测、基于线稿的任务检索、角色图像生成等任务。
地址:http://www.manga109.org/en/
+ IIT-CFW:IIF-CFW数据集共包含8928个带有标注的明星人物卡通头像,覆盖100个人物形象,每个人卡通头像数不等。 另外,其还提供了1000张真实人脸照(100个公众人物,每个人10张真实头像)。该数据集既可以用于研究动漫人物识别,也经常被用于研究跨模态的检索任务。
地址: http://cvit.iiit.ac.in/research/projects/cvit-projects/cartoonfaces
#### 2.2.2 商品识别
+ AliProduct: AliProduct数据集是目前开源最大的商品数据集,它是一个SKU级别的图像分类数据集, 包含5万类别、300万张商品图像,商品图像的类别和总量均为业界之最。此数据集中涵盖了大量的生活用品、食物等,数据集中没有人工标注,数据较脏,数据分布较不均衡,且有很多相似的商品图片。
地址: https://retailvisionworkshop.github.io/recognition_challenge_2020/
+ Product-10k: Products-10k数据集中的所有图片均来自京东商城。数据集中共包含1万个经常购买的SKU。所有SKU组织成一个层次结构。总共有近19万张图片。在实际应用场景中,图像量的分布是不均衡的。所有图像都由生产专家团队手工检查/标记。
地址:https://www.kaggle.com/c/products-10k/data?select=train.csv
+ DeepFashion-Inshop: 同通用图像识别数据集中的In-shop Clothes
### 2.2.3 Logo识别
+ Logo-2K+: Logo-2K+是一个仅用于logo图像识别的数据集,其包含10个大类,2341个小类和167140张图片。
地址: https://github.com/msn199959/Logo-2k-plus-Dataset
+ Tsinghua-Tencent 100K: 该数据集是从10万张腾讯街景全景图中创建的一个大型交通标志基准数据集。它提供包含30000个交通标志实例的100000张图像。这些图像涵盖了照度和天气条件的巨大变化。基准测试中的每个交通标志都标注了类别标签、边界框和像素掩码。 它总共包含222个类别 (0 background + 221 traffic signs)
地址: https://cg.cs.tsinghua.edu.cn/traffic-sign/
### 2.2.4 车辆识别
+ CompCars: 图像主要来自网络和监控数据,其中网络数据包含163个汽车制造商、1716个汽车型号的汽车。共136,726张全车图像,27,618张部分车图像。其中网络汽车数据包含bounding box、视角、5个属性(最大速度、排量、车门数、车座数、汽车类型)。监控数据包含50,000张前视角图像。
地址: http://mmlab.ie.cuhk.edu.hk/datasets/comp_cars/
+ BoxCars: 此数据集共包含21250辆车、63750张图像、27个汽车制造商、148个细类别,此数据集全部来自监控数据。
地址: https://github.com/JakubSochor/BoxCars
+ PKU-VD Dataset:该数据集包含了两个大型车辆数据集(VD1和VD2),它们分别从两个城市的真实世界不受限制的场景拍摄图像。其中VD1是从高分辨率交通摄像头获得的,VD2中的图像则是从监视视频中获取的。作者对原始数据执行车辆检测,以确保每个图像仅包含一辆车辆。由于隐私保护的限制,所有车牌号码都已被黑色覆盖遮挡。所有车辆图像均从前视图进行拍摄。 数据集中为每个图像提供了多样化的属性注释,包括身份编号,精确的车辆模型和车辆颜色。VD1原先包含1097649张图像,1232种车俩模型,11种车辆颜色,但删除图像里面有多辆车辆以及从车辆后方拍摄的图片,该数据集仅剩846358张图像,141756辆车辆。 VD2包含807260张图像,79763辆车辆,1112种车辆模型,11种车辆颜色。
地址: https://pkuml.org/resources/pku-vds.html
# 使用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 tools/static/train.py -c configs/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" \
tools/static/train.py \
-c ./configs/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" \
tools/static/train.py \
-c configs/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)
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
>> >>
* Q: 怎样根据自己的任务选择合适的模型进行训练? * Q: 怎样根据自己的任务选择合适的模型进行训练?
* A: 如果希望在服务器部署,或者希望精度尽可能地高,对模型存储大小或者预测速度的要求不是很高,那么推荐使用ResNet_vd、Res2Net_vd、DenseNet、Xception等适合于服务器端的系列模型;如果希望在移动端侧部署,则推荐使用MobileNetV3、GhostNet等适合于移动端的系列模型。同时,我们推荐在选择模型的时候可以参考[模型库](https://github.com/PaddlePaddle/PaddleClas/tree/master/docs/zh_CN/models)中的速度-精度指标图。 * A: 如果希望在服务器部署,或者希望精度尽可能地高,对模型存储大小或者预测速度的要求不是很高,那么推荐使用ResNet_vd、Res2Net_vd、DenseNet、Xception等适合于服务器端的系列模型;如果希望在移动端侧部署,则推荐使用MobileNetV3、GhostNet等适合于移动端的系列模型。同时,我们推荐在选择模型的时候可以参考[模型库](../models)中的速度-精度指标图。
>> >>
* Q: 如何进行参数初始化,什么样的初始化可以加快模型收敛? * Q: 如何进行参数初始化,什么样的初始化可以加快模型收敛?
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
>> >>
* Q: 当前主流的学习率下降策略有哪些?一般需要怎么选择呢? * Q: 当前主流的学习率下降策略有哪些?一般需要怎么选择呢?
* A: 学习率是通过损失函数的梯度调整网络权重的超参数的速度。学习率越低,损失函数的变化速度就越慢。虽然使用低学习率可以确保不会错过任何局部极小值,但也意味着将花费更长的时间来进行收敛,特别是在被困在高原区域的情况下。在整个训练过程中,我们不能使用同样的学习率来更新权重,否则无法到达最优点,所以需要在训练过程中调整学习率的大小。在训练初始阶段,由于权重处于随机初始化的状态,损失函数相对容易进行梯度下降,所以可以设置一个较大的学习率。在训练后期,由于权重参数已经接近最优值,较大的学习率无法进一步寻找最优值,所以需要设置一个较小的学习率。在训练整个过程中,很多研究者使用的学习率下降方式是piecewise_decay,即阶梯式下降学习率,如在ResNet50标准的训练中,我们设置的初始学习率是0.1,每30epoch学习率下降到原来的1/10,一共迭代120epoch。除了piecewise_decay,很多研究者也提出了学习率的其他下降方式,如polynomial_decay(多项式下降)、exponential_decay(指数下降),cosine_decay(余弦下降)等,其中cosine_decay无需调整超参数,鲁棒性也比较高,所以成为现在提高模型精度首选的学习率下降方式。Cosine_decay和piecewise_decay的学习率变化曲线如下图所示,容易观察到,在整个训练过程中,cosine_decay都保持着较大的学习率,所以其收敛较为缓慢,但是最终的收敛效果较peicewise_decay更好一些。 * A: 学习率是通过损失函数的梯度调整网络权重的超参数的速度。学习率越低,损失函数的变化速度就越慢。虽然使用低学习率可以确保不会错过任何局部极小值,但也意味着将花费更长的时间来进行收敛,特别是在被困在高原区域的情况下。在整个训练过程中,我们不能使用同样的学习率来更新权重,否则无法到达最优点,所以需要在训练过程中调整学习率的大小。在训练初始阶段,由于权重处于随机初始化的状态,损失函数相对容易进行梯度下降,所以可以设置一个较大的学习率。在训练后期,由于权重参数已经接近最优值,较大的学习率无法进一步寻找最优值,所以需要设置一个较小的学习率。在训练整个过程中,很多研究者使用的学习率下降方式是piecewise_decay,即阶梯式下降学习率,如在ResNet50标准的训练中,我们设置的初始学习率是0.1,每30epoch学习率下降到原来的1/10,一共迭代120epoch。除了piecewise_decay,很多研究者也提出了学习率的其他下降方式,如polynomial_decay(多项式下降)、exponential_decay(指数下降),cosine_decay(余弦下降)等,其中cosine_decay无需调整超参数,鲁棒性也比较高,所以成为现在提高模型精度首选的学习率下降方式。Cosine_decay和piecewise_decay的学习率变化曲线如下图所示,容易观察到,在整个训练过程中,cosine_decay都保持着较大的学习率,所以其收敛较为缓慢,但是最终的收敛效果较peicewise_decay更好一些。
![](../images/models/lr_decay.jpeg) ![](../../images/models/lr_decay.jpeg)
>> >>
* Q: Warmup学习率策略是什么?一般用在什么样的场景中? * Q: Warmup学习率策略是什么?一般用在什么样的场景中?
* A: Warmup策略顾名思义就是让学习率先预热一下,在训练初期我们不直接使用最大的学习率,而是用一个逐渐增大的学习率去训练网络,当学习率增大到最高点时,再使用学习率下降策略中提到的学习率下降方式衰减学习率的值。如果使用较大的batch_size训练神经网络时,我们建议您使用warmup策略。实验表明,在batch_size较大时,warmup可以稳定提升模型的精度。在训练MobileNetV3等batch_size较大的实验中,我们默认将warmup中的epoch设置为5,即先用5epoch将学习率从0增加到最大值,再去做相应的学习率衰减。 * A: Warmup策略顾名思义就是让学习率先预热一下,在训练初期我们不直接使用最大的学习率,而是用一个逐渐增大的学习率去训练网络,当学习率增大到最高点时,再使用学习率下降策略中提到的学习率下降方式衰减学习率的值。如果使用较大的batch_size训练神经网络时,我们建议您使用warmup策略。实验表明,在batch_size较大时,warmup可以稳定提升模型的精度。在训练MobileNetV3等batch_size较大的实验中,我们默认将warmup中的epoch设置为5,即先用5epoch将学习率从0增加到最大值,再去做相应的学习率衰减。
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
>> >>
* Q: 数据量不足的情况下,目前有哪些常见的数据增广方法来增加训练样本的丰富度呢? * Q: 数据量不足的情况下,目前有哪些常见的数据增广方法来增加训练样本的丰富度呢?
* A: PaddleClas中将目前比较常见的数据增广方法分为了三大类,分别是图像变换类、图像裁剪类和图像混叠类,图像变换类主要包括AutoAugment和RandAugment,图像裁剪类主要包括CutOut、RandErasing、HideAndSeek和GridMask,图像混叠类主要包括Mixup和Cutmix,更详细的关于数据增广的介绍可以参考:[数据增广章节](./advanced_tutorials/image_augmentation/ImageAugment.md) * A: PaddleClas中将目前比较常见的数据增广方法分为了三大类,分别是图像变换类、图像裁剪类和图像混叠类,图像变换类主要包括AutoAugment和RandAugment,图像裁剪类主要包括CutOut、RandErasing、HideAndSeek和GridMask,图像混叠类主要包括Mixup和Cutmix,更详细的关于数据增广的介绍可以参考:[数据增广章节](../algorithm_introduction/DataAugmentation.md)
>> >>
* Q: 对于遮挡情况比较常见的图像分类场景,该使用什么数据增广方法去提升模型的精度呢? * Q: 对于遮挡情况比较常见的图像分类场景,该使用什么数据增广方法去提升模型的精度呢?
* A: 在训练的过程中可以尝试对训练集使用CutOut、RandErasing、HideAndSeek和GridMask等裁剪类数据增广方法,让模型也能够不止学习到显著区域,也能关注到非显著性区域,从而在遮挡的情况下,也能较好地完成识别任务。 * A: 在训练的过程中可以尝试对训练集使用CutOut、RandErasing、HideAndSeek和GridMask等裁剪类数据增广方法,让模型也能够不止学习到显著区域,也能关注到非显著性区域,从而在遮挡的情况下,也能较好地完成识别任务。
......
...@@ -84,7 +84,7 @@ pip install paddle2onnx ...@@ -84,7 +84,7 @@ pip install paddle2onnx
``` ```
其中: 其中:
* `InputSpec()` 函数用于描述模型输入的签名信息,包括输入数据的 `shape`、`type` 和 `name`(可省略); * `InputSpec()` 函数用于描述模型输入的签名信息,包括输入数据的 `shape`、`type` 和 `name`(可省略);
* `paddle.onnx.export()` 函数需要指定模型组网对象 `net`,导出模型的保存路径 `save_path`,模型的输入数据描述 `input_spec`。 * `paddle.onnx.export()` 函数需要指定模型组网对象 `net`,导出模型的保存路径 `save_path`,模型的输入数据描述 `input_spec`。
需要注意,`paddlepaddle` 版本需大于 `2.0.0`。关于 `paddle.onnx.export()` 函数的更多参数说明请参考[paddle.onnx.export](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/onnx/export_cn.html#export)。 需要注意,`paddlepaddle` 版本需大于 `2.0.0`。关于 `paddle.onnx.export()` 函数的更多参数说明请参考[paddle.onnx.export](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/onnx/export_cn.html#export)。
...@@ -337,6 +337,6 @@ pip install paddle2onnx ...@@ -337,6 +337,6 @@ pip install paddle2onnx
``` ```
其中: 其中:
* `InputSpec()` 函数用于描述模型输入的签名信息,包括输入数据的 `shape`、`type` 和 `name`(可省略); * `InputSpec()` 函数用于描述模型输入的签名信息,包括输入数据的 `shape`、`type` 和 `name`(可省略);
* `paddle.onnx.export()` 函数需要指定模型组网对象 `net`,导出模型的保存路径 `save_path`,模型的输入数据描述 `input_spec`。 * `paddle.onnx.export()` 函数需要指定模型组网对象 `net`,导出模型的保存路径 `save_path`,模型的输入数据描述 `input_spec`。
需要注意,`paddlepaddle` 版本需大于 `2.0.0`。关于 `paddle.onnx.export()` 函数的更多参数说明请参考[paddle.onnx.export](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/onnx/export_cn.html#export)。 需要注意,`paddlepaddle` 版本需大于 `2.0.0`。关于 `paddle.onnx.export()` 函数的更多参数说明请参考[paddle.onnx.export](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/onnx/export_cn.html#export)。
# 特征图可视化指南
## 一、概述
特征图是输入图片在卷积网络中的特征表达,对特征图的研究可以有利于我们对于模型的理解与设计,所以基于动态图我们使用本工具来可视化特征图。
## 二、准备工作
首先需要选定研究的模型,本文设定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)
# 特征提取
## 1. 特征提取简介
特征提取是图像识别中的关键一环,它的作用是将输入的图片转化为固定维度的特征向量,用于后续的[向量检索](./vector_search.md)。好的特征需要具备相似度保持性,即在特征空间中,相似度高的图片对其特征相似度要比较高(距离比较近);相似度低的图片,其特征相似度要比较小(距离比较远)。依据应用场景的不同, 我们可以选用不同长度的实值特征(real-valued feature)或者是二值特征(binary feature)。顾名思义,实值特征的每个元素都是一个实数,而二值特征每个元素为非0即1(或者表示为-1和1),二者的差异见下表所示。
![image](https://user-images.githubusercontent.com/17264083/139409293-772ffc53-2bee-4736-8fa2-32d99a916572.png)
[Deep Metric Learning](../algorithm_introduction/metric_learning.md)和 DeepHash分别用以研究如何通过深度学习的方法获得好的实值和二值特征表示。本文主要介绍如何使用PaddleClas构建一个特征学习网络, 如何进行训练、评估和推理。
## 2. 网络结构
![](./framework.png)
为了图像识别任务的灵活定制,我们将整个网络分为Backbone, Neck, Head以及Loss部分,整体结构如上图所示,下面分别介绍各自的功能:
- Backbone: 指定所使用的骨干网络。值得注意的是,PaddleClas提供的基于ImageNet的预训练模型,最后一层的输出为1000, 我们需要依据所需的特征维度定制最后一层的输出。
- Neck: 用以特征增强及特征维度变换; 这儿的Neck,可以是一个简单的Linear Layer,用来做特征维度变换;也可以是较复杂的FPN结构,用以做特征增强。
- Head: 用来将feature转化为logits; 除了常用的Fc Layer外,我们还提供了cosmargin, arcmargin, circlemargin模块
- Loss: 指定所所用的Loss函数; Loss是特征提取能力的关键, Deep Metric Learing和Deep Hash很多的研究工作都聚焦在loss设计上。 我们将Loss设计为组合loss的形式, 可以方便得将Classification Loss和Similarity Preserving Loss组合在一起
## 3. 配置文件介绍
下面以商品识别模型为例,介绍配置文件的含义:
## 网络结构
```
Arch:
name: RecModel
infer_output_key: features
infer_add_softmax: False
Backbone:
name: PPLCNet_x2_5
pretrained: True
use_ssld: True
BackboneStopLayer:
name: flatten_0
Neck:
name: FC
embedding_size: 1280
class_num: 512
Head:
name: ArcMargin
embedding_size: 512
class_num: 185341
margin: 0.2
scale: 30
```
- **name**: 模型的名字,有别于PaddleClas提供的标准分类模型,定制化的识别模型,统一命名为RecModel
- **infer_output_key**: 推理时需要用到的Tensor的key, 训练模型下,网络会以字典的形式输出features和logits. 识别任务中,推理时只需要用到features即可
- **infer_output_key**: 推理时是否需要加softmax。为了和分类任务的统一,分类任务推理时需要加softmax操作,识别任务不需要
- **Backbone**: 骨干网络, 此处选用的是经过SSLD蒸馏之后的预训练模型
- **BackboneStopLayer**: 该处用以指示在何处截断网络,关于TheseLayer的用法,请参考文档xxx
- **Neck**: 用以进行特征维度转换,此处输出512维的特征向量
- **Head**: 采用ArcMargin, 此处可以依据训练数据修改类别数class_num, 以及超参数margin和scale
## Loss构成
### 单Loss示例
```
Loss:
Train:
- CELoss:
weight: 1.0
Eval:
- CELoss:
weight: 1.0
```
可以看到此处选用的是CELoss, 结合Head部分的ArcMargin, 因此使用的是[ArcFace](https://arxiv.org/abs/1801.07698)中的算法
### 组合Loss示例
```
Loss:
Train:
- CELoss:
weight: 1.0
- TripletLossV2:
weight: 1.0
margin: 0.5
Eval:
- CELoss:
weight: 1.0
```
可以看到此处选用的是CELoss和TripletLoss的一个组合,两者的比例为1:1.
# 4.训练、评估、推理
下面以`ppcls/configs/Products/ResNet50_vd_SOP.yaml`为例,介绍模型的训练、评估、推理过程
## 4.1 数据准备
首先,下载SOP数据集, 数据链接: https://cvgl.stanford.edu/projects/lifted_struct/
## 4.2 训练
- 单机单卡训练
```
python tools/train.py -c ppcls/configs/ResNet50_vd_SOP.yaml
```
- 单机多卡训练
```
python -m paddle.distributed.launch
--gpus="0,1,2,3" tools/train.py
-c ppcls/configs/ResNet50_vd_SOP.yaml
```
训练完成之后,会在`output`目录下生成`best_model`
## 4.3 评估
- 单卡评估
```
python tools/eval.py -c ppcls/configs/ResNet50_vd_SOP.yaml -o Global.pretrained_model="output/ReModel/best_model"
```
- 多卡评估
```
python -m paddle.distributed.launch
--gpus="0,1,2,3" tools/eval.py
-c ppcls/configs/ResNet50_vd_SOP.yaml
-o Global.pretrained_model="output/ReModel/best_model"
```
## 4.4 推理
推理过程包括两个步骤: 1) 导出推理模型; 2) 获取特征向量
### 4.4.1 导出推理模型
```
python tools/export_model -c ppcls/configs/ResNet50_vd_SOP.yaml -o Global.pretrained_model="output/ReModel/best_model"
```
生成的推理模型位于`inference`目录,名字为`inference.pd*`
### 4.4.2 获取特征向量
```
cd deploy
python python/inference_rec.py -c configs/inference_product.yaml -o rec_inference_model_dir="../inference/inference"
```
# 向量检索
向量检索技术在图像识别、图像检索中应用比较广泛。其主要目标是,对于给定的查询向量,在已经建立好的向量库中,与库中所有的待查询向量,进行特征向量的相似度或距离计算,得到相似度排序。在图像识别系统中,我们使用[Faiss](https://github.com/facebookresearch/faiss)对此部分进行支持,具体信息请详查[Faiss官网](https://github.com/facebookresearch/faiss)`Faiss`主要有以下优势
- 适配性好:支持Windos、Linux、MacOS系统
- 安装方便: 支持`python`接口,直接使用`pip`安装
- 算法丰富:支持多种检索算法,满足不同场景的需求
- 同时支持CPU、GPU,能够加速检索过程
值得注意的是,为了更好是适配性,目前版本,`PaddleClas`中暂时**只使用CPU进行向量检索**
本文档主要主要介绍PaddleClas中检索模块的安装、使用的检索算法,及使用过程中的相关配置文件中参数介绍。
## 一、检索库安装
`Faiss`具体安装方法如下:
```python
pip install faiss-cpu==1.7.1post2
```
若使用时,不能正常引用,则`uninstall` 之后,重新`install`,尤其是`windows`下。
## 二、使用的检索算法
目前`PaddleClas`中检索模块,支持如下三种检索算法
- **HNSW32**: 一种图索引方法。检索精度较高,速度较快。但是特征库只支持添加图像功能,不支持删除图像特征功能。(默认方法)
- **IVF**:倒排索引检索方法。速度较快,但是精度略低。特征库支持增加、删除图像特征功能。
- **FLAT**: 暴力检索算法。精度最高,但是数据量大时,检索速度较慢。特征库支持增加、删除图像特征功能。
每种检索算法,满足不同场景。其中`HNSW32`为默认方法,此方法的检索精度、检索速度可以取得一个较好的平衡,具体算法介绍可以查看[官方文档](https://github.com/facebookresearch/faiss/wiki)
## 三、相关配置文档参数介绍
涉及检索模块配置文件位于:`deploy/configs/`下,其中`build_*.yaml`是建立特征库的相关配置文件,`inference_*.yaml`是检索或者分类的推理配置文件。
### 3.1 建库配置文件参数
示例建库的配置如下
```yaml
# indexing engine config
IndexProcess:
index_method: "HNSW32" # supported: HNSW32, IVF, Flat
index_dir: "./recognition_demo_data_v1.1/gallery_product/index"
image_root: "./recognition_demo_data_v1.1/gallery_product/"
data_file: "./recognition_demo_data_v1.1/gallery_product/data_file.txt"
index_operation: "new" # suported: "append", "remove", "new"
delimiter: "\t"
dist_type: "IP"
embedding_size: 512
```
- **index_method**:使用的检索算法。目前支持三种,HNSW32、IVF、Flat
- **index_dir**:构建的特征库所存放的文件夹
- **image_root**:构建特征库所需要的标注图像所存储的文件夹位置
- **data_file**:构建特征库所需要的标注图像的数据列表,每一行的格式:relative_path label
- **index_operation**: 此次运行建库的操作:`new`新建,`append`将data_file的图像特征添加到特征库中,`remove`将data_file的图像从特征库中删除
- **delimiter****data_file**中每一行的间隔符
- **dist_type**: 特征匹配过程中使用的相似度计算方式。`IP`内积相似度计算方式,`L2`欧式距离计算方法
- **embedding_size**:特征维度
### 3.2 检索配置文件参数
```yaml
IndexProcess:
index_dir: "./recognition_demo_data_v1.1/gallery_logo/index/"
return_k: 5
score_thres: 0.5
```
与建库配置文件不同,新参数主要如下:
- `return_k`: 检索结果返回`k`个结果
- `score_thres`: 检索匹配的阈值
欢迎使用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
```
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
- Linux 环境,推荐使用 docker。 - Linux 环境,推荐使用 docker。
- Windows 环境,目前支持基于 `Visual Studio 2019 Community` 进行编译;此外,如果您希望通过生成 `sln解决方案` 的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681) - Windows 环境,目前支持基于 `Visual Studio 2019 Community` 进行编译;此外,如果您希望通过生成 `sln解决方案` 的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681)
* 该文档主要介绍基于 Linux 环境下的 PaddleClas C++ 预测流程,如果需要在 Windows 环境下使用预测库进行 C++ 预测,具体编译方法请参考 [Windows下编译教程](./docs/windows_vs2019_build.md) * 该文档主要介绍基于 Linux 环境下的 PaddleClas C++ 预测流程,如果需要在 Windows 环境下使用预测库进行 C++ 预测,具体编译方法请参考 [Windows下编译教程](./cpp_deploy_on_windows.md)
### 1.1 编译opencv库 ### 1.1 编译opencv库
...@@ -76,7 +76,7 @@ opencv3/ ...@@ -76,7 +76,7 @@ opencv3/
* 有 2 种方式获取 Paddle 预测库,下面进行详细介绍。 * 有 2 种方式获取 Paddle 预测库,下面进行详细介绍。
#### 1.2.1 预测库源码编译 #### 1.2.1 预测库源码编译
如果希望获取最新预测库特性,可以从 GitHub 上克隆 Paddle 最新代码,从源码编译预测库。对于不同平台的编译流程,请参考[Paddle预测库官网](https://paddleinference.paddlepaddle.org.cn/v2.1/user_guides/source_compile.html)的说明。编译示例如下: 如果希望获取最新预测库特性,可以从 GitHub 上克隆 Paddle 最新代码,从源码编译预测库。对于不同平台的编译流程,请参考 [Paddle预测库官网](https://paddleinference.paddlepaddle.org.cn/v2.1/user_guides/source_compile.html) 的说明。编译示例如下:
1. 使用Git获取源代码: 1. 使用Git获取源代码:
...@@ -226,13 +226,13 @@ make ...@@ -226,13 +226,13 @@ make
* `DPADDLE_LIB`:Paddle 预测库路径,一般使用下载并解压的预编译库路径 `paddle_inference` 即可,或编译生成的预测库的路径 `build/paddle_inference_install_dir`,注意该路径下需要有 `paddle` 和 `third_party` 两个子路径; * `DPADDLE_LIB`:Paddle 预测库路径,一般使用下载并解压的预编译库路径 `paddle_inference` 即可,或编译生成的预测库的路径 `build/paddle_inference_install_dir`,注意该路径下需要有 `paddle` 和 `third_party` 两个子路径;
* `DCMP_STATIC`:是否将 `config lib` 和 `cls lib` 编译为静态链接库(`.a`),默认为 `ON`,如需编译为动态链接库(`.so`),请设置为 `OFF`。 * `DCMP_STATIC`:是否将 `config lib` 和 `cls lib` 编译为静态链接库(`.a`),默认为 `ON`,如需编译为动态链接库(`.so`),请设置为 `OFF`。
执行上述命令后,将在目录 `./lib/` 下生成 `config lib` 和 `cls lib` 的动态链接库(`libcls.so` 和 `libconfig.so`)或静态链接库(`libcls.a` 和 `libconfig.a`)。在[编译 PaddleClas C++ 预测 demo](#2.1)中,可以通过指定编译选项 `DCLS_LIB` 和 `DCONFIG_LIB` 指定已有链接库的路径,链接库同样也可用于二次开发。 执行上述命令后,将在目录 `./lib/` 下生成 `config lib` 和 `cls lib` 的动态链接库(`libcls.so` 和 `libconfig.so`)或静态链接库(`libcls.a` 和 `libconfig.a`)。在[2.1 编译 PaddleClas C++ 预测 demo](#2.1)中,可以通过指定编译选项 `DCLS_LIB` 和 `DCONFIG_LIB` 指定已有链接库的路径,链接库同样也可用于二次开发。
## 3. 运行 demo ## 3. 运行 demo
### 3.1 准备 inference model ### 3.1 准备 inference model
首先需要准备 inference model,关于将模型导出为 inference model 的具体步骤,可以参考[模型导出](../../docs/zh_CN/tutorials/getting_started.md#4-使用inference模型进行模型推理)文档。假设导出的预测模型文件放在`./inference`目录下,则目录结构如下。 首先需要准备 inference model,关于将模型导出为 inference model 的具体步骤,可以参考 [模型导出](./export_model.md) 文档。假设导出的预测模型文件放在 `./inference` 目录下,则目录结构如下。
``` ```
inference/ inference/
...@@ -270,7 +270,7 @@ sh tools/run.sh ...@@ -270,7 +270,7 @@ sh tools/run.sh
* 最终屏幕上会输出结果,如下图所示。 * 最终屏幕上会输出结果,如下图所示。
<div align="center"> <div align="center">
<img src="./docs/imgs/cpp_infer_result.png" width="600"> <img src="../../images/inference_deployment/cpp_infer_result.png" width="600">
</div> </div>
其中`class id`表示置信度最高的类别对应的id,score表示图片属于该类别的概率。 其中 `class id` 表示置信度最高的类别对应的 id,score 表示图片属于该类别的概率。
...@@ -14,9 +14,10 @@ PaddleClas 在 Windows 平台下基于 `Visual Studio 2019 Community` 进行了 ...@@ -14,9 +14,10 @@ PaddleClas 在 Windows 平台下基于 `Visual Studio 2019 Community` 进行了
以下示例基于 `Visual Studio 2019 Community` 版本,以工作目录为 `D:\projects` 进行演示。 以下示例基于 `Visual Studio 2019 Community` 版本,以工作目录为 `D:\projects` 进行演示。
<a name="1.1"></a>
### 1.1 下载 PaddlePaddle C++ 预测库 paddle_inference_install_dir ### 1.1 下载 PaddlePaddle C++ 预测库 paddle_inference_install_dir
PaddlePaddle C++ 预测库针对不同的 `CPU ``CUDA` 版本提供了不同的预编译版本,请根据实际情况下载: [C++预测库下载列表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/windows_cpp_inference.html),建议选择 `2.1.1` 版本。 PaddlePaddle C++ 预测库针对不同的 `CPU ``CUDA` 版本提供了不同的预编译版本,请根据实际情况下载: [C++预测库下载列表](https://paddleinference.paddlepaddle.org.cn/user_guides/download_lib.html#windows),建议选择 `2.1.1` 版本。
**注意**:在选择预测库时,所选预测库版本需要与后续编译选项一致: **注意**:在选择预测库时,所选预测库版本需要与后续编译选项一致:
* CPU 预测库仅可用于 GPU 预测,具体又分为 `mkl``openblas`,分别对应其低层实现基于 `MKL` 数学运算库 和 `OpenBLAS` 数学运算库; * CPU 预测库仅可用于 GPU 预测,具体又分为 `mkl``openblas`,分别对应其低层实现基于 `MKL` 数学运算库 和 `OpenBLAS` 数学运算库;
...@@ -97,13 +98,13 @@ paddle_inference_install_dir ...@@ -97,13 +98,13 @@ paddle_inference_install_dir
![step6](../../images/inference_deployment/vs2019_step6.png) ![step6](../../images/inference_deployment/vs2019_step6.png)
在编译完成后,会生成可执行文件 `clas_system.exe`。并且,如未设置 `DCONFIG_LIB``DCLS_LIB`,则会在 `.\lib\` 目录下生成 `config lib` 和 `cls lib` 两个静态链接库文件(`libconfig.a`、`libcls.a`)。类似地,你也可以仅编译生成 `config lib` 和 `cls lib` 两个静态链接库文件,只需打开路径为 `D:\projects\PaddleClas\deploy\cpp\lib\CMakeList.txt` 的 `CMake` 文件并进行编译即可,具体参考[使用 Visual Studio 2019 编译](#2),完成编译后,同样可在 `.\lib\` 目录下生成静态链接库文件,静态链接库文件可用于二次开发。 在编译完成后,会生成可执行文件 `clas_system.exe`。并且,如未设置 `DCONFIG_LIB``DCLS_LIB`,则会在 `.\lib\` 目录下生成 `config lib` 和 `cls lib` 两个静态链接库文件(`libconfig.a`、`libcls.a`)。类似地,你也可以仅编译生成 `config lib` 和 `cls lib` 两个静态链接库文件,只需打开路径为 `D:\projects\PaddleClas\deploy\cpp\lib\CMakeList.txt` 的 `CMake` 文件并进行编译即可,具体参考[2. 使用 Visual Studio 2019 编译](#2),完成编译后,同样可在 `.\lib\` 目录下生成静态链接库文件,静态链接库文件可用于二次开发。
## 3. 预测 ## 3. 预测
### 3.1 准备 inference model ### 3.1 准备 inference model
首先需要准备 inference model,关于将模型导出为 inference model 的具体步骤,可以参考[模型导出](../../docs/zh_CN/tutorials/getting_started.md#4-使用inference模型进行模型推理)文档。假设导出的预测模型文件放在`./inference`目录下,则目录结构如下。 首先需要准备 inference model,关于将模型导出为 inference model 的具体步骤,可以参考 [模型导出](./export_model.md) 文档。假设导出的预测模型文件放在 `./inference` 目录下,则目录结构如下。
``` ```
inference/ inference/
...@@ -146,4 +147,4 @@ cd D:\projects\PaddleClas\deploy\cpp\out\build\x64-Release ...@@ -146,4 +147,4 @@ cd D:\projects\PaddleClas\deploy\cpp\out\build\x64-Release
### 4. 注意事项 ### 4. 注意事项
* 在 Windows 下的终端中执行文件 exe 时,可能会发生乱码的现象,此时需要在终端中输入 `CHCP 65001`,将终端的编码方式由 GBK 编码(默认)改为 UTF-8 编码,更加具体的解释可以参考这篇博客:[https://blog.csdn.net/qq_35038153/article/details/78430359](https://blog.csdn.net/qq_35038153/article/details/78430359) * 在 Windows 下的终端中执行文件 exe 时,可能会发生乱码的现象,此时需要在终端中输入 `CHCP 65001`,将终端的编码方式由 GBK 编码(默认)改为 UTF-8 编码,更加具体的解释可以参考这篇博客:[https://blog.csdn.net/qq_35038153/article/details/78430359](https://blog.csdn.net/qq_35038153/article/details/78430359)
* 如果需要使用 CPU 预测,PaddlePaddle 在 Windows 上仅支持 avx 的 CPU 预测,目前不支持 noavx 的 CPU 预测; * 如果需要使用 CPU 预测,PaddlePaddle 在 Windows 上仅支持 avx 的 CPU 预测,目前不支持 noavx 的 CPU 预测;
* 在使用生成的 `clas_system.exe` 进行预测时,如提示 `由于找不到paddle_fluid.dll,无法继续执行代码。重新安装程序可能会解决此问题`,请检查是否将 Paddle 预测库路径添加到系统环境变量,详见[Step1: 下载PaddlePaddle C++ 预测库 paddle_inference_install_dir](#step1-下载paddlepaddle-c-预测库-paddle_inference_install_dir) * 在使用生成的 `clas_system.exe` 进行预测时,如提示 `由于找不到paddle_fluid.dll,无法继续执行代码。重新安装程序可能会解决此问题`,请检查是否将 Paddle 预测库路径添加到系统环境变量,详见[1.1 下载 PaddlePaddle C++ 预测库 paddle_inference_install_dir](#1.1)
...@@ -37,7 +37,7 @@ pip3 install paddlehub==2.1.0 --upgrade -i https://pypi.tuna.tsinghua.edu.cn/sim ...@@ -37,7 +37,7 @@ pip3 install paddlehub==2.1.0 --upgrade -i https://pypi.tuna.tsinghua.edu.cn/sim
``` ```
需要注意, 需要注意,
* 模型文件(包括 `.pdmodel``.pdiparams`)名称必须为`inference` * 模型文件(包括 `.pdmodel``.pdiparams`)名称必须为`inference`
* 我们也提供了大量基于ImageNet-1k数据集的预训练模型,模型列表及下载地址详见[模型库概览](../../docs/zh_CN/models/models_intro.md),也可以使用自己训练转换好的模型。 * 我们也提供了大量基于ImageNet-1k数据集的预训练模型,模型列表及下载地址详见[模型库概览](../models/models_intro.md),也可以使用自己训练转换好的模型。
## 4. 安装服务模块 ## 4. 安装服务模块
...@@ -186,7 +186,7 @@ list: 返回结果 ...@@ -186,7 +186,7 @@ list: 返回结果
```hub serving start -m clas_system``` ```hub serving start -m clas_system```
**注意**: **注意**:
常用参数可在 [params.py](./clas/params.py) 中修改: 常用参数可在 `PaddleClas/deploy/hubserving/clas/params.py` 中修改:
* 更换模型,需要修改模型文件路径参数: * 更换模型,需要修改模型文件路径参数:
```python ```python
"inference_model_dir": "inference_model_dir":
...@@ -200,4 +200,4 @@ list: 返回结果 ...@@ -200,4 +200,4 @@ list: 返回结果
'class_id_map_file': 'class_id_map_file':
``` ```
为了避免不必要的延时以及能够以 batch_size 进行预测,数据预处理逻辑(包括 `resize`、`crop` 等操作)均在客户端完成,因此需要在 [test_hubserving.py](./test_hubserving.py#L35-L52) 中修改。 为了避免不必要的延时以及能够以 batch_size 进行预测,数据预处理逻辑(包括 `resize`、`crop` 等操作)均在客户端完成,因此需要在 `PaddleClas/deploy/hubserving/test_hubserving.py#L35-L52`中修改。
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
本教程将介绍基于[Paddle Lite](https://github.com/PaddlePaddle/Paddle-Lite)在移动端部署 PaddleClas 分类模型的详细步骤。 本教程将介绍基于[Paddle Lite](https://github.com/PaddlePaddle/Paddle-Lite)在移动端部署 PaddleClas 分类模型的详细步骤。
Paddle Lite是飞桨轻量化推理引擎,为手机、IOT端提供高效推理能力,并广泛整合跨平台硬件,为端侧部署及应用落地问题提供轻量化的部署方案。如果希望直接测试速度,可以参考[Paddle-Lite移动端benchmark测试教程](../../docs/zh_CN/extension/paddle_mobile_inference.md) Paddle Lite是飞桨轻量化推理引擎,为手机、IOT端提供高效推理能力,并广泛整合跨平台硬件,为端侧部署及应用落地问题提供轻量化的部署方案。
<!-- TODO(gaotingquan): 下述 benchmark 文档在新文档结构中缺失 -->
<!-- 如果希望直接测试速度,可以参考[Paddle-Lite移动端benchmark测试教程](../../docs/zh_CN/extension/paddle_mobile_inference.md)。 -->
--- ---
...@@ -15,11 +17,7 @@ Paddle Lite 目前支持以下平台部署: ...@@ -15,11 +17,7 @@ Paddle Lite 目前支持以下平台部署:
### 1.1 准备交叉编译环境 ### 1.1 准备交叉编译环境
交叉编译环境用于编译 Paddle Lite 和 PaddleClas 的 C++ demo。 交叉编译环境用于编译 Paddle Lite 和 PaddleClas 的 C++ demo。
支持多种开发环境,不同开发环境的编译流程请参考对应文档。 支持多种开发环境,关于 Docker、Linux、macOS、Windows 等不同开发环境的编译流程请参考[文档](https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_env.html)
1. [Docker](https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_env.html#docker)
2. [Linux](https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_env.html#linux)
3. [MAC OS](https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_env.html#mac-os)
### 1.2 准备预测库 ### 1.2 准备预测库
...@@ -44,7 +42,8 @@ cd Paddle-Lite ...@@ -44,7 +42,8 @@ cd Paddle-Lite
git checkout develop git checkout develop
./lite/tools/build_android.sh --arch=armv8 --with_cv=ON --with_extra=ON ./lite/tools/build_android.sh --arch=armv8 --with_cv=ON --with_extra=ON
``` ```
<!-- TODO(gaotingquan): 需要与lite同学确认,该编译选项是否需要更新:with_cv with_extra, -->
<!-- https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_options.html -->
**注意**:编译Paddle-Lite获得预测库时,需要打开`--with_cv=ON --with_extra=ON`两个选项,`--arch`表示`arm`版本,这里指定为armv8,更多编译命令介绍请参考[链接](https://paddle-lite.readthedocs.io/zh/latest/user_guides/Compile/Android.html#id2) **注意**:编译Paddle-Lite获得预测库时,需要打开`--with_cv=ON --with_extra=ON`两个选项,`--arch`表示`arm`版本,这里指定为armv8,更多编译命令介绍请参考[链接](https://paddle-lite.readthedocs.io/zh/latest/user_guides/Compile/Android.html#id2)
直接下载预测库并解压后,可以得到`inference_lite_lib.android.armv8/`文件夹,通过编译Paddle-Lite得到的预测库位于`Paddle-Lite/build.lite.android.armv8.gcc/inference_lite_lib.android.armv8/`文件夹下。 直接下载预测库并解压后,可以得到`inference_lite_lib.android.armv8/`文件夹,通过编译Paddle-Lite得到的预测库位于`Paddle-Lite/build.lite.android.armv8.gcc/inference_lite_lib.android.armv8/`文件夹下。
...@@ -197,7 +196,7 @@ cp ../../../cxx/lib/libpaddle_light_api_shared.so ./debug/ ...@@ -197,7 +196,7 @@ cp ../../../cxx/lib/libpaddle_light_api_shared.so ./debug/
``` ```
`prepare.sh``PaddleClas/deploy/lite/imgs/tabby_cat.jpg` 作为测试图像,将测试图像复制到 `demo/cxx/clas/debug/` 文件夹下。 `prepare.sh``PaddleClas/deploy/lite/imgs/tabby_cat.jpg` 作为测试图像,将测试图像复制到 `demo/cxx/clas/debug/` 文件夹下。
`paddle_lite_opt` 工具优化后的模型文件放置到 `/{lite prediction library path}/inference_lite_lib.android.armv8/demo/cxx/clas/debug/` 文件夹下。本例中,使用 [2.1.3](#2.1.3) 生成的 `MobileNetV3_large_x1_0.nb` 模型文件。 `paddle_lite_opt` 工具优化后的模型文件放置到 `/{lite prediction library path}/inference_lite_lib.android.armv8/demo/cxx/clas/debug/` 文件夹下。本例中,使用 [2.1.3 转换示例](#2.1.3) 生成的 `MobileNetV3_large_x1_0.nb` 模型文件。
执行完成后,clas 文件夹下将有如下文件格式: 执行完成后,clas 文件夹下将有如下文件格式:
...@@ -253,7 +252,7 @@ export LD_LIBRARY_PATH=/data/local/tmp/debug:$LD_LIBRARY_PATH ...@@ -253,7 +252,7 @@ export LD_LIBRARY_PATH=/data/local/tmp/debug:$LD_LIBRARY_PATH
运行效果如下: 运行效果如下:
<div align="center"> <div align="center">
<img src="./imgs/lite_demo_result.png" width="600"> <img src="../../images/inference_deployment/lite_demo_result.png" width="600">
</div> </div>
## FAQ ## FAQ
......
...@@ -21,10 +21,10 @@ pip3 install dist/* ...@@ -21,10 +21,10 @@ pip3 install dist/*
## 2. 快速开始 ## 2. 快速开始
* 使用`ResNet50`模型,以下图(`'docs/images/whl/demo.jpg'`)为例进行说明。 * 使用`ResNet50`模型,以下图(`PaddleClas/docs/images/inference_deployment/whl_demo.jpg`)为例进行说明。
<div align="center"> <div align="center">
<img src="../images/whl/demo.jpg" width = "400" /> <img src="../../images/inference_deployment/whl_demo.jpg" width = "400" />
</div> </div>
...@@ -32,7 +32,7 @@ pip3 install dist/* ...@@ -32,7 +32,7 @@ pip3 install dist/*
```python ```python
from paddleclas import PaddleClas from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50') clas = PaddleClas(model_name='ResNet50')
infer_imgs='docs/images/whl/demo.jpg' infer_imgs='docs/images/inference_deployment/whl_demo.jpg'
result=clas.predict(infer_imgs) result=clas.predict(infer_imgs)
print(next(result)) print(next(result))
``` ```
...@@ -46,12 +46,12 @@ print(next(result)) ...@@ -46,12 +46,12 @@ print(next(result))
* 在命令行中使用 * 在命令行中使用
```bash ```bash
paddleclas --model_name=ResNet50 --infer_imgs="docs/images/whl/demo.jpg" paddleclas --model_name=ResNet50 --infer_imgs="docs/images/inference_deployment/whl_demo.jpg"
``` ```
``` ```
>>> result >>> result
filename: docs/images/whl/demo.jpg, top-5, class_ids: [8, 7, 136, 80, 84], scores: [0.79368, 0.16329, 0.01853, 0.00959, 0.00239], label_names: ['hen', 'cock', 'European gallinule, Porphyrio porphyrio', 'black grouse', 'peacock'] filename: docs/images/inference_deployment/whl_demo.jpg, top-5, class_ids: [8, 7, 136, 80, 84], scores: [0.79368, 0.16329, 0.01853, 0.00959, 0.00239], label_names: ['hen', 'cock', 'European gallinule, Porphyrio porphyrio', 'black grouse', 'peacock']
Predict complete! Predict complete!
``` ```
...@@ -77,7 +77,7 @@ Predict complete! ...@@ -77,7 +77,7 @@ Predict complete!
* 命令行中 * 命令行中
```bash ```bash
from paddleclas import PaddleClas, get_default_confg from paddleclas import PaddleClas, get_default_confg
paddleclas --model_name=ViT_base_patch16_384 --infer_imgs='docs/images/whl/demo.jpg' --resize_short=384 --crop_size=384 paddleclas --model_name=ViT_base_patch16_384 --infer_imgs='docs/images/inference_deployment/whl_demo.jpg' --resize_short=384 --crop_size=384
``` ```
* Python代码中 * Python代码中
...@@ -109,14 +109,14 @@ paddleclas -h ...@@ -109,14 +109,14 @@ paddleclas -h
```python ```python
from paddleclas import PaddleClas from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50') clas = PaddleClas(model_name='ResNet50')
infer_imgs = 'docs/images/whl/demo.jpg' infer_imgs = 'docs/images/inference_deployment/whl_demo.jpg'
result=clas.predict(infer_imgs) result=clas.predict(infer_imgs)
print(next(result)) print(next(result))
``` ```
* CLI * CLI
```bash ```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/demo.jpg' paddleclas --model_name='ResNet50' --infer_imgs='docs/images/inference_deployment/whl_demo.jpg'
``` ```
...@@ -127,14 +127,14 @@ paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/demo.jpg' ...@@ -127,14 +127,14 @@ paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/demo.jpg'
```python ```python
from paddleclas import PaddleClas from paddleclas import PaddleClas
clas = PaddleClas(inference_model_dir='./inference/') clas = PaddleClas(inference_model_dir='./inference/')
infer_imgs = 'docs/images/whl/demo.jpg' infer_imgs = 'docs/images/inference_deployment/whl_demo.jpg'
result=clas.predict(infer_imgs) result=clas.predict(infer_imgs)
print(next(result)) print(next(result))
``` ```
* CLI * CLI
```bash ```bash
paddleclas --inference_model_dir='./inference/' --infer_imgs='docs/images/whl/demo.jpg' paddleclas --inference_model_dir='./inference/' --infer_imgs='docs/images/inference_deployment/whl_demo.jpg'
``` ```
...@@ -164,14 +164,14 @@ paddleclas --model_name='ResNet50' --infer_imgs='docs/images/' --batch_size 2 ...@@ -164,14 +164,14 @@ paddleclas --model_name='ResNet50' --infer_imgs='docs/images/' --batch_size 2
```python ```python
from paddleclas import PaddleClas from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50') clas = PaddleClas(model_name='ResNet50')
infer_imgs = 'https://raw.githubusercontent.com/paddlepaddle/paddleclas/release/2.2/docs/images/whl/demo.jpg' infer_imgs = 'https://raw.githubusercontent.com/paddlepaddle/paddleclas/release/2.2/docs/images/inference_deployment/whl_demo.jpg'
result=clas.predict(infer_imgs) result=clas.predict(infer_imgs)
print(next(result)) print(next(result))
``` ```
* CLI * CLI
```bash ```bash
paddleclas --model_name='ResNet50' --infer_imgs='https://raw.githubusercontent.com/paddlepaddle/paddleclas/release/2.2/docs/images/whl/demo.jpg' paddleclas --model_name='ResNet50' --infer_imgs='https://raw.githubusercontent.com/paddlepaddle/paddleclas/release/2.2/docs/images/inference_deployment/whl_demo.jpg'
``` ```
...@@ -183,7 +183,7 @@ paddleclas --model_name='ResNet50' --infer_imgs='https://raw.githubusercontent.c ...@@ -183,7 +183,7 @@ paddleclas --model_name='ResNet50' --infer_imgs='https://raw.githubusercontent.c
import cv2 import cv2
from paddleclas import PaddleClas from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50') clas = PaddleClas(model_name='ResNet50')
infer_imgs = cv2.imread("docs/images/whl/demo.jpg") infer_imgs = cv2.imread("docs/images/inference_deployment/whl_demo.jpg")
result=clas.predict(infer_imgs) result=clas.predict(infer_imgs)
print(next(result)) print(next(result))
``` ```
...@@ -229,12 +229,12 @@ class_id<space>class_name<\n> ...@@ -229,12 +229,12 @@ class_id<space>class_name<\n>
```python ```python
from paddleclas import PaddleClas from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50', class_id_map_file='./ppcls/utils/imagenet1k_label_list.txt') clas = PaddleClas(model_name='ResNet50', class_id_map_file='./ppcls/utils/imagenet1k_label_list.txt')
infer_imgs = 'docs/images/whl/demo.jpg' infer_imgs = 'docs/images/inference_deployment/whl_demo.jpg'
result=clas.predict(infer_imgs) result=clas.predict(infer_imgs)
print(next(result)) print(next(result))
``` ```
* CLI * CLI
```bash ```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/demo.jpg' --class_id_map_file='./ppcls/utils/imagenet1k_label_list.txt' paddleclas --model_name='ResNet50' --infer_imgs='docs/images/inference_deployment/whl_demo.jpg' --class_id_map_file='./ppcls/utils/imagenet1k_label_list.txt'
``` ```
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
--- ---
目前, **PaddleClas** 要求 **PaddlePaddle** 版本 `>=2.0`。建议使用我们提供的 Docker 运行 PaddleClas,有关 Docker、nvidia-docker 的相关使用教程可以参考[链接](https://www.runoob.com/Docker/Docker-tutorial.html)。如果不使用 Docker,可以直接跳过 [2.1](#2.1) 部分内容,从 [2.2](#2.2) 部分开始。 目前, **PaddleClas** 要求 **PaddlePaddle** 版本 `>=2.0`。建议使用我们提供的 Docker 运行 PaddleClas,有关 Docker、nvidia-docker 的相关使用教程可以参考[链接](https://www.runoob.com/Docker/Docker-tutorial.html)。如果不使用 Docker,可以直接跳过 [2.(建议)使用 Docker 环境](#2) 部分内容,从 [3. 通过 pip 安装 PaddlePaddle](#3) 部分开始。
## 1. 环境要求 ## 1. 环境要求
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* 当 CUDA 版本为 10.2 时,显卡驱动版本 `>= 440.33` * 当 CUDA 版本为 10.2 时,显卡驱动版本 `>= 440.33`
* 更多 CUDA 版本与要求的显卡驱动版本可以参考[链接](https://docs.nvidia.com/deploy/cuda-compatibility/index.html) * 更多 CUDA 版本与要求的显卡驱动版本可以参考[链接](https://docs.nvidia.com/deploy/cuda-compatibility/index.html)
<a name="2"></a>
## 2.(建议)使用 Docker 环境 ## 2.(建议)使用 Docker 环境
* 切换到工作目录下 * 切换到工作目录下
...@@ -40,16 +42,18 @@ sudo docker run --name ppcls -v $PWD:/paddle --shm-size=8G --network=host -it pa ...@@ -40,16 +42,18 @@ sudo docker run --name ppcls -v $PWD:/paddle --shm-size=8G --network=host -it pa
**注意** **注意**
* 首次使用该镜像时,下述命令会自动下载该镜像文件,下载需要一定的时间,请耐心等待; * 首次使用该镜像时,下述命令会自动下载该镜像文件,下载需要一定的时间,请耐心等待;
* 下述命令会创建一个 Docker 容器,之后再次使用该容器时无需再次运行该命令; * 上述命令会创建一个名为 ppcls 的 Docker 容器,之后再次使用该容器时无需再次运行该命令;
* 参数 `--shm-size=8G` 将设置容器的共享内存为8G,如机器环境允许,建议将该参数设置较大,如 `64G` * 参数 `--shm-size=8G` 将设置容器的共享内存为8G,如机器环境允许,建议将该参数设置较大,如 `64G`
* 您也可以访问 [DockerHub](https://hub.Docker.com/r/paddlepaddle/paddle/tags/)获取与您机器适配的镜像。 * 您也可以访问 [DockerHub](https://hub.Docker.com/r/paddlepaddle/paddle/tags/) 获取与您机器适配的镜像;
* 退出/进入 docker 容器:
* 在进入 Docker 容器后,可使用组合键 `Ctrl + P + Q` 退出当前容器,同时不关闭该容器;
* 如需再次进入容器,可使用下述命令:
* 退出/进入 docker 容器 ```shell
在进入 Docker 容器后,可使用组合键 `Ctrl + P + Q` 退出当前容器,同时不关闭该容器。如需再次进入容器,可使用下述命令: sudo Docker exec -it ppcls /bin/bash
```
```shell <a name="3"></a>
sudo Docker exec -it ppcls /bin/bash
```
## 3. 通过 pip 安装 PaddlePaddle ## 3. 通过 pip 安装 PaddlePaddle
...@@ -65,7 +69,7 @@ pip3 install paddlepaddle-gpu --upgrade -i https://mirror.baidu.com/pypi/simple ...@@ -65,7 +69,7 @@ pip3 install paddlepaddle-gpu --upgrade -i https://mirror.baidu.com/pypi/simple
**注意:** **注意:**
* 如果先安装了 CPU 版本的 PaddlePaddle,之后想切换到 GPU 版本,那么需要使用 pip 先卸载 CPU 版本的 PaddlePaddle,再安装 GPU 版本的 PaddlePaddle,否则容易导致 PaddlePaddle 冲突。 * 如果先安装了 CPU 版本的 PaddlePaddle,之后想切换到 GPU 版本,那么需要使用 pip 先卸载 CPU 版本的 PaddlePaddle,再安装 GPU 版本的 PaddlePaddle,否则容易导致 PaddlePaddle 冲突。
* 您也可以从源码编译安装 PaddlePaddle,请参照[PaddlePaddle 安装文档](http://www.paddlepaddle.org.cn/install/quick)中的说明进行操作。 * 您也可以从源码编译安装 PaddlePaddle,请参照 [PaddlePaddle 安装文档](http://www.paddlepaddle.org.cn/install/quick) 中的说明进行操作。
## 4. 验证安装 ## 4. 验证安装
...@@ -83,6 +87,6 @@ python -c "import paddle; print(paddle.__version__)" ...@@ -83,6 +87,6 @@ python -c "import paddle; print(paddle.__version__)"
``` ```
**注意** **注意**
- 从源码编译的 PaddlePaddle 版本号为 `0.0.0`,请确保使用了 PaddlePaddle 2.0 及之后的源码编译; - 从源码编译的 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) - PaddleClas 基于 PaddlePaddle 高性能的分布式训练能力,若您从源码编译,请确保打开编译选项 `WITH_DISTRIBUTE=ON`。具体编译选项参考 [编译选项表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/install/Tables.html#bianyixuanxiangbiao)
- 在 Docker 中运行时,为保证 Docker 容器有足够的共享内存用于 Paddle 的数据读取加速,在创建Docker 容器时,请设置参数 `--shm_size=8g`,条件允许的话可以设置为更大的值。 - 在 Docker 中运行时,为保证 Docker 容器有足够的共享内存用于 Paddle 的数据读取加速,在创建 Docker 容器时,请设置参数 `--shm_size=8g`,条件允许的话可以设置为更大的值。
## PaddleClas 功能特性
飞桨图像识别套件 PaddleClas 是飞桨为工业界和学术界所准备的一个图像识别任务的工具集,助力使用者训练出更好的视觉模型和应用落地。具体地,它包含以下几个核心特性。
- 实用的图像识别系统:集成了目标检测、特征学习、图像检索等模块,广泛适用于各类图像识别任务。
提供商品识别、车辆识别、 logo 识别和动漫人物识别等4个场景应用示例。
- 丰富的预训练模型库:提供了 36 个系列共 175 个 ImageNet 预训练模型,其中 7 个精选系列模型支持结构快速修改。
- 全面易用的特征学习组件:集成 arcmargin , triplet loss 等 12 度量学习方法,通过配置文件即可随意组合切换。
- SSLD 知识蒸馏: 14 个分类预训练模型,精度普遍提升 3% 以上;其中 ResNet50_vd 模型在 ImageNet-1k 数据集上的 Top-1 精度达到了 84.0% , Res2Net200_vd 预训练模型 Top-1 精度高达 85.1% 。
- 数据增广:支持 AutoAugment 、 Cutout 、 Cutmix 等 8 种数据增广算法详细介绍、代码复现和在统一实验环境下的效果评估。
<div align="center">
<img src="../../images/recognition.gif" width = "400" />
</div>
更多关于图像识别快速体验、算法详解、模型训练评估与预测部署方法,请参考[首页README文档教程](../../../README_ch.md)
## 识别效果展示
- 商品识别
<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>
[更多效果图](../../images/recognition/more_demo_images)
@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 @@ ...@@ -2,26 +2,13 @@
## 概述 ## 概述
基于ImageNet1k分类数据集,PaddleClas支持的29种系列分类网络结构以及对应的134个图像分类预训练模型如下所示,训练技巧、每个系列网络结构的简单介绍和性能评估将在相应章节展现。 基于ImageNet1k分类数据集,PaddleClas支持的36种系列分类网络结构以及对应的175个图像分类预训练模型如下所示,训练技巧、每个系列网络结构的简单介绍和性能评估将在相应章节展现。
## 评估环境 ## 评估环境
* CPU的评估环境基于骁龙855(SD855)。 * 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) ![](../../images/models/T4_benchmark/t4.fp32.bs4.main_fps_top1.png)
...@@ -34,6 +21,7 @@ python tools/infer/predict.py \ ...@@ -34,6 +21,7 @@ python tools/infer/predict.py \
## 预训练模型列表及下载地址 ## 预训练模型列表及下载地址
- ResNet及其Vd系列 - ResNet及其Vd系列
- ResNet系列<sup>[[1](#ref1)]</sup>([论文地址](http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html)) - 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) - [ResNet18](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet18_pretrained.pdparams)
...@@ -52,12 +40,23 @@ python tools/infer/predict.py \ ...@@ -52,12 +40,23 @@ python tools/infer/predict.py \
- [ResNet152_vd](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/ResNet152_vd_pretrained.pdparams) - [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) - [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](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) - [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) - [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系列<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_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) - [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 \ ...@@ -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_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](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) - [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系列 - SEResNeXt与Res2Net系列
- ResNeXt系列<sup>[[7](#ref7)]</sup>([论文地址](https://arxiv.org/abs/1611.05431)) - ResNeXt系列<sup>[[7](#ref7)]</sup>([论文地址](https://arxiv.org/abs/1611.05431))
...@@ -217,9 +226,38 @@ python tools/infer/predict.py \ ...@@ -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_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_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) - [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)) - 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 \ ...@@ -234,6 +272,40 @@ python tools/infer/predict.py \
- [VGG19](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/VGG19_pretrained.pdparams) - [VGG19](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/VGG19_pretrained.pdparams)
- DarkNet系列<sup>[[21](#ref21)]</sup>([论文地址](https://arxiv.org/abs/1506.02640)) - DarkNet系列<sup>[[21](#ref21)]</sup>([论文地址](https://arxiv.org/abs/1506.02640))
- [DarkNet53](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/DarkNet53_pretrained.pdparams) - [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里给出了相应的训练超参数。 **注意**:以上模型中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 \ ...@@ -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="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="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
# 开始使用 # 图像分类
--- ---
请参考[安装指南](./install.md)配置运行环境,并根据[快速开始](./quick_start_new_user.md)文档准备flower102数据集,本章节下面所有的实验均以flower102数据集为例。 图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题,也是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在很多领域有广泛应用,包括安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等。
一般来说,图像分类通过手工特征或特征学习方法对整个图像进行全部描述,然后使用分类器判别物体类别,因此如何提取图像的特征至关重要。在深度学习算法之前使用较多的是基于词袋(Bag of Words)模型的物体分类方法。而基于深度学习的图像分类方法,可以通过有监督或无监督的方式学习层次化的特征描述,从而取代了手工设计或选择图像特征的工作。深度学习模型中的卷积神经网络(Convolution Neural Network, CNN)近年来在图像领域取得了惊人的成绩,CNN直接利用图像像素信息作为输入,最大程度上保留了输入图像的所有信息,通过卷积操作进行特征的提取和高层抽象,模型输出直接是图像识别的结果。这种基于"输入-输出"直接端到端的学习方法取得了非常好的效果,得到了广泛的应用。
图像分类是计算机视觉里很基础但又重要的一个领域,其研究成果一直影响着计算机视觉甚至深度学习的发展,图像分类有很多子领域,如多标签分类、细粒度分类等,此处只对单标签图像分类做一个简述。
具体图像分类算法介绍详见[文档](../algorithm_introduction/image_classification.md)
## 一、数据集介绍
### 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的标准图像变换,也提供了多种数据增强的方法,相关代码可以[数据处理](../../../ppcls/data/preprocess),配置文件可以参考[数据增强配置文件](../../../ppcls/configs/ImageNet/DataAugment), 相关数据增强算法详见数据[增强介绍文档](../algorithm_introduction/DataAugmentation.md)
### 2.2 模型准备
在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了35个系列共164个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](../algorithm_introduction/ImageNet_models.md)
### 2.3 模型训练
在准备好数据、模型后,便可以开始迭代模型并更新模型的参数。经过多次迭代最终可以得到训练好的模型来做图像分类任务。图像分类的训练过程需要很多经验,涉及很多超参数的设置,PaddleClas提供了一些列的[训练调优方法](./train_strategy.md),可以快速助你获得高精度的模型。
### 2.4 模型评估
当训练得到一个模型之后,如何确定模型的好坏,需要将模型在验证集上进行评估。评估指标一般是Top1-Acc或者Top5-Acc,该指标越高往往代表模型性能越好。
## 三、使用方法介绍
请参考[安装指南](../installation/install_paddleclas.md)配置运行环境,并根据[快速开始](../quick_start/quick_start_classification.md)文档准备flower102数据集,本章节下面所有的实验均以flower102数据集为例。
PaddleClas目前支持的训练/评估环境如下: PaddleClas目前支持的训练/评估环境如下:
```shell ```shell
...@@ -12,12 +52,13 @@ PaddleClas目前支持的训练/评估环境如下: ...@@ -12,12 +52,13 @@ PaddleClas目前支持的训练/评估环境如下:
└── Linux └── Linux
``` ```
## 1. 基于CPU/单卡GPU上的训练与评估 ### 3.1 基于CPU/单卡GPU上的训练与评估
在基于CPU/单卡GPU上训练与评估,推荐使用`tools/train.py``tools/eval.py`脚本。关于Linux平台多卡GPU环境下的训练与评估,请参考[2. 基于Linux+GPU的模型训练与评估](#2) 在基于CPU/单卡GPU上训练与评估,推荐使用`tools/train.py``tools/eval.py`脚本。关于Linux平台多卡GPU环境下的训练与评估,请参考[3.2. 基于Linux+GPU的模型训练与评估](#3.2)
<a name="1.1"></a> <a name="3.1.1"></a>
### 1.1 模型训练
#### 3.1.1 模型训练
准备好配置文件之后,可以使用下面的方式启动训练。 准备好配置文件之后,可以使用下面的方式启动训练。
...@@ -55,7 +96,7 @@ python3 tools/train.py \ ...@@ -55,7 +96,7 @@ python3 tools/train.py \
训练期间也可以通过VisualDL实时观察loss变化,详见[VisualDL](../extension/VisualDL.md) 训练期间也可以通过VisualDL实时观察loss变化,详见[VisualDL](../extension/VisualDL.md)
### 1.2 模型微调 #### 3.1.2 模型微调
根据自己的数据集路径设置好配置文件后,可以通过加载预训练模型的方式进行微调,如下所示。 根据自己的数据集路径设置好配置文件后,可以通过加载预训练模型的方式进行微调,如下所示。
...@@ -68,10 +109,11 @@ python3 tools/train.py \ ...@@ -68,10 +109,11 @@ python3 tools/train.py \
其中`Arch.pretrained`设置为`True`表示加载ImageNet的预训练模型,此外,`Arch.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。 其中`Arch.pretrained`设置为`True`表示加载ImageNet的预训练模型,此外,`Arch.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。
我们也提供了大量基于`ImageNet-1k`数据集的预训练模型,模型列表及下载地址详见[模型库概览](../models/models_intro.md) 我们也提供了大量基于`ImageNet-1k`数据集的预训练模型,模型列表及下载地址详见[模型库概览](../algorithm_introduction/ImageNet_models.md)
<a name="3.1.3"></a>
<a name="1.3"></a> #### 3.1.3 模型恢复训练
### 1.3 模型恢复训练
如果训练任务因为其他原因被终止,也可以加载断点权重文件,继续训练: 如果训练任务因为其他原因被终止,也可以加载断点权重文件,继续训练:
...@@ -102,8 +144,9 @@ python3 tools/train.py \ ...@@ -102,8 +144,9 @@ python3 tools/train.py \
. .
``` ```
<a name="1.4"></a> <a name="3.1.4"></a>
### 1.4 模型评估
#### 3.1.4 模型评估
可以通过以下命令进行模型评估。 可以通过以下命令进行模型评估。
...@@ -119,14 +162,15 @@ python3 tools/eval.py \ ...@@ -119,14 +162,15 @@ python3 tools/eval.py \
* `Arch.name`:模型名称 * `Arch.name`:模型名称
* `Global.pretrained_model`:待评估的模型预训练模型文件路径 * `Global.pretrained_model`:待评估的模型预训练模型文件路径
**注意:** 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[1.3 模型恢复训练](#1.3) **注意:** 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[3.1.3 模型恢复训练](#3.1.3)
<a name="3.2"></a>
<a name="2"></a> ### 3.2. 基于Linux+多卡GPU的模型训练与评估
## 2. 基于Linux+GPU的模型训练与评估
如果机器环境为Linux+GPU,那么推荐使用`paddle.distributed.launch`启动模型训练脚本(`tools/train.py`)、评估脚本(`tools/eval.py`),可以更方便地启动多卡训练与评估。 如果机器环境为Linux+GPU,那么推荐使用`paddle.distributed.launch`启动模型训练脚本(`tools/train.py`)、评估脚本(`tools/eval.py`),可以更方便地启动多卡训练与评估。
### 2.1 模型训练 #### 3.2.1 模型训练
参考如下方式启动模型训练,`paddle.distributed.launch`通过设置`gpus`指定GPU运行卡号: 参考如下方式启动模型训练,`paddle.distributed.launch`通过设置`gpus`指定GPU运行卡号:
...@@ -134,22 +178,20 @@ python3 tools/eval.py \ ...@@ -134,22 +178,20 @@ python3 tools/eval.py \
# PaddleClas通过launch方式启动多卡多进程训练 # PaddleClas通过launch方式启动多卡多进程训练
export CUDA_VISIBLE_DEVICES=0,1,2,3 export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \ python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \ --gpus="0,1,2,3" \
tools/train.py \ tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml
``` ```
输出日志信息的格式同上,详见[1.1 模型训练](#1.1) 输出日志信息的格式同上,详见[3.1.1 模型训练](#3.1.1)
### 2.2 模型微调 #### 3.2.2 模型微调
根据自己的数据集配置好配置文件之后,可以加载预训练模型进行微调,如下所示。 根据自己的数据集配置好配置文件之后,可以加载预训练模型进行微调,如下所示。
``` ```shell
export CUDA_VISIBLE_DEVICES=0,1,2,3 export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \ python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \ --gpus="0,1,2,3" \
tools/train.py \ tools/train.py \
...@@ -163,7 +205,7 @@ python3 -m paddle.distributed.launch \ ...@@ -163,7 +205,7 @@ python3 -m paddle.distributed.launch \
<a name="model_resume"></a> <a name="model_resume"></a>
### 2.3 模型恢复训练 #### 3.2.3 模型恢复训练
如果训练任务因为其他原因被终止,也可以加载断点权重文件继续训练。 如果训练任务因为其他原因被终止,也可以加载断点权重文件继续训练。
...@@ -178,10 +220,9 @@ python3 -m paddle.distributed.launch \ ...@@ -178,10 +220,9 @@ python3 -m paddle.distributed.launch \
-o Global.device=gpu -o Global.device=gpu
``` ```
其中配置文件不需要做任何修改,只需要在训练时设置`Global.checkpoints`参数即可,该参数表示加载的断点权重文件路径,使用该参数会同时加载保存的模型参数权重和学习率、优化器等信息,详见[1.3 模型恢复训练](#1.3) 其中配置文件不需要做任何修改,只需要在训练时设置`Global.checkpoints`参数即可,该参数表示加载的断点权重文件路径,使用该参数会同时加载保存的模型参数权重和学习率、优化器等信息,详见[3.1.3 模型恢复训练](#3.1.3)
#### 3.2.4 模型评估
### 2.4 模型评估
可以通过以下命令进行模型评估。 可以通过以下命令进行模型评估。
...@@ -193,16 +234,15 @@ python3 -m paddle.distributed.launch \ ...@@ -193,16 +234,15 @@ python3 -m paddle.distributed.launch \
-o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model -o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model
``` ```
参数说明详见[1.4 模型评估](#1.4) 参数说明详见[3.1.4 模型评估](#3.1.4)
<a name="model_infer"></a> <a name="model_infer"></a>
## 3. 使用预训练模型进行模型预测
### 3.3 使用预训练模型进行模型预测
模型训练完成之后,可以加载训练得到的预训练模型,进行模型预测。在模型库的 `tools/infer/infer.py` 中提供了完整的示例,只需执行下述命令即可完成模型预测: 模型训练完成之后,可以加载训练得到的预训练模型,进行模型预测。在模型库的 `tools/infer/infer.py` 中提供了完整的示例,只需执行下述命令即可完成模型预测:
```python ```python
python3 tools/infer.py \ python3 tools/infer.py \
-c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \
-o Infer.infer_imgs=dataset/flowers102/jpg/image_00001.jpg \ -o Infer.infer_imgs=dataset/flowers102/jpg/image_00001.jpg \
...@@ -215,7 +255,7 @@ python3 tools/infer.py \ ...@@ -215,7 +255,7 @@ python3 tools/infer.py \
<a name="model_inference"></a> <a name="model_inference"></a>
## 4. 使用inference模型进行模型推理 ### 3.4 使用inference模型进行模型推理
通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。接下来介绍如何用预测引擎进行推理: 通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。接下来介绍如何用预测引擎进行推理:
首先,对训练好的模型进行转换: 首先,对训练好的模型进行转换:
...@@ -227,7 +267,7 @@ python3 tools/export_model.py \ ...@@ -227,7 +267,7 @@ python3 tools/export_model.py \
``` ```
其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[1.3 模型恢复训练](#1.3))。 其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[3.1.3 模型恢复训练](#3.1.3))。
上述命令将生成模型结构文件(`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理: 上述命令将生成模型结构文件(`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理:
...@@ -256,6 +296,7 @@ python3 python/predict_cls.py \ ...@@ -256,6 +296,7 @@ python3 python/predict_cls.py \
+ `Global.use_fp16`:是否启用`FP16`,默认为`False` + `Global.use_fp16`:是否启用`FP16`,默认为`False`
**注意**: 如果使用`Transformer`系列模型,如`DeiT_***_384`, `ViT_***_384`等,请注意模型的输入数据尺寸,需要设置参数`resize_short=384`, `resize=384` 注意: 如果使用`Transformer`系列模型,如`DeiT_***_384`, `ViT_***_384`等,请注意模型的输入数据尺寸,需要设置参数`resize_short=384`, `resize=384`
* 如果你希望提升评测模型速度,使用gpu评测时,建议开启TensorRT加速预测,使用cpu评测时,建议开启MKL-DNN加速预测。 如果你希望提升评测模型速度,使用gpu评测时,建议开启TensorRT加速预测,使用cpu评测时,建议开启MKL-DNN加速预测。
```
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
| image_shape | 图片大小 | [3,224,224] | list, shape: (3,) | | image_shape | 图片大小 | [3,224,224] | list, shape: (3,) |
| save_inference_dir | inference模型的保存路径 | "./inference" | str | | save_inference_dir | inference模型的保存路径 | "./inference" | str |
| eval_mode | eval的模式 | "classification" | "retrieval" | | eval_mode | eval的模式 | "classification" | "retrieval" |
| to_static | 是否改为静态图模式 | False | True |
| ues_dali | 是否使用dali库进行图像预处理 | False | True |
**注**`pretrained_model`也可以填写存放预训练模型的http地址。 **注**`pretrained_model`也可以填写存放预训练模型的http地址。
......
# 开始使用 # 图像识别
--- ---
首先,请参考[安装指南](./install.md)配置运行环境 在PaddleClas中,图像识别,是指给定一张查询图像,系统能够识别该查询图像类别。广义上,图像分类也是图像识别的一种。但是与普通图像识别不同的是,图像分类只能判别出模型已经学习的类别,如果需要添加新的类别,分类模型只能重新训练。PaddleClas中的图像识别,**对于陌生类别,只需要更新相应的检索库**,就能够正确的识别出查询图像的类别,而无需重新训练模型,这大大增加了识别系统的可用性,同时降低了更新模型的需求,方便用户部署应用
PaddleClas图像检索部分目前支持的训练/评估环境如下: 对于一张待查询图片,PaddleClas中的图像识别流程主要分为三部分:
```shell
└── CPU/单卡GPU 1. 主体检测:对于给定一个查询图像,主体检测器首先检测出图像的物体,从而去掉无用背景信息,提高识别精度。
   ├── Linux 2. 特征提取:对主体检测的各个候选区域,通过特征模型,进行特征提取
   └── Windows 3. 特征检索:将提取的特征与特征库中的向量进行相似度比对,得到其标签信息
其中特征库,需要利用已经标注好的图像数据集提前建立。完整的图像识别系统,如下图所示
<div align="center">
<img src="../../images/structure.png" width = "400" />
</div>
体验整体图像识别系统,或查看特征库建立方法,详见[图像识别快速开始文档](../quick_start/quick_start_recognition.md) 。其中,图像识别快速开始文档主要讲解整体流程的使用过程。以下内容,主要对上述三个步骤的训练部分进行介绍。
首先,请参考[安装指南](../installation/install_paddleclas.md)配置运行环境。
具体目录如下:
- [主体检测](#主体检测)
- [特征模型训练](#特征模型训练)
- [2.1. 特征模型数据准备与处理](#特征模型数据准备与处理)
- [2. 特征模型基于单卡GPU上的训练与评估](#特征模型基于单卡GPU上的训练与评估)
- [2.1 特征模型训练](#特征模型训练)
- [2.2 特征模型恢复训练](#特征模型恢复训练)
- [2.3 特征模型评估](#特征模型评估)
- [3. 特征模型导出inference模型](#特征模型导出inference模型)
- [特征检索](#特征检索)
- [基础知识](#基础知识)
<a name="主体检测"></a>
## 一、主体检测
主体检测训练过程基于 [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection/tree/develop) ,唯一的区别在于,主体检测任务中,所有的检测框均属于前景,在这里需要将标注文件中,检测框的 `category_id` 修改为1,同时将整个标注文件中的 `categories` 映射表修改为下面的格式,即整个类别映射表中只包含`前景`类别。
```json
[{u'id': 1, u'name': u'foreground', u'supercategory': u'foreground'}]
``` ```
## 目录
* [1. 数据准备与处理](#数据准备与处理) 关于主体检测训练方法可以参考: [PaddleDetection训练教程](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/docs/tutorials/GETTING_STARTED_cn.md#4-%E8%AE%AD%E7%BB%83)
* [2. 基于单卡GPU上的训练与评估](#基于单卡GPU上的训练与评估)
* [2.1 模型训练](#模型训练) 更多关于 PaddleClas 中提供的主体检测的模型介绍与下载请参考:[主体检测教程](../image_recognition_pipeline/mainbody_detection.md)
* [2.2 模型恢复训练](#模型恢复训练)
* [2.3 模型评估](#模型评估) <a name="特征模型训练"></a>
* [3. 导出inference模型](#导出inference模型)
## 二、特征模型训练
<a name="数据的准备与处理"></a>
## 1. 数据的准备与处理 <a name="特征模型数据准备与处理"></a>
### 2.1 特征模型数据的准备与处理
* 进入PaddleClas目录。 * 进入PaddleClas目录。
...@@ -64,12 +96,12 @@ tree -r -i -f test | grep jpg | awk -F "/" '{print $0" "int($2) " "NR}' > test_l ...@@ -64,12 +96,12 @@ tree -r -i -f test | grep jpg | awk -F "/" '{print $0" "int($2) " "NR}' > test_l
``` ```
├── 1 ├── 1
   ├── Black_Footed_Albatross_0001_796111.jpg ├── Black_Footed_Albatross_0001_796111.jpg
   ├── Black_Footed_Albatross_0002_55.jpg ├── Black_Footed_Albatross_0002_55.jpg
... ...
├── 10 ├── 10
   ├── Red_Winged_Blackbird_0001_3695.jpg ├── Red_Winged_Blackbird_0001_3695.jpg
   ├── Red_Winged_Blackbird_0005_5636.jpg ├── Red_Winged_Blackbird_0005_5636.jpg
... ...
``` ```
...@@ -98,21 +130,30 @@ train/99/Ovenbird_0130_92452.jpg 99 5 ...@@ -98,21 +130,30 @@ train/99/Ovenbird_0130_92452.jpg 99 5
cd ../../ cd ../../
``` ```
<a name="基于单卡GPU上的训练与评估"></a> <a name="特征模型基于单卡GPU上的训练与评估"></a>
## 2. 基于单卡GPU上的训练与评估
### 2.2 特征模型GPU上的训练与评估
在基于单卡GPU上训练与评估,推荐使用`tools/train.py``tools/eval.py`脚本。 在基于单卡GPU上训练与评估,推荐使用`tools/train.py``tools/eval.py`脚本。
<a name="模型训练"></a> <a name="特征模型训练"></a>
### 2.1 模型训练
#### 2.2.1 特征模型训练
准备好配置文件之后,可以使用下面的方式启动图像检索任务的训练。PaddleClas训练图像检索任务的方法是度量学习,关于度量学习的解析请参考[度量学习](#度量学习) 准备好配置文件之后,可以使用下面的方式启动图像检索任务的训练。PaddleClas训练图像检索任务的方法是度量学习,关于度量学习的解析请参考[度量学习](#度量学习)
``` ```shell
# 单卡GPU
python3 tools/train.py \ python3 tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \
-o Arch.Backbone.pretrained=True \ -o Arch.Backbone.pretrained=True \
-o Global.device=gpu -o Global.device=gpu
# 多卡GPU
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch 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` 其中,`-c`用于指定配置文件的路径,`-o`用于指定需要修改或者添加的参数,其中`-o Arch.Backbone.pretrained=True`表示Backbone部分使用预训练模型,此外,`Arch.Backbone.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。`-o Global.device=gpu`表示使用GPU进行训练。如果希望使用CPU进行训练,则需要将`Global.device`设置为`cpu`
...@@ -141,19 +182,27 @@ Loss: ...@@ -141,19 +182,27 @@ Loss:
weight: 1.0 weight: 1.0
margin: 0.5 margin: 0.5
``` ```
最终的总Loss是所有Loss的加权和,其中weight定义了特定Loss在最终总Loss的权重。如果想替换其他Loss,也可以在配置文件中更改Loss字段,目前支持的Loss请参考[Loss](../../../ppcls/loss) 最终的总Loss是所有Loss的加权和,其中weight定义了特定Loss在最终总Loss的权重。如果想替换其他Loss,也可以在配置文件中更改Loss字段,目前支持的Loss请参考[Loss](../../../ppcls/loss)
<a name="模型恢复训练"></a> <a name="特征模型恢复训练"></a>
### 2.2 模型恢复训练
#### 2.2.2 特征模型恢复训练
如果训练任务因为其他原因被终止,也可以加载断点权重文件,继续训练: 如果训练任务因为其他原因被终止,也可以加载断点权重文件,继续训练:
``` ```shell
# 单卡
python3 tools/train.py \ python3 tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \
-o Global.checkpoints="./output/RecModel/epoch_5" \ -o Global.checkpoints="./output/RecModel/epoch_5" \
-o Global.device=gpu -o Global.device=gpu
# 多卡
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch tools/train.py \
-c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \
-o Global.checkpoints="./output/RecModel/epoch_5" \
-o Global.device=gpu
``` ```
其中配置文件不需要做任何修改,只需要在继续训练时设置`Global.checkpoints`参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。 其中配置文件不需要做任何修改,只需要在继续训练时设置`Global.checkpoints`参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。
...@@ -176,15 +225,22 @@ python3 tools/train.py \ ...@@ -176,15 +225,22 @@ python3 tools/train.py \
. .
``` ```
<a name="模型评估"></a> <a name="特征模型评估"></a>
### 2.3 模型评估
#### 2.2.3 特征模型评估
可以通过以下命令进行模型评估。 可以通过以下命令进行模型评估。
```bash ```bash
# 单卡
python3 tools/eval.py \ python3 tools/eval.py \
-c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \
-o Global.pretrained_model=./output/RecModel/best_model -o Global.pretrained_model=./output/RecModel/best_model
# 多卡
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch 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`参数更新配置,如上所示。 上述命令将使用`./configs/quick_start/MobileNetV1_retrieval.yaml`作为配置文件,对上述训练得到的模型`./output/RecModel/best_model`进行评估。你也可以通过更改配置文件中的参数来设置评估,也可以通过`-o`参数更新配置,如上所示。
...@@ -194,14 +250,15 @@ python3 tools/eval.py \ ...@@ -194,14 +250,15 @@ python3 tools/eval.py \
* `Global.pretrained_model`:待评估的模型的预训练模型文件路径,不同于`Global.Backbone.pretrained`,此处的预训练模型是整个模型的权重,而`Global.Backbone.pretrained`只是Backbone部分的权重。当需要做模型评估时,需要加载整个模型的权重。 * `Global.pretrained_model`:待评估的模型的预训练模型文件路径,不同于`Global.Backbone.pretrained`,此处的预训练模型是整个模型的权重,而`Global.Backbone.pretrained`只是Backbone部分的权重。当需要做模型评估时,需要加载整个模型的权重。
* `Metric.Eval`:待评估的指标,默认评估recall@1、recall@5、mAP。当你不准备评测某一项指标时,可以将对应的试标从配置文件中删除;当你想增加某一项评测指标时,也可以参考[Metric](../../../ppcls/metric/metrics.py)部分在配置文件`Metric.Eval`中添加相关的指标。 * `Metric.Eval`:待评估的指标,默认评估recall@1、recall@5、mAP。当你不准备评测某一项指标时,可以将对应的试标从配置文件中删除;当你想增加某一项评测指标时,也可以参考[Metric](../../../ppcls/metric/metrics.py)部分在配置文件`Metric.Eval`中添加相关的指标。
**注意:** **注意:**
* 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[2.2 模型恢复训练](#模型恢复训练) * 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[2.2.2 特征模型恢复训练](#特征模型恢复训练)
* Metric learning任务一般不评测TopkAcc。 * Metric learning任务一般不评测TopkAcc。
<a name="导出inference模型"></a> <a name="特征模型导出inference模型"></a>
## 3. 导出inference模型
### 2.3 特征模型导出inference模型
通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。对训练好的模型进行转换: 通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。对训练好的模型进行转换:
...@@ -212,20 +269,52 @@ python3 tools/export_model.py \ ...@@ -212,20 +269,52 @@ python3 tools/export_model.py \
-o Global.save_inference_dir=./inference -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特征。 其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[2.2.2 特征模型恢复训练](#特征模型恢复训练))。当执行后,会在当前目录下生成`./inference`目录,目录下包含`inference.pdiparams``inference.pdiparams.info``inference.pdmodel`文件。`Global.save_inference_dir`可以指定导出inference模型的路径。此处保存的inference模型在embedding特征层做了截断,即模型最终的输出为n维embedding特征。
上述命令将生成模型结构文件(`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理。使用inference模型推理的流程可以参考[基于Python预测引擎预测推理](https://github.com/PaddlePaddle/PaddleClas/blob/develop/docs/zh_CN/inference.md) 上述命令将生成模型结构文件(`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理。使用inference模型推理的流程可以参考[基于Python预测引擎预测推理](https://github.com/PaddlePaddle/PaddleClas/blob/develop/docs/zh_CN/inference.md)
## 基础知识 <a name="特征检索"></a>
## 三、特征检索
PaddleClas图像检索部分目前支持的环境如下:
```shell
└── CPU/单卡GPU
├── Linux
├── MacOS
└── Windows
```
此部分使用了[Faiss](https://github.com/facebookresearch/faiss)作为检索库,其是一个高效的特征检索及聚类的库。此库中集成了多种相似度检索算法,以满足不同的检索场景。在PaddleClas中,支持三种检索算法:
- **HNSW32**: 一种图索引方法。检索精度较高,速度较快。但是特征库只支持添加图像功能,不支持删除图像特征功能。(默认方法)
- **IVF**:倒排索引检索方法。速度较快,但是精度略低。特征库支持增加、删除图像特功能。
- **FLAT**: 暴力检索算法。精度最高,但是数据量大时,检索速度较慢。特征库支持增加、删除图像特征功能。
详细介绍请参考[Faiss](https://github.com/facebookresearch/faiss)官方文档。
具体安装方法如下:
```python
pip install faiss-cpu==1.7.1post2
```
若使用时,不能正常引用,则`uninstall` 之后,重新`install`,尤其是`windows`下。
<a name="基础知识"></a>
## 四、基础知识
图像检索指的是给定一个包含特定实例(例如特定目标、场景、物品等)的查询图像,图像检索旨在从数据库图像中找到包含相同实例的图像。不同于图像分类,图像检索解决的是一个开集问题,训练集中可能不包含被识别的图像的类别。图像检索的整体流程为:首先将图像中表示为一个合适的特征向量,其次,对这些图像的特征向量用欧式距离或余弦距离进行最近邻搜索以找到底库中相似的图像,最后,可以使用一些后处理技术对检索结果进行微调,确定被识别图像的类别等信息。所以,决定一个图像检索算法性能的关键在于图像对应的特征向量的好坏。 图像检索指的是给定一个包含特定实例(例如特定目标、场景、物品等)的查询图像,图像检索旨在从数据库图像中找到包含相同实例的图像。不同于图像分类,图像检索解决的是一个开集问题,训练集中可能不包含被识别的图像的类别。图像检索的整体流程为:首先将图像中表示为一个合适的特征向量,其次,对这些图像的特征向量用欧式距离或余弦距离进行最近邻搜索以找到底库中相似的图像,最后,可以使用一些后处理技术对检索结果进行微调,确定被识别图像的类别等信息。所以,决定一个图像检索算法性能的关键在于图像对应的特征向量的好坏。
<a name="度量学习"></a> <a name="度量学习"></a>
- 度量学习(Metric Learning) - 度量学习(Metric Learning)
度量学习研究如何在一个特定的任务上学习一个距离函数,使得该距离函数能够帮助基于近邻的算法 (kNN、k-means等) 取得较好的性能。深度度量学习 (Deep Metric Learning )是度量学习的一种方法,它的目标是学习一个从原始特征到低维稠密的向量空间 (嵌入空间,embedding space) 的映射,使得同类对象在嵌入空间上使用常用的距离函数 (欧氏距离、cosine距离等) 计算的距离比较近,而不同类的对象之间的距离则比较远。深度度量学习在计算机视觉领域取得了非常多的成功的应用,比如人脸识别、商品识别、图像检索、行人重识别等。 度量学习研究如何在一个特定的任务上学习一个距离函数,使得该距离函数能够帮助基于近邻的算法 (kNN、k-means等) 取得较好的性能。深度度量学习 (Deep Metric Learning )是度量学习的一种方法,它的目标是学习一个从原始特征到低维稠密的向量空间 (嵌入空间,embedding space) 的映射,使得同类对象在嵌入空间上使用常用的距离函数 (欧氏距离、cosine距离等) 计算的距离比较近,而不同类的对象之间的距离则比较远。深度度量学习在计算机视觉领域取得了非常多的成功的应用,比如人脸识别、商品识别、图像检索、行人重识别等。更详细的介绍请参考[此文档](../algorithm_introduction/metric_learning.md)
<a name="图像检索数据集介绍"></a> <a name="图像检索数据集介绍"></a>
- 图像检索数据集介绍 - 图像检索数据集介绍
- 训练集合(train dataset):用来训练模型,使模型能够学习该集合的图像特征。 - 训练集合(train dataset):用来训练模型,使模型能够学习该集合的图像特征。
...@@ -243,6 +332,6 @@ python3 tools/export_model.py \ ...@@ -243,6 +332,6 @@ python3 tools/export_model.py \
<a name="平均检索精度"></a> <a name="平均检索精度"></a>
- 平均检索精度(mAP) - 平均检索精度(mAP)
- AP: AP指的是不同召回率上的正确率的平均值 - AP: AP指的是不同召回率上的正确率的平均值
- mAP: 测试集中所有图片对应的AP的的平均值 - mAP: 测试集中所有图片对应的AP的的平均值
# 训练技巧
## 1.优化器的选择
自深度学习发展以来,就有很多关于优化器的研究者工作,优化器的目的是为了让损失函数尽可能的小,从而找到合适的参数来完成某项任务。目前业界主要用到的优化器有SGD、RMSProp、Adam、AdaDelt等,其中由于带momentum的SGD优化器广泛应用于学术界和工业界,所以我们发布的模型也大都使用该优化器来实现损失函数的梯度下降。带momentum的SGD优化器有两个劣势,其一是收敛速度慢,其二是初始学习率的设置需要依靠大量的经验,然而如果初始学习率设置得当并且迭代轮数充足,该优化器也会在众多的优化器中脱颖而出,使得其在验证集上获得更高的准确率。一些自适应学习率的优化器如Adam、RMSProp等,收敛速度往往比较快,但是最终的收敛精度会稍差一些。如果追求更快的收敛速度,我们推荐使用这些自适应学习率的优化器,如果追求更高的收敛精度,我们推荐使用带momentum的SGD优化器。
## 2.学习率以及学习率下降策略的选择
学习率的选择往往和优化器以及数据和任务有关系。这里主要介绍以momentum+SGD作为优化器训练ImageNet-1k的学习率以及学习率下降的选择。
### 学习率的概念:
学习率是通过损失函数的梯度调整网络权重的超参数的速度。学习率越低,损失函数的变化速度就越慢。虽然使用低学习率可以确保不会错过任何局部极小值,但也意味着将花费更长的时间来进行收敛,特别是在被困在高原区域的情况下。
### 学习率下降策略:
在整个训练过程中,我们不能使用同样的学习率来更新权重,否则无法到达最优点,所以需要在训练过程中调整学习率的大小。在训练初始阶段,由于权重处于随机初始化的状态,损失函数相对容易进行梯度下降,所以可以设置一个较大的学习率。在训练后期,由于权重参数已经接近最优值,较大的学习率无法进一步寻找最优值,所以需要设置一个较小的学习率。在训练整个过程中,很多研究者使用的学习率下降方式是piecewise_decay,即阶梯式下降学习率,如在ResNet50标准的训练中,我们设置的初始学习率是0.1,每30epoch学习率下降到原来的1/10,一共迭代120epoch。除了piecewise_decay,很多研究者也提出了学习率的其他下降方式,如polynomial_decay(多项式下降)、exponential_decay(指数下降),cosine_decay(余弦下降)等,其中cosine_decay无需调整超参数,鲁棒性也比较高,所以成为现在提高模型精度首选的学习率下降方式。Cosine_decay和piecewise_decay的学习率变化曲线如下图所示,容易观察到,在整个训练过程中,cosine_decay都保持着较大的学习率,所以其收敛较为缓慢,但是最终的收敛效果较peicewise_decay更好一些。
![](../../images/models/lr_decay.jpeg)
另外,从图中我们也可以看到,cosine_decay里学习率小的轮数较少,这样会影响到最终的精度,所以为了使得cosine_decay发挥更好的效果,建议迭代更多的轮数,如200轮。
### warmup策略
如果使用较大的batch_size训练神经网络时,我们建议您使用warmup策略。Warmup策略顾名思义就是让学习率先预热一下,在训练初期我们不直接使用最大的学习率,而是用一个逐渐增大的学习率去训练网络,当学习率增大到最高点时,再使用学习率下降策略中提到的学习率下降方式衰减学习率的值。实验表明,在batch_size较大时,warmup可以稳定提升模型的精度。在训练MobileNetV3等batch_size较大的实验中,我们默认将warmup中的epoch设置为5,即先用5epoch将学习率从0增加到最大值,再去做相应的学习率衰减。
## 3.batch_size的选择
batch_size是训练神经网络中的一个重要的超参数,该值决定了一次将多少数据送入神经网络参与训练。在论文[1]中,作者通过实验发现,当batch_size的值与学习率的值呈线性关系时,收敛精度几乎不受影响。在训练ImageNet数据时,大部分的神经网络选择的初始学习率为0.1,batch_size是256,所以根据实际的模型大小和显存情况,可以将学习率设置为0.1\*k,batch_size设置为256\*k。
## 4.weight_decay的选择
过拟合是机器学习中常见的一个名词,简单理解即为模型在训练数据上表现很好,但在测试数据上表现较差,在卷积神经网络中,同样存在过拟合的问题,为了避免过拟合,很多正则方式被提出,其中,weight_decay是其中一个广泛使用的避免过拟合的方式。Weight_decay等价于在最终的损失函数后添加L2正则化,L2正则化使得网络的权重倾向于选择更小的值,最终整个网络中的参数值更趋向于0,模型的泛化性能相应提高。在各大深度学习框架的实现中,该值表达的含义是L2正则前的系数,在paddle框架中,该值的名称是l2_decay,所以以下都称其为l2_decay。该系数越大,表示加入的正则越强,模型越趋于欠拟合状态。在训练ImageNet的任务中,大多数的网络将该参数值设置为1e-4,在一些小的网络如MobileNet系列网络中,为了避免网络欠拟合,该值设置为1e-5~4e-5之间。当然,该值的设置也和具体的数据集有关系,当任务的数据集较大时,网络本身趋向于欠拟合状态,可以将该值适当减小,当任务的数据集较小时,网络本身趋向于过拟合状态,可以将该值适当增大。下表展示了MobileNetV1_x0_25在ImageNet-1k上使用不同l2_decay的精度情况。由于MobileNetV1_x0_25是一个比较小的网络,所以l2_decay过大会使网络趋向于欠拟合状态,所以在该网络中,相对1e-4,3e-5是更好的选择。
| 模型 | L2_decay | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| MobileNetV1_x0_25 | 1e-4 | 43.79%/67.61% | 50.41%/74.70% |
| MobileNetV1_x0_25 | 3e-5 | 47.38%/70.83% | 51.45%/75.45% |
另外,该值的设置也和训练过程中是否使用其他正则化有关系。如果训练过程中的数据预处理比较复杂,相当于训练任务变的更难,可以将该值适当减小,下表展示了在ImageNet-1k上,ResNet50在使用randaugment预处理方式后使用不同l2_decay的精度。容易观察到,在任务变难后,使用更小的l2_decay有助于模型精度的提升。
| 模型 | L2_decay | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| ResNet50 | 1e-4 | 75.13%/90.42% | 77.65%/93.79% |
| ResNet50 | 7e-5 | 75.56%/90.55% | 78.04%/93.74% |
综上所述,l2_decay可以根据具体的任务和模型去做相应的调整,通常简单的任务或者较大的模型,推荐使用较大的l2_decay,复杂的任务或者较小的模型,推荐使用较小的l2_decay。
## 5.label_smoothing的选择
Label_smoothing是深度学习中的一种正则化方法,其全称是 Label Smoothing Regularization(LSR),即标签平滑正则化。在传统的分类任务计算损失函数时,是将真实的one hot标签与神经网络的输出做相应的交叉熵计算,而label_smoothing是将真实的one hot标签做一个标签平滑的处理,使得网络学习的标签不再是一个hard label,而是一个有概率值的soft label,其中在类别对应的位置的概率最大,其他位置概率是一个非常小的数。具体的计算方式参见论文[2]。在label_smoothing里,有一个epsilon的参数值,该值描述了将标签软化的程度,该值越大,经过label smoothing后的标签向量的标签概率值越小,标签越平滑,反之,标签越趋向于hard label,在训练ImageNet-1k的实验里通常将该值设置为0.1。
在训练ImageNet-1k的实验中,我们发现,ResNet50大小级别及其以上的模型在使用label_smooting后,精度有稳定的提升。下表展示了ResNet50_vd在使用label_smoothing前后的精度指标。
| 模型 | Use_label_smoothing | Test acc1 |
|:--:|:--:|:--:|
| ResNet50_vd | 0 | 77.9% |
| ResNet50_vd | 1 | 78.4% |
同时,由于label_smoohing相当于一种正则方式,在相对较小的模型上,精度提升不明显甚至会有所下降,下表展示了ResNet18在ImageNet-1k上使用label_smoothing前后的精度指标。可以明显看到,在使用label_smoothing后,精度有所下降。
| 模型 | Use_label_smoohing | Train acc1/acc5 | Test acc1/acc5 |
|:--:|:--:|:--:|:--:|
| ResNet18 | 0 | 69.81%/87.70% | 70.98%/89.92% |
| ResNet18 | 1 | 68.00%/86.56% | 70.81%/89.89% |
综上所述,较大的模型使用label_smoohing可以有效提升模型的精度,较小的模型使用label_smoohing可能会降低模型的精度,所以在决定是否使用label_smoohing前,需要评估模型的大小和任务的难易程度。
## 6.针对小模型更改图片的crop面积与拉伸变换程度
在ImageNet-1k数据的标准预处理中,random_crop函数中定义了scale和ratio两个值,两个值分别确定了图片crop的大小和图片的拉伸程度,其中scale的默认取值范围是0.08-1(lower_scale-upper_scale),ratio的默认取值范围是3/4-4/3(lower_ratio-upper_ratio)。在非常小的网络训练中,此类数据增强会使得网络欠拟合,导致精度有所下降。为了提升网络的精度,可以使其数据增强变的更弱,即增大图片的crop区域或者减弱图片的拉伸变换程度。我们可以分别通过增大lower_scale的值或缩小lower_ratio与upper_scale的差距来实现更弱的图片变换。下表列出了使用不同lower_scale训练MobileNetV2_x0_25的精度,可以看到,增大图片的crop区域面积后训练精度和验证精度均有提升。
| 模型 | Scale取值范围 | Train_acc1/acc5 | Test_acc1/acc5 |
|:--:|:--:|:--:|:--:|
| MobileNetV2_x0_25 | [0.08,1] | 50.36%/72.98% | 52.35%/75.65% |
| MobileNetV2_x0_25 | [0.2,1] | 54.39%/77.08% | 53.18%/76.14% |
## 7.使用数据增广方式提升精度
一般来说,数据集的规模对性能影响至关重要,但是图片的标注往往比较昂贵,所以有标注的图片数量往往比较稀少,在这种情况下,数据的增广尤为重要。在训练ImageNet-1k的标准数据增广中,主要使用了random_crop与random_flip两种数据增广方式,然而,近些年,越来越多的数据增广方式被提出,如cutout、mixup、cutmix、AutoAugment等。实验表明,这些数据的增广方式可以有效提升模型的精度,下表列出了ResNet50在8种不同的数据增广方式的表现,可以看出,相比baseline,所有的数据增广方式均有收益,其中cutmix是目前最有效的数据增广。更多数据增广的介绍请参考[**数据增广章节**](../algorithm_introduction/DataAugmentation.md)
| 模型 | 数据增广方式 | Test top-1 |
|:--:|:--:|:--:|
| ResNet50 | 标准变换 | 77.31% |
| ResNet50 | Auto-Augment | 77.95% |
| ResNet50 | Mixup | 78.28% |
| ResNet50 | Cutmix | 78.39% |
| ResNet50 | Cutout | 78.01% |
| ResNet50 | Gridmask | 77.85% |
| ResNet50 | Random-Augment | 77.70% |
| ResNet50 | Random-Erasing | 77.91% |
| ResNet50 | Hide-and-Seek | 77.43% |
## 8. 通过train_acc和test_acc确定调优策略
在训练网络的过程中,通常会打印每一个epoch的训练集准确率和验证集准确率,二者刻画了该模型在两个数据集上的表现。通常来说,训练集的准确率比验证集准确率微高或者二者相当是比较不错的状态。如果发现训练集的准确率比验证集高很多,说明在这个任务上已经过拟合,需要在训练过程中加入更多的正则,如增大l2_decay的值,加入更多的数据增广策略,加入label_smoothing策略等;如果发现训练集的准确率比验证集低一些,说明在这个任务上可能欠拟合,需要在训练过程中减弱正则效果,如减小l2_decay的值,减少数据增广方式,增大图片crop区域面积,减弱图片拉伸变换,去除label_smoothing等。
## 9.通过已有的预训练模型提升自己的数据集的精度
在现阶段计算机视觉领域中,加载预训练模型来训练自己的任务已成为普遍的做法,相比从随机初始化开始训练,加载预训练模型往往可以提升特定任务的精度。一般来说,业界广泛使用的预训练模型是通过训练128万张图片1000类的ImageNet-1k数据集得到的,该预训练模型的fc层权重是是一个k\*1000的矩阵,其中k是fc层以前的神经元数,在加载预训练权重时,无需加载fc层的权重。在学习率方面,如果您的任务训练的数据集特别小(如小于1千张),我们建议你使用较小的初始学习率,如0.001(batch_size:256,下同),以免较大的学习率破坏预训练权重。如果您的训练数据集规模相对较大(大于10万),我们建议你尝试更大的初始学习率,如0.01或者更大。
> 如果您觉得此文档对您有帮助,欢迎star我们的项目:[https://github.com/PaddlePaddle/PaddleClas](https://github.com/PaddlePaddle/PaddleClas)
## 参考文献
[1]P. Goyal, P. Dolla ́r, R. B. Girshick, P. Noordhuis, L. Wesolowski, A. Kyrola, A. Tulloch, Y. Jia, and K. He. Accurate, large minibatch SGD: training imagenet in 1 hour. CoRR, abs/1706.02677, 2017.
[2]C.Szegedy,V.Vanhoucke,S.Ioffe,J.Shlens,andZ.Wojna. Rethinking the inception architecture for computer vision. CoRR, abs/1512.00567, 2015.
...@@ -6,7 +6,7 @@ PaddleClas的建设源于百度实际视觉业务应用的淬炼和视觉前沿 ...@@ -6,7 +6,7 @@ PaddleClas的建设源于百度实际视觉业务应用的淬炼和视觉前沿
* 2019年Kaggle Open Images V5图像目标检测挑战赛亚军 * 2019年Kaggle Open Images V5图像目标检测挑战赛亚军
* 技术报告可以参考:[https://arxiv.org/pdf/1911.07171.pdf](https://arxiv.org/pdf/1911.07171.pdf) * 技术报告可以参考:[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) * 详细文档与开源的模型可以参考:[OIDV5目标检测github地址](https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.2/static/docs/featured_model/champion_model/OIDV5_BASELINE_MODEL.md)
* 2019年Kaggle地标检索挑战赛亚军 * 2019年Kaggle地标检索挑战赛亚军
* 技术报告可以参考:[https://arxiv.org/abs/1906.03990](https://arxiv.org/abs/1906.03990) * 技术报告可以参考:[https://arxiv.org/abs/1906.03990](https://arxiv.org/abs/1906.03990)
......
## 识别效果展示 ## 识别效果展示
- 商品识别 - 商品识别
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_product/channelhandle_5.jpg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_product/channelhandle_5.jpg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_product/cliniqueblush_1.jpg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_product/cliniqueblush_1.jpg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_product/daoxiangcunjinzhubing_10.jpg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_product/daoxiangcunjinzhubing_10.jpg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_product/gannidress_10.jpg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_product/gannidress_10.jpg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_product/gbyingerche_15.jpg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_product/gbyingerche_15.jpg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_product/lafiolewine_03.jpg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_product/lafiolewine_03.jpg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_product/taochunqiu_8.jpg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_product/taochunqiu_8.jpg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_product/weiduomeinaiyougege_10.jpg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_product/weiduomeinaiyougege_10.jpg" width = "400" />
</div> </div>
- 动漫人物识别 - 动漫人物识别
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_cartoon/labixiaoxin-005.jpeg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_cartoon/labixiaoxin-005.jpeg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_cartoon/liuchuanfeng-010.jpeg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_cartoon/liuchuanfeng-010.jpeg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_cartoon/zhangchulan-007.jpeg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_cartoon/zhangchulan-007.jpeg" width = "400" />
</div> </div>
- logo识别 - logo识别
...@@ -49,13 +49,13 @@ ...@@ -49,13 +49,13 @@
- 车辆识别 - 车辆识别
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_vehicle/audia5-115.jpeg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_vehicle/audia5-115.jpeg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_vehicle/bentian-yage-101.jpeg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_vehicle/bentian-yage-101.jpeg" width = "400" />
</div> </div>
<div align="center"> <div align="center">
<img src="../images/recognition/more_demo_images/output_vehicle/bmw-m340-107.jpeg" width = "400" /> <img src="../../images/recognition/more_demo_images/output_vehicle/bmw-m340-107.jpeg" width = "400" />
</div> </div>
[更多效果图](https://github.com/PaddlePaddle/PaddleClas/tree/release/2.2/docs/images/recognition/more_demo_images) [更多效果图](../../images/recognition/more_demo_images)
# 版本更新信息
## v2.3
- 模型更新
- 添加轻量化模型预训练权重,包括检测模型、特征模型
- 发布PP-LCNet系列模型,此系列模型是专门在CPU上设计运行的自研模型
- SwinTransformer、Twins、Deit支持从scrach直接训练,达到论文精度
- 框架基础能力
- 添加DeepHash模块,支持特征模型直接输出二值特征
- 添加PKSampler,特征模型不能多机多卡的训练的问题
- 支持PaddleSlim:支持分类模型、特征模型的量化、裁剪训练及离线量化功能
- Legendary models支持模型中间结果输出
- 支持多标签分类训练
- 预测部署
- 使用Faiss替换原有特征检索库,提升平台适配性
- 支持PaddleServing:支持分类模型、图像识别流程的部署
- 推荐库版本
- python版本:3.7
- PaddlePaddle版本:2.1.3
- PaddleSlim版本:2.2.0
- PaddleServing版本:0.6.1
## v2.2
- 模型更新
- 添加LeViT、Twins、TNT、DLA、HardNet、RedNet、SwinTransfomer模型
- 框架基础能力
- 将分类模型分为两类
- legendary models:引入TheseusLayer基类,及增加了修改网络功能接口,同时支持网络截断输出功能
- model zoo:其他普通分类模型
- 添加Metric Learning算法支持
- 添加多种相关Loss算法,及基础网络模块gears(支持与backbone、loss组合)方便使用
- 同时支持普通分类及metric learning相关任务训练
- 支持静态图训练
- 分类训练支持dali加速
- 支持fp16训练
- 应用更新
- 添加商品识别、车辆识别(车辆细粒度分类、车辆ReID)、logo识别、动漫人物识别应用具体案例及相关模型
- 添加图像识别完整pipeline,包含检测模块、特征提取模块、向量检索模块
- 预测部署
- 添加百度自研向量检索模块Mobius,支持图像识别系统预测部署
- 图像识别,建立特征库支持 batch_size>1
- 文档更新
- 添加图像识别相关文档
- 修复之前文档bug
- 推荐库版本
- python版本:3.7
- PaddlePaddle:2.1.2
...@@ -74,6 +74,8 @@ cd ../../ ...@@ -74,6 +74,8 @@ cd ../../
## 4. 模型训练 ## 4. 模型训练
<a name="4.1"></a>
### 4.1 使用CPU进行模型训练 ### 4.1 使用CPU进行模型训练
由于使用CPU来进行模型训练,计算速度较慢,因此,此处以 ShuffleNetV2_x0_25 为例。此模型计算量较小,在 CPU 上计算速度较快。但是也因为模型较小,训练好的模型精度也不会太高。 由于使用CPU来进行模型训练,计算速度较慢,因此,此处以 ShuffleNetV2_x0_25 为例。此模型计算量较小,在 CPU 上计算速度较快。但是也因为模型较小,训练好的模型精度也不会太高。
...@@ -137,7 +139,7 @@ python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml ...@@ -137,7 +139,7 @@ python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml
python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.pretrained=True python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.pretrained=True
``` ```
**注**:此训练脚本使用 GPU,如使用 CPU 可按照上文中[使用CPU进行模型训练](#使用CPU进行模型训练)所示,进行修改。 **注**:此训练脚本使用 GPU,如使用 CPU 可按照上文中[4.1 使用CPU进行模型训练](#4.1)所示,进行修改。
验证集的 `Top1 Acc` 曲线如下所示,最高准确率为 `0.9402`,加载预训练模型之后,flowers102 数据集精度大幅提升,绝对精度涨幅超过 65%。 验证集的 `Top1 Acc` 曲线如下所示,最高准确率为 `0.9402`,加载预训练模型之后,flowers102 数据集精度大幅提升,绝对精度涨幅超过 65%。
......
# 30分钟玩转PaddleClas(进阶版) # 30分钟玩转PaddleClas(进阶版)
此处提供了专业用户在linux操作系统上使用PaddleClas的快速上手教程,主要内容基于CIFAR-100数据集,快速体验不同模型的训练、加载不同预训练模型、SSLD知识蒸馏方案和数据增广的效果。请事先参考[安装指南](install.md)配置运行环境和克隆PaddleClas代码。 此处提供了专业用户在linux操作系统上使用PaddleClas的快速上手教程,主要内容基于CIFAR-100数据集,快速体验不同模型的训练、加载不同预训练模型、SSLD知识蒸馏方案和数据增广的效果。请事先参考[安装指南](../installation/install_paddleclas.md)配置运行环境和克隆PaddleClas代码。
## 一、数据和模型准备 ## 一、数据和模型准备
...@@ -95,7 +95,7 @@ python3 -m paddle.distributed.launch \ ...@@ -95,7 +95,7 @@ python3 -m paddle.distributed.launch \
## 三、数据增广 ## 三、数据增广
PaddleClas包含了很多数据增广的方法,如Mixup、Cutout、RandomErasing等,具体的方法可以参考[数据增广的章节](../advanced_tutorials/image_augmentation/ImageAugment.md) PaddleClas包含了很多数据增广的方法,如Mixup、Cutout、RandomErasing等,具体的方法可以参考[数据增广的章节](../algorithm_introduction/DataAugmentation.md)
### 数据增广的尝试-Mixup ### 数据增广的尝试-Mixup
...@@ -125,7 +125,7 @@ python3 -m paddle.distributed.launch \ ...@@ -125,7 +125,7 @@ python3 -m paddle.distributed.launch \
## 四、知识蒸馏 ## 四、知识蒸馏
PaddleClas包含了自研的SSLD知识蒸馏方案,具体的内容可以参考[知识蒸馏章节](../advanced_tutorials/distillation/distillation.md), 本小节将尝试使用知识蒸馏技术对MobileNetV3_large_x1_0模型进行训练,使用`2.1.2小节`训练得到的ResNet50_vd模型作为蒸馏所用的教师模型,首先将`2.1.2小节`训练得到的ResNet50_vd模型保存到指定目录,脚本如下。 PaddleClas包含了自研的SSLD知识蒸馏方案,具体的内容可以参考[知识蒸馏章节](../algorithm_introduction/knowledge_distillation.md), 本小节将尝试使用知识蒸馏技术对MobileNetV3_large_x1_0模型进行训练,使用`2.1.2小节`训练得到的ResNet50_vd模型作为蒸馏所用的教师模型,首先将`2.1.2小节`训练得到的ResNet50_vd模型保存到指定目录,脚本如下。
```shell ```shell
mkdir pretrained mkdir pretrained
......
# 图像识别快速开始 # 图像识别快速开始
本文档包含3个部分:环境配置、图像识别体验、未知类别的图像识别体验。 本文档包含 3 个部分:环境配置、图像识别体验、未知类别的图像识别体验。
如果图像类别已经存在于图像索引库中,那么可以直接参考[图像识别体验](#图像识别体验)章节,完成图像识别过程;如果希望识别未知类别的图像,即图像类别之前不存在于索引库中,那么可以参考[未知类别的图像识别体验](#未知类别的图像识别体验)章节,完成建立索引并识别的过程。 如果图像类别已经存在于图像索引库中,那么可以直接参考[图像识别体验](#图像识别体验)章节,完成图像识别过程;如果希望识别未知类别的图像,即图像类别之前不存在于索引库中,那么可以参考[未知类别的图像识别体验](#未知类别的图像识别体验)章节,完成建立索引并识别的过程。
...@@ -21,9 +21,9 @@ ...@@ -21,9 +21,9 @@
<a name="环境配置"></a> <a name="环境配置"></a>
## 1. 环境配置 ## 1. 环境配置
* 安装:请先参考[快速安装](./install.md)配置PaddleClas运行环境。 * 安装:请先参考[快速安装](./install.md)配置 PaddleClas 运行环境。
* 进入`deploy`运行目录。本部分所有内容与命令均需要在`deploy`目录下运行,可以通过下面的命令进入`deploy`目录。 * 进入 `deploy` 运行目录。本部分所有内容与命令均需要在 `deploy` 目录下运行,可以通过下面的命令进入 `deploy` 目录。
``` ```
cd deploy cd deploy
...@@ -32,14 +32,14 @@ ...@@ -32,14 +32,14 @@
<a name="图像识别体验"></a> <a name="图像识别体验"></a>
## 2. 图像识别体验 ## 2. 图像识别体验
检测模型与4个方向(Logo、动漫人物、车辆、商品)的识别inference模型、测试数据下载地址以及对应的配置文件地址如下。 检测模型与 4 个方向( Logo、动漫人物、车辆、商品 )的识别 inference 模型、测试数据下载地址以及对应的配置文件地址如下。
服务器端通用主体检测模型与各方向识别模型: 服务器端通用主体检测模型与各方向识别模型:
| 模型简介 | 推荐场景 | inference模型 | 预测配置文件 | 构建索引库的配置文件 | | 模型简介 | 推荐场景 | inference模型 | 预测配置文件 | 构建索引库的配置文件 |
| ------------ | ------------- | -------- | ------- | -------- | | ------------ | ------------- | -------- | ------- | -------- |
| 通用主体检测模型 | 通用场景 |[模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar) | - | - | | 通用主体检测模型 | 通用场景 |[模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar) | - | - |
| Logo识别模型 | Logo场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/logo_rec_ResNet50_Logo3K_v1.0_infer.tar) | [inference_logo.yaml](../../../deploy/configs/inference_logo.yaml) | [build_logo.yaml](../../../deploy/configs/build_logo.yaml) | | Logo 识别模型 | Logo场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/logo_rec_ResNet50_Logo3K_v1.0_infer.tar) | [inference_logo.yaml](../../../deploy/configs/inference_logo.yaml) | [build_logo.yaml](../../../deploy/configs/build_logo.yaml) |
| 动漫人物识别模型 | 动漫人物场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/cartoon_rec_ResNet50_iCartoon_v1.0_infer.tar) | [inference_cartoon.yaml](../../../deploy/configs/inference_cartoon.yaml) | [build_cartoon.yaml](../../../deploy/configs/build_cartoon.yaml) | | 动漫人物识别模型 | 动漫人物场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/cartoon_rec_ResNet50_iCartoon_v1.0_infer.tar) | [inference_cartoon.yaml](../../../deploy/configs/inference_cartoon.yaml) | [build_cartoon.yaml](../../../deploy/configs/build_cartoon.yaml) |
| 车辆细分类模型 | 车辆场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_cls_ResNet50_CompCars_v1.0_infer.tar) | [inference_vehicle.yaml](../../../deploy/configs/inference_vehicle.yaml) | [build_vehicle.yaml](../../../deploy/configs/build_vehicle.yaml) | | 车辆细分类模型 | 车辆场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/vehicle_cls_ResNet50_CompCars_v1.0_infer.tar) | [inference_vehicle.yaml](../../../deploy/configs/inference_vehicle.yaml) | [build_vehicle.yaml](../../../deploy/configs/build_vehicle.yaml) |
| 商品识别模型 | 商品场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/product_ResNet50_vd_aliproduct_v1.0_infer.tar) | [inference_product.yaml](../../../deploy/configs/inference_product.yaml) | [build_product.yaml](../../../deploy/configs/build_product.yaml) | | 商品识别模型 | 商品场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/product_ResNet50_vd_aliproduct_v1.0_infer.tar) | [inference_product.yaml](../../../deploy/configs/inference_product.yaml) | [build_product.yaml](../../../deploy/configs/build_product.yaml) |
...@@ -52,12 +52,12 @@ ...@@ -52,12 +52,12 @@
| 轻量级通用主体检测模型 | 通用场景 |[模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar) | - | - | | 轻量级通用主体检测模型 | 通用场景 |[模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar) | - | - |
| 轻量级通用识别模型 | 通用场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.tar) | [inference_product.yaml](../../../deploy/configs/inference_product.yaml) | [build_product.yaml](../../../deploy/configs/build_product.yaml) | | 轻量级通用识别模型 | 通用场景 | [模型下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/general_PPLCNet_x2_5_lite_v1.0_infer.tar) | [inference_product.yaml](../../../deploy/configs/inference_product.yaml) | [build_product.yaml](../../../deploy/configs/build_product.yaml) |
本章节demo数据下载地址如下: [数据下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognition_demo_data_v1.1.tar) 本章节 demo 数据下载地址如下: [数据下载链接](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognition_demo_data_v1.1.tar)
**注意** **注意**
1. windows 环境下如果没有安装wget,可以按照下面的步骤安装wget与tar命令,也可以在,下载模型时将链接复制到浏览器中下载,并解压放置在相应目录下;linux或者macOS用户可以右键点击,然后复制下载链接,即可通过`wget`命令下载。 1. windows 环境下如果没有安装 wget , 可以按照下面的步骤安装 wget 与 tar 命令,也可以在下载模型时将链接复制到浏览器中下载,并解压放置在相应目录下; linux 或者 macOS 用户可以右键点击,然后复制下载链接,即可通过 `wget` 命令下载。
2. 如果macOS环境下没有安装`wget`命令,可以运行下面的命令进行安装。 2. 如果 macOS 环境下没有安装 `wget` 命令,可以运行下面的命令进行安装。
3. 轻量级通用识别模型的预测配置文件和构建索引的配置文件目前使用的是服务器端商品识别模型的配置,您可以自行修改模型的路径完成相应的索引构建和识别预测。 3. 轻量级通用识别模型的预测配置文件和构建索引的配置文件目前使用的是服务器端商品识别模型的配置,您可以自行修改模型的路径完成相应的索引构建和识别预测。
```shell ```shell
...@@ -67,7 +67,7 @@ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/ ...@@ -67,7 +67,7 @@ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/
brew install wget brew install wget
``` ```
3. 如果希望在windows环境下安装wget,可以参考:[链接](https://www.cnblogs.com/jeshy/p/10518062.html);如果希望在windows环境中安装tar命令,可以参考:[链接](https://www.cnblogs.com/chooperman/p/14190107.html) 4. 如果希望在 windows 环境下安装 wget ,可以参考:[链接](https://www.cnblogs.com/jeshy/p/10518062.html);如果希望在 windows 环境中安装 tar 命令,可以参考:[链接](https://www.cnblogs.com/chooperman/p/14190107.html)
* 可以按照下面的命令下载并解压数据与模型 * 可以按照下面的命令下载并解压数据与模型
...@@ -85,24 +85,24 @@ wget {数据下载链接地址} && tar -xf {压缩包的名称} ...@@ -85,24 +85,24 @@ wget {数据下载链接地址} && tar -xf {压缩包的名称}
<a name="下载、解压inference_模型与demo数据"></a> <a name="下载、解压inference_模型与demo数据"></a>
### 2.1 下载、解压inference 模型与demo数据 ### 2.1 下载、解压 inference 模型与 demo 数据
以商品识别为例,下载demo数据集以及通用检测、识别模型,命令如下。 以商品识别为例,下载 demo 数据集以及通用检测、识别模型,命令如下。
```shell ```shell
mkdir models mkdir models
cd models cd models
# 下载通用检测inference模型并解压 # 下载通用检测 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 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
# 下载识别inference模型并解压 # 下载识别 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 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 ../ cd ../
# 下载demo数据并解压 # 下载 demo 数据并解压
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognition_demo_data_v1.1.tar && tar -xf recognition_demo_data_v1.1.tar wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognition_demo_data_v1.1.tar && tar -xf recognition_demo_data_v1.1.tar
``` ```
解压完毕后,`recognition_demo_data_v1.1`文件夹下应有如下文件结构: 解压完毕后,`recognition_demo_data_v1.1` 文件夹下应有如下文件结构:
``` ```
├── recognition_demo_data_v1.1 ├── recognition_demo_data_v1.1
...@@ -117,10 +117,10 @@ wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognit ...@@ -117,10 +117,10 @@ wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognit
├── ... ├── ...
``` ```
其中`gallery_xxx`文件夹中存放的是用于构建索引库的原始图像,`test_xxx`文件夹中存放的是用于测试识别效果的图像列表。 其中 `gallery_xxx` 文件夹中存放的是用于构建索引库的原始图像, `test_xxx` 文件夹中存放的是用于测试识别效果的图像列表。
`models`文件夹下应有如下文件结构: `models` 文件夹下应有如下文件结构:
``` ```
├── product_ResNet50_vd_aliproduct_v1.0_infer ├── product_ResNet50_vd_aliproduct_v1.0_infer
...@@ -134,7 +134,8 @@ wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognit ...@@ -134,7 +134,8 @@ wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/recognit
``` ```
**注意** **注意**
如果使用轻量级通用识别模型,Demo数据需要重新提取特征、够建索引,方式如下:
如果使用轻量级通用识别模型, Demo 数据需要重新提取特征、够建索引,方式如下:
```shell ```shell
python3.7 python/build_gallery.py -c configs/build_product.yaml -o Global.rec_inference_model_dir=./models/general_PPLCNet_x2_5_lite_v1.0_infer python3.7 python/build_gallery.py -c configs/build_product.yaml -o Global.rec_inference_model_dir=./models/general_PPLCNet_x2_5_lite_v1.0_infer
...@@ -143,21 +144,21 @@ python3.7 python/build_gallery.py -c configs/build_product.yaml -o Global.rec_in ...@@ -143,21 +144,21 @@ python3.7 python/build_gallery.py -c configs/build_product.yaml -o Global.rec_in
<a name="商品识别与检索"></a> <a name="商品识别与检索"></a>
### 2.2 商品识别与检索 ### 2.2 商品识别与检索
以商品识别demo为例,展示识别与检索过程(如果希望尝试其他方向的识别与检索效果,在下载解压好对应的demo数据与模型之后,替换对应的配置文件即可完成预测)。 以商品识别 demo 为例,展示识别与检索过程(如果希望尝试其他方向的识别与检索效果,在下载解压好对应的 demo 数据与模型之后,替换对应的配置文件即可完成预测)。
注意,此部分使用了`faiss`作为检索库,安装方法如下: 注意,此部分使用了 `faiss` 作为检索库,安装方法如下:
```python ```python
pip install faiss-cpu==1.7.1post2 pip install faiss-cpu==1.7.1post2
``` ```
若使用时,不能正常引用,则`uninstall` 之后,重新`install`,尤其是windows下。 若使用时,不能正常引用,则 `uninstall` 之后,重新 `install` ,尤其是 windows 下。
<a name="识别单张图像"></a> <a name="识别单张图像"></a>
#### 2.2.1 识别单张图像 #### 2.2.1 识别单张图像
运行下面的命令,对图像`./recognition_demo_data_v1.1/test_product/daoxiangcunjinzhubing_6.jpg`进行识别与检索 运行下面的命令,对图像 `./recognition_demo_data_v1.1/test_product/daoxiangcunjinzhubing_6.jpg` 进行识别与检索
```shell ```shell
# 使用下面的命令使用GPU进行预测 # 使用下面的命令使用GPU进行预测
...@@ -175,7 +176,7 @@ python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.u ...@@ -175,7 +176,7 @@ python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.u
最终输出结果如下。 最终输出结果如下。
``` ```json
[{'bbox': [287, 129, 497, 326], 'rec_docs': '稻香村金猪饼', 'rec_scores': 0.8309420943260193}, {'bbox': [99, 242, 313, 426], 'rec_docs': '稻香村金猪饼', 'rec_scores': 0.7245652079582214}] [{'bbox': [287, 129, 497, 326], 'rec_docs': '稻香村金猪饼', 'rec_scores': 0.8309420943260193}, {'bbox': [99, 242, 313, 426], 'rec_docs': '稻香村金猪饼', 'rec_scores': 0.7245652079582214}]
``` ```
...@@ -191,16 +192,16 @@ python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.u ...@@ -191,16 +192,16 @@ python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.u
<a name="基于文件夹的批量识别"></a> <a name="基于文件夹的批量识别"></a>
#### 2.2.2 基于文件夹的批量识别 #### 2.2.2 基于文件夹的批量识别
如果希望预测文件夹内的图像,可以直接修改配置文件中的`Global.infer_imgs`字段,也可以通过下面的`-o`参数修改对应的配置。 如果希望预测文件夹内的图像,可以直接修改配置文件中的 `Global.infer_imgs` 字段,也可以通过下面的 `-o` 参数修改对应的配置。
```shell ```shell
# 使用下面的命令使用GPU进行预测,如果希望使用CPU预测,可以在命令后面添加-o Global.use_gpu=False # 使用下面的命令使用GPU进行预测,如果希望使用CPU预测,可以在命令后面添加 -o Global.use_gpu=False
python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.infer_imgs="./recognition_demo_data_v1.1/test_product/" python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.infer_imgs="./recognition_demo_data_v1.1/test_product/"
``` ```
终端中会输出该文件夹内所有图像的识别结果,如下所示。 终端中会输出该文件夹内所有图像的识别结果,如下所示。
``` ```json
... ...
[{'bbox': [37, 29, 123, 89], 'rec_docs': '香奈儿包', 'rec_scores': 0.6163763999938965}, {'bbox': [153, 96, 235, 175], 'rec_docs': '香奈儿包', 'rec_scores': 0.5279821157455444}] [{'bbox': [37, 29, 123, 89], 'rec_docs': '香奈儿包', 'rec_scores': 0.6163763999938965}, {'bbox': [153, 96, 235, 175], 'rec_docs': '香奈儿包', 'rec_scores': 0.5279821157455444}]
[{'bbox': [735, 562, 1133, 851], 'rec_docs': '香奈儿包', 'rec_scores': 0.5588355660438538}] [{'bbox': [735, 562, 1133, 851], 'rec_docs': '香奈儿包', 'rec_scores': 0.5588355660438538}]
...@@ -212,19 +213,19 @@ python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.i ...@@ -212,19 +213,19 @@ python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.i
... ...
``` ```
所有图像的识别结果可视化图像也保存在`output`文件夹内。 所有图像的识别结果可视化图像也保存在 `output`文件夹内。
更多地,可以通过修改`Global.rec_inference_model_dir`字段来更改识别inference模型的路径,通过修改`IndexProcess.index_dir`字段来更改索引库索引的路径。 更多地,可以通过修改 `Global.rec_inference_model_dir` 字段来更改识别 inference 模型的路径,通过修改 `IndexProcess.index_dir` 字段来更改索引库索引的路径。
<a name="未知类别的图像识别体验"></a> <a name="未知类别的图像识别体验"></a>
## 3. 未知类别的图像识别体验 ## 3. 未知类别的图像识别体验
对图像`./recognition_demo_data_v1.1/test_product/anmuxi.jpg`进行识别,命令如下 对图像 `./recognition_demo_data_v1.1/test_product/anmuxi.jpg` 进行识别,命令如下
```shell ```shell
# 使用下面的命令使用GPU进行预测,如果希望使用CPU预测,可以在命令后面添加-o Global.use_gpu=False # 使用下面的命令使用 GPU 进行预测,如果希望使用 CPU 预测,可以在命令后面添加 -o Global.use_gpu=False
python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.infer_imgs="./recognition_demo_data_v1.1/test_product/anmuxi.jpg" python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.infer_imgs="./recognition_demo_data_v1.1/test_product/anmuxi.jpg"
``` ```
...@@ -244,20 +245,20 @@ python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.i ...@@ -244,20 +245,20 @@ python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.i
<a name="准备新的数据与标签"></a> <a name="准备新的数据与标签"></a>
### 3.1 准备新的数据与标签 ### 3.1 准备新的数据与标签
首先需要将与待检索图像相似的图像列表拷贝到索引库原始图像的文件夹(`./recognition_demo_data_v1.1/gallery_product/gallery`)中,运行下面的命令拷贝相似图像。 首先需要将与待检索图像相似的图像列表拷贝到索引库原始图像的文件夹( `./recognition_demo_data_v1.1/gallery_product/gallery` )中,运行下面的命令拷贝相似图像。
```shell ```shell
cp -r ../docs/images/recognition/product_demo/gallery/anmuxi ./recognition_demo_data_v1.1/gallery_product/gallery/ cp -r ../docs/images/recognition/product_demo/gallery/anmuxi ./recognition_demo_data_v1.1/gallery_product/gallery/
``` ```
然后需要编辑记录了图像路径和标签信息的文本文件(`./recognition_demo_data_v1.1/gallery_product/data_file_update.txt`),这里基于原始标签文件,新建一个文件。命令如下。 然后需要编辑记录了图像路径和标签信息的文本文件( `./recognition_demo_data_v1.1/gallery_product/data_file_update.txt` ),这里基于原始标签文件,新建一个文件。命令如下。
```shell ```shell
# 复制文件 # 复制文件
cp recognition_demo_data_v1.1/gallery_product/data_file.txt recognition_demo_data_v1.1/gallery_product/data_file_update.txt cp recognition_demo_data_v1.1/gallery_product/data_file.txt recognition_demo_data_v1.1/gallery_product/data_file_update.txt
``` ```
然后在文件`recognition_demo_data_v1.1/gallery_product/data_file_update.txt`中添加以下的信息, 然后在文件 `recognition_demo_data_v1.1/gallery_product/data_file_update.txt` 中添加以下的信息,
``` ```
gallery/anmuxi/001.jpg 安慕希酸奶 gallery/anmuxi/001.jpg 安慕希酸奶
...@@ -268,19 +269,19 @@ gallery/anmuxi/005.jpg 安慕希酸奶 ...@@ -268,19 +269,19 @@ gallery/anmuxi/005.jpg 安慕希酸奶
gallery/anmuxi/006.jpg 安慕希酸奶 gallery/anmuxi/006.jpg 安慕希酸奶
``` ```
每一行的文本中,第一个字段表示图像的相对路径,第二个字段表示图像对应的标签信息,中间用`tab`键分隔开(注意:有些编辑器会将`tab`自动转换为`空格`,这种情况下会导致文件解析报错)。 每一行的文本中,第一个字段表示图像的相对路径,第二个字段表示图像对应的标签信息,中间用 `tab` 键分隔开(注意:有些编辑器会将 `tab` 自动转换为 `空格` ,这种情况下会导致文件解析报错)。
<a name="建立新的索引库"></a> <a name="建立新的索引库"></a>
### 3.2 建立新的索引库 ### 3.2 建立新的索引库
使用下面的命令构建index索引,加速识别后的检索过程。 使用下面的命令构建 `index` 索引,加速识别后的检索过程。
```shell ```shell
python3.7 python/build_gallery.py -c configs/build_product.yaml -o IndexProcess.data_file="./recognition_demo_data_v1.1/gallery_product/data_file_update.txt" -o IndexProcess.index_dir="./recognition_demo_data_v1.1/gallery_product/index_update" python3.7 python/build_gallery.py -c configs/build_product.yaml -o IndexProcess.data_file="./recognition_demo_data_v1.1/gallery_product/data_file_update.txt" -o IndexProcess.index_dir="./recognition_demo_data_v1.1/gallery_product/index_update"
``` ```
最终新的索引信息保存在文件夹`./recognition_demo_data_v1.1/gallery_product/index_update`中。 最终新的索引信息保存在文件夹 `./recognition_demo_data_v1.1/gallery_product/index_update` 中。
<a name="基于新的索引库的图像识别"></a> <a name="基于新的索引库的图像识别"></a>
...@@ -289,13 +290,13 @@ python3.7 python/build_gallery.py -c configs/build_product.yaml -o IndexProcess. ...@@ -289,13 +290,13 @@ python3.7 python/build_gallery.py -c configs/build_product.yaml -o IndexProcess.
使用新的索引库,对上述图像进行识别,运行命令如下。 使用新的索引库,对上述图像进行识别,运行命令如下。
```shell ```shell
# 使用下面的命令使用GPU进行预测,如果希望使用CPU预测,可以在命令后面添加-o Global.use_gpu=False # 使用下面的命令使用 GPU 进行预测,如果希望使用 CPU 预测,可以在命令后面添加 -o Global.use_gpu=False
python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.infer_imgs="./recognition_demo_data_v1.1/test_product/anmuxi.jpg" -o IndexProcess.index_dir="./recognition_demo_data_v1.1/gallery_product/index_update" python3.7 python/predict_system.py -c configs/inference_product.yaml -o Global.infer_imgs="./recognition_demo_data_v1.1/test_product/anmuxi.jpg" -o IndexProcess.index_dir="./recognition_demo_data_v1.1/gallery_product/index_update"
``` ```
输出结果如下。 输出结果如下。
``` ```json
[{'bbox': [243, 80, 523, 522], 'rec_docs': '安慕希酸奶', 'rec_scores': 0.5570770502090454}] [{'bbox': [243, 80, 523, 522], 'rec_docs': '安慕希酸奶', 'rec_scores': 0.5570770502090454}]
``` ```
......
# 数据说明
---
## 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
```
初级使用
================================
.. 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的大小。
# PaddleClas wheel package使用说明
## 1. 安装
* pip安装
```bash
pip3 install paddleclas==2.2.1
```
* 本地构建并安装
```bash
python3 setup.py bdist_wheel
pip3 install dist/*
```
## 2. 快速开始
* 使用`ResNet50`模型,以下图(`'docs/images/whl/demo.jpg'`)为例进行说明。
<div align="center">
<img src="../images/whl/demo.jpg" width = "400" />
</div>
* 在Python代码中使用
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50')
infer_imgs='docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
**注意**`PaddleClas.predict()` 为可迭代对象(`generator`),因此需要使用 `next()` 函数或 `for` 循环对其迭代调用。每次调用将以 `batch_size` 为单位进行一次预测,并返回预测结果。返回结果示例如下:
```
>>> result
[{'class_ids': [8, 7, 136, 80, 84], 'scores': [0.79368, 0.16329, 0.01853, 0.00959, 0.00239], 'label_names': ['hen', 'cock', 'European gallinule, Porphyrio porphyrio', 'black grouse', 'peacock']}]
```
* 在命令行中使用
```bash
paddleclas --model_name=ResNet50 --infer_imgs="docs/images/whl/demo.jpg"
```
```
>>> result
filename: docs/images/whl/demo.jpg, top-5, class_ids: [8, 7, 136, 80, 84], scores: [0.79368, 0.16329, 0.01853, 0.00959, 0.00239], label_names: ['hen', 'cock', 'European gallinule, Porphyrio porphyrio', 'black grouse', 'peacock']
Predict complete!
```
## 3. 参数解释
以下参数可在命令行方式使用中通过参数指定,或在Python代码中实例化PaddleClas对象时作为构造函数的参数使用。
* model_name(str): 模型名称,使用PaddleClas提供的基于ImageNet1k的预训练模型。
* inference_model_dir(str): 本地模型文件目录,当未指定 `model_name` 时该参数有效。该目录下需包含 `inference.pdmodel``inference.pdiparams` 两个模型文件。
* infer_imgs(str): 待预测图片文件路径,或包含图片文件的目录,或网络图片的URL。
* use_gpu(bool): 是否使用GPU,默认为 `True`
* gpu_mem(int): 使用的GPU显存大小,当 `use_gpu``True` 时有效,默认为8000。
* use_tensorrt(bool): 是否开启TensorRT预测,可提升GPU预测性能,需要使用带TensorRT的预测库,默认为 `False`
* enable_mkldnn(bool): 是否开启MKLDNN,当 `use_gpu``False` 时有效,默认 `False`
* cpu_num_threads(int): cpu预测时的线程数,当 `use_gpu``False``enable_mkldnn``True` 时有效,默认值为 `10`
* batch_size(int): 预测时每个batch的样本数量,默认为 `1`
* resize_short(int): 按图像较短边进行等比例缩放,默认为 `256`
* crop_size(int): 将图像裁剪到指定大小,默认为 `224`
* topk(int): 打印(返回)预测结果的前 `topk` 个类别和对应的分类概率,默认为 `5`
* class_id_map_file(str): `class id``label` 的映射关系文件。默认使用 `ImageNet1K` 数据集的映射关系。
* save_dir(str): 将预测结果作为预标注数据保存的路径,默认为 `None`,即不保存。
**注意**: 如果使用`Transformer`系列模型,如`DeiT_***_384`, `ViT_***_384`等,请注意模型的输入数据尺寸,需要设置参数`resize_short=384`, `crop_size=384`,如下所示。
* 命令行中
```bash
from paddleclas import PaddleClas, get_default_confg
paddleclas --model_name=ViT_base_patch16_384 --infer_imgs='docs/images/whl/demo.jpg' --resize_short=384 --crop_size=384
```
* Python代码中
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ViT_base_patch16_384', resize_short=384, crop_size=384)
```
## 4. 使用示例
PaddleClas提供两种使用方式:
1. Python代码中使用;
2. 命令行中使用。
### 4.1 查看帮助信息
* CLI
```bash
paddleclas -h
```
### 4.2 使用PaddleClas提供的预训练模型进行预测
可以使用PaddleClas提供的预训练模型来预测,并通过参数`model_name`指定。此时PaddleClas会根据`model_name`自动下载指定模型,并保存在目录`~/.paddleclas/`下。
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50')
infer_imgs = 'docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/demo.jpg'
```
### 4.3 使用本地模型文件预测
可以使用本地的模型文件进行预测,通过参数`inference_model_dir`指定模型文件目录即可。需要注意,模型文件目录下必须包含`inference.pdmodel``inference.pdiparams`两个文件。
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(inference_model_dir='./inference/')
infer_imgs = 'docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --inference_model_dir='./inference/' --infer_imgs='docs/images/whl/demo.jpg'
```
### 4.4 批量预测
当参数 `infer_imgs` 为包含图片文件的目录时,可以对图片进行批量预测,只需通过参数 `batch_size` 指定batch大小。
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50', batch_size=2)
infer_imgs = 'docs/images/'
result=clas.predict(infer_imgs)
for r in result:
print(r)
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/' --batch_size 2
```
### 4.5 对网络图片进行预测
可以对网络图片进行预测,只需通过参数`infer_imgs`指定图片`url`。此时图片会下载并保存在`~/.paddleclas/images/`目录下。
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50')
infer_imgs = 'https://raw.githubusercontent.com/paddlepaddle/paddleclas/release/2.2/docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='https://raw.githubusercontent.com/paddlepaddle/paddleclas/release/2.2/docs/images/whl/demo.jpg'
```
### 4.6 对`NumPy.ndarray`格式数据进行预测
在Python中,可以对`Numpy.ndarray`格式的图像数据进行预测,只需通过参数`infer_imgs`指定即可。注意该图像数据必须为三通道图像数据。
* python
```python
import cv2
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50')
infer_imgs = cv2.imread("docs/images/whl/demo.jpg")
result=clas.predict(infer_imgs)
print(next(result))
```
### 4.7 保存预测结果
可以指定参数`pre_label_out_dir='./output_pre_label/'`,将图片按其top1预测结果保存到`pre_label_out_dir`目录下对应类别的文件夹中。
* python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50', save_dir='./output_pre_label/')
infer_imgs = 'docs/images/whl/' # it can be infer_imgs folder path which contains all of images you want to predict.
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/' --save_dir='./output_pre_label/'
```
### 4.8 指定label name
可以通过参数`class_id_map_file`指定`class id``lable`的对应关系。PaddleClas默认使用ImageNet1K的label_name(`ppcls/utils/imagenet1k_label_list.txt`)。
`class_id_map_file`文件内容格式应为:
```
class_id<space>class_name<\n>
```
例如:
```
0 tench, Tinca tinca
1 goldfish, Carassius auratus
2 great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias
......
```
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50', class_id_map_file='./ppcls/utils/imagenet1k_label_list.txt')
infer_imgs = 'docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/demo.jpg' --class_id_map_file='./ppcls/utils/imagenet1k_label_list.txt'
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册