未验证 提交 fe9c0c63 编写于 作者: C cuicheng01 提交者: GitHub

Merge pull request #1363 from cuicheng01/release/2.3

Merge new docs to release/2.3
# 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
## 模型量化、裁剪使用介绍
复杂的模型有利于提高模型的性能,但也导致模型中存在一定冗余。此部分提供精简模型的功能,包括两部分:模型量化(量化训练、离线量化)、模型剪枝。
其中模型量化将全精度缩减到定点数减少这种冗余,达到减少模型计算复杂度,提高模型推理性能的目的。
模型量化可以在基本不损失模型的精度的情况下,将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 分类训练阶段的标准数据增广方式分为以下几个步骤:
其中 ImageNet 分类训练阶段的标准数据增方式分为以下几个步骤:
1. 图像解码:简写为 `ImageDecode`
2. 随机裁剪到长宽均为 224 的图像:简写为 `RandCrop`
......@@ -25,7 +25,7 @@
增广后的可视化效果如下所示。
![](../../../images/image_aug/image_aug_samples_s.jpg)
![](../../images/image_aug/image_aug_samples_s.jpg)
具体如下表所示:
......@@ -43,7 +43,7 @@
| **Process** | (N, 3, 224, 224)<br>float32 | (N, 3, 224, 224)<br>float32 | \- | \- | \- | \- | \- | \- | Y | Y |
PaddleClas中集成了上述所有的数据增广策略,每种数据增广策略的参考论文与参考开源代码均在下面的介绍中列出。下文将介绍这些策略的原理与使用方法,并以下图为例,对变换后的效果进行可视化。为了说明问题,本章节中将 `RandCrop` 替换为 `Resize`
PaddleClas中集成了上述所有的数据增强策略,每种数据增强策略的参考论文与参考开源代码均在下面的介绍中列出。下文将介绍这些策略的原理与使用方法,并以下图为例,对变换后的效果进行可视化。为了说明问题,本章节中将 `RandCrop` 替换为 `Resize`
![][test_baseline]
......@@ -53,6 +53,7 @@ PaddleClas中集成了上述所有的数据增广策略,每种数据增广策
+ AutoAugment
+ RandAugment
+ TimmAutoAugment
## 3.1 AutoAugment
......@@ -60,30 +61,9 @@ PaddleClas中集成了上述所有的数据增广策略,每种数据增广策
开源代码github地址:[https://github.com/DeepVoltaire/AutoAugment](https://github.com/DeepVoltaire/AutoAugment)
不同于常规的人工设计图像增广方式,AutoAugment 是在一系列图像增广子策略的搜索空间中通过搜索算法找到的适合特定数据集的图像增广方案。针对 ImageNet 数据集,最终搜索出来的数据增广方案包含 25 个子策略组合,每个子策略中都包含两种变换,针对每幅图像都随机的挑选一个子策略组合,然后以一定的概率来决定是否执行子策略中的每种变换。
不同于常规的人工设计图像增广方式,AutoAugment 是在一系列图像增广子策略的搜索空间中通过搜索算法找到的适合特定数据集的图像增广方案。针对 ImageNet 数据集,最终搜索出来的数据增方案包含 25 个子策略组合,每个子策略中都包含两种变换,针对每幅图像都随机的挑选一个子策略组合,然后以一定的概率来决定是否执行子策略中的每种变换。
PaddleClas中`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)
```
结果如下图所示。
经过AutoAugment数据增强后结果如下图所示。
![][test_autoaugment]
......@@ -96,31 +76,18 @@ for file_name in file_names:
`AutoAugment` 的搜索方法比较暴力,直接在数据集上搜索针对该数据集的最优策略,其计算量很大。在 `RandAugment` 文章中作者发现,一方面,针对越大的模型,越大的数据集,使用 `AutoAugment` 方式搜索到的增广方式产生的收益也就越小;另一方面,这种搜索出的最优策略是针对该数据集的,其迁移能力较差,并不太适合迁移到其他数据集上。
`RandAugment` 中,作者提出了一种随机增广的方式,不再像 `AutoAugment` 中那样使用特定的概率确定是否使用某种子策略,而是所有的子策略都会以同样的概率被选择到,论文中的实验也表明这种数据增广方式即使在大模型的训练中也具有很好的效果。
PaddleClas中`RandAugment`的使用方法如下所示。
```python
`RandAugment` 中,作者提出了一种随机增广的方式,不再像 `AutoAugment` 中那样使用特定的概率确定是否使用某种子策略,而是所有的子策略都会以同样的概率被选择到,论文中的实验也表明这种数据增强方式即使在大模型的训练中也具有很好的效果。
size = 224
decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
randaugment_op = RandAugment()
经过RandAugment数据增强后结果如下图所示。
ops = [decode_op, resize_op, randaugment_op]
![][test_randaugment]
imgs_dir = 图像路径
fnames = os.listdir(imgs_dir)
for f in fnames:
data = open(os.path.join(imgs_dir, f)).read()
img = transform(data, ops)
```
## 3.3 TimmAutoAugment
结果如下图所示。
开源代码github地址:[https://github.com/rwightman/pytorch-image-models/blob/master/timm/data/auto_augment.py](https://github.com/rwightman/pytorch-image-models/blob/master/timm/data/auto_augment.py)
![][test_randaugment]
`TimmAutoAugment`是开源作者对AutoAugment和RandAugment的改进,事实证明,其在很多视觉任务上有更好的表现,目前绝大多数VisionTransformer模型都是基于TimmAutoAugment去实现的。
# 四、图像裁剪类
......@@ -145,26 +112,7 @@ for f in fnames:
Cutout 可以理解为 Dropout 的一种扩展操作,不同的是 Dropout 是对图像经过网络后生成的特征进行遮挡,而 Cutout 是直接对输入的图像进行遮挡,相对于Dropout对噪声的鲁棒性更好。作者在论文中也进行了说明,这样做法有以下两点优势:(1) 通过 Cutout 可以模拟真实场景中主体被部分遮挡时的分类场景;(2) 可以促进模型充分利用图像中更多的内容来进行分类,防止网络只关注显著性的图像区域,从而发生过拟合。
PaddleClas中`Cutout`的使用方法如下所示。
```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)
```
结果如下图所示。
经过RandAugment数据增强后结果如下图所示。
![][test_cutout]
......@@ -179,25 +127,7 @@ for f in fnames:
PaddleClas中`RandomErasing`的使用方法如下所示。
```python
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))
```
结果如下图所示。
经过RandomErasing数据增强后结果如下图所示。
![][test_randomerassing]
......@@ -217,25 +147,8 @@ for f in fnames:
PaddleClas中`HideAndSeek`的使用方法如下所示。
```python
size = 224
decode_op = DecodeImage()
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))
```
结果如下图所示。
经过HideAndSeek数据增强后结果如下图所示。
![][test_hideandseek]
......@@ -265,31 +178,7 @@ for f in fnames:
论文中验证上述第二种方法的训练效果更好一些。
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))
```
结果如下图所示。
经过GridMask数据增强后结果如下图所示。
![][test_gridmask]
......@@ -313,34 +202,8 @@ Mixup 是最先提出的图像混叠增广方案,其原理简单、方便实
如下是 `imaug` 中的实现,需要指出的是,下述实现会出现对同一幅进行相加的情况,也就是最终得到的图和原图一样,随着 `batch-size` 的增加这种情况出现的概率也会逐渐减小。
PaddleClas中`Mixup`的使用方法如下所示。
```python
size = 224
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)
```
结果如下图所示。
经过Mixup数据增强结果如下图所示。
![][test_mixup]
......@@ -352,167 +215,11 @@ new_batch = mixup_op(batch)
`Mixup` 直接对两幅图进行相加不一样,`Cutmix` 是从一幅图中随机裁剪出一个 `ROI`,然后覆盖当前图像中对应的区域,代码实现如下所示:
```python
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)
```
结果如下图所示。
经过Cutmix数据增强后结果如下图所示。
![][test_cutmix]
# 六、实验
基于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)
关于数据增强相关的实战部分实参考[数据增强实战](../advanced_tutorials/DataAugmentation.md)
# 参考文献
......@@ -536,14 +243,14 @@ sh tools/train.sh
[test_baseline]: ../../../images/image_aug/test_baseline.jpeg
[test_autoaugment]: ../../../images/image_aug/test_autoaugment.jpeg
[test_cutout]: ../../../images/image_aug/test_cutout.jpeg
[test_gridmask]: ../../../images/image_aug/test_gridmask.jpeg
[gridmask-0]: ../../../images/image_aug/gridmask-0.png
[test_hideandseek]: ../../../images/image_aug/test_hideandseek.jpeg
[test_randaugment]: ../../../images/image_aug/test_randaugment.jpeg
[test_randomerassing]: ../../../images/image_aug/test_randomerassing.jpeg
[hide_and_seek_mask_expanation]: ../../../images/image_aug/hide-and-seek-visual.png
[test_mixup]: ../../../images/image_aug/test_mixup.png
[test_cutmix]: ../../../images/image_aug/test_cutmix.png
[test_baseline]: ../../images/image_aug/test_baseline.jpeg
[test_autoaugment]: ../../images/image_aug/test_autoaugment.jpeg
[test_cutout]: ../../images/image_aug/test_cutout.jpeg
[test_gridmask]: ../../images/image_aug/test_gridmask.jpeg
[gridmask-0]: ../../images/image_aug/gridmask-0.png
[test_hideandseek]: ../../images/image_aug/test_hideandseek.jpeg
[test_randaugment]: ../../images/image_aug/test_randaugment.jpeg
[test_randomerassing]: ../../images/image_aug/test_randomerassing.jpeg
[hide_and_seek_mask_expanation]: ../../images/image_aug/hide-and-seek-visual.png
[test_mixup]: ../../images/image_aug/test_mixup.png
[test_cutmix]: ../../images/image_aug/test_cutmix.png
......@@ -7,24 +7,25 @@
### 模型库概览图
基于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时间)。
常见服务器端模型的精度指标与其预测耗时的变化曲线如下图所示。
![](../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>
### SSLD知识蒸馏预训练模型
基于SSLD知识蒸馏的预训练模型列表如下所示,更多关于SSLD知识蒸馏方案的介绍可以参考:[SSLD知识蒸馏文档](./advanced_tutorials/distillation/distillation.md)
基于SSLD知识蒸馏的预训练模型列表如下所示,更多关于SSLD知识蒸馏方案的介绍可以参考:[SSLD知识蒸馏文档](./knowledge_distillation.md)
* 服务器端知识蒸馏模型
......@@ -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) |
* 端侧知识蒸馏模型
* 移动端知识蒸馏模型
| 模型 | 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 @@
<a name="PP-LCNet系列"></a>
### 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) | 下载地址 |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
......@@ -86,7 +87,7 @@ PP-LCNet系列模型的精度、速度指标如下表所示,更多关于该系
<a name="ResNet及其Vd系列"></a>
### 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) | 下载地址 |
|---------------------|-----------|-----------|-----------------------|----------------------|----------|-----------|----------------------------------------------------------------------------------------------|
......@@ -110,7 +111,7 @@ ResNet及其Vd系列模型的精度、速度指标如下表所示,更多关于
<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) | 下载地址 |
|----------------------------------|-----------|-----------|------------------------|----------|-----------|---------|-----------------------------------------------------------------------------------------------------------|
......@@ -155,7 +156,7 @@ ResNet及其Vd系列模型的精度、速度指标如下表所示,更多关于
<a name="SEResNeXt与Res2Net系列"></a>
### 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) | 下载地址 |
......@@ -190,7 +191,7 @@ SEResNeXt与Res2Net系列模型的精度、速度指标如下表所示,更多
<a name="DPN与DenseNet系列"></a>
### 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) | 下载地址 |
......@@ -211,7 +212,7 @@ DPN与DenseNet系列模型的精度、速度指标如下表所示,更多关于
<a name="HRNet系列"></a>
### 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) | 下载地址 |
......@@ -231,7 +232,7 @@ HRNet系列模型的精度、速度指标如下表所示,更多关于该系列
<a name="Inception系列"></a>
### 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) | 下载地址 |
|--------------------|-----------|-----------|-----------------------|----------------------|----------|-----------|---------------------------------------------------------------------------------------------|
......@@ -248,7 +249,7 @@ Inception系列模型的精度、速度指标如下表所示,更多关于该
<a name="EfficientNet与ResNeXt101_wsl系列"></a>
### 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) | 下载地址 |
......@@ -272,7 +273,7 @@ EfficientNet与ResNeXt101_wsl系列模型的精度、速度指标如下表所示
<a name="ResNeSt与RegNet系列"></a>
### 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) | 下载地址 |
......@@ -285,7 +286,7 @@ ResNeSt与RegNet系列模型的精度、速度指标如下表所示,更多关
<a name="ViT_and_DeiT系列"></a>
### 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) | 下载地址 |
......@@ -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_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) |
| | | | | | | | |
| 模型 | 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)系列
| 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_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>
### 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) | 下载地址 |
......@@ -336,7 +337,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
### 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) | 下载地址 |
| -------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -348,7 +349,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
### 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) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -362,7 +363,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
### 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) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -380,7 +381,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="LeViT系列"></a>
### 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) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -395,7 +396,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="Twins系列"></a>
### 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) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -411,7 +412,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="HarDNet系列"></a>
### 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) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -423,7 +424,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="DLA系列"></a>
### 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) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -440,7 +441,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="RedNet系列"></a>
### 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) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -453,7 +454,7 @@ ViT(Vision Transformer)与DeiT(Data-efficient Image Transformers)系列
<a name="TNT系列"></a>
### 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) | 下载地址 |
| ---------- | --------- | --------- | ---------------- | ---------------- | -------- | --------- | ------------------------------------------------------------ |
......@@ -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) | 下载地址 |
......
......@@ -28,7 +28,7 @@ CIFAR-10数据集由10个类的60000个彩色图像组成,图像分辨率为32
### 2.2 模型准备
在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了35个系列共164个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](../ImageNet_models_cn.md)
在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了36个系列共175个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](./ImageNet_models.md)
### 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
...
```
## 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 |
从官方下载数据后,按如下组织数据
从官方下载数据后,按如下格式组织数据,即可在 PaddleClas 中使用 ImageNet1k 数据集进行训练。
```bash
PaddleClas/dataset/ILSVRC2012/
......@@ -47,7 +53,7 @@ PaddleClas/dataset/ILSVRC2012/
|_ val_list.txt
```
## 3. Flowers102 数据集
### 2.2 Flowers102
数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注|
:------:|:---------------:|:---------------------:|:-----------:|:-----------:
......@@ -81,3 +87,21 @@ PaddleClas/dataset/flowers102/
|_ train_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 @@
>>
* 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: 如何进行参数初始化,什么样的初始化可以加快模型收敛?
......@@ -67,7 +67,7 @@
>>
* 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更好一些。
![](../images/models/lr_decay.jpeg)
![](../../images/models/lr_decay.jpeg)
>>
* Q: Warmup学习率策略是什么?一般用在什么样的场景中?
* A: Warmup策略顾名思义就是让学习率先预热一下,在训练初期我们不直接使用最大的学习率,而是用一个逐渐增大的学习率去训练网络,当学习率增大到最高点时,再使用学习率下降策略中提到的学习率下降方式衰减学习率的值。如果使用较大的batch_size训练神经网络时,我们建议您使用warmup策略。实验表明,在batch_size较大时,warmup可以稳定提升模型的精度。在训练MobileNetV3等batch_size较大的实验中,我们默认将warmup中的epoch设置为5,即先用5epoch将学习率从0增加到最大值,再去做相应的学习率衰减。
......@@ -125,7 +125,7 @@
>>
* 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: 对于遮挡情况比较常见的图像分类场景,该使用什么数据增广方法去提升模型的精度呢?
* A: 在训练的过程中可以尝试对训练集使用CutOut、RandErasing、HideAndSeek和GridMask等裁剪类数据增广方法,让模型也能够不止学习到显著区域,也能关注到非显著性区域,从而在遮挡的情况下,也能较好地完成识别任务。
......
......@@ -84,7 +84,7 @@ pip install paddle2onnx
```
其中:
* `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)。
......@@ -337,6 +337,6 @@ pip install paddle2onnx
```
其中:
* `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)。
# 特征图可视化指南
## 一、概述
特征图是输入图片在卷积网络中的特征表达,对特征图的研究可以有利于我们对于模型的理解与设计,所以基于动态图我们使用本工具来可视化特征图。
## 二、准备工作
首先需要选定研究的模型,本文设定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`: 检索匹配的阈值
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册