未验证 提交 3e46edee 编写于 作者: W WuHaobo 提交者: GitHub

Merge branch 'master' into master

...@@ -2,34 +2,34 @@ ...@@ -2,34 +2,34 @@
## 简介 ## 简介
PaddleClas的目的是为工业界和学术界提供一个图像分类任务相关的百宝箱,特色如下: PaddleClas的目的是为工业界和学术界提供一个图像分类任务相关的百宝箱,特色如下:
- 模型库:17种分类网络结构以及训练技巧,118个分类预训练模型以及性能评估 - 模型库:ResNet_vd、MobileNetV3等25种系列的分类网络结构和训练技巧,以及对应的117个分类预训练模型和性能评估
- 高阶使用:高精度的实用模型蒸馏方案(准确率82.39%的ResNet50_vd和78.9%的MobileNetV3)、8种数据增广方法的复现和验证 - 高阶使用:高精度的实用模型蒸馏方案(准确率82.39%的ResNet50_vd和78.9%的MobileNetV3)、8种数据增广方法的复现和验证
- 应用拓展:常见视觉任务的特色方案,包括图像分类领域的迁移学习(百度自研的10w类图像分类预训练模型)、通用目标检测(mAP 47.8%的实用检测方案)、自然场景文字检测和识别 - 应用拓展:常见视觉任务的特色方案,包括图像分类领域的迁移学习(百度自研的10w类图像分类预训练模型)和通用目标检测(mAP 47.8%的实用检测方案)
- 实用工具:便于工业应用部署的实用工具,包括TensorRT预测、移动端预测、INT8量化、多机训练、PaddleHub等 - 实用工具:便于工业应用部署的实用工具,包括TensorRT预测、移动端预测、INT8量化、多机训练、PaddleHub等
- 赛事支持:助力多个视觉全球挑战赛取得领先成绩,包括2018年Kaggle Open Images V4图像目标检测挑战赛冠军、2019年Kaggle地标检索挑战赛亚军等 - 赛事支持:助力多个视觉全球挑战赛取得领先成绩,包括2018年Kaggle Open Images V4图像目标检测挑战赛冠军、2019年Kaggle地标检索挑战赛亚军等
## 模型库 ## 模型库
<div align="center"> <div align="center">
<img src="docs/images/models/main_fps_top1.png" width="600"> <img src="docs/images/models/main_fps_top1.png" width="600">
</div> </div>
基于ImageNet1k分类数据集,PaddleClas提供ResNet、ResNet_vd、EfficientNet、Res2Net、HRNet、MobileNetV3等17种主流分类网络结构的简单介绍,论文指标复现配置,以及在复现过程中的训练技巧。与此同时,PaddleClas也提供了118个图像分类预训练模型,并且基于TensorRT评估了所有模型的GPU预测时间,以及在骁龙855(SD855)上评估了移动端模型的CPU预测时间和存储大小。 基于ImageNet1k分类数据集,PaddleClas提供ResNet、ResNet_vd、EfficientNet、Res2Net、HRNet、MobileNetV3等25种常用分类网络结构的简单介绍,论文指标复现配置,以及在复现过程中的训练技巧。与此同时,PaddleClas也提供了117个图像分类预训练模型,并且基于TensorRT评估了所有模型的GPU预测时间,以及在骁龙855(SD855)上评估了移动端模型的CPU预测时间和存储大小。
上图展示了一些适合服务器端应用的模型,使用V100 GPU,FP16和TensorRT预测一个batch的时间,其中batch_size=32,图中ResNet50_vd_ssld,是采用PaddleClas提供的SSLD蒸馏方法训练的模型。不同模型的FLOPS和Parameters、FP16和FP32的预测时间以及不同batch_size的预测时间正在持续更新中。 上图展示了一些适合服务器端应用的模型,使用V100,FP16和TensorRT预测一个batch的时间,其中batch_size=32,图中ResNet50_vd_ssld,是采用PaddleClas提供的SSLD蒸馏方法训练的模型。图中相同颜色和符号的点代表同一系列不同规模的模型。不同模型的FLOPS和Parameters、FP16和FP32的预测时间以及不同batch_size的预测时间正在持续更新中。
<div align="center"> <div align="center">
<img <img
src="docs/images/models/mobile_arm_top1.png" width="1000"> src="docs/images/models/mobile_arm_top1.png" width="600">
</div> </div>
上图展示了一些适合移动端应用的模型,在SD855上预测一张图像的CPU时间以及模型的存储大小。图中MV3_large_x1_0_ssld(M是MobileNet的简称),MV3_small_x1_0_ssld和MV1_ssld,是采用PaddleClas提供的SSLD蒸馏方法训练的模型。MV3_large_x1_0_ssld_int8是进一步进行INT8量化的模型。不同模型的FLOPS和Parameters、以及更多的GPU预测时间正在持续更新中。 上图展示了一些适合移动端应用的模型,在SD855上预测一张图像的CPU时间以及模型的存储大小。图中MV3_large_x1_0_ssld(M是MobileNet的简称),MV3_small_x1_0_ssld、MV2_ssld和MV1_ssld,是采用PaddleClas提供的SSLD蒸馏方法训练的模型。MV3_large_x1_0_ssld_int8是进一步进行INT8量化的模型。不同模型的FLOPS和Parameters、以及更多的GPU预测时间正在持续更新中。
- TODO - TODO
- [ ] EfficientLite、GhostNet、RegNet论文指标复现和性能评估 - [ ] EfficientLite、GhostNet、RegNet论文指标复现和性能评估
## 高阶使用 ## 高阶使用
...@@ -55,7 +55,7 @@ src="docs/images/distillation/distillation_perform.png" width="500"> ...@@ -55,7 +55,7 @@ src="docs/images/distillation/distillation_perform.png" width="500">
<div align="center"> <div align="center">
<img <img
src="docs/images/image_aug/main_image_aug.png" width="600"> src="docs/images/image_aug/main_image_aug.png" width="600">
</div> </div>
- TODO - TODO
- [ ] 更多的优化器支持和效果验证 - [ ] 更多的优化器支持和效果验证
...@@ -66,7 +66,7 @@ src="docs/images/image_aug/main_image_aug.png" width="600"> ...@@ -66,7 +66,7 @@ src="docs/images/image_aug/main_image_aug.png" width="600">
### 图像分类的迁移学习 ### 图像分类的迁移学习
在实际应用中,由于训练数据的匮乏,往往将ImageNet1K数据集训练的分类模型作为预训练模型,进行图像分类的迁移学习。为了进一步助力实际问题的解决,PaddleClas计划开源百度自研的基于10万种类别,4千多万的有标签数据训练的预训练模型,同时给出不同的超参搜索方法。该部分内容正在持续更新中。 在实际应用中,由于训练数据的匮乏,往往将ImageNet1K数据集训练的分类模型作为预训练模型,进行图像分类的迁移学习。为了进一步助力实际问题的解决,PaddleClas计划开源百度自研的基于10万种类别,4千多万的有标签数据训练的预训练模型,同时给出多种超参搜索方法。该部分内容正在持续更新中。
### 通用目标检测 ### 通用目标检测
...@@ -105,4 +105,4 @@ PaddleClas的建设源于百度实际视觉业务应用的淬炼和视觉前沿 ...@@ -105,4 +105,4 @@ PaddleClas的建设源于百度实际视觉业务应用的淬炼和视觉前沿
## 版本更新 ## 版本更新
## 如何贡献代码 ## 如何贡献代码
我们非常欢迎你为PaddleClas提供代码,也十分感谢你的反馈。 我们非常欢迎你为PaddleClas贡献代码,也十分感谢你的反馈。
...@@ -80,3 +80,4 @@ if not on_rtd: # only import and set the theme if we're building docs locally ...@@ -80,3 +80,4 @@ if not on_rtd: # only import and set the theme if we're building docs locally
html_static_path = ['_static'] html_static_path = ['_static']
#html_logo = './images/logo.png' #html_logo = './images/logo.png'
...@@ -13,7 +13,5 @@ ...@@ -13,7 +13,5 @@
zh_cn/model_zoo.md zh_cn/model_zoo.md
zh_cn/change_log.md zh_cn/change_log.md
zh_cn/faq.md zh_cn/faq.md
:math:`PaddlePaddle2020` :math:`PaddlePaddle2020`
# 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)
rm -f $(BUILDDIR)/html/index_en.html
# 分类预测框架
## 一、简介
Paddle 的模型保存有多种不同的形式,大体可分为两类:
1. persistable 模型(fluid.save_persistabels保存的模型)
一般做为模型的 checkpoint,可以加载后重新训练。persistable 模型保存的是零散的权重文件,每个文件代表模型中的一个 Variable,这些零散的文件不包含结构信息,需要结合模型的结构一起使用。
```
resnet50-vd-persistable/
├── bn2a_branch1_mean
├── bn2a_branch1_offset
├── bn2a_branch1_scale
├── bn2a_branch1_variance
├── bn2a_branch2a_mean
├── bn2a_branch2a_offset
├── bn2a_branch2a_scale
├── ...
└── res5c_branch2c_weights
```
2. inference 模型(fluid.io.save_inference_model保存的模型)
一般是模型训练完成后保存的固化模型,用于预测部署。与 persistable 模型相比,inference 模型会额外保存模型的结构信息,用于配合权重文件构成完整的模型。如下所示,`model` 中保存的即为模型的结构信息。
```
resnet50-vd-persistable/
├── bn2a_branch1_mean
├── bn2a_branch1_offset
├── bn2a_branch1_scale
├── bn2a_branch1_variance
├── bn2a_branch2a_mean
├── bn2a_branch2a_offset
├── bn2a_branch2a_scale
├── ...
├── res5c_branch2c_weights
└── model
```
为了方便起见,paddle 在保存 inference 模型的时候也可以将所有的权重文件保存成一个`params`文件,如下所示:
```
resnet50-vd
├── model
└── params
```
在 Paddle 中训练引擎和预测引擎都支持模型的预测推理,只不过预测引擎不需要进行反向操作,因此可以进行定制型的优化(如层融合,kernel 选择等),达到低时延、高吞吐的目的。训练引擎既可以支持 persistable 模型,也可以支持 inference 模型,而预测引擎只支持 inference 模型,因此也就衍生出了三种不同的预测方式:
1. 预测引擎 + inference 模型
2. 训练引擎 + persistable 模型
3. 训练引擎 + inference 模型
不管是何种预测方式,基本都包含以下几个主要的步骤:
+ 构建引擎
+ 构建待预测数据
+ 执行预测
+ 预测结果解析
不同预测方式,主要有两方面不同:构建引擎和执行预测,以下的几个部分我们会具体介绍。
## 二、模型转换
在任务的训练阶段,通常我们会保存一些 checkpoint(persistable 模型),这些只是模型权重文件,不能直接被预测引擎直接加载预测,所以我们通常会在训练完之后,找到合适的 checkpoint 并将其转换为 inference 模型。主要分为两个步骤:1. 构建训练引擎,2. 保存 inference 模型,如下所示:
```python
import fluid
from ppcls.modeling.architectures.resnet_vd import ResNet50_vd
place = fluid.CPUPlace()
exe = fluid.Executor(place)
startup_prog = fluid.Program()
infer_prog = fluid.Program()
with fluid.program_guard(infer_prog, startup_prog):
with fluid.unique_name.guard():
image = create_input()
image = fluid.data(name='image', shape=[None, 3, 224, 224], dtype='float32')
out = ResNet50_vd.net(input=input, class_dim=1000)
infer_prog = infer_prog.clone(for_test=True)
fluid.load(program=infer_prog, model_path=persistable 模型路径, executor=exe)
fluid.io.save_inference_model(
dirname='./output/',
feeded_var_names=[image.name],
main_program=infer_prog,
target_vars=out,
executor=exe,
model_filename='model',
params_filename='params')
```
在模型库的 `tools/export_model.py` 中提供了完整的示例,只需执行下述命令即可完成转换:
```python
python tools/export_model.py \
--m=模型名称 \
--p=persistable 模型路径 \
--o=model和params保存路径
```
## 三、预测引擎 + inference 模型预测
在模型库的 `tools/predict.py` 中提供了完整的示例,只需执行下述命令即可完成预测:
```
python ./predict.py \
-i=./test.jpeg \
-m=./resnet50-vd/model \
-p=./resnet50-vd/params \
--use_gpu=1 \
--use_tensorrt=True
```
参数说明:
+ `image_file`(简写 i):待预测的图片文件路径,如 `./test.jpeg`
+ `model_file`(简写 m):模型文件路径,如 `./resnet50-vd/model`
+ `params_file`(简写 p):权重文件路径,如 `./resnet50-vd/params`
+ `batch_size`(简写 b):批大小,如 `1`
+ `ir_optim`:是否使用 `IR` 优化,默认值:True
+ `use_tensorrt`:是否使用 TesorRT 预测引擎,默认值:True
+ `gpu_mem`: 初始分配GPU显存,以M单位
+ `use_gpu`:是否使用 GPU 预测,默认值:True
+ `enable_benchmark`:是否启用benchmark,默认值:False
+ `model_name`:模型名字
注意:
当启用benchmark时,默认开启tersorrt进行预测
构建预测引擎:
```python
from paddle.fluid.core import AnalysisConfig
from paddle.fluid.core import create_paddle_predictor
config = AnalysisConfig(model文件路径, params文件路径)
config.enable_use_gpu(8000, 0)
config.disable_glog_info()
config.switch_ir_optim(True)
config.enable_tensorrt_engine(
precision_mode=AnalysisConfig.Precision.Float32,
max_batch_size=1)
# no zero copy方式需要去除fetch feed op
config.switch_use_feed_fetch_ops(False)
predictor = create_paddle_predictor(config)
```
执行预测:
```python
import numpy as np
input_names = predictor.get_input_names()
input_tensor = predictor.get_input_tensor(input_names[0])
input = np.random.randn(1, 3, 224, 224).astype("float32")
input_tensor.reshape([1, 3, 224, 224])
input_tensor.copy_from_cpu(input)
predictor.zero_copy_run()
```
更多预测参数说明可以参考官网 [Paddle Python 预测 API](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/python_infer_cn.html)。如果需要在业务的生产环境部署,也推荐使用 [Paddel C++ 预测 API](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/native_infer.html),官网提供了丰富的预编译预测库 [Paddle C++ 预测库](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html)
默认情况下,Paddle 的 wheel 包中是不包含 TensorRT 预测引擎的,如果需要使用 TensorRT 进行预测优化,需要自己编译对应的 wheel 包,编译方式可以参考 Paddle 的编译指南 [Paddle 编译](https://www.paddlepaddle.org.cn/documentation/docs/zh/install/compile/fromsource.html)
## 四、训练引擎 + persistable 模型预测
在模型库的 `tools/infer.py` 中提供了完整的示例,只需执行下述命令即可完成预测:
```python
python tools/infer.py \
--i=待预测的图片文件路径 \
--m=模型名称 \
--p=persistable 模型路径 \
--use_gpu=True
```
参数说明:
+ `image_file`(简写 i):待预测的图片文件路径,如 `./test.jpeg`
+ `model_file`(简写 m):模型文件路径,如 `./resnet50-vd/model`
+ `params_file`(简写 p):权重文件路径,如 `./resnet50-vd/params`
+ `use_gpu` : 是否开启GPU训练,默认值:True
训练引擎构建:
由于 persistable 模型不包含模型的结构信息,因此需要先构建出网络结构,然后 load 权重来构建训练引擎。
```python
import fluid
from ppcls.modeling.architectures.resnet_vd import ResNet50_vd
place = fluid.CPUPlace()
exe = fluid.Executor(place)
startup_prog = fluid.Program()
infer_prog = fluid.Program()
with fluid.program_guard(infer_prog, startup_prog):
with fluid.unique_name.guard():
image = create_input()
image = fluid.data(name='image', shape=[None, 3, 224, 224], dtype='float32')
out = ResNet50_vd.net(input=input, class_dim=1000)
infer_prog = infer_prog.clone(for_test=True)
fluid.load(program=infer_prog, model_path=persistable 模型路径, executor=exe)
```
执行预测:
```python
outputs = exe.run(infer_prog,
feed={image.name: data},
fetch_list=[out.name],
return_numpy=False)
```
上述执行预测时候的参数说明可以参考官网 [fluid.Executor](https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/executor_cn/Executor_cn.html)
## 五、训练引擎 + inference 模型预测
在模型库的 `tools/py_infer.py` 中提供了完整的示例,只需执行下述命令即可完成预测:
```python
python tools/py_infer.py \
--i=图片路径 \
--d=模型的存储路径 \
--m=保存的模型文件 \
--p=保存的参数文件 \
--use_gpu=True
```
+ `image_file`(简写 i):待预测的图片文件路径,如 `./test.jpeg`
+ `model_file`(简写 m):模型文件路径,如 `./resnet50_vd/model`
+ `params_file`(简写 p):权重文件路径,如 `./resnet50_vd/params`
+ `model_dir`(简写d):模型路径,如`./resent50_vd`
+ `use_gpu`:是否开启GPU,默认值:True
训练引擎构建:
由于 inference 模型已包含模型的结构信息,因此不再需要提前构建模型结构,直接 load 模型结构和权重文件来构建训练引擎。
```python
import fluid
place = fluid.CPUPlace()
exe = fluid.Executor(place)
[program, feed_names, fetch_lists] = fluid.io.load_inference_model(
模型的存储路径,
exe,
model_filename=保存的模型文件,
params_filename=保存的参数文件)
compiled_program = fluid.compiler.CompiledProgram(program)
```
> `load_inference_model` 既支持零散的权重文件集合,也支持融合后的单个权重文件。
执行预测:
```python
outputs = exe.run(compiled_program,
feed={feed_names[0]: data},
fetch_list=fetch_lists,
return_numpy=False)
```
上述执行预测时候的参数说明可以参考官网 [fluid.Executor](https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/executor_cn/Executor_cn.html)
# DPN与DenseNet系列 # DPN与DenseNet系列
## 概述 ## 概述
正在持续更新中......
![](../../images/models/DPN.png) ![](../../images/models/DPN.png)
所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。 所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。
更多的模型概述正在持续更新中。
## 精度、FLOPS和参数量 ## 精度、FLOPS和参数量
......
# EfficientNet与ResNeXt101_wsl系列 # EfficientNet与ResNeXt101_wsl系列
## 概述 ## 概述
正在持续更新中......
![](../../images/models/EfficientNet.png) ![](../../images/models/EfficientNet.png)
更多的模型简介正在持续更新中。
在预测时,图像的crop_size和resize_short_size如下表所示。 在预测时,图像的crop_size和resize_short_size如下表所示。
| Models | crop_size | resize_short_size | | Models | crop_size | resize_short_size |
|:--:|:--:|:--:| |:--:|:--:|:--:|
| ResNeXt101_32x8d_wsl | 224 | 256 | | ResNeXt101_32x8d_wsl | 224 | 224 |
| ResNeXt101_32x16d_wsl | 224 | 256 | | ResNeXt101_32x16d_wsl | 224 | 224 |
| ResNeXt101_32x32d_wsl | 224 | 256 | | ResNeXt101_32x32d_wsl | 224 | 224 |
| ResNeXt101_32x48d_wsl | 224 | 256 | | ResNeXt101_32x48d_wsl | 224 | 224 |
| Fix_ResNeXt101_32x48d_wsl | 320 | 320 | | Fix_ResNeXt101_32x48d_wsl | 320 | 320 |
| EfficientNetB0 | 224 | 256 | | EfficientNetB0 | 224 | 256 |
| EfficientNetB1 | 240 | 272 | | EfficientNetB1 | 240 | 272 |
......
# HRNet系列 # HRNet系列
## 概述 ## 概述
正在持续更新中......
![](../../images/models/HRNet.png) ![](../../images/models/HRNet.png)
所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。 所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。
更多的模型概述正在持续更新中。
## 精度、FLOPS和参数量 ## 精度、FLOPS和参数量
......
# Inception系列 # Inception系列
## 概述 ## 概述
正在持续更新中......
![](../../images/models/Inception.png) ![](../../images/models/Inception.png)
GoogLeNet在预测时,图像的crop_size设置为224,resize_short_size设置为256,其余模型在预测时,图像的crop_size设置为299,resize_short_size设置为320。
所有模型在预测时,图像的crop_size设置为299,resize_short_size设置为320。
更多的模型简介正在持续更新中。
## 精度、FLOPS和参数量 ## 精度、FLOPS和参数量
......
# 移动端系列 # 移动端系列
## 概述 ## 概述
MobileNetV1是Google于2017年发布的用于移动设备或嵌入式设备中的网络。该网络将传统的卷积操作替换深度可分离卷积,即Depthwise卷积和Pointwise卷积的组合,相比传统的卷积操作,该组合可以大大节省参数量和计算量。与此同时,MobileNetV1也可以用于目标检测、图像分割等其他视觉任务中。
MobileNetV2是Google继MobileNetV1提出的一种轻量级网络。相比MobileNetV1,MobileNetV2提出了Linear bottlenecks与Inverted residual block作为网络基本结构,通过大量地堆叠这些基本模块,构成了MobileNetV2的网络结构。最终,在FLOPS只有MobileNetV1的一半的情况下取得了更高的分类精度。
ShuffleNet系列网络是旷视提出的轻量化网络结构,到目前为止,该系列网络一共有两种典型的结构,即ShuffleNetV1与ShuffleNetV2。ShuffleNet中的Channel Shuffle操作可以将组间的信息进行交换,并且可以实现端到端的训练。在ShuffleNetV2的论文中,作者提出了设计轻量级网络的四大准则,并且根据四大准则与ShuffleNetV1的不足,设计了ShuffleNetV2网络。
MobileNetV3是Google于2019年提出的一种基于NAS的新的轻量级网络,为了进一步提升效果,将relu和sigmoid激活函数分别替换为hard_swish与hard_sigmoid激活函数,同时引入了一些专门减小网络计算量的改进策略。
![](../../images/models/mobile_arm_top1.png) ![](../../images/models/mobile_arm_top1.png)
![](../../images/models/mobile_arm_storage.png) ![](../../images/models/mobile_arm_storage.png)
![](../../images/models/mobile_trt.png) ![](../../images/models/mobile_trt.png)
目前PaddleClas开源的的移动端系列的预训练模型一共有32个,其指标如图所示。从图片可以看出,越新的轻量级模型往往有更优的表现,MobileNetV3代表了目前最新的轻量级神经网络结构。在MobileNetV3中,作者为了获得更高的精度,在global-avg-pooling后使用了1x1的卷积。该操作大幅提升了参数量但对计算量影响不大,所以如果从存储角度评价模型的优异程度,MobileNetV3优势不是很大,但由于其更小的计算量,使得其有更快的推理速度。此外,我们模型库中的ssld蒸馏模型表现优异,从各个考量角度下,都刷新了当前轻量级模型的精度。由于MobileNetV3模型结构复杂,分支较多,对GPU并不友好,GPU预测速度不如MobileNetV1。
所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。 **注意**:所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。
更多的模型概述正在持续更新中。
## 精度、FLOPS和参数量 ## 精度、FLOPS和参数量
......
# 其他模型 # 其他模型
## 概述 ## 概述
正在持续更新中......
DarkNet53在预测时,图像的crop_size设置为256,resize_short_size设置为256;其余模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。 DarkNet53在预测时,图像的crop_size设置为256,resize_short_size设置为256;其余模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。
更多的模型简介正在持续更新中。
## 精度、FLOPS和参数量 ## 精度、FLOPS和参数量
......
...@@ -2,12 +2,17 @@ ...@@ -2,12 +2,17 @@
## 概述 ## 概述
![](../../images/models/ResNet.png) ResNet系列模型是在2015年提出的,一举在ILSVRC2015比赛中取得冠军,top5错误率为3.57%。该网络创新性的提出了残差结构,通过堆叠多个残差结构从而构建了ResNet网络。实验表明使用残差块可以有效地提升收敛速度和精度。
斯坦福大学的Joyce Xu将ResNet称为「真正重新定义了我们看待神经网络的方式」的三大架构之一。由于ResNet卓越的性能,越来越多的来自学术界和工业界学者和工程师对其结构进行了改进,比较出名的有Wide-ResNet, ResNet-vc ,ResNet-vd, Res2Net等,其中ResNet-vc与ResNet-vd的参数量和计算量与ResNet几乎一致,所以在此我们将其与ResNet统一归为ResNet系列。
所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256 本次发布ResNet系列的模型包括ResNet50,ResNet50_vd,ResNet50_vd_ssld,ResNet200_vd等14个预训练模型。在训练层面上,ResNet的模型采用了训练ImageNet的标准训练流程,而其余改进版模型采用了更多的训练策略,如learning rate的下降方式采用了cosine decay,引入了label smoothing的标签正则方式,在数据预处理加入了mixup的操作,迭代总轮数从120个epoch增加到200个epoch
更多的模型概述正在持续更新中。 其中,ResNet50_vd_v2与ResNet50_vd_ssld采用了知识蒸馏,保证模型结构不变的情况下,进一步提升了模型的精度,具体地,ResNet50_vd_v2的teacher模型是ResNet152_vd(top1准确率80.59%),数据选用的是ImageNet-1k的训练集,ResNet50_vd_ssld的teacher模型是ResNeXt101_32x16d_wsl(top1准确率84.2%),数据选用结合了ImageNet-1k的训练集和ImageNet-22k挖掘的400万数据。知识蒸馏的具体方法正在持续更新中。
![](../../images/models/ResNet.png)
通过上述曲线可以看出,层数越多,准确率越高,但是相应的参数量、计算量和延时都会增加。ResNet50_vd_ssld通过用更强的teacher和更多的数据,将其在ImageNet-1k上的验证集top-1精度进一步提高,达到了82.39%,刷新了ResNet50系列模型的精度。
**注意**:所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。
## 精度、FLOPS和参数量 ## 精度、FLOPS和参数量
......
# SEResNeXt与Res2Net系列 # SEResNeXt与Res2Net系列
## 概述 ## 概述
ResNeXt是ResNet的典型变种网络之一,ResNeXt发表于2017年的CVPR会议。在此之前,提升模型精度的方法主要集中在将网络变深或者变宽,这样增加了参数量和计算量,推理速度也会相应变慢。ResNeXt结构提出了通道分组(cardinality)的概念,作者通过实验发现增加通道的组数比增加深度和宽度更有效。其可以在不增加参数复杂度的前提下提高准确率,同时还减少了参数的数量,所以是比较成功的ResNet的变种。
![](../../images/models/SeResNeXt.png) SENet是2017年ImageNet分类比赛的冠军方案,其提出了一个全新的SE结构,该结构可以迁移到任何其他网络中,其通过控制scale的大小,把每个通道间重要的特征增强,不重要的特征减弱,从而让提取的特征指向性更强。
所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。 Res2Net是2019年提出的一种全新的对ResNet的改进方案,该方案可以和现有其他优秀模块轻松整合,在不增加计算负载量的情况下,在ImageNet、CIFAR-100等数据集上的测试性能超过了ResNet。Res2Net结构简单,性能优越,进一步探索了CNN在更细粒度级别的多尺度表示能力。Res2Net揭示了一个新的提升模型精度的维度,即scale,其是除了深度、宽度和基数的现有维度之外另外一个必不可少的更有效的因素。该网络在其他视觉任务如目标检测、图像分割等也有相当不错的表现。
![](../../images/models/SeResNeXt.png)
目前PaddleClas开源的这三类的预训练模型一共有24个,其指标如图所示,从图中可以看出,在同样Flops和Params下,改进版的模型往往有更高的精度,但是推理速度往往不如ResNet系列。另一方面,Res2Net表现也较为优秀,相比ResNeXt中的group操作、SEResNet中的SE结构操作,Res2Net在相同Flops、Params和推理速度下往往精度更佳。
更多的模型概述正在持续更新中 **注意**:所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256
## 精度、FLOPS和参数量 ## 精度、FLOPS和参数量
......
# 训练技巧 # 训练技巧
coming soon...... 正在持续更新中......
此差异已折叠。
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
--- ---
请事先参考[安装指南](install.md)配置运行环境 请事先参考[安装指南](install.md)配置运行环境
## 1 设置环境变量 ## 一、设置环境变量
**设置PYTHONPATH环境变量:** **设置PYTHONPATH环境变量:**
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
export PYTHONPATH=path_to_PaddleClas:$PYTHONPATH export PYTHONPATH=path_to_PaddleClas:$PYTHONPATH
``` ```
## 2 模型训练与评估 ## 二、模型训练与评估
PaddleClas 提供模型训练与评估脚本:tools/train.py和tools/eval.py PaddleClas 提供模型训练与评估脚本:tools/train.py和tools/eval.py
...@@ -23,7 +23,7 @@ python -m paddle.distributed.launch \ ...@@ -23,7 +23,7 @@ python -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \ --selected_gpus="0,1,2,3" \
--log_dir=log_ResNet50 \ --log_dir=log_ResNet50 \
train.py \ train.py \
-c ../configs/ResNet/ResNet50.yaml \ -c ./configs/ResNet/ResNet50.yaml \
``` ```
- 输出日志示例如下: - 输出日志示例如下:
...@@ -39,7 +39,7 @@ python -m paddle.distributed.launch \ ...@@ -39,7 +39,7 @@ python -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \ --selected_gpus="0,1,2,3" \
--log_dir=log_ResNet50_vd \ --log_dir=log_ResNet50_vd \
train.py \ train.py \
-c ../configs/ResNet/ResNet50_vd.yaml \ -c ./configs/ResNet/ResNet50_vd.yaml \
-o use_mix=1 \ -o use_mix=1 \
``` ```
...@@ -57,8 +57,30 @@ epoch:0 train step:522 loss:1.6330 lr:0.100000 elapse:0.210 ...@@ -57,8 +57,30 @@ epoch:0 train step:522 loss:1.6330 lr:0.100000 elapse:0.210
```bash ```bash
python eval.py \ python eval.py \
-c ../configs/eval.yaml \ -c ./configs/eval.yaml \
-o architecture="ResNet50_vd" \ -o architecture="ResNet50_vd" \
-o pretrained_model=path_to_pretrained_models -o pretrained_model=path_to_pretrained_models
``` ```
您可以更改configs/eval.yaml中的architecture字段和pretrained_model字段来配置评估模型,或是通过-o参数更新配置。 您可以更改configs/eval.yaml中的architecture字段和pretrained_model字段来配置评估模型,或是通过-o参数更新配置。
## 三、模型推理
PaddlePaddle提供三种方式进行预测推理,接下来介绍如何用预测引擎进行推理:
首先,对训练好的模型进行转换
```bash
python tools/export_model.py \
-model=模型名字 \
-pretrained_model=预训练模型路径 \
-output_path=预测模型保存路径
```
之后,通过预测引擎进行推理
```bash
python tools/predict.py \
-m model文件路径 \
-p params文件路径 \
-i 图片路径 \
--use_gpu=1 \
--use_tensorrt=True
```
更多使用方法和推理方式请参考[分类预测框架](../extension/paddle_inference.md)
...@@ -12,14 +12,17 @@ ...@@ -12,14 +12,17 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import utils import utils
import argparse import argparse
import numpy as np import numpy as np
import logging
import time
from paddle.fluid.core import PaddleTensor from paddle.fluid.core import PaddleTensor
from paddle.fluid.core import AnalysisConfig from paddle.fluid.core import AnalysisConfig
from paddle.fluid.core import create_paddle_predictor from paddle.fluid.core import create_paddle_predictor
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def parse_args(): def parse_args():
def str2bool(v): def str2bool(v):
...@@ -29,26 +32,38 @@ def parse_args(): ...@@ -29,26 +32,38 @@ def parse_args():
parser.add_argument("-i", "--image_file", type=str) parser.add_argument("-i", "--image_file", type=str)
parser.add_argument("-m", "--model_file", type=str) parser.add_argument("-m", "--model_file", type=str)
parser.add_argument("-p", "--params_file", type=str) parser.add_argument("-p", "--params_file", type=str)
parser.add_argument("-b", "--max_batch_size", type=int, default=1) parser.add_argument("-b", "--batch_size", type=int, default=1)
parser.add_argument("--use_fp16", type=str2bool, default=False)
parser.add_argument("--use_gpu", type=str2bool, default=True) parser.add_argument("--use_gpu", type=str2bool, default=True)
parser.add_argument("--ir_optim", type=str2bool, default=True) parser.add_argument("--ir_optim", type=str2bool, default=True)
parser.add_argument("--use_tensorrt", type=str2bool, default=False) parser.add_argument("--use_tensorrt", type=str2bool, default=False)
parser.add_argument("--gpu_mem", type=int, default=8000)
parser.add_argument("--enable_benchmark", type=str2bool, default=False)
parser.add_argument("--model_name", type=str)
return parser.parse_args() return parser.parse_args()
def create_predictor(args): def create_predictor(args):
config = AnalysisConfig(args.model_file, args.params_file) config = AnalysisConfig(args.model_file, args.params_file)
if args.use_gpu: if args.use_gpu:
config.enable_use_gpu(1000, 0) config.enable_use_gpu(args.gpu_mem, 0)
else: else:
config.disable_gpu() config.disable_gpu()
config.switch_ir_optim(args.ir_optim) # default true config.disable_glog_info()
config.switch_ir_optim(args.ir_optim) # default true
if args.use_tensorrt: if args.use_tensorrt:
config.enable_tensorrt_engine( config.enable_tensorrt_engine(
precision_mode=AnalysisConfig.Precision.Float32, precision_mode=AnalysisConfig.Precision.Half if args.use_fp16 else AnalysisConfig.Precision.Float32,
max_batch_size=args.max_batch_size) max_batch_size=args.batch_size)
config.enable_memory_optim()
# use zero copy
config.switch_use_feed_fetch_ops(False)
predictor = create_paddle_predictor(config) predictor = create_paddle_predictor(config)
return predictor return predictor
...@@ -64,7 +79,7 @@ def create_operators(): ...@@ -64,7 +79,7 @@ def create_operators():
resize_op = utils.ResizeImage(resize_short=256) resize_op = utils.ResizeImage(resize_short=256)
crop_op = utils.CropImage(size=(size, size)) crop_op = utils.CropImage(size=(size, size))
normalize_op = utils.NormalizeImage( normalize_op = utils.NormalizeImage(
scale=img_scale, mean=img_mean, std=img_std) scale=img_scale, mean=img_mean, std=img_std)
totensor_op = utils.ToTensor() totensor_op = utils.ToTensor()
return [decode_op, resize_op, crop_op, normalize_op, totensor_op] return [decode_op, resize_op, crop_op, normalize_op, totensor_op]
...@@ -78,25 +93,49 @@ def preprocess(fname, ops): ...@@ -78,25 +93,49 @@ def preprocess(fname, ops):
return data return data
def postprocess(outputs, topk=5):
output = outputs[0]
prob = output.as_ndarray().flatten()
index = prob.argsort(axis=0)[-topk:][::-1].astype('int32')
return zip(index, prob[index])
def main(): def main():
args = parse_args() args = parse_args()
if not args.enable_benchmark:
assert args.batch_size == 1
assert args.use_fp16 == False
else:
assert args.use_gpu == True
assert args.model_name is not None
assert args.use_tensorrt == True
# HALF precission predict only work when using tensorrt
if args.use_fp16==True:
assert args.use_tensorrt == True
operators = create_operators() operators = create_operators()
predictor = create_predictor(args) predictor = create_predictor(args)
data = preprocess(args.image_file, operators) inputs = preprocess(args.image_file, operators)
inputs = [PaddleTensor(data.copy())] inputs = np.expand_dims(inputs, axis=0).repeat(args.batch_size, axis=0).copy()
outputs = predictor.run(inputs)
probs = postprocess(outputs)
for idx, prob in probs: input_names = predictor.get_input_names()
print("class id: {:d}, probability: {:.4f}".format(idx, prob)) input_tensor = predictor.get_input_tensor(input_names[0])
input_tensor.copy_from_cpu(inputs)
if not args.enable_benchmark:
predictor.zero_copy_run()
else:
for i in range(0,1010):
if i == 10:
start = time.time()
predictor.zero_copy_run()
end = time.time()
fp_message = "FP16" if args.use_fp16 else "FP32"
logger.info("{0}\t{1}\tbatch size: {2}\ttime(ms): {3}".format(args.model_name, fp_message, args.batch_size, end-start))
output_names = predictor.get_output_names()
output_tensor = predictor.get_output_tensor(output_names[0])
output = output_tensor.copy_to_cpu()
output = output.flatten()
cls = np.argmax(output)
score = output[cls]
logger.info("class: {0}".format(cls))
logger.info("score: {0}".format(score))
if __name__ == "__main__": if __name__ == "__main__":
......
#!/usr/bin/env bash
python ./cpp_infer.py \
-i=./test.jpeg \
-m=./resnet50-vd/model \
-p=./resnet50-vd/params \
--use_gpu=1
python ./cpp_infer.py \
-i=./test.jpeg \
-m=./resnet50-vd/model \
-p=./resnet50-vd/params \
--use_gpu=0
python py_infer.py \
-i=./test.jpeg \
-d ./resnet50-vd/ \
-m=model -p=params \
--use_gpu=0
python py_infer.py \
-i=./test.jpeg \
-d ./resnet50-vd/ \
-m=model -p=params \
--use_gpu=1
python infer.py \
-i=./test.jpeg \
-m ResNet50_vd \
-p ./resnet50-vd-persistable/ \
--use_gpu=0
python infer.py \
-i=./test.jpeg \
-m ResNet50_vd \
-p ./resnet50-vd-persistable/ \
--use_gpu=1
python export_model.py \
-m ResNet50_vd \
-p ./resnet50-vd-persistable/ \
-o ./test/
python py_infer.py \
-i=./test.jpeg \
-d ./test/ \
-m=model \
-p=params \
--use_gpu=0
...@@ -81,5 +81,4 @@ class ToTensor(object): ...@@ -81,5 +81,4 @@ class ToTensor(object):
def __call__(self, img): def __call__(self, img):
img = img.transpose((2, 0, 1)) img = img.transpose((2, 0, 1))
img = np.expand_dims(img, axis=0)
return img return img
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册