未验证 提交 092ff478 编写于 作者: S SunAhong1993 提交者: GitHub

Merge pull request #6 from PaddlePaddle/develop

00
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
- id: check-symlinks - id: check-symlinks
- id: check-added-large-files - id: check-added-large-files
- repo: local - repo: local
hooks: hooks:
- id: copyright_checker - id: copyright_checker
name: copyright_checker name: copyright_checker
...@@ -21,3 +22,19 @@ ...@@ -21,3 +22,19 @@
language: system language: system
files: \.(c|cc|cxx|cpp|cu|h|hpp|hxx|proto|py)$ files: \.(c|cc|cxx|cpp|cu|h|hpp|hxx|proto|py)$
exclude: (?!.*third_party)^.*$ exclude: (?!.*third_party)^.*$
hooks:
- id: clang-format-with-version-check
name: clang-format
description: Format files with ClangFormat.
entry: bash ./tools/codestyle/clang_format.hook -i
language: system
files: \.(c|cc|cxx|cpp|cu|h|hpp|hxx|proto)$
hooks:
- id: cpplint-cpp-source
name: cpplint
description: Check C++ code style using cpplint.py.
entry: bash cpplint_pre_commit.hook
language: system
files: \.(c|cc|cxx|cpp|cu|h|hpp|hxx)$
...@@ -11,18 +11,18 @@ PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习 ...@@ -11,18 +11,18 @@ PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习
## 特点 ## 特点
- **全流程打通** - **全流程打通**
- 数据准备:支持LabelMe,精灵标注等主流数据标注工具协议,同时无缝集成[EasyData智能数据服务平台](https://ai.baidu.com/easydata/), 助力开发者高效获取AI开发所需高质量数据。 - **数据准备**:支持[EasyData智能数据服务平台](https://ai.baidu.com/easydata/)数据协议,通过平台便捷完成智能标注,低质数据清洗工作, 同时兼容主流标注工具协议, 助力开发者更快完成数据准备工作。
- 模型训练:基于飞桨核心框架集成[PaddleClas](https://github.com/PaddlePaddle/PaddleClas), [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection), [PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg)视觉开发套件,[VisualDL](https://github.com/PaddlePaddle/VisualDL)可视化分析组件,高效完成模型训练。 - **模型训练**:集成[PaddleClas](https://github.com/PaddlePaddle/PaddleClas), [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection), [PaddleSeg](https://github.com/PaddlePaddle/PaddleSeg)视觉开发套件,丰富的高质量预训练模型,更快实现工业级模型效果。
- 多端部署:内置[PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim)模型压缩工具和AES模型加密SDK,结合Paddle Inference和[Paddle Lite](https://github.com/PaddlePaddle/Paddle-Lite)便捷完成高性能且可靠的多端部署。 - **模型调优**:内置模型可解释性模块、[VisualDL](https://github.com/PaddlePaddle/VisualDL)可视化分析组件, 提供丰富的信息更好地理解模型,优化模型。
- **多端安全部署**:内置[PaddleSlim](https://github.com/PaddlePaddle/PaddleSlim)模型压缩工具和**模型加密部署模块**,结合Paddle Inference或[Paddle Lite](https://github.com/PaddlePaddle/Paddle-Lite)便捷完成高性能的多端安全部署。
- **融合产业实践** - **融合产业实践**
- 精选飞桨产业实践的成熟模型结构,开放案例实践教程,加速开发者产业落地。 - 精选飞桨产业实践的成熟模型结构,开放案例实践教程,加速开发者产业落地。
- 通过[PaddleHub](https://github.com/PaddlePaddle/Paddle)内置丰富的飞桨高质量预训练模型,助力开发者高效实现飞桨Master模式。
- **易用易集成** - **易用易集成**
- PadldeX提供简洁易用的全流程API,几行代码即可实现上百种数据增强、模型可解释性、C++模型部署等功能 - 统一易用的全流程API,5步完成模型训练,10行代码实现Python/C++高性能部署
- 提供以PaddleX API为核心集成的跨平台GUI界面,降低深度学习全流程应用门槛 - 提供以PaddleX为核心集成的跨平台可视化工具PaddleX-GUI,快速体验飞桨深度学习全流程
## 安装 ## 安装
...@@ -31,7 +31,7 @@ PaddleX提供两种开发模式,满足不同场景和用户需求: ...@@ -31,7 +31,7 @@ PaddleX提供两种开发模式,满足不同场景和用户需求:
- **Python开发模式:** 通过Python API方式完成全流程使用或集成,该模型提供全面、灵活、开放的深度学习功能,有更高的定制化空间。 - **Python开发模式:** 通过Python API方式完成全流程使用或集成,该模型提供全面、灵活、开放的深度学习功能,有更高的定制化空间。
- **GUI开发模式:** 以PaddleX API为核心集成的跨平台GUI客户端,支持`Python开发模式`下的常用功能,以更低门槛的方式快速完成产业验证的模型训练。 - **Padlde-GUI模式:** PaddleX-GUI支持`Python开发模式`下的常用功能,以更低门槛的方式快速完成产业验证的模型训练。
开发者可根据自身需要按需选择不同的模式进行安装使用。 开发者可根据自身需要按需选择不同的模式进行安装使用。
...@@ -47,21 +47,21 @@ PaddleX提供两种开发模式,满足不同场景和用户需求: ...@@ -47,21 +47,21 @@ PaddleX提供两种开发模式,满足不同场景和用户需求:
``` ```
pip install paddlex -i https://mirror.baidu.com/pypi/simple pip install paddlex -i https://mirror.baidu.com/pypi/simple
``` ```
安装的相关问题参考[PaddleX安装](https://paddlex.readthedocs.io/zh_CN/latest/install.html)
### GUI开发模式安装 ### PaddleX-GUI安装
进入PaddleX官网[下载使用](https://www.paddlepaddle.org.cn/paddle/paddlex),申请下载绿色安装包,开箱即用。 进入PaddleX官网[下载使用](https://www.paddlepaddle.org.cn/paddle/paddlex),申请下载绿色安装包,开箱即用。
GUI模式的使用教程可参考[PaddleX GUI模式使用教程](https://paddlex.readthedocs.io/zh_CN/latest/paddlex_gui/index.html) Paddle-GUI的使用教程可参考[PaddleX-GUI模式使用教程](https://paddlex.readthedocs.io/zh_CN/latest/paddlex_gui/index.html)
## 使用文档 ## 使用文档
推荐访问[PaddleX在线使用文档](https://paddlex.readthedocs.io/zh_CN/latest/index.html),快速查阅读使用教程和API文档说明。 推荐访问[PaddleX在线使用文档](https://paddlex.readthedocs.io/zh_CN/latest/index.html),快速查阅读使用教程和API文档说明。
- [10分钟快速上手](https://paddlex.readthedocs.io/zh_CN/latest/quick_start.html) - [10分钟快速上手使用](https://paddlex.readthedocs.io/zh_CN/latest/quick_start.html)
- [PaddleX模型训练](https://paddlex.readthedocs.io/zh_CN/latest/tutorials/train/index.html#id1) - [PaddleX全流程开发教程](https://paddlex.readthedocs.io/zh_CN/latest/tutorials/index.html)
- [PaddleX模型压缩](https://paddlex.readthedocs.io/zh_CN/latest/slim/index.html#id1) - [PaddleX视觉方案介绍](https://paddlex.readthedocs.io/zh_CN/latest/cv_solutions.html)
- [PaddleX模型库](https://paddlex.readthedocs.io/zh_CN/latest/model_zoo.html#id1) - [PaddleX API参考文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/index.html)
- [PaddleX多端部署](docs/deploy.md)
## 在线教程 ## 在线教程
...@@ -74,12 +74,16 @@ GUI模式的使用教程可参考[PaddleX GUI模式使用教程](https://paddlex ...@@ -74,12 +74,16 @@ GUI模式的使用教程可参考[PaddleX GUI模式使用教程](https://paddlex
## 交流与反馈 ## 交流与反馈
- 项目官网: https://www.paddlepaddle.org.cn/paddle/paddlex - 项目官网: https://www.paddlepaddle.org.cn/paddle/paddlex
- PaddleX用户QQ群: 1045148026 (手机QQ扫描如下二维码快速加入) - PaddleX用户交流群: 1045148026 (手机QQ扫描如下二维码快速加入)
<img src="./docs/images/QQGroup.jpeg" width="195" height="300" alt="QQGroup" align="center" /> <img src="./docs/images/QQGroup.jpeg" width="195" height="300" alt="QQGroup" align="center" />
## FAQ ## FAQ
## 更新日志 ## 更新日志
* 2020.05.20
**`v1.0.0`**
* 正式版本发布。
## 贡献代码 ## 贡献代码
......
# 模型部署 # 多端安全部署
本目录为PaddleX模型部署代码, 编译和使用的教程参考: 本目录为PaddleX模型部署代码,编译和使用教程参考:
- [C++部署文档](../docs/tutorials/deploy/deploy.md#C部署) - [服务端部署(支持Python部署、C++部署、模型加密部署)](../docs/tutorials/deploy/deploy_server/)
- [OpenVINO部署文档](../docs/tutorials/deploy/deploy.md#openvino部署) - [OpenVINO部署](../docs/tutorials/deploy/deploy_openvino.md)
- [移动端部署](../docs/tutorials/deploy/deploy_lite.md)
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
import paddlelite.lite as lite
import os
import argparse
def export_lite():
opt = lite.Opt()
model_file = os.path.join(FLAGS.model_path, '__model__')
params_file = os.path.join(FLAGS.model_path, '__params__')
opt.run_optimize("", model_file, params_file, FLAGS.place, FLAGS.save_dir)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--model_path",
type=str,
default="",
help="model path.",
required=True)
parser.add_argument(
"--place",
type=str,
default="arm",
help="preprocess config path.",
required=True)
parser.add_argument(
"--save_dir",
type=str,
default="paddlex.onnx",
help="Directory for storing the output visualization files.",
required=True)
FLAGS = parser.parse_args()
export_lite()
# 常见问题 # 常见问题
## 1. 训练过程因显存不够出错 ## 1. 训练参数如何调整
> 参考[参数调整文档](appendix/parameters.md)
## 2. 训练过程因显存不够出错
> 通过使用在终端`nvidia-smi`命令,查看GPU是否被其它任务占用,尝试清除其它任务; > 通过使用在终端`nvidia-smi`命令,查看GPU是否被其它任务占用,尝试清除其它任务;
> 调低训练时的`batch_size`参数,从而降低显存的要求,注意需等比例调低`learning_rate`等参数; > 调低训练时的`batch_size`参数,从而降低显存的要求,注意需等比例调低`learning_rate`等参数;
> 选用更小的模型或backbone。 > 选用更小的模型或backbone。
## 2. 是否有更小的模型,适用于更低配置的设备上运行 ## 3. 是否有更小的模型,适用于更低配置的设备上运行
> 可以使用模型裁剪,参考文档[模型裁剪使用教程](slim/prune.md),通过调整裁剪参数,可以控制模型裁剪后的大小,在实际实验中,如VOC检测数据,使用yolov3-mobilenet,原模型大小为XXM,裁剪后为XX M,精度基本保持不变 > 可以使用模型裁剪,参考文档[模型裁剪使用教程](slim/prune.md),通过调整裁剪参数,可以控制模型裁剪后的大小,在实际实验中,如VOC检测数据,使用yolov3-mobilenet,原模型大小为XXM,裁剪后为XX M,精度基本保持不变
## 3. 如何配置训练时GPU的卡数 ## 4. 如何配置训练时GPU的卡数
> 通过在终端export环境变量,或在Python代码中设置,可参考文档[CPU/多卡GPU训练](gpu_configure.md) > 通过在终端export环境变量,或在Python代码中设置,可参考文档[CPU/多卡GPU训练](gpu_configure.md)
## 4. 想将之前训练的模型参数上继续训练 ## 5. 想将之前训练的模型参数上继续训练
> 在训练调用`train`接口时,将`pretrain_weights`设为之前的模型保存路径即可 > 在训练调用`train`接口时,将`pretrain_weights`设为之前的模型保存路径即可
## 5. PaddleX保存的模型分为正常训练过程中产生、裁剪训练产生、导出为部署模型和量化保存这么多种,有什么差别,怎么区分 ## 6. PaddleX保存的模型分为正常训练过程中产生、裁剪训练产生、导出为部署模型和量化保存这么多种,有什么差别,怎么区分
**不同模型的功能差异** **不同模型的功能差异**
...@@ -40,20 +43,20 @@ ...@@ -40,20 +43,20 @@
>> 通过模型目录下model.yml文件中`status`字段来区别不同的模型类型, 'Normal'、'Prune'、'Infer'、'Quant'分别表示正常模型训练保存、裁剪训练保存、导出的部署模型、量化保存模型 >> 通过模型目录下model.yml文件中`status`字段来区别不同的模型类型, 'Normal'、'Prune'、'Infer'、'Quant'分别表示正常模型训练保存、裁剪训练保存、导出的部署模型、量化保存模型
## 6. 模型训练需要太久时间,或者训练速度太慢,怎么提速 ## 7. 模型训练需要太久时间,或者训练速度太慢,怎么提速
> 1.模型训练速度与用户选定的模型大小,和设定的`batch_size`相关,模型大小可直接参考[模型库](model_zoo.md)中的指标,一般而言,模型越大,训练速度就越慢; > 1.模型训练速度与用户选定的模型大小,和设定的`batch_size`相关,模型大小可直接参考[模型库](model_zoo.md)中的指标,一般而言,模型越大,训练速度就越慢;
> 2.在模型速度之外,模型训练完成所需的时间又与用户设定的`num_epochs`迭代轮数相关,用户可以通过观察模型在验证集上的指标来决定是否提示结束掉训练进程(训练时设定`save_interval_epochs`参数,训练过程会每间隔`save_interval_epochs`轮数在验证集上计算指标,并保存模型); > 2.在模型速度之外,模型训练完成所需的时间又与用户设定的`num_epochs`迭代轮数相关,用户可以通过观察模型在验证集上的指标来决定是否提示结束掉训练进程(训练时设定`save_interval_epochs`参数,训练过程会每间隔`save_interval_epochs`轮数在验证集上计算指标,并保存模型);
## 7. 如何设定迭代的轮数 ## 8. 如何设定迭代的轮数
> 1. 用户自行训练时,如不确定迭代的轮数,可以将轮数设高一些,同时注意设置`save_interval_epochs`,这样模型迭代每间隔相应轮数就会在验证集上进行评估和保存,可以根据不同轮数模型在验证集上的评估指标,判断模型是否已经收敛,若模型已收敛,可以自行结束训练进程 > 1. 用户自行训练时,如不确定迭代的轮数,可以将轮数设高一些,同时注意设置`save_interval_epochs`,这样模型迭代每间隔相应轮数就会在验证集上进行评估和保存,可以根据不同轮数模型在验证集上的评估指标,判断模型是否已经收敛,若模型已收敛,可以自行结束训练进程
> >
## 8. 只有CPU,没有GPU,如何提升训练速度 ## 9. 只有CPU,没有GPU,如何提升训练速度
> 当没有GPU时,可以根据自己的CPU配置,选择是否使用多CPU进行训练,具体配置方式可以参考文档[多卡CPU/GPU训练](gpu_configure.md) > 当没有GPU时,可以根据自己的CPU配置,选择是否使用多CPU进行训练,具体配置方式可以参考文档[多卡CPU/GPU训练](gpu_configure.md)
> >
## 9. 电脑不能联网,训练时因为下载预训练模型失败,如何解决 ## 10. 电脑不能联网,训练时因为下载预训练模型失败,如何解决
> 可以预先通过其它方式准备好预训练模型,然后训练时自定义`pretrain_weights`即可,可参考文档[无联网模型训练](how_to_offline_run.md) > 可以预先通过其它方式准备好预训练模型,然后训练时自定义`pretrain_weights`即可,可参考文档[无联网模型训练](how_to_offline_run.md)
## 10. 每次训练新的模型,都需要重新下载预训练模型,怎样可以下载一次就搞定 ## 11. 每次训练新的模型,都需要重新下载预训练模型,怎样可以下载一次就搞定
> 1.可以按照9的方式来解决这个问题 > 1.可以按照9的方式来解决这个问题
> 2.每次训练前都设定`paddlex.pretrain_dir`路径,如设定`paddlex.pretrain_dir='/usrname/paddlex`,如此下载完的预训练模型会存放至`/usrname/paddlex`目录下,而已经下载在该目录的模型也不会再次重复下载 > 2.每次训练前都设定`paddlex.pretrain_dir`路径,如设定`paddlex.pretrain_dir='/usrname/paddlex`,如此下载完的预训练模型会存放至`/usrname/paddlex`目录下,而已经下载在该目录的模型也不会再次重复下载
...@@ -114,27 +114,54 @@ pdx.slim.visualize(model, 'mobilenetv2.sensitivities', save_dir='./') ...@@ -114,27 +114,54 @@ pdx.slim.visualize(model, 'mobilenetv2.sensitivities', save_dir='./')
# 可视化结果保存在./sensitivities.png # 可视化结果保存在./sensitivities.png
``` ```
## 可解释性结果可视化 ## LIME可解释性结果可视化
``` ```
paddlex.interpret.visualize(img_file, paddlex.interpret.lime(img_file,
model, model,
dataset=None, num_samples=3000,
algo='lime', batch_size=50,
num_samples=3000, save_dir='./')
batch_size=50,
save_dir='./')
``` ```
将模型预测结果的可解释性可视化,目前只支持分类模型。 使用LIME算法将模型预测结果的可解释性可视化。
LIME表示与模型无关的局部可解释性,可以解释任何模型。LIME的思想是以输入样本为中心,在其附近的空间中进行随机采样,每个采样通过原模型得到新的输出,这样得到一系列的输入和对应的输出,LIME用一个简单的、可解释的模型(比如线性回归模型)来拟合这个映射关系,得到每个输入维度的权重,以此来解释模型。
**注意:** 可解释性结果可视化目前只支持分类模型。
### 参数 ### 参数
>* **img_file** (str): 预测图像路径。 >* **img_file** (str): 预测图像路径。
>* **model** (paddlex.cv.models): paddlex中的模型。 >* **model** (paddlex.cv.models): paddlex中的模型。
>* **dataset** (paddlex.datasets): 数据集读取器,默认为None。
>* **algo** (str): 可解释性方式,当前可选'lime'和'normlime'。
>* **num_samples** (int): LIME用于学习线性模型的采样数,默认为3000。 >* **num_samples** (int): LIME用于学习线性模型的采样数,默认为3000。
>* **batch_size** (int): 预测数据batch大小,默认为50。 >* **batch_size** (int): 预测数据batch大小,默认为50。
>* **save_dir** (str): 可解释性可视化结果(保存为png格式文件)和中间文件存储路径。 >* **save_dir** (str): 可解释性可视化结果(保存为png格式文件)和中间文件存储路径。
### 使用示例 ### 使用示例
> 对预测可解释性结果可视化的过程可参见[代码](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/interpret.py)。 > 对预测可解释性结果可视化的过程可参见[代码](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/lime.py)。
## NormLIME可解释性结果可视化
```
paddlex.interpret.normlime(img_file,
model,
dataset=None,
num_samples=3000,
batch_size=50,
save_dir='./')
```
使用NormLIME算法将模型预测结果的可解释性可视化。
NormLIME是利用一定数量的样本来出一个全局的解释。NormLIME会提前计算一定数量的测试样本的LIME结果,然后对相同的特征进行权重的归一化,这样来得到一个全局的输入和输出的关系。
**注意:** 可解释性结果可视化目前只支持分类模型。
### 参数
>* **img_file** (str): 预测图像路径。
>* **model** (paddlex.cv.models): paddlex中的模型。
>* **dataset** (paddlex.datasets): 数据集读取器,默认为None。
>* **num_samples** (int): LIME用于学习线性模型的采样数,默认为3000。
>* **batch_size** (int): 预测数据batch大小,默认为50。
>* **save_dir** (str): 可解释性可视化结果(保存为png格式文件)和中间文件存储路径。
**注意:** dataset`读取的是一个数据集,该数据集不宜过大,否则计算时间会较长,但应包含所有类别的数据。
### 使用示例
> 对预测可解释性结果可视化的过程可参见[代码](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/normlime.py)。
...@@ -8,13 +8,7 @@ ...@@ -8,13 +8,7 @@
model_zoo.md model_zoo.md
metrics.md metrics.md
parameters.md
how_to_convert_dataset.md how_to_convert_dataset.md
datasets.md datasets.md
* PaddleX版本: v0.1.7
* 项目官网: http://www.paddlepaddle.org.cn/paddle/paddlex
* 项目GitHub: https://github.com/PaddlePaddle/PaddleX/tree/develop
* 官方QQ用户群: 1045148026
* GitHub Issue反馈: http://www.github.com/PaddlePaddle/PaddleX/issues
# 训练参数调整
PaddleX所有训练接口中,内置的参数均为根据单GPU卡相应batch_size下的较优参数,用户在自己的数据上训练模型,涉及到参数调整时,如无太多参数调优经验,则可参考如下方式
## 1.Epoch数的调整
Epoch数是模型训练过程,迭代的轮数,用户可以设置较大的数值,根据模型迭代过程在验证集上的指标表现,来判断模型是否收敛,进而提前终止训练。此外也可以使用`train`接口中的`early_stop`策略,模型在训练过程会自动判断模型是否收敛自动中止。
## 2.Batch Size的调整
Batch Size指模型在训练过程中,一次性处理的样本数量, 如若使用多卡训练, batch_size会均分到各张卡上(因此需要让batch size整除卡数)。这个参数跟机器的显存/内存高度相关,`batch_size`越高,所消耗的显存/内存就越高。PaddleX在各个`train`接口中均配置了默认的batch size,如若用户调整batch size,则也注意需要对应调整其它参数,如下表所示展示YOLOv3在训练时的参数配置
| 参数 | 默认值 | 调整比例 | 示例 |
|:---------------- | :------------ | :------------------ | :------------ |
| train_batch_size | 8 | 调整为 8*alpha | 16 |
| learning_rate | 1.0/8000 | 调整为 alpha/8000 | 2.0/8000 |
| warmup_steps | 1000 | 调整为 1000/alpha<br>(该参数也可以自行根据数据情况调整) | 500 |
| lr_decay_epochs | [213, 240] | 不变 | [213, 240] |
更多训练接口可以参考
- [分类模型-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/classification.html#train)
- [目标检测检测FasterRCNN-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#id2)
- [目标检测YOLOv3-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#train)
- [实例分割MaskRCNN-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/instance_segmentation.html#train)
- [语义分割DeepLabv3p-train](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#train)
- [语义分割UNet](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#id2)
...@@ -11,10 +11,10 @@ PaddleX目前提供了4种视觉任务解决方案,分别为图像分类、目 ...@@ -11,10 +11,10 @@ PaddleX目前提供了4种视觉任务解决方案,分别为图像分类、目
| 模型 | 模型大小 | GPU预测速度 | CPU预测速度 | ARM芯片预测速度 | 准确率 | 备注 | | 模型 | 模型大小 | GPU预测速度 | CPU预测速度 | ARM芯片预测速度 | 准确率 | 备注 |
| :--------- | :------ | :---------- | :-----------| :------------- | :----- | :--- | | :--------- | :------ | :---------- | :-----------| :------------- | :----- | :--- |
| MobileNetV3_small_ssld | 12M | ? | ? | ? | 71.3% |适用于移动端场景 | | MobileNetV3_small_ssld | 12M | - | - | - | 71.3% |适用于移动端场景 |
| MobileNetV3_large_ssld | 21M | ? | ? | ? | 79.0% | 适用于移动端/服务端场景 | | MobileNetV3_large_ssld | 21M | - | - | - | 79.0% | 适用于移动端/服务端场景 |
| ResNet50_vd_ssld | 102.8MB | ? | ? | ? | 82.4% | 适用于服务端场景 | | ResNet50_vd_ssld | 102.8MB | - | - | - | 82.4% | 适用于服务端场景 |
| ResNet101_vd_ssld | 179.2MB | ? | ? | ? |83.7% | 适用于服务端场景 | | ResNet101_vd_ssld | 179.2MB | - | - | - |83.7% | 适用于服务端场景 |
除上述模型外,PaddleX还支持近20种图像分类模型,模型列表可参考[PaddleX模型库](../appendix/model_zoo.md) 除上述模型外,PaddleX还支持近20种图像分类模型,模型列表可参考[PaddleX模型库](../appendix/model_zoo.md)
...@@ -28,10 +28,10 @@ PaddleX目前提供了4种视觉任务解决方案,分别为图像分类、目 ...@@ -28,10 +28,10 @@ PaddleX目前提供了4种视觉任务解决方案,分别为图像分类、目
| 模型 | 模型大小 | GPU预测速度 | CPU预测速度 |ARM芯片预测速度 | BoxMAP | 备注 | | 模型 | 模型大小 | GPU预测速度 | CPU预测速度 |ARM芯片预测速度 | BoxMAP | 备注 |
| :------- | :------- | :--------- | :---------- | :------------- | :----- | :--- | | :------- | :------- | :--------- | :---------- | :------------- | :----- | :--- |
| YOLOv3-MobileNetV1 | 101.2M | ? | ? | ? | 29.3 | | | YOLOv3-MobileNetV1 | 101.2M | - | - | - | 29.3 | |
| YOLOv3-MobileNetV3 | 94.6M | ? | ? | ? | 31.6 | | | YOLOv3-MobileNetV3 | 94.6M | - | - | - | 31.6 | |
| YOLOv3-ResNet34 | 169.7M | ? | ? | ? | 36.2 | | | YOLOv3-ResNet34 | 169.7M | - | - | - | 36.2 | |
| YOLOv3-DarkNet53 | 252.4 | ? | ? | ? | 38.9 | | | YOLOv3-DarkNet53 | 252.4 | - | - | - | 38.9 | |
除YOLOv3模型外,PaddleX同时也支持FasterRCNN模型,支持FPN结构和5种backbone网络,详情可参考[PaddleX模型库](../appendix/model_zoo.md) 除YOLOv3模型外,PaddleX同时也支持FasterRCNN模型,支持FPN结构和5种backbone网络,详情可参考[PaddleX模型库](../appendix/model_zoo.md)
...@@ -44,8 +44,8 @@ PaddleX目前提供了实例分割MaskRCNN模型,支持5种不同的backbone ...@@ -44,8 +44,8 @@ PaddleX目前提供了实例分割MaskRCNN模型,支持5种不同的backbone
| 模型 | 模型大小 | GPU预测速度 | CPU预测速度 | ARM芯片预测速度 | BoxMAP | SegMAP | 备注 | | 模型 | 模型大小 | GPU预测速度 | CPU预测速度 | ARM芯片预测速度 | BoxMAP | SegMAP | 备注 |
| :---- | :------- | :---------- | :---------- | :------------- | :----- | :----- | :--- | | :---- | :------- | :---------- | :---------- | :------------- | :----- | :----- | :--- |
| MaskRCNN-ResNet50_vd-FPN | 185.5M | ? | ? | ? | 39.8 | 35.4 | | | MaskRCNN-ResNet50_vd-FPN | 185.5M | - | - | - | 39.8 | 35.4 | |
| MaskRCNN-ResNet101_vd-FPN | 268.6M | ? | ? | ? | 41.4 | 36.8 | | | MaskRCNN-ResNet101_vd-FPN | 268.6M | - | - | - | 41.4 | 36.8 | |
## 语义分割 ## 语义分割
...@@ -57,7 +57,7 @@ PaddleX目前提供了实例分割MaskRCNN模型,支持5种不同的backbone ...@@ -57,7 +57,7 @@ PaddleX目前提供了实例分割MaskRCNN模型,支持5种不同的backbone
| 模型 | 模型大小 | GPU预测速度 | CPU预测速度 | ARM芯片预测速度 | mIOU | 备注 | | 模型 | 模型大小 | GPU预测速度 | CPU预测速度 | ARM芯片预测速度 | mIOU | 备注 |
| :---- | :------- | :---------- | :---------- | :------------- | :----- | :----- | | :---- | :------- | :---------- | :---------- | :------------- | :----- | :----- |
| DeepLabv3p-MobileNetV2_x0.25 | | ? | ? | ? | ? | ? | | DeepLabv3p-MobileNetV2_x0.25 | | - | - | - | - | - |
| DeepLabv3p-MobileNetV2_x1.0 | | ? | ? | ? | ? | ? | | DeepLabv3p-MobileNetV2_x1.0 | | - | - | - | - | - |
| DeepLabv3p-Xception65 | | ? | ? | ? | ? | ? | | DeepLabv3p-Xception65 | | - | - | - | - | - |
| UNet | | ? | ? | ? | ? | ? | | UNet | | - | - | - | - | - |
...@@ -3,19 +3,18 @@ ...@@ -3,19 +3,18 @@
PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习全流程开发工具。具备 **全流程打通** 、**融合产业实践** 、**易用易集成** 三大特点。 PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习全流程开发工具。具备 **全流程打通** 、**融合产业实践** 、**易用易集成** 三大特点。
全流程打通 全流程打通
| - **数据准备**: 支持LabelMe,精灵标注等主流数据标注工具协议,同时无缝集成 `EasyData智能数据服务平台 <https://ai.baidu.com/easydata/>`_ ,助力开发者高效获取AI开发所需高质量数据。 | - **数据准备**: 支持 `EasyData智能数据服务平台数据协议 <https://ai.baidu.com/easydata/>`_ ,通过平台便捷完成智能标注,低质数据清洗工作;同时兼容主流标注工具协议, 助力开发者更快完成数据准备工作。
| - **模型训练**: 基于飞桨核心框架集成 `PaddleClas <https://github.com/PaddlePaddle/PaddleClas>`_ ,`PaddleDetection <https://github.com/PaddlePaddle/PaddleDetection>`_ ,`PaddleSeg <https://github.com/PaddlePaddle/PaddleSeg>`_ 视觉开发套件 ,`VisualDL <https://github.com/PaddlePaddle/VisualDL>`_ 可视化分析组件,高效完成模型训练。 | - **模型训练**: 基于飞桨核心框架集成 `PaddleClas <https://github.com/PaddlePaddle/PaddleClas>`_ ,`PaddleDetection <https://github.com/PaddlePaddle/PaddleDetection>`_ ,`PaddleSeg <https://github.com/PaddlePaddle/PaddleSeg>`_ 视觉开发套件,丰富的高质量预训练模型,更快实现工业级模型训练。
| _ **多端部署**: 内置 `PaddleSlim <https://github.com/PaddlePaddle/PaddleSlim>`_ 模型压缩工具和AES模型加密SDK,结合Paddle Inference和 `Paddle Lite <https://github.com/PaddlePaddle/Paddle-Lite>`_ 便捷完成高性能且可靠的多端部署。 | - **模型调优**: 内置模型可解释性模块、`VisualDL <https://github.com/PaddlePaddle/VisualDL>`_ 可视化分析组件,提供丰富的信息更好地理解模型,优化模型。
| - **多端安全部署**: 内置 `PaddleSlim <https://github.com/PaddlePaddle/PaddleSlim>`_ 模型压缩工具和AES模型加密SDK,结合Paddle Inference和 `Paddle Lite <https://github.com/PaddlePaddle/Paddle-Lite>`_ 便捷完成高性能的多端安全部署。
融合产业实践 融合产业实践
| - 精选飞桨产业实践的成熟模型结构,开放案例实践教程,加速开发者产业落地。 | - 精选飞桨产业实践的成熟模型结构,开放案例实践教程,加速开发者产业落地。
| - 通过 `PaddleHub <https://github.com/PaddlePaddle/PaddleHub>`_ 内置丰富的飞桨高质量预训练模型,助力开发者高效实现飞桨Master模式。
易用易集成 易用易集成
| - PadldeX提供简洁易用的全流程API,几行代码即可实现上百种数据增强、模型可解释性、C++模型部署等功能 | - 统一易用的全流程API,5步完成模型训练,10行代码实现Python/C++高性能部署
| - 提供以PaddleX API为核心集成的跨平台GUI界面,降低深度学习全流程应用门槛 | - 提供以PaddleX为核心集成的跨平台可视化开发工具PaddleX-GUI,更低门槛快速体验飞桨深度学习全流程
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
...@@ -31,7 +30,7 @@ PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习 ...@@ -31,7 +30,7 @@ PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习
FAQ.md FAQ.md
appendix/index.rst appendix/index.rst
* PaddleX版本: v0.1.7 * PaddleX版本: v1.0.0
* 项目官网: http://www.paddlepaddle.org.cn/paddle/paddlex * 项目官网: http://www.paddlepaddle.org.cn/paddle/paddlex
* 项目GitHub: https://github.com/PaddlePaddle/PaddleX/tree/develop * 项目GitHub: https://github.com/PaddlePaddle/PaddleX/tree/develop
* 官方QQ用户群: 1045148026 * 官方QQ用户群: 1045148026
......
// Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <iostream>
int main() {
std::cout << "haha" << std::endl;
return 0;
}
# PaddleX使用教程
- [模型训练](./train)
- [模型裁剪](./compress)
# 移动端部署
step 1: 安装PaddleLite
```
pip install paddlelite
```
step 2: 将PaddleX模型导出为inference模型
参考[导出inference模型](deploy_server/deploy_python.html#inference)将模型导出为inference格式模型。
step 3: 将inference模型转换成PaddleLite模型
```
python /path/to/PaddleX/deploy/lite/export_lite.py --model_path /path/to/inference_model --save_dir /path/to/onnx_model
```
`--model_path`用于指定inference模型的路径,`--save_dir`用于指定Lite模型的保存路径。
step 4: 预测
Lite模型预测正在集成中,即将开源...
# OpenVINO 分类demo编译 # OpenVINO部署
## 说明 ## 方案简介
OpenVINO部署方案位于目录`PaddleX/deploy/openvino/`下,且独立于PaddleX其他模块,该方案目前支持在 **Linux** 完成编译和部署运行。
PaddleX到OpenVINO的部署流程如下:
> PaddleX --> ONNX --> OpenVINO IR --> OpenVINO Inference Engine
|目前支持OpenVINO部署的PaddleX模型|
|-----|
|ResNet18|
|ResNet34|
|ResNet50|
|ResNet101|
|ResNet50_vd|
|ResNet101_vd|
|ResNet50_vd_ssld|
|ResNet101_vd_ssld|
|DarkNet53|
|MobileNetV1|
|MobileNetV2|
|DenseNet121|
|DenseNet161|
|DenseNet201|
## 部署流程
### 说明
本文档在 `Ubuntu`使用`GCC 4.8.5` 进行了验证,如果需要使用更多G++版本和平台的OpenVino编译,请参考: [OpenVINO](https://github.com/openvinotoolkit/openvino/blob/2020/build-instruction.md) 本文档在 `Ubuntu`使用`GCC 4.8.5` 进行了验证,如果需要使用更多G++版本和平台的OpenVino编译,请参考: [OpenVINO](https://github.com/openvinotoolkit/openvino/blob/2020/build-instruction.md)
## 验证环境
### 验证环境
* Ubuntu* 16.04 (64-bit) with GCC* 4.8.5 * Ubuntu* 16.04 (64-bit) with GCC* 4.8.5
* CMake 3.12 * CMake 3.12
* Python 2.7 or higher * Python 2.7 or higher
请确保系统已经安装好上述基本软件,**下面所有示例以工作目录 `/root/projects/`演示** 请确保系统已经安装好上述基本软件,**下面所有示例以工作目录 `/root/projects/`演示**
`git clone https://github.com/PaddlePaddle/PaddleX.git` ```
git clone https://github.com/PaddlePaddle/PaddleX.git
```
**说明**:其中`C++`预测代码在`/root/projects/PaddleX/deploy/openvino` 目录,该目录不依赖任何`PaddleX`下其他目录。 **说明**:其中`C++`预测代码在`/root/projects/PaddleX/deploy/openvino` 目录,该目录不依赖任何`PaddleX`下其他目录。
...@@ -29,7 +58,7 @@ ...@@ -29,7 +58,7 @@
- ngraph: - ngraph:
说明:openvino编译的过程中会生成ngraph的lib文件,位于{openvino根目录}/bin/intel64/Release/lib/下。 说明:openvino编译的过程中会生成ngraph的lib文件,位于{openvino根目录}/bin/intel64/Release/lib/下。
### Step2: 编译demo ### Step2: 编译
编译`cmake`的命令在`scripts/build.sh`中,请根据Step1中编译软件的实际情况修改主要参数,其主要内容说明如下: 编译`cmake`的命令在`scripts/build.sh`中,请根据Step1中编译软件的实际情况修改主要参数,其主要内容说明如下:
...@@ -51,7 +80,7 @@ cmake .. \ ...@@ -51,7 +80,7 @@ cmake .. \
-DOPENCV_DIR=${OPENCV_DIR} \ -DOPENCV_DIR=${OPENCV_DIR} \
-DGFLAGS_DIR=${GFLAGS_DIR} \ -DGFLAGS_DIR=${GFLAGS_DIR} \
-DOPENVINO_DIR=${OPENVINO_DIR} \ -DOPENVINO_DIR=${OPENVINO_DIR} \
-DNGRAPH_LIB=${NGRAPH_LIB} -DNGRAPH_LIB=${NGRAPH_LIB}
make make
``` ```
...@@ -62,10 +91,17 @@ make ...@@ -62,10 +91,17 @@ make
### Step3: 模型转换 ### Step3: 模型转换
[]()生成的onnx文件转换为OpencVINO支持的格式,请参考:[Model Optimizer文档](https://docs.openvinotoolkit.org/latest/_docs_MO_DG_Deep_Learning_Model_Optimizer_DevGuide.html) 将PaddleX模型转换成ONNX模型:
```
paddlex --export_onnx --model_dir=/path/to/xiaoduxiong_epoch_12 --save_dir=/path/to/onnx_model
```
将生成的onnx模型转换为OpenVINO支持的格式,请参考:[Model Optimizer文档](https://docs.openvinotoolkit.org/latest/_docs_MO_DG_Deep_Learning_Model_Optimizer_DevGuide.html)
### Step4: 预测 ### Step4: 预测
编译成功后,预测demo的可执行程序分别为`build/classifer`,其主要命令参数说明如下:
编译成功后,分类任务的预测可执行程序为`classifier`,其主要命令参数说明如下:
| 参数 | 说明 | | 参数 | 说明 |
| ---- | ---- | | ---- | ---- |
...@@ -74,17 +110,14 @@ make ...@@ -74,17 +110,14 @@ make
| --image_list | 按行存储图片路径的.txt文件 | | --image_list | 按行存储图片路径的.txt文件 |
| --device | 运行的平台, 默认值为"CPU" | | --device | 运行的平台, 默认值为"CPU" |
#### 样例
## 样例
可使用[小度熊识别模型](deploy.md#导出inference模型)中导出的`inference_model`和测试图片进行预测。
`样例一` `样例一`
测试图片 `/path/to/xiaoduxiong.jpeg` 测试图片 `/path/to/xiaoduxiong.jpeg`
```shell ```shell
./build/classifier --model_dir=/path/to/inference_model --image=/path/to/xiaoduxiong.jpeg ./build/classifier --model_dir=/path/to/openvino_model --image=/path/to/xiaoduxiong.jpeg
``` ```
...@@ -97,7 +130,7 @@ make ...@@ -97,7 +130,7 @@ make
... ...
/path/to/images/xiaoduxiongn.jpeg /path/to/images/xiaoduxiongn.jpeg
``` ```
```shell ```shell
./build/classifier --model_dir=/path/to/models/inference_model --image_list=/root/projects/images_list.txt - ./build/classifier --model_dir=/path/to/models/openvino_model --image_list=/root/projects/images_list.txt
``` ```
# Linux平台编译指南 # Linux平台部署
## 说明 ## 说明
本文档在 `Linux`平台使用`GCC 4.8.5``GCC 4.9.4`测试过,如果需要使用更高G++版本编译使用,则需要重新编译Paddle预测库,请参考: [从源码编译Paddle预测库](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html#id12) 本文档在 `Linux`平台使用`GCC 4.8.5``GCC 4.9.4`测试过,如果需要使用更高G++版本编译使用,则需要重新编译Paddle预测库,请参考: [从源码编译Paddle预测库](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html#id12)
...@@ -103,6 +103,9 @@ make ...@@ -103,6 +103,9 @@ make
``` ```
### Step5: 预测及可视化 ### Step5: 预测及可视化
参考[导出inference模型](../deploy_python.html#inference)将模型导出为inference格式模型。
编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifer``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下: 编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifer``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下:
| 参数 | 说明 | | 参数 | 说明 |
...@@ -117,7 +120,7 @@ make ...@@ -117,7 +120,7 @@ make
## 样例 ## 样例
可使用[小度熊识别模型](deploy.md#导出inference模型)中导出的`inference_model`和测试图片进行预测。 可使用[小度熊识别模型](../deploy_python.html#inference)中导出的`inference_model`和测试图片进行预测。
`样例一` `样例一`
......
# Visual Studio 2019 Community CMake 编译指南 # Windows平台部署
## 说明 ## 说明
Windows 平台下,我们使用`Visual Studio 2019 Community` 进行了测试。微软从`Visual Studio 2017`开始即支持直接管理`CMake`跨平台编译项目,但是直到`2019`才提供了稳定和完全的支持,所以如果你想使用CMake管理项目编译构建,我们推荐你使用`Visual Studio 2019`环境下构建。 Windows 平台下,我们使用`Visual Studio 2019 Community` 进行了测试。微软从`Visual Studio 2017`开始即支持直接管理`CMake`跨平台编译项目,但是直到`2019`才提供了稳定和完全的支持,所以如果你想使用CMake管理项目编译构建,我们推荐你使用`Visual Studio 2019`环境下构建。
...@@ -62,19 +62,19 @@ PaddlePaddle C++ 预测库针对不同的`CPU`,`CUDA`,以及是否支持Tens ...@@ -62,19 +62,19 @@ PaddlePaddle C++ 预测库针对不同的`CPU`,`CUDA`,以及是否支持Tens
1. 打开Visual Studio 2019 Community,点击`继续但无需代码` 1. 打开Visual Studio 2019 Community,点击`继续但无需代码`
![step2](images/vs2019_step1.png) ![step2](../../images/vs2019_step1.png)
2. 点击: `文件`->`打开`->`CMake` 2. 点击: `文件`->`打开`->`CMake`
![step2.1](images/vs2019_step2.png) ![step2.1](../../images/vs2019_step2.png)
选择项目代码所在路径,并打开`CMakeList.txt`: 选择项目代码所在路径,并打开`CMakeList.txt`:
![step2.2](images/vs2019_step3.png) ![step2.2](../../images/vs2019_step3.png)
3. 点击:`项目`->`PADDLEX_INFERENCE的CMake设置` 3. 点击:`项目`->`PADDLEX_INFERENCE的CMake设置`
![step3](images/vs2019_step4.png) ![step3](../../images/vs2019_step4.png)
4. 点击`浏览`,分别设置编译选项指定`CUDA`、`OpenCV`、`Paddle预测库`的路径 4. 点击`浏览`,分别设置编译选项指定`CUDA`、`OpenCV`、`Paddle预测库`的路径
...@@ -88,17 +88,19 @@ PaddlePaddle C++ 预测库针对不同的`CPU`,`CUDA`,以及是否支持Tens ...@@ -88,17 +88,19 @@ PaddlePaddle C++ 预测库针对不同的`CPU`,`CUDA`,以及是否支持Tens
**注意:** 1. 使用`CPU`版预测库,请把`WITH_GPU`的``去掉勾 2. 如果使用的是`openblas`版本,请把`WITH_MKL`的``去掉勾 **注意:** 1. 使用`CPU`版预测库,请把`WITH_GPU`的``去掉勾 2. 如果使用的是`openblas`版本,请把`WITH_MKL`的``去掉勾
![step4](images/vs2019_step5.png) ![step4](../../images/vs2019_step5.png)
**设置完成后**, 点击上图中`保存并生成CMake缓存以加载变量`。 **设置完成后**, 点击上图中`保存并生成CMake缓存以加载变量`。
5. 点击`生成`->`全部生成` 5. 点击`生成`->`全部生成`
![step6](images/vs2019_step6.png) ![step6](../../images/vs2019_step6.png)
### Step5: 预测及可视化 ### Step5: 预测及可视化
参考[导出inference模型](../deploy_python.html#inference)将模型导出为inference格式模型。
上述`Visual Studio 2019`编译产出的可执行文件在`out\build\x64-Release`目录下,打开`cmd`,并切换到该目录: 上述`Visual Studio 2019`编译产出的可执行文件在`out\build\x64-Release`目录下,打开`cmd`,并切换到该目录:
``` ```
...@@ -106,7 +108,7 @@ d: ...@@ -106,7 +108,7 @@ d:
cd D:\projects\PaddleX\deploy\cpp\out\build\x64-Release cd D:\projects\PaddleX\deploy\cpp\out\build\x64-Release
``` ```
编译成功后,预测demo的入口程序为`demo\detector`,`demo\classifer`,`demo\segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下: 编译成功后,预测demo的入口程序为`paddlex_inference\detector.exe`,`paddlex_inference\classifer.exe`,`paddlex_inference\segmenter.exe`,用户可根据自己的模型类型选择,其主要命令参数说明如下:
| 参数 | 说明 | | 参数 | 说明 |
| ---- | ---- | | ---- | ---- |
...@@ -120,14 +122,14 @@ cd D:\projects\PaddleX\deploy\cpp\out\build\x64-Release ...@@ -120,14 +122,14 @@ cd D:\projects\PaddleX\deploy\cpp\out\build\x64-Release
## 样例 ## 样例
可使用[小度熊识别模型](deploy.md#导出inference模型)中导出的`inference_model`和测试图片进行预测。 可使用[小度熊识别模型](../deploy_python.html#inference)中导出的`inference_model`和测试图片进行预测。
`样例一`: `样例一`:
不使用`GPU`测试图片 `\\path\\to\\xiaoduxiong.jpeg` 不使用`GPU`测试图片 `\\path\\to\\xiaoduxiong.jpeg`
```shell ```shell
.\detector --model_dir=\\path\\to\\inference_model --image=D:\\images\\xiaoduxiong.jpeg --save_dir=output .\\paddlex_inference\\detector.exe --model_dir=\\path\\to\\inference_model --image=D:\\images\\xiaoduxiong.jpeg --save_dir=output
``` ```
图片文件`可视化预测结果`会保存在`save_dir`参数设置的目录下。 图片文件`可视化预测结果`会保存在`save_dir`参数设置的目录下。
...@@ -143,6 +145,6 @@ cd D:\projects\PaddleX\deploy\cpp\out\build\x64-Release ...@@ -143,6 +145,6 @@ cd D:\projects\PaddleX\deploy\cpp\out\build\x64-Release
\\path\\to\\images\\xiaoduxiongn.jpeg \\path\\to\\images\\xiaoduxiongn.jpeg
``` ```
```shell ```shell
.\detector --model_dir=\\path\\to\\inference_model --image_list=\\path\\to\\images_list.txt --use_gpu=1 --save_dir=output .\\paddlex_inference\\detector.exe --model_dir=\\path\\to\\inference_model --image_list=\\path\\to\\images_list.txt --use_gpu=1 --save_dir=output
``` ```
图片文件`可视化预测结果`会保存在`save_dir`参数设置的目录下。 图片文件`可视化预测结果`会保存在`save_dir`参数设置的目录下。
C++部署
==============
C++部署方案位于目录PaddleX/deploy/cpp/下,且独立于PaddleX其他模块。该方案支持在 Windows 和 Linux 完成编译、二次开发集成和部署运行,支持在Linux上完成加密部署。
.. toctree::
:maxdepth: 1
deploy_cpp_win_vs2019.md
deploy_cpp_linux.md
# 模型预测部署 # Python部署
PaddleX已经集成了基于Python的高性能预测接口,在安装PaddleX后,可参照如下代码示例,进行预测。相关的接口文档可参考[paddlex.deploy](../../../apis/deploy.md)
本文档指引用户如何采用更高性能地方式来部署使用PaddleX训练的模型。使用本文档模型部署方式,会在模型运算过程中,对模型计算图进行优化,同时减少内存操作,相对比普通的paddlepaddle模型加载和预测方式,预测速度平均可提升1倍,具体各模型性能对比见[预测性能对比](#预测性能对比) ## 导出inference模型
## 服务端部署
### 导出inference模型
在服务端部署的模型需要首先将模型导出为inference格式模型,导出的模型将包括`__model__``__params__``model.yml`三个文名,分别为模型的网络结构,模型权重和模型的配置文件(包括数据预处理参数等等)。在安装完PaddleX后,在命令行终端使用如下命令导出模型到当前目录`inferece_model`下。 在服务端部署的模型需要首先将模型导出为inference格式模型,导出的模型将包括`__model__``__params__``model.yml`三个文名,分别为模型的网络结构,模型权重和模型的配置文件(包括数据预处理参数等等)。在安装完PaddleX后,在命令行终端使用如下命令导出模型到当前目录`inferece_model`下。
> 可直接下载小度熊分拣模型测试本文档的流程[xiaoduxiong_epoch_12.tar.gz](https://bj.bcebos.com/paddlex/models/xiaoduxiong_epoch_12.tar.gz) > 可直接下载小度熊分拣模型测试本文档的流程[xiaoduxiong_epoch_12.tar.gz](https://bj.bcebos.com/paddlex/models/xiaoduxiong_epoch_12.tar.gz)
...@@ -22,59 +19,17 @@ paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./infer ...@@ -22,59 +19,17 @@ paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./infer
paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./inference_model --fixed_input_shape=[640,960] paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./inference_model --fixed_input_shape=[640,960]
``` ```
### Python部署 ## 预测部署
PaddleX已经集成了基于Python的高性能预测接口,在安装PaddleX后,可参照如下代码示例,进行预测。相关的接口文档可参考[paddlex.deploy](apis/deploy.md)
> 点击下载测试图片 [xiaoduxiong_test_image.tar.gz](https://bj.bcebos.com/paddlex/datasets/xiaoduxiong_test_image.tar.gz) > 点击下载测试图片 [xiaoduxiong_test_image.tar.gz](https://bj.bcebos.com/paddlex/datasets/xiaoduxiong_test_image.tar.gz)
``` ```
import paddlex as pdx import paddlex as pdx
predictor = pdx.deploy.create_predictor('./inference_model') predictor = pdx.deploy.Predictor('./inference_model')
result = predictor.predict(image='xiaoduxiong_test_image/JPEGImages/WeChatIMG110.jpeg') result = predictor.predict(image='xiaoduxiong_test_image/JPEGImages/WeChatIMG110.jpeg')
``` ```
### C++部署 ## 预测性能对比
### 测试环境
C++部署方案位于目录`deploy/cpp/`下,且独立于PaddleX其他模块。该方案支持在 Windows 和 Linux 完成编译、二次开发集成和部署运行。具体使用方法和编译:
- Linux平台:[linux](deploy_cpp_linux.md)
- window平台:[windows](deploy_cpp_win_vs2019.md)
### OpenVINO部署demo
OpenVINO部署demo位于目录`deploy/openvino/`下,且独立于PaddleX其他模块,该demo目前支持在 Linux 完成编译和部署运行。目前PaddleX到OpenVINO的部署流程如下:
graph LR
PaddleX --> ONNX --> OpenVINO IR --> OpenVINO Inference Engine
#### step1
PaddleX输出ONNX模型方法如下:
```
paddlex --export_onnx --model_dir=./xiaoduxiong_epoch_12 --save_dir=./onnx_model
```
|目前支持的模型|
|-----|
|ResNet18|
|ResNet34|
|ResNet50|
|ResNet101|
|ResNet50_vd|
|ResNet101_vd|
|ResNet50_vd_ssld|
|ResNet101_vd_ssld
|DarkNet53|
|MobileNetV1|
|MobileNetV2|
|DenseNet121|
|DenseNet161|
|DenseNet201|
得到ONNX模型后,OpenVINO的部署参考:[OpenVINO部署](deploy_openvino.md)
### 预测性能对比
#### 测试环境
- CUDA 9.0 - CUDA 9.0
- CUDNN 7.5 - CUDNN 7.5
...@@ -84,6 +39,9 @@ paddlex --export_onnx --model_dir=./xiaoduxiong_epoch_12 --save_dir=./onnx_model ...@@ -84,6 +39,9 @@ paddlex --export_onnx --model_dir=./xiaoduxiong_epoch_12 --save_dir=./onnx_model
- Executor 指采用paddlepaddle普通的python预测方式 - Executor 指采用paddlepaddle普通的python预测方式
- Batch Size均为1,耗时单位为ms/image,只计算模型运行时间,不包括数据的预处理和后处理 - Batch Size均为1,耗时单位为ms/image,只计算模型运行时间,不包括数据的预处理和后处理
### 性能对比
| 模型 | AnalysisPredictor耗时 | Executor耗时 | 输入图像大小 | | 模型 | AnalysisPredictor耗时 | Executor耗时 | 输入图像大小 |
| :---- | :--------------------- | :------------ | :------------ | | :---- | :--------------------- | :------------ | :------------ |
| resnet50 | 4.84 | 7.57 | 224*224 | | resnet50 | 4.84 | 7.57 | 224*224 |
...@@ -95,7 +53,3 @@ paddlex --export_onnx --model_dir=./xiaoduxiong_epoch_12 --save_dir=./onnx_model ...@@ -95,7 +53,3 @@ paddlex --export_onnx --model_dir=./xiaoduxiong_epoch_12 --save_dir=./onnx_model
| faster_rcnn_r50_1x | 326.11 | 347.22 | 800*1067 | | faster_rcnn_r50_1x | 326.11 | 347.22 | 800*1067 |
| mask_rcnn_r50_fpn_1x | 67.49 | 91.02 | 800*1088 | | mask_rcnn_r50_fpn_1x | 67.49 | 91.02 | 800*1088 |
| mask_rcnn_r50_1x | 326.11 | 350.94 | 800*1067 | | mask_rcnn_r50_1x | 326.11 | 350.94 | 800*1067 |
## 移动端部署
> Lite模型导出正在集成中,即将开源...
# Paddle模型加密方案 # 模型加密部署
飞桨团队推出模型加密方案,使用业内主流的AES加密技术对最终模型进行加密。飞桨用户可以通过PaddleX导出模型后,使用该方案对模型进行加密,预测时使用解密SDK进行模型解密并完成推理,大大提升AI应用安全性和开发效率 PaddleX提供一个轻量级的模型加密部署方案,通过PaddleX内置的模型加密工具对推理模型进行加密,预测部署SDK支持直接加载密文模型并完成推理,提升AI模型部署的安全性
**注意:目前加密方案仅支持Linux系统** **注意:目前加密方案仅支持Linux系统**
## 1. 方案简介 ## 1. 方案简介
### 1.1 加密工具 ### 1.1 简介
(1)加密算法的选择和支持的库
一般使用OpenSSL库来支持数据的加解密,OpenSSL提供了大量的加解密算法,包括对称加密算法(AES等)和非对称加密算法(RSA等)。
两种算法使用的场景不同,非对称加密算法一般应用于数字签名和密钥协商的场景下,而对称加密算法一般应用于纯数据加密场景,性能更优。在对模型的加密过程中使用对称加密算法。
以下对模型加密场景实现的说明中以开发一个C/C++库为基础,采用AES对称加密算法,为了加解密前后能够快速判断解密是否成功,使用AES-GCM加解密模式,在密钥的安全性上使用长度为256位的密钥数据。
(2)实现模型保护的一般步骤:
![](../images/encryption_process.png)
下面是对提供的C/C++加解密库内部实现的中文描述,参考以下步骤可以实现 一套加解密库 来适应自己的场景并通过内存数据load到paddlepaddle中(c/c++预测服务)
> 1)考虑到加密的模型文件解密后需要从内存加载数据,使用conbine的模式生成模型文件和参数文件。
>
> 2)项目集成OpenSSL,使用静态库的形式。
>
> 3)实现AES算法接口,借助OpenSSL提供的EVP接口,在EVP接口中指定算法类型,算法使用对称加解密算法中的AES,加解密模式使用AES-GCM, 密钥长度为256位,AES-GCM的实现可以参考官方提供的例子自己进行封装接口:https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption。
>
> 4)利用OpenSSL库实现SHA256摘要算法,这部分下面有用(可选)。关于SHA256的hash计算可以参考OpenSSL提供的example:https://wiki.openssl.org/index.php/EVP_Message_Digests
>
> 5)在模型加密环节直接对model文件和params文件的数据内容进行加密后保存到新的文件,为了新的文件能够被区分和可迭代,除了加密后的数据外还添加了头部信息,比如为了判断该文件类型使用固定的魔数作为文件的开头;为了便于后面需求迭代写入版本号以示区别;为了能够在解密时判断是否采用了相同的密钥将加密时的密钥进行SHA256计算后存储;这三部分构成了目前加密后文件的头部信息。加密后的文件包含头部信息 + 密文信息。
>
> 6)在模型解密环节根据加密后的文件读取相关的加密数据到内存中,对内存数据使用AES算法进行解密,注意解密时需要采用与加密时一致的加密算法和加密的模式,以及密钥的数据和长度,否则会导致解密后数据错误。
>
> 7)集成模型预测的C/C++库,在具体使用paddlepaddle预测时一般涉及paddle::AnalysisConfig和paddle:Predictor,为了能够从内存数据中直接load解密后的模型明文数据(避免模型解密后创建临时文件),这里需要将AnalysisConfig的模型加载函数从SetModel替换为SetModelBuffer来实现从内存中加载模型数据。
需要注意的是,在本方案中,密钥集成在上层预测服务的代码中。故模型的安全强度等同于代码抵御逆向调试的强度。为了保护密钥和模型的安全,开发者还需对自己的应用进行加固保护。常见的应用加固手段有:代码混淆,二进制文件加壳 等等,亦或将加密机制更改为AES白盒加密技术来保护密钥。这类技术领域内有大量商业和开源产品可供选择,此处不一一赘述。
### 1.2 加密工具
[PaddleX模型加密工具](https://bj.bcebos.com/paddlex/tools/paddlex-encryption.zip)。在编译部署代码时,编译脚本会自动下载加密工具,您也可以选择手动下载。 [PaddleX模型加密工具](https://bj.bcebos.com/paddlex/tools/paddlex-encryption.zip)。在编译部署代码时,编译脚本会自动下载加密工具,您也可以选择手动下载。
...@@ -20,7 +52,7 @@ paddlex-encryption ...@@ -20,7 +52,7 @@ paddlex-encryption
└── tool # paddlex_encrypt_tool └── tool # paddlex_encrypt_tool
``` ```
### 1.2 加密PaddleX模型 ### 1.3 加密PaddleX模型
对模型完成加密后,加密工具会产生随机密钥信息(用于AES加解密使用),需要在后续加密部署时传入该密钥来用于解密。 对模型完成加密后,加密工具会产生随机密钥信息(用于AES加解密使用),需要在后续加密部署时传入该密钥来用于解密。
> 密钥由32字节key + 16字节iv组成, 注意这里产生的key是经过base64编码后的,这样可以扩充key的选取范围 > 密钥由32字节key + 16字节iv组成, 注意这里产生的key是经过base64编码后的,这样可以扩充key的选取范围
...@@ -29,12 +61,13 @@ paddlex-encryption ...@@ -29,12 +61,13 @@ paddlex-encryption
./paddlex-encryption/tool/paddlex_encrypt_tool -model_dir /path/to/paddlex_inference_model -save_dir /path/to/paddlex_encrypted_model ./paddlex-encryption/tool/paddlex_encrypt_tool -model_dir /path/to/paddlex_inference_model -save_dir /path/to/paddlex_encrypted_model
``` ```
`-model_dir`用于指定inference模型路径,可使用[导出小度熊识别模型](deploy.md#导出inference模型)中导出的`inference_model`。加密完成后,加密过的模型会保存至指定的`-save_dir`下,包含`__model__.encrypted``__params__.encrypted``model.yml`三个文件,同时生成密钥信息,命令输出如下图所示,密钥为`kLAl1qOs5uRbFt0/RrIDTZW2+tOf5bzvUIaHGF8lJ1c=` `-model_dir`用于指定inference模型路径(参考[导出inference模型](deploy_python.html#inference)将模型导出为inference格式模型),可使用[导出小度熊识别模型](deploy_python.html#inference)中导出的`inference_model`。加密完成后,加密过的模型会保存至指定的`-save_dir`下,包含`__model__.encrypted``__params__.encrypted``model.yml`三个文件,同时生成密钥信息,命令输出如下图所示,密钥为`kLAl1qOs5uRbFt0/RrIDTZW2+tOf5bzvUIaHGF8lJ1c=`
![](images/encryt.png)
![](../images/encrypt.png)
## 2. PaddleX C++加密部署 ## 2. PaddleX C++加密部署
参考[Linux平台编译指南](deploy_cpp_linux.md)编译C++部署代码。编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifer``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下: 参考[Linux平台编译指南](deploy_cpp/deploy_cpp_linux.html#linux)编译C++部署代码。编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifer``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下:
| 参数 | 说明 | | 参数 | 说明 |
| ---- | ---- | | ---- | ---- |
...@@ -44,13 +77,13 @@ paddlex-encryption ...@@ -44,13 +77,13 @@ paddlex-encryption
| use_gpu | 是否使用 GPU 预测, 支持值为0或1(默认值为0) | | use_gpu | 是否使用 GPU 预测, 支持值为0或1(默认值为0) |
| use_trt | 是否使用 TensorTr 预测, 支持值为0或1(默认值为0) | | use_trt | 是否使用 TensorTr 预测, 支持值为0或1(默认值为0) |
| gpu_id | GPU 设备ID, 默认值为0 | | gpu_id | GPU 设备ID, 默认值为0 |
| save_dir | 保存可视化结果的路径, 默认值为"output",classfier无该参数 | | save_dir | 保存可视化结果的路径, 默认值为"output",classifier无该参数 |
| key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 | | key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 |
## 样例 ## 样例
可使用[导出小度熊识别模型](deploy.md#导出inference模型)中的测试图片进行预测。 可使用[导出小度熊识别模型](deploy_python.html#inference)中的测试图片进行预测。
`样例一` `样例一`
......
服务端部署
==============
.. toctree::
:maxdepth: 2
deploy_python.md
deploy_cpp/index.rst
encryption.md
docs/tutorials/deploy/images/vs2019_step4.png

396.6 KB | W: | H:

docs/tutorials/deploy/images/vs2019_step4.png

77.3 KB | W: | H:

docs/tutorials/deploy/images/vs2019_step4.png
docs/tutorials/deploy/images/vs2019_step4.png
docs/tutorials/deploy/images/vs2019_step4.png
docs/tutorials/deploy/images/vs2019_step4.png
  • 2-up
  • Swipe
  • Onion skin
多端部署 多端安全部署
============== ==============
本文档指引用户如何采用更高性能地方式来部署使用PaddleX训练的模型。本文档模型部署采用Paddle Inference高性能部署方式,在模型运算过程中,对模型计算图进行优化,同时减少内存操作,具体各模型性能对比见服务端Python部署的预测性能对比章节。
同时结合产业实践开发者对模型知识产权的保护需求,提供了轻量级模型加密部署的方案,提升深度学习模型部署的安全性。
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: 文档目录:
deploy_server/index.rst
deploy_openvino.md
deploy_lite.md
...@@ -53,4 +53,4 @@ log_level = 2 ...@@ -53,4 +53,4 @@ log_level = 2
from . import interpret from . import interpret
__version__ = '0.2.0.github' __version__ = '1.0.1.github'
# copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
......
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from six import text_type as _text_type from six import text_type as _text_type
import argparse import argparse
import sys import sys
......
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
# #
#Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
#You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
#Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#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.
from __future__ import absolute_import from __future__ import absolute_import
import paddle.fluid as fluid import paddle.fluid as fluid
......
import paddlex import paddlex
#import paddlehub as hub import paddlehub as hub
import os import os
import os.path as osp import os.path as osp
...@@ -85,53 +85,49 @@ def get_pretrain_weights(flag, model_type, backbone, save_dir): ...@@ -85,53 +85,49 @@ def get_pretrain_weights(flag, model_type, backbone, save_dir):
backbone = 'DetResNet50' backbone = 'DetResNet50'
assert backbone in image_pretrain, "There is not ImageNet pretrain weights for {}, you may try COCO.".format( assert backbone in image_pretrain, "There is not ImageNet pretrain weights for {}, you may try COCO.".format(
backbone) backbone)
url = image_pretrain[backbone] # url = image_pretrain[backbone]
fname = osp.split(url)[-1].split('.')[0] # fname = osp.split(url)[-1].split('.')[0]
paddlex.utils.download_and_decompress(url, path=new_save_dir) # paddlex.utils.download_and_decompress(url, path=new_save_dir)
return osp.join(new_save_dir, fname) # return osp.join(new_save_dir, fname)
# try: try:
# hub.download(backbone, save_path=new_save_dir) hub.download(backbone, save_path=new_save_dir)
# except Exception as e: except Exception as e:
# if isinstance(e, hub.ResourceNotFoundError): if isinstance(e, hub.ResourceNotFoundError):
# raise Exception( raise Exception("Resource for backbone {} not found".format(
# "Resource for backbone {} not found".format(backbone)) backbone))
# elif isinstance(e, hub.ServerConnectionError): elif isinstance(e, hub.ServerConnectionError):
# raise Exception( raise Exception(
# "Cannot get reource for backbone {}, please check your internet connecgtion" "Cannot get reource for backbone {}, please check your internet connecgtion"
# .format(backbone)) .format(backbone))
# else: else:
# raise Exception( raise Exception(
# "Unexpected error, please make sure paddlehub >= 1.6.2") "Unexpected error, please make sure paddlehub >= 1.6.2")
# return osp.join(new_save_dir, backbone) return osp.join(new_save_dir, backbone)
elif flag == 'COCO': elif flag == 'COCO':
new_save_dir = save_dir new_save_dir = save_dir
if hasattr(paddlex, 'pretrain_dir'): if hasattr(paddlex, 'pretrain_dir'):
new_save_dir = paddlex.pretrain_dir new_save_dir = paddlex.pretrain_dir
url = coco_pretrain[backbone] url = coco_pretrain[backbone]
fname = osp.split(url)[-1].split('.')[0] fname = osp.split(url)[-1].split('.')[0]
paddlex.utils.download_and_decompress(url, path=new_save_dir) # paddlex.utils.download_and_decompress(url, path=new_save_dir)
return osp.join(new_save_dir, fname) # return osp.join(new_save_dir, fname)
# new_save_dir = save_dir assert backbone in coco_pretrain, "There is not COCO pretrain weights for {}, you may try ImageNet.".format(
# if hasattr(paddlex, 'pretrain_dir'): backbone)
# new_save_dir = paddlex.pretrain_dir try:
# assert backbone in coco_pretrain, "There is not COCO pretrain weights for {}, you may try ImageNet.".format( hub.download(backbone, save_path=new_save_dir)
# backbone) except Exception as e:
# try: if isinstance(hub.ResourceNotFoundError):
# hub.download(backbone, save_path=new_save_dir) raise Exception("Resource for backbone {} not found".format(
# except Exception as e: backbone))
# if isinstance(hub.ResourceNotFoundError): elif isinstance(hub.ServerConnectionError):
# raise Exception( raise Exception(
# "Resource for backbone {} not found".format(backbone)) "Cannot get reource for backbone {}, please check your internet connecgtion"
# elif isinstance(hub.ServerConnectionError): .format(backbone))
# raise Exception( else:
# "Cannot get reource for backbone {}, please check your internet connecgtion" raise Exception(
# .format(backbone)) "Unexpected error, please make sure paddlehub >= 1.6.2")
# else: return osp.join(new_save_dir, backbone)
# raise Exception(
# "Unexpected error, please make sure paddlehub >= 1.6.2")
# return osp.join(new_save_dir, backbone)
else: else:
raise Exception( raise Exception(
"pretrain_weights need to be defined as directory path or `IMAGENET` or 'COCO' (download pretrain weights automatically)." "pretrain_weights need to be defined as directory path or `IMAGENET` or 'COCO' (download pretrain weights automatically)."
......
...@@ -15,4 +15,5 @@ ...@@ -15,4 +15,5 @@
from __future__ import absolute_import from __future__ import absolute_import
from . import visualize from . import visualize
visualize = visualize.visualize lime = visualize.lime
\ No newline at end of file normlime = visualize.normlime
\ No newline at end of file
...@@ -242,7 +242,13 @@ class NormLIME(object): ...@@ -242,7 +242,13 @@ class NormLIME(object):
self.label_names = label_names self.label_names = label_names
def predict_cluster_labels(self, feature_map, segments): def predict_cluster_labels(self, feature_map, segments):
return self.kmeans_model.predict(get_feature_for_kmeans(feature_map, segments)) X = get_feature_for_kmeans(feature_map, segments)
try:
cluster_labels = self.kmeans_model.predict(X)
except AttributeError:
from sklearn.metrics import pairwise_distances_argmin_min
cluster_labels, _ = pairwise_distances_argmin_min(X, self.kmeans_model.cluster_centers_)
return cluster_labels
def predict_using_normlime_weights(self, pred_labels, predicted_cluster_labels): def predict_using_normlime_weights(self, pred_labels, predicted_cluster_labels):
# global weights # global weights
......
...@@ -30,17 +30,10 @@ The code in this file (lime_base.py) is modified from https://github.com/marcotc ...@@ -30,17 +30,10 @@ The code in this file (lime_base.py) is modified from https://github.com/marcotc
import numpy as np import numpy as np
import scipy as sp import scipy as sp
import sklearn
import sklearn.preprocessing
from skimage.color import gray2rgb
from sklearn.linear_model import Ridge, lars_path
from sklearn.utils import check_random_state
import tqdm import tqdm
import copy import copy
from functools import partial from functools import partial
from skimage.segmentation import quickshift
from skimage.measure import regionprops
class LimeBase(object): class LimeBase(object):
...@@ -59,6 +52,7 @@ class LimeBase(object): ...@@ -59,6 +52,7 @@ class LimeBase(object):
generate random numbers. If None, the random state will be generate random numbers. If None, the random state will be
initialized using the internal numpy seed. initialized using the internal numpy seed.
""" """
from sklearn.utils import check_random_state
self.kernel_fn = kernel_fn self.kernel_fn = kernel_fn
self.verbose = verbose self.verbose = verbose
self.random_state = check_random_state(random_state) self.random_state = check_random_state(random_state)
...@@ -75,6 +69,7 @@ class LimeBase(object): ...@@ -75,6 +69,7 @@ class LimeBase(object):
(alphas, coefs), both are arrays corresponding to the (alphas, coefs), both are arrays corresponding to the
regularization parameter and coefficients, respectively regularization parameter and coefficients, respectively
""" """
from sklearn.linear_model import lars_path
x_vector = weighted_data x_vector = weighted_data
alphas, _, coefs = lars_path(x_vector, alphas, _, coefs = lars_path(x_vector,
weighted_labels, weighted_labels,
...@@ -106,6 +101,7 @@ class LimeBase(object): ...@@ -106,6 +101,7 @@ class LimeBase(object):
def feature_selection(self, data, labels, weights, num_features, method): def feature_selection(self, data, labels, weights, num_features, method):
"""Selects features for the model. see interpret_instance_with_data to """Selects features for the model. see interpret_instance_with_data to
understand the parameters.""" understand the parameters."""
from sklearn.linear_model import Ridge
if method == 'none': if method == 'none':
return np.array(range(data.shape[1])) return np.array(range(data.shape[1]))
elif method == 'forward_selection': elif method == 'forward_selection':
...@@ -213,7 +209,7 @@ class LimeBase(object): ...@@ -213,7 +209,7 @@ class LimeBase(object):
score is the R^2 value of the returned interpretation score is the R^2 value of the returned interpretation
local_pred is the prediction of the interpretation model on the original instance local_pred is the prediction of the interpretation model on the original instance
""" """
from sklearn.linear_model import Ridge
weights = self.kernel_fn(distances) weights = self.kernel_fn(distances)
labels_column = neighborhood_labels[:, label] labels_column = neighborhood_labels[:, label]
used_features = self.feature_selection(neighborhood_data, used_features = self.feature_selection(neighborhood_data,
...@@ -376,6 +372,7 @@ class LimeImageInterpreter(object): ...@@ -376,6 +372,7 @@ class LimeImageInterpreter(object):
generate random numbers. If None, the random state will be generate random numbers. If None, the random state will be
initialized using the internal numpy seed. initialized using the internal numpy seed.
""" """
from sklearn.utils import check_random_state
kernel_width = float(kernel_width) kernel_width = float(kernel_width)
if kernel is None: if kernel is None:
...@@ -422,6 +419,10 @@ class LimeImageInterpreter(object): ...@@ -422,6 +419,10 @@ class LimeImageInterpreter(object):
An ImageIinterpretation object (see lime_image.py) with the corresponding An ImageIinterpretation object (see lime_image.py) with the corresponding
interpretations. interpretations.
""" """
import sklearn
from skimage.measure import regionprops
from skimage.segmentation import quickshift
from skimage.color import gray2rgb
if len(image.shape) == 2: if len(image.shape) == 2:
image = gray2rgb(image) image = gray2rgb(image)
......
...@@ -17,6 +17,7 @@ import numpy as np ...@@ -17,6 +17,7 @@ import numpy as np
import glob import glob
from paddlex.interpret.as_data_reader.readers import read_image from paddlex.interpret.as_data_reader.readers import read_image
import paddlex.utils.logging as logging
from . import lime_base from . import lime_base
from ._session_preparation import compute_features_for_kmeans, h_pre_models_kmeans from ._session_preparation import compute_features_for_kmeans, h_pre_models_kmeans
...@@ -113,11 +114,10 @@ def precompute_lime_weights(list_data_, predict_fn, num_samples, batch_size, sav ...@@ -113,11 +114,10 @@ def precompute_lime_weights(list_data_, predict_fn, num_samples, batch_size, sav
save_path = os.path.join(save_dir, save_path) save_path = os.path.join(save_dir, save_path)
if os.path.exists(save_path): if os.path.exists(save_path):
print(f'{save_path} exists, not computing this one.') logging.info(save_path + ' exists, not computing this one.', use_color=True)
continue continue
img_file_name = each_data_ if isinstance(each_data_, str) else data_index
print('processing', each_data_ if isinstance(each_data_, str) else data_index, logging.info('processing '+ img_file_name + ' [{}/{}]'.format(data_index, len(list_data_)), use_color=True)
f', {data_index}/{len(list_data_)}')
image_show = read_image(each_data_) image_show = read_image(each_data_)
result = predict_fn(image_show) result = predict_fn(image_show)
...@@ -149,9 +149,12 @@ def precompute_lime_weights(list_data_, predict_fn, num_samples, batch_size, sav ...@@ -149,9 +149,12 @@ def precompute_lime_weights(list_data_, predict_fn, num_samples, batch_size, sav
interpreter = algo.interpret_instance(image_show[0], predict_fn, pred_label, 0, interpreter = algo.interpret_instance(image_show[0], predict_fn, pred_label, 0,
num_samples=num_samples, batch_size=batch_size) num_samples=num_samples, batch_size=batch_size)
cluster_labels = kmeans_model.predict( X = get_feature_for_kmeans(compute_features_for_kmeans(image_show).transpose((1, 2, 0)), interpreter.segments)
get_feature_for_kmeans(compute_features_for_kmeans(image_show).transpose((1, 2, 0)), interpreter.segments) try:
) cluster_labels = kmeans_model.predict(X)
except AttributeError:
from sklearn.metrics import pairwise_distances_argmin_min
cluster_labels, _ = pairwise_distances_argmin_min(X, kmeans_model.cluster_centers_)
save_one_lime_predict_and_kmean_labels( save_one_lime_predict_and_kmean_labels(
interpreter.local_weights, pred_label, interpreter.local_weights, pred_label,
cluster_labels, cluster_labels,
......
...@@ -22,20 +22,65 @@ from .interpretation_predict import interpretation_predict ...@@ -22,20 +22,65 @@ from .interpretation_predict import interpretation_predict
from .core.interpretation import Interpretation from .core.interpretation import Interpretation
from .core.normlime_base import precompute_normlime_weights from .core.normlime_base import precompute_normlime_weights
from .core._session_preparation import gen_user_home from .core._session_preparation import gen_user_home
def visualize(img_file, def lime(img_file,
model,
num_samples=3000,
batch_size=50,
save_dir='./'):
"""使用LIME算法将模型预测结果的可解释性可视化。
LIME表示与模型无关的局部可解释性,可以解释任何模型。LIME的思想是以输入样本为中心,
在其附近的空间中进行随机采样,每个采样通过原模型得到新的输出,这样得到一系列的输入
和对应的输出,LIME用一个简单的、可解释的模型(比如线性回归模型)来拟合这个映射关系,
得到每个输入维度的权重,以此来解释模型。
注意:LIME可解释性结果可视化目前只支持分类模型。
Args:
img_file (str): 预测图像路径。
model (paddlex.cv.models): paddlex中的模型。
num_samples (int): LIME用于学习线性模型的采样数,默认为3000。
batch_size (int): 预测数据batch大小,默认为50。
save_dir (str): 可解释性可视化结果(保存为png格式文件)和中间文件存储路径。
"""
assert model.model_type == 'classifier', \
'Now the interpretation visualize only be supported in classifier!'
if model.status != 'Normal':
raise Exception('The interpretation only can deal with the Normal model')
if not osp.exists(save_dir):
os.makedirs(save_dir)
model.arrange_transforms(
transforms=model.test_transforms, mode='test')
tmp_transforms = copy.deepcopy(model.test_transforms)
tmp_transforms.transforms = tmp_transforms.transforms[:-2]
img = tmp_transforms(img_file)[0]
img = np.around(img).astype('uint8')
img = np.expand_dims(img, axis=0)
interpreter = None
interpreter = get_lime_interpreter(img, model, num_samples=num_samples, batch_size=batch_size)
img_name = osp.splitext(osp.split(img_file)[-1])[0]
interpreter.interpret(img, save_dir=save_dir)
def normlime(img_file,
model, model,
dataset=None, dataset=None,
algo='lime',
num_samples=3000, num_samples=3000,
batch_size=50, batch_size=50,
save_dir='./'): save_dir='./'):
"""可解释性可视化。 """使用NormLIME算法将模型预测结果的可解释性可视化。
NormLIME是利用一定数量的样本来出一个全局的解释。NormLIME会提前计算一定数量的测
试样本的LIME结果,然后对相同的特征进行权重的归一化,这样来得到一个全局的输入和输出的关系。
注意1:dataset读取的是一个数据集,该数据集不宜过大,否则计算时间会较长,但应包含所有类别的数据。
注意2:NormLIME可解释性结果可视化目前只支持分类模型。
Args: Args:
img_file (str): 预测图像路径。 img_file (str): 预测图像路径。
model (paddlex.cv.models): paddlex中的模型。 model (paddlex.cv.models): paddlex中的模型。
dataset (paddlex.datasets): 数据集读取器,默认为None。 dataset (paddlex.datasets): 数据集读取器,默认为None。
algo (str): 可解释性方式,当前可选'lime'和'normlime'。
num_samples (int): LIME用于学习线性模型的采样数,默认为3000。 num_samples (int): LIME用于学习线性模型的采样数,默认为3000。
batch_size (int): 预测数据batch大小,默认为50。 batch_size (int): 预测数据batch大小,默认为50。
save_dir (str): 可解释性可视化结果(保存为png格式文件)和中间文件存储路径。 save_dir (str): 可解释性可视化结果(保存为png格式文件)和中间文件存储路径。
...@@ -54,21 +99,16 @@ def visualize(img_file, ...@@ -54,21 +99,16 @@ def visualize(img_file,
img = np.around(img).astype('uint8') img = np.around(img).astype('uint8')
img = np.expand_dims(img, axis=0) img = np.expand_dims(img, axis=0)
interpreter = None interpreter = None
if algo == 'lime': if dataset is None:
interpreter = get_lime_interpreter(img, model, dataset, num_samples=num_samples, batch_size=batch_size) raise Exception('The dataset is None. Cannot implement this kind of interpretation')
elif algo == 'normlime': interpreter = get_normlime_interpreter(img, model, dataset,
if dataset is None: num_samples=num_samples, batch_size=batch_size,
raise Exception('The dataset is None. Cannot implement this kind of interpretation')
interpreter = get_normlime_interpreter(img, model, dataset,
num_samples=num_samples, batch_size=batch_size,
save_dir=save_dir) save_dir=save_dir)
else:
raise Exception('The {} interpretation method is not supported yet!'.format(algo))
img_name = osp.splitext(osp.split(img_file)[-1])[0] img_name = osp.splitext(osp.split(img_file)[-1])[0]
interpreter.interpret(img, save_dir=save_dir) interpreter.interpret(img, save_dir=save_dir)
def get_lime_interpreter(img, model, dataset, num_samples=3000, batch_size=50): def get_lime_interpreter(img, model, num_samples=3000, batch_size=50):
def predict_func(image): def predict_func(image):
image = image.astype('float32') image = image.astype('float32')
for i in range(image.shape[0]): for i in range(image.shape[0]):
...@@ -79,8 +119,8 @@ def get_lime_interpreter(img, model, dataset, num_samples=3000, batch_size=50): ...@@ -79,8 +119,8 @@ def get_lime_interpreter(img, model, dataset, num_samples=3000, batch_size=50):
model.test_transforms.transforms = tmp_transforms model.test_transforms.transforms = tmp_transforms
return out[0] return out[0]
labels_name = None labels_name = None
if dataset is not None: if hasattr(model, 'labels'):
labels_name = dataset.labels labels_name = model.labels
interpreter = Interpretation('lime', interpreter = Interpretation('lime',
predict_func, predict_func,
labels_name, labels_name,
......
...@@ -19,7 +19,7 @@ long_description = "PaddleX. A end-to-end deeplearning model development toolkit ...@@ -19,7 +19,7 @@ long_description = "PaddleX. A end-to-end deeplearning model development toolkit
setuptools.setup( setuptools.setup(
name="paddlex", name="paddlex",
version='0.2.0', version='1.0.1',
author="paddlex", author="paddlex",
author_email="paddlex@baidu.com", author_email="paddlex@baidu.com",
description=long_description, description=long_description,
...@@ -30,7 +30,7 @@ setuptools.setup( ...@@ -30,7 +30,7 @@ setuptools.setup(
setup_requires=['cython', 'numpy'], setup_requires=['cython', 'numpy'],
install_requires=[ install_requires=[
"pycocotools;platform_system!='Windows'", 'pyyaml', 'colorama', 'tqdm', "pycocotools;platform_system!='Windows'", 'pyyaml', 'colorama', 'tqdm',
'paddleslim==1.0.1', 'visualdl>=2.0.0a2' 'paddleslim==1.0.1', 'visualdl>=2.0.0b', 'paddlehub>=1.6.2'
], ],
classifiers=[ classifiers=[
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
......
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
# #
#Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
#You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
#Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#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 argparse import argparse
import os import os
......
#copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
# #
#Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
#You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
#Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#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 argparse import argparse
import os import os
......
import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import os.path as osp
import paddlex as pdx
# 下载和解压Imagenet果蔬分类数据集
veg_dataset = 'https://bj.bcebos.com/paddlex/interpret/mini_imagenet_veg.tar.gz'
pdx.utils.download_and_decompress(veg_dataset, path='./')
# 下载和解压已训练好的MobileNetV2模型
model_file = 'https://bj.bcebos.com/paddlex/interpret/mini_imagenet_veg_mobilenetv2.tar.gz'
pdx.utils.download_and_decompress(model_file, path='./')
# 加载模型
model = pdx.load_model('mini_imagenet_veg_mobilenetv2')
# 可解释性可视化
pdx.interpret.lime(
'mini_imagenet_veg/mushroom/n07734744_1106.JPEG',
model,
save_dir='./')
...@@ -24,15 +24,8 @@ test_dataset = pdx.datasets.ImageNet( ...@@ -24,15 +24,8 @@ test_dataset = pdx.datasets.ImageNet(
transforms=model.test_transforms) transforms=model.test_transforms)
# 可解释性可视化 # 可解释性可视化
pdx.interpret.visualize( pdx.interpret.normlime(
'mini_imagenet_veg/mushroom/n07734744_1106.JPEG',
model,
test_dataset,
algo='lime',
save_dir='./')
pdx.interpret.visualize(
'mini_imagenet_veg/mushroom/n07734744_1106.JPEG', 'mini_imagenet_veg/mushroom/n07734744_1106.JPEG',
model, model,
test_dataset, test_dataset,
algo='normlime',
save_dir='./') save_dir='./')
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册