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

Merge branch 'master' into master

......@@ -2,34 +2,34 @@
## 简介
PaddleClas的目的是为工业界和学术界提供一个图像分类任务相关的百宝箱,特色如下:
- 模型库:17种分类网络结构以及训练技巧,118个分类预训练模型以及性能评估
- 模型库:ResNet_vd、MobileNetV3等25种系列的分类网络结构和训练技巧,以及对应的117个分类预训练模型和性能评估
- 高阶使用:高精度的实用模型蒸馏方案(准确率82.39%的ResNet50_vd和78.9%的MobileNetV3)、8种数据增广方法的复现和验证
- 应用拓展:常见视觉任务的特色方案,包括图像分类领域的迁移学习(百度自研的10w类图像分类预训练模型)、通用目标检测(mAP 47.8%的实用检测方案)、自然场景文字检测和识别
- 应用拓展:常见视觉任务的特色方案,包括图像分类领域的迁移学习(百度自研的10w类图像分类预训练模型)和通用目标检测(mAP 47.8%的实用检测方案)
- 实用工具:便于工业应用部署的实用工具,包括TensorRT预测、移动端预测、INT8量化、多机训练、PaddleHub等
- 赛事支持:助力多个视觉全球挑战赛取得领先成绩,包括2018年Kaggle Open Images V4图像目标检测挑战赛冠军、2019年Kaggle地标检索挑战赛亚军等
## 模型库
<div align="center">
<img src="docs/images/models/main_fps_top1.png" width="600">
</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">
<img
src="docs/images/models/mobile_arm_top1.png" width="1000">
src="docs/images/models/mobile_arm_top1.png" width="600">
</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论文指标复现和性能评估
## 高阶使用
......@@ -55,7 +55,7 @@ src="docs/images/distillation/distillation_perform.png" width="500">
<div align="center">
<img
src="docs/images/image_aug/main_image_aug.png" width="600">
</div>
</div>
- TODO
- [ ] 更多的优化器支持和效果验证
......@@ -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的建设源于百度实际视觉业务应用的淬炼和视觉前沿
## 版本更新
## 如何贡献代码
我们非常欢迎你为PaddleClas提供代码,也十分感谢你的反馈。
我们非常欢迎你为PaddleClas贡献代码,也十分感谢你的反馈。
......@@ -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_logo = './images/logo.png'
......@@ -13,7 +13,5 @@
zh_cn/model_zoo.md
zh_cn/change_log.md
zh_cn/faq.md
: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系列
## 概述
正在持续更新中......
![](../../images/models/DPN.png)
所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。
更多的模型概述正在持续更新中。
## 精度、FLOPS和参数量
......
# EfficientNet与ResNeXt101_wsl系列
## 概述
正在持续更新中......
![](../../images/models/EfficientNet.png)
更多的模型简介正在持续更新中。
在预测时,图像的crop_size和resize_short_size如下表所示。
| Models | crop_size | resize_short_size |
|:--:|:--:|:--:|
| ResNeXt101_32x8d_wsl | 224 | 256 |
| ResNeXt101_32x16d_wsl | 224 | 256 |
| ResNeXt101_32x32d_wsl | 224 | 256 |
| ResNeXt101_32x48d_wsl | 224 | 256 |
| ResNeXt101_32x8d_wsl | 224 | 224 |
| ResNeXt101_32x16d_wsl | 224 | 224 |
| ResNeXt101_32x32d_wsl | 224 | 224 |
| ResNeXt101_32x48d_wsl | 224 | 224 |
| Fix_ResNeXt101_32x48d_wsl | 320 | 320 |
| EfficientNetB0 | 224 | 256 |
| EfficientNetB1 | 240 | 272 |
......
# HRNet系列
## 概述
正在持续更新中......
![](../../images/models/HRNet.png)
所有模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。
更多的模型概述正在持续更新中。
## 精度、FLOPS和参数量
......
# Inception系列
## 概述
正在持续更新中......
![](../../images/models/Inception.png)
所有模型在预测时,图像的crop_size设置为299,resize_short_size设置为320。
更多的模型简介正在持续更新中。
GoogLeNet在预测时,图像的crop_size设置为224,resize_short_size设置为256,其余模型在预测时,图像的crop_size设置为299,resize_short_size设置为320。
## 精度、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_storage.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和参数量
......
# 其他模型
## 概述
正在持续更新中......
DarkNet53在预测时,图像的crop_size设置为256,resize_short_size设置为256;其余模型在预测时,图像的crop_size设置为224,resize_short_size设置为256。
更多的模型简介正在持续更新中。
## 精度、FLOPS和参数量
......
......@@ -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和参数量
......
# 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和参数量
......
# 训练技巧
coming soon......
正在持续更新中......
此差异已折叠。
......@@ -2,7 +2,7 @@
---
请事先参考[安装指南](install.md)配置运行环境
## 1 设置环境变量
## 一、设置环境变量
**设置PYTHONPATH环境变量:**
......@@ -10,7 +10,7 @@
export PYTHONPATH=path_to_PaddleClas:$PYTHONPATH
```
## 2 模型训练与评估
## 二、模型训练与评估
PaddleClas 提供模型训练与评估脚本:tools/train.py和tools/eval.py
......@@ -23,7 +23,7 @@ python -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \
--log_dir=log_ResNet50 \
train.py \
-c ../configs/ResNet/ResNet50.yaml \
-c ./configs/ResNet/ResNet50.yaml \
```
- 输出日志示例如下:
......@@ -39,7 +39,7 @@ python -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \
--log_dir=log_ResNet50_vd \
train.py \
-c ../configs/ResNet/ResNet50_vd.yaml \
-c ./configs/ResNet/ResNet50_vd.yaml \
-o use_mix=1 \
```
......@@ -57,8 +57,30 @@ epoch:0 train step:522 loss:1.6330 lr:0.100000 elapse:0.210
```bash
python eval.py \
-c ../configs/eval.yaml \
-c ./configs/eval.yaml \
-o architecture="ResNet50_vd" \
-o pretrained_model=path_to_pretrained_models
```
您可以更改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 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import utils
import argparse
import numpy as np
import logging
import time
from paddle.fluid.core import PaddleTensor
from paddle.fluid.core import AnalysisConfig
from paddle.fluid.core import create_paddle_predictor
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def parse_args():
def str2bool(v):
......@@ -29,26 +32,38 @@ def parse_args():
parser.add_argument("-i", "--image_file", type=str)
parser.add_argument("-m", "--model_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("--ir_optim", type=str2bool, default=True)
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()
def create_predictor(args):
config = AnalysisConfig(args.model_file, args.params_file)
if args.use_gpu:
config.enable_use_gpu(1000, 0)
config.enable_use_gpu(args.gpu_mem, 0)
else:
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:
config.enable_tensorrt_engine(
precision_mode=AnalysisConfig.Precision.Float32,
max_batch_size=args.max_batch_size)
precision_mode=AnalysisConfig.Precision.Half if args.use_fp16 else AnalysisConfig.Precision.Float32,
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)
return predictor
......@@ -64,7 +79,7 @@ def create_operators():
resize_op = utils.ResizeImage(resize_short=256)
crop_op = utils.CropImage(size=(size, size))
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()
return [decode_op, resize_op, crop_op, normalize_op, totensor_op]
......@@ -78,25 +93,49 @@ def preprocess(fname, ops):
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():
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()
predictor = create_predictor(args)
data = preprocess(args.image_file, operators)
inputs = [PaddleTensor(data.copy())]
outputs = predictor.run(inputs)
probs = postprocess(outputs)
inputs = preprocess(args.image_file, operators)
inputs = np.expand_dims(inputs, axis=0).repeat(args.batch_size, axis=0).copy()
for idx, prob in probs:
print("class id: {:d}, probability: {:.4f}".format(idx, prob))
input_names = predictor.get_input_names()
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__":
......
#!/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):
def __call__(self, img):
img = img.transpose((2, 0, 1))
img = np.expand_dims(img, axis=0)
return img
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册