提交 0433f1d2 编写于 作者: F FlyingQianMM

Merge branch 'develop' of https://github.com/PaddlePaddle/PaddleX into develop_qh

# download pre-compiled opencv lib
OPENCV_URL=https://bj.bcebos.com/paddlex/deploy/tools/opencv3_aarch.tgz
if [ ! -d "./deps/opencv3" ]; then
mkdir -p deps
cd deps
wget -c ${OPENCV_URL}
tar xvfj opencv3_aarch.tgz
rm -rf opencv3_aarch.tgz
cd ..
fi
# 是否使用GPU(即是否使用 CUDA)
WITH_GPU=OFF
# 使用MKL or openblas
WITH_MKL=OFF
# 是否集成 TensorRT(仅WITH_GPU=ON 有效)
WITH_TENSORRT=OFF
# TensorRT 的路径,如果需要集成TensorRT,需修改为您实际安装的TensorRT路径
TENSORRT_DIR=/root/projects/TensorRT/
# Paddle 预测库路径, 请修改为您实际安装的预测库路径
PADDLE_DIR=/root/projects/fluid_inference
# Paddle 的预测库是否使用静态库来编译
# 使用TensorRT时,Paddle的预测库通常为动态库
WITH_STATIC_LIB=OFF
# CUDA 的 lib 路径
CUDA_LIB=/usr/local/cuda/lib64
# CUDNN 的 lib 路径
CUDNN_LIB=/usr/local/cuda/lib64
# 是否加载加密后的模型
WITH_ENCRYPTION=OFF
# OPENCV 路径, 如果使用自带预编译版本可不修改
sh $(pwd)/scripts/jetson_bootstrap.sh # 下载预编译版本的opencv
OPENCV_DIR=$(pwd)/deps/opencv3
# 以下无需改动
rm -rf build
mkdir -p build
cd build
cmake .. \
-DWITH_GPU=${WITH_GPU} \
-DWITH_MKL=${WITH_MKL} \
-DWITH_TENSORRT=${WITH_TENSORRT} \
-DWITH_ENCRYPTION=${WITH_ENCRYPTION} \
-DTENSORRT_DIR=${TENSORRT_DIR} \
-DPADDLE_DIR=${PADDLE_DIR} \
-DWITH_STATIC_LIB=${WITH_STATIC_LIB} \
-DCUDA_LIB=${CUDA_LIB} \
-DCUDNN_LIB=${CUDNN_LIB} \
-DENCRYPTION_DIR=${ENCRYPTION_DIR} \
-DOPENCV_DIR=${OPENCV_DIR}
make
# 常见问题
## 1. 训练参数如何调整
> 参考[参数调整文档](appendix/parameters.md)
## 2. 训练过程因显存不够出错
> 通过使用在终端`nvidia-smi`命令,查看GPU是否被其它任务占用,尝试清除其它任务;
> 调低训练时的`batch_size`参数,从而降低显存的要求,注意需等比例调低`learning_rate`等参数;
> 选用更小的模型或backbone。
## 3. 是否有更小的模型,适用于更低配置的设备上运行
> 可以使用模型裁剪,参考文档[模型裁剪使用教程](slim/prune.md),通过调整裁剪参数,可以控制模型裁剪后的大小,在实际实验中,如VOC检测数据,使用yolov3-mobilenet,原模型大小为XXM,裁剪后为XX M,精度基本保持不变
## 4. 如何配置训练时GPU的卡数
> 通过在终端export环境变量,或在Python代码中设置,可参考文档[CPU/多卡GPU训练](appendix/gpu_configure.md)
## 5. 想将之前训练的模型参数上继续训练
> 在训练调用`train`接口时,将`pretrain_weights`设为之前的模型保存路径即可
## 6. PaddleX保存的模型分为正常训练过程中产生、裁剪训练产生、导出为部署模型和量化保存这么多种,有什么差别,怎么区分
**不同模型的功能差异**
>1.正常模型训练保存
>
>>模型在正常训练过程,每间隔n个epoch保存的模型目录,模型可作为预训练模型参数,可使用PaddleX加载预测、或导出部署模型
>2.裁剪训练保存
>
>>模型在裁剪训练过程,每间隔n个epoch保存的模型目录,模型不可作为预训练模型参数,可使用PaddleX加载预测、或导出部署模型
>3.导出部署模型
>
>>为了模型在服务端部署,导出的模型目录,不可作为预训练模型参数,可使用PaddleX加载预测
>4.量化保存模型
>
>>为了提升模型预测速度,将模型参数进行量化保存的模型目录,模型不可作为预训练模型参数,可使用PaddleX加载预测
**区分方法**
>> 通过模型目录下model.yml文件中`status`字段来区别不同的模型类型, 'Normal'、'Prune'、'Infer'、'Quant'分别表示正常模型训练保存、裁剪训练保存、导出的部署模型、量化保存模型
## 7. 模型训练需要太久时间,或者训练速度太慢,怎么提速
> 1.模型训练速度与用户选定的模型大小,和设定的`batch_size`相关,模型大小可直接参考[模型库](model_zoo.md)中的指标,一般而言,模型越大,训练速度就越慢;
> 2.在模型速度之外,模型训练完成所需的时间又与用户设定的`num_epochs`迭代轮数相关,用户可以通过观察模型在验证集上的指标来决定是否提示结束掉训练进程(训练时设定`save_interval_epochs`参数,训练过程会每间隔`save_interval_epochs`轮数在验证集上计算指标,并保存模型);
## 8. 如何设定迭代的轮数
> 1. 用户自行训练时,如不确定迭代的轮数,可以将轮数设高一些,同时注意设置`save_interval_epochs`,这样模型迭代每间隔相应轮数就会在验证集上进行评估和保存,可以根据不同轮数模型在验证集上的评估指标,判断模型是否已经收敛,若模型已收敛,可以自行结束训练进程
>
## 9. 只有CPU,没有GPU,如何提升训练速度
> 当没有GPU时,可以根据自己的CPU配置,选择是否使用多CPU进行训练,具体配置方式可以参考文档[多卡CPU/GPU训练](appendix/gpu_configure.md)
>
## 10. 电脑不能联网,训练时因为下载预训练模型失败,如何解决
> 可以预先通过其它方式准备好预训练模型,然后训练时自定义`pretrain_weights`即可,可参考文档[无联网模型训练](how_to_offline_run.md)
## 11. 每次训练新的模型,都需要重新下载预训练模型,怎样可以下载一次就搞定
> 1.可以按照9的方式来解决这个问题
> 2.每次训练前都设定`paddlex.pretrain_dir`路径,如设定`paddlex.pretrain_dir='/usrname/paddlex`,如此下载完的预训练模型会存放至`/usrname/paddlex`目录下,而已经下载在该目录的模型也不会再次重复下载
## 12. PaddleX GUI启动时提示"Failed to execute script PaddleX",如何解决?
> 1. 请检查目标机器上PaddleX程序所在路径是否包含中文。目前暂不支持中文路径,请尝试将程序移动到英文目录。
> 2. 如果您的系统是Windows 7或者Windows Server 2012时,原因是缺少MFPlat.DLL/MF.dll/MFReadWrite.dll等OpenCV依赖的DLL,请按如下方式安装桌面体验:通过“我的电脑”-->“属性”-->"管理"打开服务器管理器,点击右上角“管理”选择“添加角色和功能”。点击“服务器选择”-->“功能”,拖动滚动条到最下端,点开“用户界面和基础结构”,勾选“桌面体验”后点击“安装”,等安装完成尝试再次运行PaddleX。
> 3. 请检查目标机器上是否有其他的PaddleX程序或者进程在运行中,如有请退出或者重启机器看是否解决
> 4. 请确认运行程序的用户是否有管理员权限,如非管理员权限用户请尝试使用管理员运行看是否成功
文件模式从 100755 更改为 100644
# 检测和实例分割数据集 # 数据集读取
## VOCDetection类 ## paddlex.datasets.ImageNet
> **用于图像分类模型**
```
paddlex.datasets.ImageNet(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False)
```
读取ImageNet格式的分类数据集,并对样本进行相应的处理。ImageNet数据集格式的介绍可查看文档:[数据集格式说明](../data/format/index.html)
示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/classification/mobilenetv2.py#L25)
> **参数**
> > * **data_dir** (str): 数据集所在的目录路径。
> > * **file_list** (str): 描述数据集图片文件和类别id的文件路径(文本内每行路径为相对`data_dir`的相对路径)。
> > * **label_list** (str): 描述数据集包含的类别信息文件路径。
> > * **transforms** (paddlex.cls.transforms): 数据集中每个样本的预处理/增强算子,详见[paddlex.cls.transforms](./transforms/cls_transforms.md)。
> > * **num_workers** (int|str):数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
> > * **buffer_size** (int): 数据集中样本在预处理过程中队列的缓存长度,以样本数为单位。默认为100。
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
## paddlex.datasets.PascalVOC
> **用于目标检测模型**
``` ```
paddlex.datasets.VOCDetection(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False) paddlex.datasets.PascalVOC(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False)
``` ```
> 仅用于**目标检测**。读取PascalVOC格式的检测数据集,并对样本进行相应的处理。PascalVOC数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) > 读取PascalVOC格式的检测数据集,并对样本进行相应的处理。PascalVOC数据集格式的介绍可查看文档:[数据集格式说明](../data/format/index.html)
> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/yolov3_darknet53.py#L29) > 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/yolov3_darknet53.py#L29)
...@@ -21,23 +41,13 @@ paddlex.datasets.VOCDetection(data_dir, file_list, label_list, transforms=None, ...@@ -21,23 +41,13 @@ paddlex.datasets.VOCDetection(data_dir, file_list, label_list, transforms=None,
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。 > > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。 > > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
> 【可选】支持在训练过程中加入无目标真值的背景图片来减少背景误检,定义VOCDetection类后调用其成员函数`add_negative_samples`添加背景图片即可: ## paddlex.datasets.MSCOCO
> ``` > **用于实例分割/目标检测模型**
> add_negative_samples(image_dir)
> ```
> > 示例:[代码](../../tuning_strategy/detection/negatives_training.html#id4)
> > **参数**
> > > * **image_dir** (str): 背景图片所在的目录路径。
## CocoDetection类
``` ```
paddlex.datasets.CocoDetection(data_dir, ann_file, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False) paddlex.datasets.MSCOCO(data_dir, ann_file, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False)
``` ```
> 用于**目标检测或实例分割**。读取MSCOCO格式的检测数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。MSCOCO数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) > 读取MSCOCO格式的检测数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。MSCOCO数据集格式的介绍可查看文档:[数据集格式说明](../data/format/index.html)
> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/mask_rcnn_r50_fpn.py#L27) > 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/mask_rcnn_r50_fpn.py#L27)
...@@ -51,23 +61,53 @@ paddlex.datasets.CocoDetection(data_dir, ann_file, transforms=None, num_workers= ...@@ -51,23 +61,53 @@ paddlex.datasets.CocoDetection(data_dir, ann_file, transforms=None, num_workers=
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。 > > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。 > > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
> 【可选】支持在训练过程中加入无目标真值的背景图片来减少背景误检,定义CocoDetection类后调用其成员函数`add_negative_samples`添加背景图片即可: ## paddlex.datasets.SegDataset
> ``` > **用于语义分割模型**
> add_negative_samples(image_dir) ```
> ``` paddlex.datasets.SegDataset(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False)
> > 示例:[代码](../../tuning_strategy/detection/negatives_training.html#id4) ```
> 读取语义分割任务数据集,并对样本进行相应的处理。语义分割任务数据集格式的介绍可查看文档:[数据集格式说明](../data/format/index.html)
> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/segmentation/unet.py#L27)
> **参数**
> > * **data_dir** (str): 数据集所在的目录路径。
> > * **file_list** (str): 描述数据集图片文件和对应标注文件的文件路径(文本内每行路径为相对`data_dir`的相对路径)。
> > * **label_list** (str): 描述数据集包含的类别信息文件路径。
> > * **transforms** (paddlex.seg.transforms): 数据集中每个样本的预处理/增强算子,详见[paddlex.seg.transforms](./transforms/seg_transforms.md)。
> > * **num_workers** (int|str):数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
> > * **buffer_size** (int): 数据集中样本在预处理过程中队列的缓存长度,以样本数为单位。默认为100。
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
## paddlex.datasets.EasyDataCls
> **用于图像分类模型**
```
paddlex.datasets.EasyDataCls(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False)
```
> > **参数** > 读取EasyData平台标注图像分类数据集,并对样本进行相应的处理。
> > > * **image_dir** (str): 背景图片所在的目录路径。 > **参数**
## EasyDataDet类 > > * **data_dir** (str): 数据集所在的目录路径。
> > * **file_list** (str): 描述数据集图片文件和对应标注文件的文件路径(文本内每行路径为相对`data_dir`的相对路径)。
> > * **label_list** (str): 描述数据集包含的类别信息文件路径。
> > * **transforms** (paddlex.seg.transforms): 数据集中每个样本的预处理/增强算子,详见[paddlex.cls.transforms](./transforms/cls_transforms.md)。
> > * **num_workers** (int|str):数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
> > * **buffer_size** (int): 数据集中样本在预处理过程中队列的缓存长度,以样本数为单位。默认为100。
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
## paddlex.datasets.EasyDataDet
> 用于**目标检测/实例分割模型**
``` ```
paddlex.datasets.EasyDataDet(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False) paddlex.datasets.EasyDataDet(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False)
``` ```
> 用于**目标检测或实例分割**。读取EasyData目标检测格式数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。EasyData目标检测或实例分割任务数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md) > 读取EasyData目标检测/实例分割格式数据集,并对样本进行相应的处理,该格式的数据集同样可以应用到实例分割模型的训练中。
> **参数** > **参数**
...@@ -81,13 +121,22 @@ paddlex.datasets.EasyDataDet(data_dir, file_list, label_list, transforms=None, n ...@@ -81,13 +121,22 @@ paddlex.datasets.EasyDataDet(data_dir, file_list, label_list, transforms=None, n
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。 > > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。 > > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
## paddlex.datasets.EasyDataSeg
> **用于语义分割模型**
```
paddlex.datasets.EasyDataSeg(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False)
```
> 【可选】支持在训练过程中加入无目标真值的背景图片来减少背景误检,定义EasyDataDet类后调用其成员函数`add_negative_samples`添加背景图片即可: > 读取EasyData语义分割任务数据集,并对样本进行相应的处理。
> ```
> add_negative_samples(image_dir)
> ```
> > 示例:[代码](../../tuning_strategy/detection/negatives_training.html#id4)
> > **参数**
> > > * **image_dir** (str): 背景图片所在的目录路径。 > **参数**
> > * **data_dir** (str): 数据集所在的目录路径。
> > * **file_list** (str): 描述数据集图片文件和对应标注文件的文件路径(文本内每行路径为相对`data_dir`的相对路径)。
> > * **label_list** (str): 描述数据集包含的类别信息文件路径。
> > * **transforms** (paddlex.seg.transforms): 数据集中每个样本的预处理/增强算子,详见[paddlex.seg.transforms](./transforms/seg_transforms.md)。
> > * **num_workers** (int|str):数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
> > * **buffer_size** (int): 数据集中样本在预处理过程中队列的缓存长度,以样本数为单位。默认为100。
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
# 图像分类数据集
## ImageNet类
```
paddlex.datasets.ImageNet(data_dir, file_list, label_list, transforms=None, num_workers=‘auto’, buffer_size=100, parallel_method='thread', shuffle=False)
```
读取ImageNet格式的分类数据集,并对样本进行相应的处理。ImageNet数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md)
示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/classification/mobilenetv2.py#L25)
> **参数**
> > * **data_dir** (str): 数据集所在的目录路径。
> > * **file_list** (str): 描述数据集图片文件和类别id的文件路径(文本内每行路径为相对`data_dir`的相对路径)。
> > * **label_list** (str): 描述数据集包含的类别信息文件路径。
> > * **transforms** (paddlex.cls.transforms): 数据集中每个样本的预处理/增强算子,详见[paddlex.cls.transforms](./transforms/cls_transforms.md)。
> > * **num_workers** (int|str):数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
> > * **buffer_size** (int): 数据集中样本在预处理过程中队列的缓存长度,以样本数为单位。默认为100。
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
## EasyDataCls类
```
paddlex.datasets.EasyDatasetCls(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False)
```
> 读取EasyData平台标注图像分类数据集,并对样本进行相应的处理。EasyData图像分类任务数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md)。
> **参数**
> > * **data_dir** (str): 数据集所在的目录路径。
> > * **file_list** (str): 描述数据集图片文件和对应标注文件的文件路径(文本内每行路径为相对`data_dir`的相对路径)。
> > * **label_list** (str): 描述数据集包含的类别信息文件路径。
> > * **transforms** (paddlex.seg.transforms): 数据集中每个样本的预处理/增强算子,详见[paddlex.cls.transforms](./transforms/cls_transforms.md)。
> > * **num_workers** (int|str):数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
> > * **buffer_size** (int): 数据集中样本在预处理过程中队列的缓存长度,以样本数为单位。默认为100。
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
# 数据集转换
## labelme2voc
```python
pdx.tools.labelme2voc(image_dir, json_dir, dataset_save_dir)
```
将LabelMe标注的数据集转换为VOC数据集。
> **参数**
> > * **image_dir** (str): 图像文件存放的路径。
> > * **json_dir** (str): 与每张图像对应的json文件的存放路径。
> > * **dataset_save_dir** (str): 转换后数据集存放路径。
## 其它数据集转换
### easydata2imagenet
```python
pdx.tools.easydata2imagenet(image_dir, json_dir, dataset_save_dir)
```
### easydata2voc
```python
pdx.tools.easydata2voc(image_dir, json_dir, dataset_save_dir)
```
### easydata2coco
```python
pdx.tools.easydata2coco(image_dir, json_dir, dataset_save_dir)
```
### easydata2seg
```python
pdx.tools.easydata2seg(image_dir, json_dir, dataset_save_dir)
```
### labelme2coco
```python
pdx.tools.labelme2coco(image_dir, json_dir, dataset_save_dir)
```
### labelme2seg
```python
pdx.tools.labelme2seg(image_dir, json_dir, dataset_save_dir)
```
### jingling2seg
```python
pdx.tools.jingling2seg(image_dir, json_dir, dataset_save_dir)
```
数据集-datasets
============================
PaddleX目前支持主流的CV数据集格式和 `EasyData <https://ai.baidu.com/easydata/>`_ 数据标注平台的标注数据格式,此外PaddleX也提升了数据格式转换工具API,支持包括LabelMe,精灵标注助手和EasyData平台数据格式的转换,可以参考PaddleX的tools API文档。
下表为各数据集格式与相应任务的对应关系,
+------------------------+------------+----------+----------+----------+
| 数据集格式 | 图像分类 | 目标检测 | 实例分割 | 语义分割 |
+========================+============+==========+==========+==========+
| ImageNet | √ | - | - | - |
+------------------------+------------+----------+----------+----------+
| VOCDetection | - | √ | - | - |
+------------------------+------------+----------+----------+----------+
| CocoDetection | - | √ | √ | - |
+------------------------+------------+----------+----------+----------+
| SegDataset | - | - | - | √ |
+------------------------+------------+----------+----------+----------+
| EasyDataCls | √ | - | - | - |
+------------------------+------------+----------+----------+----------+
| EasyDataDet | - | √ | √ | - |
+------------------------+------------+----------+----------+----------+
| EasyDataSeg | - | - | - | √ |
+------------------------+------------+----------+----------+----------+
.. toctree::
:maxdepth: 2
classification.md
detection.md
semantic_segmentation.md
dataset_convert.md
# 语义分割数据集
## SegDataset类
```
paddlex.datasets.SegDataset(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False)
```
> 读取语义分割任务数据集,并对样本进行相应的处理。语义分割任务数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md)
> 示例:[代码文件](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/segmentation/unet.py#L27)
> **参数**
> > * **data_dir** (str): 数据集所在的目录路径。
> > * **file_list** (str): 描述数据集图片文件和对应标注文件的文件路径(文本内每行路径为相对`data_dir`的相对路径)。
> > * **label_list** (str): 描述数据集包含的类别信息文件路径。
> > * **transforms** (paddlex.seg.transforms): 数据集中每个样本的预处理/增强算子,详见[paddlex.seg.transforms](./transforms/seg_transforms.md)。
> > * **num_workers** (int|str):数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
> > * **buffer_size** (int): 数据集中样本在预处理过程中队列的缓存长度,以样本数为单位。默认为100。
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
## EasyDataSeg类
```
paddlex.datasets.EasyDataSeg(data_dir, file_list, label_list, transforms=None, num_workers='auto', buffer_size=100, parallel_method='thread', shuffle=False)
```
> 读取EasyData语义分割任务数据集,并对样本进行相应的处理。EasyData语义分割任务数据集格式的介绍可查看文档:[数据集格式说明](../datasets.md)
> **参数**
> > * **data_dir** (str): 数据集所在的目录路径。
> > * **file_list** (str): 描述数据集图片文件和对应标注文件的文件路径(文本内每行路径为相对`data_dir`的相对路径)。
> > * **label_list** (str): 描述数据集包含的类别信息文件路径。
> > * **transforms** (paddlex.seg.transforms): 数据集中每个样本的预处理/增强算子,详见[paddlex.seg.transforms](./transforms/seg_transforms.md)。
> > * **num_workers** (int|str):数据集中样本在预处理过程中的线程或进程数。默认为'auto'。当设为'auto'时,根据系统的实际CPU核数设置`num_workers`: 如果CPU核数的一半大于8,则`num_workers`为8,否则为CPU核数的一半。
> > * **buffer_size** (int): 数据集中样本在预处理过程中队列的缓存长度,以样本数为单位。默认为100。
> > * **parallel_method** (str): 数据集中样本在预处理过程中并行处理的方式,支持'thread'线程和'process'进程两种方式。默认为'process'(Windows和Mac下会强制使用thread,该参数无效)。
> > * **shuffle** (bool): 是否需要对数据集中样本打乱顺序。默认为False。
# 预测部署-paddlex.deploy
使用Paddle Inference进行高性能的Python预测部署。更多关于Paddle Inference信息请参考[Paddle Inference文档](https://paddle-inference.readthedocs.io/en/latest/#)
## Predictor类
```
paddlex.deploy.Predictor(model_dir, use_gpu=False, gpu_id=0, use_mkl=False, use_trt=False, use_glog=False, memory_optimize=True)
```
> **参数**
> > * **model_dir**: 训练过程中保存的模型路径, 注意需要使用导出的inference模型
> > * **use_gpu**: 是否使用GPU进行预测
> > * **gpu_id**: 使用的GPU序列号
> > * **use_mkl**: 是否使用mkldnn加速库
> > * **use_trt**: 是否使用TensorRT预测引擎
> > * **use_glog**: 是否打印中间日志
> > * **memory_optimize**: 是否优化内存使用
> > ### 示例
> >
> > ```
> > import paddlex
> >
> > model = paddlex.deploy.Predictor(model_dir, use_gpu=True)
> > result = model.predict(image_file)
> > ```
### predict 接口
> ```
> predict(image, topk=1)
> ```
> **参数
* **image(str|np.ndarray)**: 待预测的图片路径或np.ndarray,若为后者需注意为BGR格式
* **topk(int)**: 图像分类时使用的参数,表示预测前topk个可能的分类
PaddleX API说明文档 API接口说明
============================ ============================
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
transforms/index.rst transforms/index.rst
datasets/index.rst datasets.md
models/index.rst models/index.rst
slim.md slim.md
load_model.md load_model.md
visualize.md visualize.md
deploy.md interpret.md
# 模型可解释性
目前PaddleX支持对于图像分类的结果以可视化的方式进行解释,支持LIME和NormLIME两种可解释性算法。
## paddlex.interpret.lime
> **LIME可解释性结果可视化**
```
paddlex.interpret.lime(img_file,
model,
num_samples=3000,
batch_size=50,
save_dir='./')
```
使用LIME算法将模型预测结果的可解释性可视化。
LIME表示与模型无关的局部可解释性,可以解释任何模型。LIME的思想是以输入样本为中心,在其附近的空间中进行随机采样,每个采样通过原模型得到新的输出,这样得到一系列的输入和对应的输出,LIME用一个简单的、可解释的模型(比如线性回归模型)来拟合这个映射关系,得到每个输入维度的权重,以此来解释模型。
**注意:** 可解释性结果可视化目前只支持分类模型。
### 参数
>* **img_file** (str): 预测图像路径。
>* **model** (paddlex.cv.models): paddlex中的模型。
>* **num_samples** (int): LIME用于学习线性模型的采样数,默认为3000。
>* **batch_size** (int): 预测数据batch大小,默认为50。
>* **save_dir** (str): 可解释性可视化结果(保存为png格式文件)和中间文件存储路径。
### 使用示例
> 对预测可解释性结果可视化的过程可参见[代码](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/lime.py)。
## paddlex.interpret.normlime
> **NormLIME可解释性结果可视化**
```
paddlex.interpret.normlime(img_file,
model,
dataset=None,
num_samples=3000,
batch_size=50,
save_dir='./',
normlime_weights_file=None)
```
使用NormLIME算法将模型预测结果的可解释性可视化。
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格式文件)和中间文件存储路径。
>* **normlime_weights_file** (str): NormLIME初始化文件名,若不存在,则计算一次,保存于该路径;若存在,则直接载入。
**注意:** dataset`读取的是一个数据集,该数据集不宜过大,否则计算时间会较长,但应包含所有类别的数据。NormLIME可解释性结果可视化目前只支持分类模型。
### 使用示例
> 对预测可解释性结果可视化的过程可参见[代码](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/normlime.py)。
# 模型加载-load_model # 模型加载
PaddleX提供了统一的模型加载接口,支持加载PaddleX保存的模型,并在验证集上进行评估或对测试图片进行预测 PaddleX提供了统一的模型加载接口,支持加载PaddleX保存的模型,并在验证集上进行评估或对测试图片进行预测
## 函数接口 ## paddlex.load_model
> **加载PaddleX保存的模型**
``` ```
paddlex.load_model(model_dir) paddlex.load_model(model_dir)
......
# 图像分类 # Image Classification
## ResNet50类 ## paddlex.cls.ResNet50
```python ```python
paddlex.cls.ResNet50(num_classes=1000) paddlex.cls.ResNet50(num_classes=1000)
...@@ -12,7 +12,7 @@ paddlex.cls.ResNet50(num_classes=1000) ...@@ -12,7 +12,7 @@ paddlex.cls.ResNet50(num_classes=1000)
> - **num_classes** (int): 类别数。默认为1000。 > - **num_classes** (int): 类别数。默认为1000。
### train 训练接口 ### train
```python ```python
train(self, num_epochs, train_dataset, train_batch_size=64, eval_dataset=None, save_interval_epochs=1, log_interval_steps=2, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=0.025, warmup_steps=0, warmup_start_lr=0.0, lr_decay_epochs=[30, 60, 90], lr_decay_gamma=0.1, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None) train(self, num_epochs, train_dataset, train_batch_size=64, eval_dataset=None, save_interval_epochs=1, log_interval_steps=2, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=0.025, warmup_steps=0, warmup_start_lr=0.0, lr_decay_epochs=[30, 60, 90], lr_decay_gamma=0.1, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None)
...@@ -41,7 +41,7 @@ train(self, num_epochs, train_dataset, train_batch_size=64, eval_dataset=None, s ...@@ -41,7 +41,7 @@ train(self, num_epochs, train_dataset, train_batch_size=64, eval_dataset=None, s
> > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。 > > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。
> > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。 > > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
### evaluate 评估接口 ### evaluate
```python ```python
evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False) evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False)
...@@ -59,7 +59,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False) ...@@ -59,7 +59,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False)
> > - **dict**: 当return_details为False时,返回dict, 包含关键字:'acc1'、'acc5',分别表示最大值的accuracy、前5个最大值的accuracy。 > > - **dict**: 当return_details为False时,返回dict, 包含关键字:'acc1'、'acc5',分别表示最大值的accuracy、前5个最大值的accuracy。
> > - **tuple** (metrics, eval_details): 当`return_details`为True时,增加返回dict,包含关键字:'true_labels'、'pred_scores',分别代表真实类别id、每个类别的预测得分。 > > - **tuple** (metrics, eval_details): 当`return_details`为True时,增加返回dict,包含关键字:'true_labels'、'pred_scores',分别代表真实类别id、每个类别的预测得分。
### predict 预测接口 ### predict
```python ```python
predict(self, img_file, transforms=None, topk=5) predict(self, img_file, transforms=None, topk=5)
...@@ -69,7 +69,7 @@ predict(self, img_file, transforms=None, topk=5) ...@@ -69,7 +69,7 @@ predict(self, img_file, transforms=None, topk=5)
> **参数** > **参数**
> >
> > - **img_file** (str): 预测图像路径 > > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)
> > - **transforms** (paddlex.cls.transforms): 数据预处理操作。 > > - **transforms** (paddlex.cls.transforms): 数据预处理操作。
> > - **topk** (int): 预测时前k个最大值。 > > - **topk** (int): 预测时前k个最大值。
...@@ -78,117 +78,31 @@ predict(self, img_file, transforms=None, topk=5) ...@@ -78,117 +78,31 @@ predict(self, img_file, transforms=None, topk=5)
> > - **list**: 其中元素均为字典。字典的关键字为'category_id'、'category'、'score', > > - **list**: 其中元素均为字典。字典的关键字为'category_id'、'category'、'score',
> > 分别对应预测类别id、预测类别标签、预测得分。 > > 分别对应预测类别id、预测类别标签、预测得分。
## 其它分类器类 ## 其它分类模型
PaddleX提供了共计22种分类器,所有分类器均提供同`ResNet50`相同的训练`train`,评估`evaluate`和预测`predict`接口,各模型效果可参考[模型库](https://paddlex.readthedocs.io/zh_CN/latest/appendix/model_zoo.html) PaddleX提供了共计22种分类模型,所有分类模型均提供同`ResNet50`相同的训练`train`,评估`evaluate`和预测`predict`接口,各模型效果可参考[模型库](https://paddlex.readthedocs.io/zh_CN/latest/appendix/model_zoo.html)
### ResNet18 | 模型 | 接口 |
```python | :---------------- | :---------------------- |
paddlex.cls.ResNet18(num_classes=1000) | ResNet18 | paddlex.cls.ResNet18(num_classes=1000) |
``` | ResNet34 | paddlex.cls.ResNet34(num_classes=1000) |
| ResNet50 | paddlex.cls.ResNet50(num_classes=1000) |
### ResNet34 | ResNet50_vd | paddlex.cls.ResNet50_vd(num_classes=1000) |
```python | ResNet50_vd_ssld | paddlex.cls.ResNet50_vd_ssld(num_classes=1000) |
paddlex.cls.ResNet34(num_classes=1000) | ResNet101 | paddlex.cls.ResNet101(num_classes=1000) |
``` | ResNet101_vd | paddlex.cls.ResNet101_vd(num_classes=1000) |
| ResNet101_vd_ssld | paddlex.cls.ResNet101_vd_ssld(num_classes=1000) |
| DarkNet53 | paddlex.cls.DarkNet53(num_classes=1000) |
### ResNet50 | MoibileNetV1 | paddlex.cls.MobileNetV1(num_classes=1000) |
```python | MobileNetV2 | paddlex.cls.MobileNetV2(num_classes=1000) |
paddlex.cls.ResNet50(num_classes=1000) | MobileNetV3_small | paddlex.cls.MobileNetV3_small(num_classes=1000) |
``` | MobileNetV3_small_ssld | paddlex.cls.MobileNetV3_small_ssld(num_classes=1000) |
| MobileNetV3_large | paddlex.cls.MobileNetV3_large(num_classes=1000) |
### ResNet50_vd | MobileNetV3_large_ssld | paddlex.cls.MobileNetV3_large_ssld(num_classes=1000) |
```python | Xception65 | paddlex.cls.Xception65(num_classes=1000) |
paddlex.cls.ResNet50_vd(num_classes=1000) | Xception71 | paddlex.cls.Xception71(num_classes=1000) |
``` | ShuffleNetV2 | paddlex.cls.ShuffleNetV2(num_classes=1000) |
| DenseNet121 | paddlex.cls.DenseNet121(num_classes=1000) |
### ResNet50_vd_ssld | DenseNet161 | paddlex.cls.DenseNet161(num_classes=1000) |
```python | DenseNet201 | paddlex.cls.DenseNet201(num_classes=1000) |
paddlex.cls.ResNet50_vd_ssld(num_classes=1000) | HRNet_W18 | paddlex.cls.HRNet_W18(num_classes=1000) |
```
### ResNet101
```python
paddlex.cls.ResNet101(num_classes=1000)
```
### ResNet101_vd
```python
paddlex.cls.ResNet101_vdnum_classes=1000)
```
### ResNet101_vd_ssld
```python
paddlex.cls.ResNet101_vd_ssld(num_classes=1000)
```
### DarkNet53
```python
paddlex.cls.DarkNet53(num_classes=1000)
```
### MobileNetV1
```python
paddlex.cls.MobileNetV1(num_classes=1000)
```
### MobileNetV2
```python
paddlex.cls.MobileNetV2(num_classes=1000)
```
### MobileNetV3_small
```python
paddlex.cls.MobileNetV3_small(num_classes=1000)
```
### MobileNetV3_small_ssld
```python
paddlex.cls.MobileNetV3_small_ssld(num_classes=1000)
```
### MobileNetV3_large
```python
paddlex.cls.MobileNetV3_large(num_classes=1000)
```
### MobileNetV3_large_ssld
```python
paddlex.cls.MobileNetV3_large_ssld(num_classes=1000)
```
### Xception65
```python
paddlex.cls.Xception65(num_classes=1000)
```
### Xception71
```python
paddlex.cls.Xception71(num_classes=1000)
```
### ShuffleNetV2
```python
paddlex.cls.ShuffleNetV2(num_classes=1000)
```
### DenseNet121
```python
paddlex.cls.DenseNet121(num_classes=1000)
```
### DenseNet161
```python
paddlex.cls.DenseNet161(num_classes=1000)
```
### DenseNet201
```python
paddlex.cls.DenseNet201(num_classes=1000)
```
### HRNet_W18
```python
paddlex.cls.HRNet_W18(num_classes=1000)
```
# 目标检测 # Object Detection
## YOLOv3类 ## paddlex.det.YOLOv3
```python ```python
paddlex.det.YOLOv3(num_classes=80, backbone='MobileNetV1', anchors=None, anchor_masks=None, ignore_threshold=0.7, nms_score_threshold=0.01, nms_topk=1000, nms_keep_topk=100, nms_iou_threshold=0.45, label_smooth=False, train_random_shapes=[320, 352, 384, 416, 448, 480, 512, 544, 576, 608]) paddlex.det.YOLOv3(num_classes=80, backbone='MobileNetV1', anchors=None, anchor_masks=None, ignore_threshold=0.7, nms_score_threshold=0.01, nms_topk=1000, nms_keep_topk=100, nms_iou_threshold=0.45, label_smooth=False, train_random_shapes=[320, 352, 384, 416, 448, 480, 512, 544, 576, 608])
...@@ -25,7 +25,7 @@ paddlex.det.YOLOv3(num_classes=80, backbone='MobileNetV1', anchors=None, anchor_ ...@@ -25,7 +25,7 @@ paddlex.det.YOLOv3(num_classes=80, backbone='MobileNetV1', anchors=None, anchor_
> > - **label_smooth** (bool): 是否使用label smooth。默认值为False。 > > - **label_smooth** (bool): 是否使用label smooth。默认值为False。
> > - **train_random_shapes** (list|tuple): 训练时从列表中随机选择图像大小。默认值为[320, 352, 384, 416, 448, 480, 512, 544, 576, 608]。 > > - **train_random_shapes** (list|tuple): 训练时从列表中随机选择图像大小。默认值为[320, 352, 384, 416, 448, 480, 512, 544, 576, 608]。
### train 训练接口 ### train
```python ```python
train(self, num_epochs, train_dataset, train_batch_size=8, eval_dataset=None, save_interval_epochs=20, log_interval_steps=2, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=1.0/8000, warmup_steps=1000, warmup_start_lr=0.0, lr_decay_epochs=[213, 240], lr_decay_gamma=0.1, metric=None, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None) train(self, num_epochs, train_dataset, train_batch_size=8, eval_dataset=None, save_interval_epochs=20, log_interval_steps=2, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=1.0/8000, warmup_steps=1000, warmup_start_lr=0.0, lr_decay_epochs=[213, 240], lr_decay_gamma=0.1, metric=None, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None)
...@@ -57,7 +57,7 @@ train(self, num_epochs, train_dataset, train_batch_size=8, eval_dataset=None, sa ...@@ -57,7 +57,7 @@ train(self, num_epochs, train_dataset, train_batch_size=8, eval_dataset=None, sa
> > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。 > > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。
> > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。 > > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
### evaluate 评估接口 ### evaluate
```python ```python
evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_details=False) evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_details=False)
...@@ -77,7 +77,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_de ...@@ -77,7 +77,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_de
> >
> > - **tuple** (metrics, eval_details) | **dict** (metrics): 当`return_details`为True时,返回(metrics, eval_details),当`return_details`为False时,返回metrics。metrics为dict,包含关键字:'bbox_mmap'或者’bbox_map‘,分别表示平均准确率平均值在各个阈值下的结果取平均值的结果(mmAP)、平均准确率平均值(mAP)。eval_details为dict,包含关键字:'bbox',对应元素预测结果列表,每个预测结果由图像id、预测框类别id、预测框坐标、预测框得分;’gt‘:真实标注框相关信息。 > > - **tuple** (metrics, eval_details) | **dict** (metrics): 当`return_details`为True时,返回(metrics, eval_details),当`return_details`为False时,返回metrics。metrics为dict,包含关键字:'bbox_mmap'或者’bbox_map‘,分别表示平均准确率平均值在各个阈值下的结果取平均值的结果(mmAP)、平均准确率平均值(mAP)。eval_details为dict,包含关键字:'bbox',对应元素预测结果列表,每个预测结果由图像id、预测框类别id、预测框坐标、预测框得分;’gt‘:真实标注框相关信息。
### predict 预测接口 ### predict
```python ```python
predict(self, img_file, transforms=None) predict(self, img_file, transforms=None)
...@@ -87,7 +87,7 @@ predict(self, img_file, transforms=None) ...@@ -87,7 +87,7 @@ predict(self, img_file, transforms=None)
> **参数** > **参数**
> >
> > - **img_file** (str): 预测图像路径 > > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)
> > - **transforms** (paddlex.det.transforms): 数据预处理操作。 > > - **transforms** (paddlex.det.transforms): 数据预处理操作。
> >
> **返回值** > **返回值**
...@@ -95,7 +95,7 @@ predict(self, img_file, transforms=None) ...@@ -95,7 +95,7 @@ predict(self, img_file, transforms=None)
> > - **list**: 预测结果列表,列表中每个元素均为一个dict,key包括'bbox', 'category', 'category_id', 'score',分别表示每个预测目标的框坐标信息、类别、类别id、置信度,其中框坐标信息为[xmin, ymin, w, h],即左上角x, y坐标和框的宽和高。 > > - **list**: 预测结果列表,列表中每个元素均为一个dict,key包括'bbox', 'category', 'category_id', 'score',分别表示每个预测目标的框坐标信息、类别、类别id、置信度,其中框坐标信息为[xmin, ymin, w, h],即左上角x, y坐标和框的宽和高。
## FasterRCNN类 ## paddlex.det.FasterRCNN
```python ```python
paddlex.det.FasterRCNN(num_classes=81, backbone='ResNet50', with_fpn=True, aspect_ratios=[0.5, 1.0, 2.0], anchor_sizes=[32, 64, 128, 256, 512]) paddlex.det.FasterRCNN(num_classes=81, backbone='ResNet50', with_fpn=True, aspect_ratios=[0.5, 1.0, 2.0], anchor_sizes=[32, 64, 128, 256, 512])
...@@ -112,7 +112,7 @@ paddlex.det.FasterRCNN(num_classes=81, backbone='ResNet50', with_fpn=True, aspec ...@@ -112,7 +112,7 @@ paddlex.det.FasterRCNN(num_classes=81, backbone='ResNet50', with_fpn=True, aspec
> > - **aspect_ratios** (list): 生成anchor高宽比的可选值。默认为[0.5, 1.0, 2.0]。 > > - **aspect_ratios** (list): 生成anchor高宽比的可选值。默认为[0.5, 1.0, 2.0]。
> > - **anchor_sizes** (list): 生成anchor大小的可选值。默认为[32, 64, 128, 256, 512]。 > > - **anchor_sizes** (list): 生成anchor大小的可选值。默认为[32, 64, 128, 256, 512]。
### train 训练接口 ### train
```python ```python
train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, save_interval_epochs=1, log_interval_steps=2,save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=0.0025, warmup_steps=500, warmup_start_lr=1.0/1200, lr_decay_epochs=[8, 11], lr_decay_gamma=0.1, metric=None, use_vdl=False, early_stop=False, early_stop_patience=5, resume_checkpoint=None) train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, save_interval_epochs=1, log_interval_steps=2,save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=0.0025, warmup_steps=500, warmup_start_lr=1.0/1200, lr_decay_epochs=[8, 11], lr_decay_gamma=0.1, metric=None, use_vdl=False, early_stop=False, early_stop_patience=5, resume_checkpoint=None)
...@@ -142,7 +142,7 @@ train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, sa ...@@ -142,7 +142,7 @@ train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, sa
> > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。 > > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。
> > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。 > > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
### evaluate 接口 ### evaluate
```python ```python
evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_details=False) evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_details=False)
...@@ -162,7 +162,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_de ...@@ -162,7 +162,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_de
> >
> > - **tuple** (metrics, eval_details) | **dict** (metrics): 当`return_details`为True时,返回(metrics, eval_details),当`return_details`为False时,返回metrics。metrics为dict,包含关键字:'bbox_mmap'或者’bbox_map‘,分别表示平均准确率平均值在各个IoU阈值下的结果取平均值的结果(mmAP)、平均准确率平均值(mAP)。eval_details为dict,包含关键字:'bbox',对应元素预测结果列表,每个预测结果由图像id、预测框类别id、预测框坐标、预测框得分;’gt‘:真实标注框相关信息。 > > - **tuple** (metrics, eval_details) | **dict** (metrics): 当`return_details`为True时,返回(metrics, eval_details),当`return_details`为False时,返回metrics。metrics为dict,包含关键字:'bbox_mmap'或者’bbox_map‘,分别表示平均准确率平均值在各个IoU阈值下的结果取平均值的结果(mmAP)、平均准确率平均值(mAP)。eval_details为dict,包含关键字:'bbox',对应元素预测结果列表,每个预测结果由图像id、预测框类别id、预测框坐标、预测框得分;’gt‘:真实标注框相关信息。
### predict 预测接口 ### predict
```python ```python
predict(self, img_file, transforms=None) predict(self, img_file, transforms=None)
...@@ -172,7 +172,7 @@ predict(self, img_file, transforms=None) ...@@ -172,7 +172,7 @@ predict(self, img_file, transforms=None)
> **参数** > **参数**
> >
> > - **img_file** (str): 预测图像路径 > > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)
> > - **transforms** (paddlex.det.transforms): 数据预处理操作。 > > - **transforms** (paddlex.det.transforms): 数据预处理操作。
> >
> **返回值** > **返回值**
......
模型集-models 视觉模型集
============================ ============================
PaddleX目前支持 `四种视觉任务解决方案 <../../cv_solutions.html>`_ ,包括图像分类、目标检测、实例分割和语义分割。对于每种视觉任务,PaddleX又提供了1种或多种模型,用户可根据需求及应用场景选取。 PaddleX目前支持 `四种视觉任务解决方案 <../../cv_solutions.html>`_ ,包括图像分类、目标检测、实例分割和语义分割。对于每种视觉任务,PaddleX又提供了1种或多种模型,用户可根据需求及应用场景选取。
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 3
classification.md classification.md
detection.md detection.md
......
# 实例分割 # Instance Segmentation
## MaskRCNN ## MaskRCNN
```python ```python
paddlex.det.MaskRCNN(num_classes=81, backbone='ResNet50', with_fpn=True, aspect_ratios=[0.5, 1.0, 2.0], anchor_sizes=[32, 64, 128, 256, 512]) paddlex.det.MaskRCNN(num_classes=81, backbone='ResNet50', with_fpn=True, aspect_ratios=[0.5, 1.0, 2.0], anchor_sizes=[32, 64, 128, 256, 512])
...@@ -17,7 +17,7 @@ paddlex.det.MaskRCNN(num_classes=81, backbone='ResNet50', with_fpn=True, aspect_ ...@@ -17,7 +17,7 @@ paddlex.det.MaskRCNN(num_classes=81, backbone='ResNet50', with_fpn=True, aspect_
> > - **aspect_ratios** (list): 生成anchor高宽比的可选值。默认为[0.5, 1.0, 2.0]。 > > - **aspect_ratios** (list): 生成anchor高宽比的可选值。默认为[0.5, 1.0, 2.0]。
> > - **anchor_sizes** (list): 生成anchor大小的可选值。默认为[32, 64, 128, 256, 512]。 > > - **anchor_sizes** (list): 生成anchor大小的可选值。默认为[32, 64, 128, 256, 512]。
#### train 训练接口 #### train
```python ```python
train(self, num_epochs, train_dataset, train_batch_size=1, eval_dataset=None, save_interval_epochs=1, log_interval_steps=20, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=1.0/800, warmup_steps=500, warmup_start_lr=1.0 / 2400, lr_decay_epochs=[8, 11], lr_decay_gamma=0.1, metric=None, use_vdl=False, early_stop=False, early_stop_patience=5, resume_checkpoint=None) train(self, num_epochs, train_dataset, train_batch_size=1, eval_dataset=None, save_interval_epochs=1, log_interval_steps=20, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=1.0/800, warmup_steps=500, warmup_start_lr=1.0 / 2400, lr_decay_epochs=[8, 11], lr_decay_gamma=0.1, metric=None, use_vdl=False, early_stop=False, early_stop_patience=5, resume_checkpoint=None)
...@@ -47,7 +47,7 @@ train(self, num_epochs, train_dataset, train_batch_size=1, eval_dataset=None, sa ...@@ -47,7 +47,7 @@ train(self, num_epochs, train_dataset, train_batch_size=1, eval_dataset=None, sa
> > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。 > > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。
> > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。 > > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
#### evaluate 评估接口 #### evaluate
```python ```python
evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_details=False) evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_details=False)
...@@ -67,7 +67,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_de ...@@ -67,7 +67,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, metric=None, return_de
> >
> > - **tuple** (metrics, eval_details) | **dict** (metrics): 当`return_details`为True时,返回(metrics, eval_details),当return_details为False时,返回metrics。metrics为dict,包含关键字:'bbox_mmap'和'segm_mmap'或者’bbox_map‘和'segm_map',分别表示预测框和分割区域平均准确率平均值在各个IoU阈值下的结果取平均值的结果(mmAP)、平均准确率平均值(mAP)。eval_details为dict,包含关键字:'bbox',对应元素预测框结果列表,每个预测结果由图像id、预测框类别id、预测框坐标、预测框得分;'mask',对应元素预测区域结果列表,每个预测结果由图像id、预测区域类别id、预测区域坐标、预测区域得分;’gt‘:真实标注框和标注区域相关信息。 > > - **tuple** (metrics, eval_details) | **dict** (metrics): 当`return_details`为True时,返回(metrics, eval_details),当return_details为False时,返回metrics。metrics为dict,包含关键字:'bbox_mmap'和'segm_mmap'或者’bbox_map‘和'segm_map',分别表示预测框和分割区域平均准确率平均值在各个IoU阈值下的结果取平均值的结果(mmAP)、平均准确率平均值(mAP)。eval_details为dict,包含关键字:'bbox',对应元素预测框结果列表,每个预测结果由图像id、预测框类别id、预测框坐标、预测框得分;'mask',对应元素预测区域结果列表,每个预测结果由图像id、预测区域类别id、预测区域坐标、预测区域得分;’gt‘:真实标注框和标注区域相关信息。
#### predict 预测接口 #### predict
```python ```python
predict(self, img_file, transforms=None) predict(self, img_file, transforms=None)
...@@ -77,7 +77,7 @@ predict(self, img_file, transforms=None) ...@@ -77,7 +77,7 @@ predict(self, img_file, transforms=None)
> **参数** > **参数**
> >
> > - **img_file** (str): 预测图像路径 > > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)
> > - **transforms** (paddlex.det.transforms): 数据预处理操作。 > > - **transforms** (paddlex.det.transforms): 数据预处理操作。
> >
> **返回值** > **返回值**
......
# 语义分割 # Semantic Segmentation
## DeepLabv3p类 ## paddlex.seg.DeepLabv3p
```python ```python
paddlex.seg.DeepLabv3p(num_classes=2, backbone='MobileNetV2_x1.0', output_stride=16, aspp_with_sep_conv=True, decoder_use_sep_conv=True, encoder_with_aspp=True, enable_decoder=True, use_bce_loss=False, use_dice_loss=False, class_weight=None, ignore_index=255) paddlex.seg.DeepLabv3p(num_classes=2, backbone='MobileNetV2_x1.0', output_stride=16, aspp_with_sep_conv=True, decoder_use_sep_conv=True, encoder_with_aspp=True, enable_decoder=True, use_bce_loss=False, use_dice_loss=False, class_weight=None, ignore_index=255)
...@@ -23,7 +23,7 @@ paddlex.seg.DeepLabv3p(num_classes=2, backbone='MobileNetV2_x1.0', output_stride ...@@ -23,7 +23,7 @@ paddlex.seg.DeepLabv3p(num_classes=2, backbone='MobileNetV2_x1.0', output_stride
> > - **class_weight** (list/str): 交叉熵损失函数各类损失的权重。当`class_weight`为list的时候,长度应为`num_classes`。当`class_weight`为str时, weight.lower()应为'dynamic',这时会根据每一轮各类像素的比重自行计算相应的权重,每一类的权重为:每类的比例 * num_classes。class_weight取默认值None是,各类的权重1,即平时使用的交叉熵损失函数。 > > - **class_weight** (list/str): 交叉熵损失函数各类损失的权重。当`class_weight`为list的时候,长度应为`num_classes`。当`class_weight`为str时, weight.lower()应为'dynamic',这时会根据每一轮各类像素的比重自行计算相应的权重,每一类的权重为:每类的比例 * num_classes。class_weight取默认值None是,各类的权重1,即平时使用的交叉熵损失函数。
> > - **ignore_index** (int): label上忽略的值,label为`ignore_index`的像素不参与损失函数的计算。默认255。 > > - **ignore_index** (int): label上忽略的值,label为`ignore_index`的像素不参与损失函数的计算。默认255。
### train 训练接口 ### train
```python ```python
train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, eval_batch_size=1, save_interval_epochs=1, log_interval_steps=2, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=0.01, lr_decay_power=0.9, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None): train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, eval_batch_size=1, save_interval_epochs=1, log_interval_steps=2, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=0.01, lr_decay_power=0.9, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None):
...@@ -51,7 +51,7 @@ train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, ev ...@@ -51,7 +51,7 @@ train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, ev
> > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。 > > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。
> > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。 > > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
### evaluate 评估接口 ### evaluate
```python ```python
evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False): evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False):
...@@ -73,7 +73,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False): ...@@ -73,7 +73,7 @@ evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False):
> > - **tuple** (metrics, eval_details):当`return_details`为True时,增加返回dict (eval_details), > > - **tuple** (metrics, eval_details):当`return_details`为True时,增加返回dict (eval_details),
> > 包含关键字:'confusion_matrix',表示评估的混淆矩阵。 > > 包含关键字:'confusion_matrix',表示评估的混淆矩阵。
### predict 预测接口 ### predict
``` ```
predict(self, im_file, transforms=None): predict(self, im_file, transforms=None):
...@@ -83,14 +83,14 @@ predict(self, im_file, transforms=None): ...@@ -83,14 +83,14 @@ predict(self, im_file, transforms=None):
> **参数** > **参数**
> > > >
> > - **img_file** (str): 预测图像路径 > > - **img_file** (str|np.ndarray): 预测图像路径或numpy数组(HWC排列,BGR格式)
> > - **transforms** (paddlex.seg.transforms): 数据预处理操作。 > > - **transforms** (paddlex.seg.transforms): 数据预处理操作。
> **返回值** > **返回值**
> > > >
> > - **dict**: 包含关键字'label_map'和'score_map', 'label_map'存储预测结果灰度图,像素值表示对应的类别,'score_map'存储各类别的概率,shape=(h, w, num_classes)。 > > - **dict**: 包含关键字'label_map'和'score_map', 'label_map'存储预测结果灰度图,像素值表示对应的类别,'score_map'存储各类别的概率,shape=(h, w, num_classes)。
## UNet类 ## paddlex.seg.UNet
```python ```python
paddlex.seg.UNet(num_classes=2, upsample_mode='bilinear', use_bce_loss=False, use_dice_loss=False, class_weight=None, ignore_index=255) paddlex.seg.UNet(num_classes=2, upsample_mode='bilinear', use_bce_loss=False, use_dice_loss=False, class_weight=None, ignore_index=255)
...@@ -107,75 +107,11 @@ paddlex.seg.UNet(num_classes=2, upsample_mode='bilinear', use_bce_loss=False, us ...@@ -107,75 +107,11 @@ paddlex.seg.UNet(num_classes=2, upsample_mode='bilinear', use_bce_loss=False, us
> > - **class_weight** (list/str): 交叉熵损失函数各类损失的权重。当`class_weight`为list的时候,长度应为`num_classes`。当`class_weight`为str时, weight.lower()应为'dynamic',这时会根据每一轮各类像素的比重自行计算相应的权重,每一类的权重为:每类的比例 * num_classes。class_weight取默认值None是,各类的权重1,即平时使用的交叉熵损失函数。 > > - **class_weight** (list/str): 交叉熵损失函数各类损失的权重。当`class_weight`为list的时候,长度应为`num_classes`。当`class_weight`为str时, weight.lower()应为'dynamic',这时会根据每一轮各类像素的比重自行计算相应的权重,每一类的权重为:每类的比例 * num_classes。class_weight取默认值None是,各类的权重1,即平时使用的交叉熵损失函数。
> > - **ignore_index** (int): label上忽略的值,label为`ignore_index`的像素不参与损失函数的计算。默认255。 > > - **ignore_index** (int): label上忽略的值,label为`ignore_index`的像素不参与损失函数的计算。默认255。
### train 训练接口 > - train 训练接口说明同 [DeepLabv3p模型train接口](#train)
> - evaluate 评估接口说明同 [DeepLabv3p模型evaluate接口](#evaluate)
> - predict 预测接口说明同 [DeepLabv3p模型predict接口](#predict)
```python ## paddlex.seg.HRNet
train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, eval_batch_size=1, save_interval_epochs=1, log_interval_steps=2, save_dir='output', pretrain_weights='COCO', optimizer=None, learning_rate=0.01, lr_decay_power=0.9, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None):
```
> UNet模型训练接口。
> **参数**
> >
> > - **num_epochs** (int): 训练迭代轮数。
> > - **train_dataset** (paddlex.datasets): 训练数据读取器。
> > - **train_batch_size** (int): 训练数据batch大小。同时作为验证数据batch大小。默认2。
> > - **eval_dataset** (paddlex.datasets): 评估数据读取器。
> > - **save_interval_epochs** (int): 模型保存间隔(单位:迭代轮数)。默认为1。
> > - **log_interval_steps** (int): 训练日志输出间隔(单位:迭代次数)。默认为2。
> > - **save_dir** (str): 模型保存路径。默认'output'
> > - **pretrain_weights** (str): 若指定为路径时,则加载路径下预训练模型;若为字符串'COCO',则自动下载在COCO图片数据上预训练的模型权重;若为None,则不使用预训练模型。默认'COCO'。
> > - **optimizer** (paddle.fluid.optimizer): 优化器。当该参数为None时,使用默认的优化器:使用fluid.optimizer.Momentum优化方法,polynomial的学习率衰减策略。
> > - **learning_rate** (float): 默认优化器的初始学习率。默认0.01。
> > - **lr_decay_power** (float): 默认优化器学习率衰减指数。默认0.9。
> > - **use_vdl** (bool): 是否使用VisualDL进行可视化。默认False。
> > - **sensitivities_file** (str): 若指定为路径时,则加载路径下敏感度信息进行裁剪;若为字符串'DEFAULT',则自动下载在Cityscapes图片数据上获得的敏感度信息进行裁剪;若为None,则不进行裁剪。默认为None。
> > - **eval_metric_loss** (float): 可容忍的精度损失。默认为0.05。
> > - **early_stop** (float): 是否使用提前终止训练策略。默认值为False。
> > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。
> > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
#### evaluate 评估接口
```
evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False):
```
> UNet模型评估接口。
> **参数**
> >
> > - **eval_dataset** (paddlex.datasets): 评估数据读取器。
> > - **batch_size** (int): 评估时的batch大小。默认1。
> > - **epoch_id** (int): 当前评估模型所在的训练轮数。
> > - **return_details** (bool): 是否返回详细信息。默认False。
> **返回值**
> >
> > - **dict**: 当return_details为False时,返回dict。包含关键字:'miou'、'category_iou'、'macc'、
> > 'category_acc'和'kappa',分别表示平均iou、各类别iou、平均准确率、各类别准确率和kappa系数。
> > - **tuple** (metrics, eval_details):当return_details为True时,增加返回dict (eval_details),
> > 包含关键字:'confusion_matrix',表示评估的混淆矩阵。
#### predict 预测接口
```
predict(self, im_file, transforms=None):
```
> UNet模型预测接口。需要注意的是,只有在训练过程中定义了eval_dataset,模型在保存时才会将预测时的图像处理流程保存在`UNet.test_transforms`和`UNet.eval_transforms`中。如未在训练时定义eval_dataset,那在调用预测`predict`接口时,用户需要再重新定义test_transforms传入给`predict`接口。
> **参数**
> >
> > - **img_file** (str): 预测图像路径。
> > - **transforms** (paddlex.seg.transforms): 数据预处理操作。
> **返回值**
> >
> > - **dict**: 包含关键字'label_map'和'score_map', 'label_map'存储预测结果灰度图,像素值表示对应的类别,'score_map'存储各类别的概率,shape=(h, w, num_classes)。
## HRNet类
```python ```python
paddlex.seg.HRNet(num_classes=2, width=18, use_bce_loss=False, use_dice_loss=False, class_weight=None, ignore_index=255) paddlex.seg.HRNet(num_classes=2, width=18, use_bce_loss=False, use_dice_loss=False, class_weight=None, ignore_index=255)
...@@ -192,75 +128,11 @@ paddlex.seg.HRNet(num_classes=2, width=18, use_bce_loss=False, use_dice_loss=Fal ...@@ -192,75 +128,11 @@ paddlex.seg.HRNet(num_classes=2, width=18, use_bce_loss=False, use_dice_loss=Fal
> > - **class_weight** (list|str): 交叉熵损失函数各类损失的权重。当`class_weight`为list的时候,长度应为`num_classes`。当`class_weight`为str时, weight.lower()应为'dynamic',这时会根据每一轮各类像素的比重自行计算相应的权重,每一类的权重为:每类的比例 * num_classes。class_weight取默认值None是,各类的权重1,即平时使用的交叉熵损失函数。 > > - **class_weight** (list|str): 交叉熵损失函数各类损失的权重。当`class_weight`为list的时候,长度应为`num_classes`。当`class_weight`为str时, weight.lower()应为'dynamic',这时会根据每一轮各类像素的比重自行计算相应的权重,每一类的权重为:每类的比例 * num_classes。class_weight取默认值None是,各类的权重1,即平时使用的交叉熵损失函数。
> > - **ignore_index** (int): label上忽略的值,label为`ignore_index`的像素不参与损失函数的计算。默认255。 > > - **ignore_index** (int): label上忽略的值,label为`ignore_index`的像素不参与损失函数的计算。默认255。
### train 训练接口 > - train 训练接口说明同 [DeepLabv3p模型train接口](#train)
> - evaluate 评估接口说明同 [DeepLabv3p模型evaluate接口](#evaluate)
```python > - predict 预测接口说明同 [DeepLabv3p模型predict接口](#predict)
train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, eval_batch_size=1, save_interval_epochs=1, log_interval_steps=2, save_dir='output', pretrain_weights='IMAGENET', optimizer=None, learning_rate=0.01, lr_decay_power=0.9, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None):
```
> HRNet模型训练接口。
> **参数**
> >
> > - **num_epochs** (int): 训练迭代轮数。
> > - **train_dataset** (paddlex.datasets): 训练数据读取器。
> > - **train_batch_size** (int): 训练数据batch大小。同时作为验证数据batch大小。默认2。
> > - **eval_dataset** (paddlex.datasets): 评估数据读取器。
> > - **save_interval_epochs** (int): 模型保存间隔(单位:迭代轮数)。默认为1。
> > - **log_interval_steps** (int): 训练日志输出间隔(单位:迭代次数)。默认为2。
> > - **save_dir** (str): 模型保存路径。默认'output'
> > - **pretrain_weights** (str): 若指定为路径时,则加载路径下预训练模型;若为字符串'IMAGENET',则自动下载在ImageNet数据集上预训练的模型权重;若为字符串'CITYSCAPES',则自动下载在CITYSCAPES图片数据上预训练的模型权重(注意:目前仅提供`width`取值为18的CITYSCAPES预训练模型);若为None,则不使用预训练模型。默认'IMAGENET'。
> > - **optimizer** (paddle.fluid.optimizer): 优化器。当该参数为None时,使用默认的优化器:使用fluid.optimizer.Momentum优化方法,polynomial的学习率衰减策略。
> > - **learning_rate** (float): 默认优化器的初始学习率。默认0.01。
> > - **lr_decay_power** (float): 默认优化器学习率衰减指数。默认0.9。
> > - **use_vdl** (bool): 是否使用VisualDL进行可视化。默认False。
> > - **sensitivities_file** (str): 若指定为路径时,则加载路径下敏感度信息进行裁剪;若为字符串'DEFAULT',则自动下载在Cityscapes图片数据上获得的敏感度信息进行裁剪;若为None,则不进行裁剪。默认为None。
> > - **eval_metric_loss** (float): 可容忍的精度损失。默认为0.05。
> > - **early_stop** (float): 是否使用提前终止训练策略。默认值为False。
> > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。
> > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
#### evaluate 评估接口
```
evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False):
```
> HRNet模型评估接口。 ## paddlex.seg.FastSCNN
> **参数**
> >
> > - **eval_dataset** (paddlex.datasets): 评估数据读取器。
> > - **batch_size** (int): 评估时的batch大小。默认1。
> > - **epoch_id** (int): 当前评估模型所在的训练轮数。
> > - **return_details** (bool): 是否返回详细信息。默认False。
> **返回值**
> >
> > - **dict**: 当return_details为False时,返回dict。包含关键字:'miou'、'category_iou'、'macc'、
> > 'category_acc'和'kappa',分别表示平均iou、各类别iou、平均准确率、各类别准确率和kappa系数。
> > - **tuple** (metrics, eval_details):当return_details为True时,增加返回dict (eval_details),
> > 包含关键字:'confusion_matrix',表示评估的混淆矩阵。
#### predict 预测接口
```
predict(self, im_file, transforms=None):
```
> HRNet模型预测接口。需要注意的是,只有在训练过程中定义了eval_dataset,模型在保存时才会将预测时的图像处理流程保存在`UNet.test_transforms`和`UNet.eval_transforms`中。如未在训练时定义eval_dataset,那在调用预测`predict`接口时,用户需要再重新定义test_transforms传入给`predict`接口。
> **参数**
> >
> > - **img_file** (str): 预测图像路径。
> > - **transforms** (paddlex.seg.transforms): 数据预处理操作。
> **返回值**
> >
> > - **dict**: 包含关键字'label_map'和'score_map', 'label_map'存储预测结果灰度图,像素值表示对应的类别,'score_map'存储各类别的概率,shape=(h, w, num_classes)。
## FastSCNN类
```python ```python
paddlex.seg.FastSCNN(num_classes=2, use_bce_loss=False, use_dice_loss=False, class_weight=None, ignore_index=255, multi_loss_weight=[1.0]) paddlex.seg.FastSCNN(num_classes=2, use_bce_loss=False, use_dice_loss=False, class_weight=None, ignore_index=255, multi_loss_weight=[1.0])
...@@ -277,69 +149,6 @@ paddlex.seg.FastSCNN(num_classes=2, use_bce_loss=False, use_dice_loss=False, cla ...@@ -277,69 +149,6 @@ paddlex.seg.FastSCNN(num_classes=2, use_bce_loss=False, use_dice_loss=False, cla
> > - **ignore_index** (int): label上忽略的值,label为`ignore_index`的像素不参与损失函数的计算。默认255。 > > - **ignore_index** (int): label上忽略的值,label为`ignore_index`的像素不参与损失函数的计算。默认255。
> > - **multi_loss_weight** (list): 多分支上的loss权重。默认计算一个分支上的loss,即默认值为[1.0]。也支持计算两个分支或三个分支上的loss,权重按[fusion_branch_weight, higher_branch_weight, lower_branch_weight]排列,fusion_branch_weight为空间细节分支和全局上下文分支融合后的分支上的loss权重,higher_branch_weight为空间细节分支上的loss权重,lower_branch_weight为全局上下文分支上的loss权重,若higher_branch_weight和lower_branch_weight未设置则不会计算这两个分支上的loss。 > > - **multi_loss_weight** (list): 多分支上的loss权重。默认计算一个分支上的loss,即默认值为[1.0]。也支持计算两个分支或三个分支上的loss,权重按[fusion_branch_weight, higher_branch_weight, lower_branch_weight]排列,fusion_branch_weight为空间细节分支和全局上下文分支融合后的分支上的loss权重,higher_branch_weight为空间细节分支上的loss权重,lower_branch_weight为全局上下文分支上的loss权重,若higher_branch_weight和lower_branch_weight未设置则不会计算这两个分支上的loss。
### train 训练接口 > - train 训练接口说明同 [DeepLabv3p模型train接口](#train)
> - evaluate 评估接口说明同 [DeepLabv3p模型evaluate接口](#evaluate)
```python > - predict 预测接口说明同 [DeepLabv3p模型predict接口](#predict)
train(self, num_epochs, train_dataset, train_batch_size=2, eval_dataset=None, eval_batch_size=1, save_interval_epochs=1, log_interval_steps=2, save_dir='output', pretrain_weights='CITYSCAPES', optimizer=None, learning_rate=0.01, lr_decay_power=0.9, use_vdl=False, sensitivities_file=None, eval_metric_loss=0.05, early_stop=False, early_stop_patience=5, resume_checkpoint=None):
```
> FastSCNN模型训练接口。
> **参数**
> >
> > - **num_epochs** (int): 训练迭代轮数。
> > - **train_dataset** (paddlex.datasets): 训练数据读取器。
> > - **train_batch_size** (int): 训练数据batch大小。同时作为验证数据batch大小。默认2。
> > - **eval_dataset** (paddlex.datasets): 评估数据读取器。
> > - **save_interval_epochs** (int): 模型保存间隔(单位:迭代轮数)。默认为1。
> > - **log_interval_steps** (int): 训练日志输出间隔(单位:迭代次数)。默认为2。
> > - **save_dir** (str): 模型保存路径。默认'output'
> > - **pretrain_weights** (str): 若指定为路径时,则加载路径下预训练模型;若为字符串'CITYSCAPES',则自动下载在CITYSCAPES图片数据上预训练的模型权重;若为None,则不使用预训练模型。默认'CITYSCAPES'。
> > - **optimizer** (paddle.fluid.optimizer): 优化器。当该参数为None时,使用默认的优化器:使用fluid.optimizer.Momentum优化方法,polynomial的学习率衰减策略。
> > - **learning_rate** (float): 默认优化器的初始学习率。默认0.01。
> > - **lr_decay_power** (float): 默认优化器学习率衰减指数。默认0.9。
> > - **use_vdl** (bool): 是否使用VisualDL进行可视化。默认False。
> > - **sensitivities_file** (str): 若指定为路径时,则加载路径下敏感度信息进行裁剪;若为字符串'DEFAULT',则自动下载在Cityscapes图片数据上获得的敏感度信息进行裁剪;若为None,则不进行裁剪。默认为None。
> > - **eval_metric_loss** (float): 可容忍的精度损失。默认为0.05。
> > - **early_stop** (float): 是否使用提前终止训练策略。默认值为False。
> > - **early_stop_patience** (int): 当使用提前终止训练策略时,如果验证集精度在`early_stop_patience`个epoch内连续下降或持平,则终止训练。默认值为5。
> > - **resume_checkpoint** (str): 恢复训练时指定上次训练保存的模型路径。若为None,则不会恢复训练。默认值为None。
#### evaluate 评估接口
```
evaluate(self, eval_dataset, batch_size=1, epoch_id=None, return_details=False):
```
> FastSCNN模型评估接口。
> **参数**
> >
> > - **eval_dataset** (paddlex.datasets): 评估数据读取器。
> > - **batch_size** (int): 评估时的batch大小。默认1。
> > - **epoch_id** (int): 当前评估模型所在的训练轮数。
> > - **return_details** (bool): 是否返回详细信息。默认False。
> **返回值**
> >
> > - **dict**: 当return_details为False时,返回dict。包含关键字:'miou'、'category_iou'、'macc'、
> > 'category_acc'和'kappa',分别表示平均iou、各类别iou、平均准确率、各类别准确率和kappa系数。
> > - **tuple** (metrics, eval_details):当return_details为True时,增加返回dict (eval_details),
> > 包含关键字:'confusion_matrix',表示评估的混淆矩阵。
#### predict 预测接口
```
predict(self, im_file, transforms=None):
```
> FastSCNN模型预测接口。需要注意的是,只有在训练过程中定义了eval_dataset,模型在保存时才会将预测时的图像处理流程保存在`UNet.test_transforms`和`UNet.eval_transforms`中。如未在训练时定义eval_dataset,那在调用预测`predict`接口时,用户需要再重新定义test_transforms传入给`predict`接口。
> **参数**
> >
> > - **img_file** (str): 预测图像路径。
> > - **transforms** (paddlex.seg.transforms): 数据预处理操作。
> **返回值**
> >
> > - **dict**: 包含关键字'label_map'和'score_map', 'label_map'存储预测结果灰度图,像素值表示对应的类别,'score_map'存储各类别的概率,shape=(h, w, num_classes)。
# 模型压缩-slim # 模型压缩
## 计算参数敏感度 ## paddlex.slim.cal_params_sensitivities
> **计算参数敏感度**
``` ```
paddlex.slim.cal_params_sensitivities(model, save_file, eval_dataset, batch_size=8) paddlex.slim.cal_params_sensitivities(model, save_file, eval_dataset, batch_size=8)
``` ```
...@@ -18,7 +19,8 @@ paddlex.slim.cal_params_sensitivities(model, save_file, eval_dataset, batch_size ...@@ -18,7 +19,8 @@ paddlex.slim.cal_params_sensitivities(model, save_file, eval_dataset, batch_size
* **batch_size** (int): 评估时的batch_size大小。 * **batch_size** (int): 评估时的batch_size大小。
## 导出量化模型 ## paddlex.slim.export_quant_model
> **导出量化模型**
``` ```
paddlex.slim.export_quant_model(model, test_dataset, batch_size=2, batch_num=10, save_dir='./quant_model', cache_dir='./temp') paddlex.slim.export_quant_model(model, test_dataset, batch_size=2, batch_num=10, save_dir='./quant_model', cache_dir='./temp')
``` ```
......
# 图像分类-cls.transforms # paddlex.cls.transforms
对图像分类任务的数据进行操作。可以利用[Compose](#compose)类将图像预处理/增强操作进行组合。 对图像分类任务的数据进行操作。可以利用[Compose](#compose)类将图像预处理/增强操作进行组合。
## Compose ## Compose
```python ```python
paddlex.cls.transforms.Compose(transforms) paddlex.cls.transforms.Compose(transforms)
``` ```
根据数据预处理/增强算子对输入数据进行操作。 [使用示例](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/classification/mobilenetv2.py#L13) 根据数据预处理/增强算子对输入数据进行操作。 [使用示例](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/classification/mobilenetv2.py#L13)
### 参数 > **参数**
* **transforms** (list): 数据预处理/数据增强列表。 > * **transforms** (list): 数据预处理/数据增强列表。
## RandomCrop类
```python
paddlex.cls.transforms.RandomCrop(crop_size=224, lower_scale=0.08, lower_ratio=3. / 4, upper_ratio=4. / 3)
```
对图像进行随机剪裁,模型训练时的数据增强操作。
1. 根据lower_scale、lower_ratio、upper_ratio计算随机剪裁的高、宽。
2. 根据随机剪裁的高、宽随机选取剪裁的起始点。
3. 剪裁图像。
4. 调整剪裁后的图像的大小到crop_size*crop_size。
### 参数
* **crop_size** (int): 随机裁剪后重新调整的目标边长。默认为224。
* **lower_scale** (float): 裁剪面积相对原面积比例的最小限制。默认为0.08。
* **lower_ratio** (float): 宽变换比例的最小限制。默认为3. / 4。
* **upper_ratio** (float): 宽变换比例的最小限制。默认为4. / 3。
## RandomHorizontalFlip类
```python
paddlex.cls.transforms.RandomHorizontalFlip(prob=0.5)
```
以一定的概率对图像进行随机水平翻转,模型训练时的数据增强操作。
### 参数
* **prob** (float): 随机水平翻转的概率。默认为0.5。
## RandomVerticalFlip类
```python
paddlex.cls.transforms.RandomVerticalFlip(prob=0.5)
```
以一定的概率对图像进行随机垂直翻转,模型训练时的数据增强操作。
### 参数
* **prob** (float): 随机垂直翻转的概率。默认为0.5。
## Normalize ## Normalize
```python ```python
paddlex.cls.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) paddlex.cls.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
``` ```
...@@ -63,7 +25,7 @@ paddlex.cls.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, ...@@ -63,7 +25,7 @@ paddlex.cls.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224,
* **mean** (list): 图像数据集的均值。默认为[0.485, 0.456, 0.406]。 * **mean** (list): 图像数据集的均值。默认为[0.485, 0.456, 0.406]。
* **std** (list): 图像数据集的标准差。默认为[0.229, 0.224, 0.225]。 * **std** (list): 图像数据集的标准差。默认为[0.229, 0.224, 0.225]。
## ResizeByShort ## ResizeByShort
```python ```python
paddlex.cls.transforms.ResizeByShort(short_size=256, max_size=-1) paddlex.cls.transforms.ResizeByShort(short_size=256, max_size=-1)
``` ```
...@@ -79,7 +41,7 @@ paddlex.cls.transforms.ResizeByShort(short_size=256, max_size=-1) ...@@ -79,7 +41,7 @@ paddlex.cls.transforms.ResizeByShort(short_size=256, max_size=-1)
* **short_size** (int): 调整大小后的图像目标短边长度。默认为256。 * **short_size** (int): 调整大小后的图像目标短边长度。默认为256。
* **max_size** (int): 长边目标长度的最大限制。默认为-1。 * **max_size** (int): 长边目标长度的最大限制。默认为-1。
## CenterCrop ## CenterCrop
```python ```python
paddlex.cls.transforms.CenterCrop(crop_size=224) paddlex.cls.transforms.CenterCrop(crop_size=224)
``` ```
...@@ -91,7 +53,44 @@ paddlex.cls.transforms.CenterCrop(crop_size=224) ...@@ -91,7 +53,44 @@ paddlex.cls.transforms.CenterCrop(crop_size=224)
### 参数 ### 参数
* **crop_size** (int): 裁剪的目标边长。默认为224。 * **crop_size** (int): 裁剪的目标边长。默认为224。
## RandomRotate类 ## RandomCrop
```python
paddlex.cls.transforms.RandomCrop(crop_size=224, lower_scale=0.08, lower_ratio=3. / 4, upper_ratio=4. / 3)
```
对图像进行随机剪裁,模型训练时的数据增强操作。
1. 根据lower_scale、lower_ratio、upper_ratio计算随机剪裁的高、宽。
2. 根据随机剪裁的高、宽随机选取剪裁的起始点。
3. 剪裁图像。
4. 调整剪裁后的图像的大小到crop_size*crop_size。
### 参数
* **crop_size** (int): 随机裁剪后重新调整的目标边长。默认为224。
* **lower_scale** (float): 裁剪面积相对原面积比例的最小限制。默认为0.08。
* **lower_ratio** (float): 宽变换比例的最小限制。默认为3. / 4。
* **upper_ratio** (float): 宽变换比例的最小限制。默认为4. / 3。
## RandomHorizontalFlip
```python
paddlex.cls.transforms.RandomHorizontalFlip(prob=0.5)
```
以一定的概率对图像进行随机水平翻转,模型训练时的数据增强操作。
### 参数
* **prob** (float): 随机水平翻转的概率。默认为0.5。
## RandomVerticalFlip
```python
paddlex.cls.transforms.RandomVerticalFlip(prob=0.5)
```
以一定的概率对图像进行随机垂直翻转,模型训练时的数据增强操作。
### 参数
* **prob** (float): 随机垂直翻转的概率。默认为0.5。
## RandomRotate
```python ```python
paddlex.cls.transforms.RandomRotate(rotate_range=30, prob=0.5) paddlex.cls.transforms.RandomRotate(rotate_range=30, prob=0.5)
``` ```
...@@ -102,7 +101,7 @@ paddlex.cls.transforms.RandomRotate(rotate_range=30, prob=0.5) ...@@ -102,7 +101,7 @@ paddlex.cls.transforms.RandomRotate(rotate_range=30, prob=0.5)
* **rotate_range** (int): 旋转度数的范围。默认为30。 * **rotate_range** (int): 旋转度数的范围。默认为30。
* **prob** (float): 随机旋转的概率。默认为0.5。 * **prob** (float): 随机旋转的概率。默认为0.5。
## RandomDistort ## RandomDistort
```python ```python
paddlex.cls.transforms.RandomDistort(brightness_range=0.9, brightness_prob=0.5, contrast_range=0.9, contrast_prob=0.5, saturation_range=0.9, saturation_prob=0.5, hue_range=18, hue_prob=0.5) paddlex.cls.transforms.RandomDistort(brightness_range=0.9, brightness_prob=0.5, contrast_range=0.9, contrast_prob=0.5, saturation_range=0.9, saturation_prob=0.5, hue_range=18, hue_prob=0.5)
``` ```
...@@ -123,15 +122,15 @@ paddlex.cls.transforms.RandomDistort(brightness_range=0.9, brightness_prob=0.5, ...@@ -123,15 +122,15 @@ paddlex.cls.transforms.RandomDistort(brightness_range=0.9, brightness_prob=0.5,
* **hue_range** (int): 色调因子的范围。默认为18。 * **hue_range** (int): 色调因子的范围。默认为18。
* **hue_prob** (float): 随机调整色调的概率。默认为0.5。 * **hue_prob** (float): 随机调整色调的概率。默认为0.5。
## ComposedClsTransforms ## ComposedClsTransforms
```python ```python
paddlex.cls.transforms.ComposedClsTransforms(mode, crop_size=[224, 224], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) paddlex.cls.transforms.ComposedClsTransforms(mode, crop_size=[224, 224], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], random_horizontal_flip=True)
``` ```
分类模型中已经组合好的数据处理流程,开发者可以直接使用ComposedClsTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomCrop](#RandomCrop)[RandomHorizontalFlip](#RandomHorizontalFlip)两种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 分类模型中已经组合好的数据处理流程,开发者可以直接使用ComposedClsTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomCrop](#RandomCrop)[RandomHorizontalFlip](#RandomHorizontalFlip)两种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。
ComposedClsTransforms共包括以下几个步骤: ComposedClsTransforms共包括以下几个步骤:
> 训练阶段: > 训练阶段:
> > 1. 随机从图像中crop一块子图,并resize成crop_size大小 > > 1. 随机从图像中crop一块子图,并resize成crop_size大小
> > 2. 将1的输出按0.5的概率随机进行水平翻转 > > 2. 将1的输出按0.5的概率随机进行水平翻转, 若random_horizontal_flip为False,则跳过此步骤
> > 3. 将图像进行归一化 > > 3. 将图像进行归一化
> 验证/预测阶段: > 验证/预测阶段:
> > 1. 将图像按比例Resize,使得最小边长度为crop_size[0] * 1.14 > > 1. 将图像按比例Resize,使得最小边长度为crop_size[0] * 1.14
...@@ -143,6 +142,7 @@ ComposedClsTransforms共包括以下几个步骤: ...@@ -143,6 +142,7 @@ ComposedClsTransforms共包括以下几个步骤:
* **crop_size** (int|list): 输入到模型里的图像大小,默认为[224, 224](与原图大小无关,根据上述几个步骤,会将原图处理成该图大小输入给模型训练) * **crop_size** (int|list): 输入到模型里的图像大小,默认为[224, 224](与原图大小无关,根据上述几个步骤,会将原图处理成该图大小输入给模型训练)
* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 * **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。
* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 * **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。
* **random_horizontal_flip**(bool): 数据增强,是否以0,5的概率使用随机水平翻转增强,仅在model为'train'时生效,默认为True。底层实现采用[paddlex.cls.transforms.RandomHorizontalFlip](#randomhorizontalflip)
### 添加数据增强方式 ### 添加数据增强方式
```python ```python
......
# 检测和实例分割-det.transforms # paddlex.det.transforms
对目标检测任务的数据进行操作。可以利用[Compose](#compose)类将图像预处理/增强操作进行组合。 对目标检测/实例分割任务的数据进行操作。可以利用[Compose](#compose)类将图像预处理/增强操作进行组合。
## Compose ## Compose
```python ```python
paddlex.det.transforms.Compose(transforms) paddlex.det.transforms.Compose(transforms)
``` ```
...@@ -12,7 +12,20 @@ paddlex.det.transforms.Compose(transforms) ...@@ -12,7 +12,20 @@ paddlex.det.transforms.Compose(transforms)
### 参数 ### 参数
* **transforms** (list): 数据预处理/数据增强列表。 * **transforms** (list): 数据预处理/数据增强列表。
## ResizeByShort类 ## Normalize
```python
paddlex.det.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
```
对图像进行标准化。
1. 归一化图像到到区间[0.0, 1.0]。
2. 对图像进行减均值除以标准差操作。
### 参数
* **mean** (list): 图像数据集的均值。默认为[0.485, 0.456, 0.406]。
* **std** (list): 图像数据集的标准差。默认为[0.229, 0.224, 0.225]。
## ResizeByShort
```python ```python
paddlex.det.transforms.ResizeByShort(short_size=800, max_size=1333) paddlex.det.transforms.ResizeByShort(short_size=800, max_size=1333)
``` ```
...@@ -28,7 +41,7 @@ paddlex.det.transforms.ResizeByShort(short_size=800, max_size=1333) ...@@ -28,7 +41,7 @@ paddlex.det.transforms.ResizeByShort(short_size=800, max_size=1333)
* **short_size** (int): 短边目标长度。默认为800。 * **short_size** (int): 短边目标长度。默认为800。
* **max_size** (int): 长边目标长度的最大限制。默认为1333。 * **max_size** (int): 长边目标长度的最大限制。默认为1333。
## Padding ## Padding
```python ```python
paddlex.det.transforms.Padding(coarsest_stride=1) paddlex.det.transforms.Padding(coarsest_stride=1)
``` ```
...@@ -41,7 +54,7 @@ paddlex.det.transforms.Padding(coarsest_stride=1) ...@@ -41,7 +54,7 @@ paddlex.det.transforms.Padding(coarsest_stride=1)
### 参数 ### 参数
* **coarsest_stride** (int): 填充后的图像长、宽为该参数的倍数,默认为1。 * **coarsest_stride** (int): 填充后的图像长、宽为该参数的倍数,默认为1。
## Resize ## Resize
```python ```python
paddlex.det.transforms.Resize(target_size=608, interp='LINEAR') paddlex.det.transforms.Resize(target_size=608, interp='LINEAR')
``` ```
...@@ -55,7 +68,7 @@ paddlex.det.transforms.Resize(target_size=608, interp='LINEAR') ...@@ -55,7 +68,7 @@ paddlex.det.transforms.Resize(target_size=608, interp='LINEAR')
* **target_size** (int/list/tuple): 短边目标长度。默认为608。 * **target_size** (int/list/tuple): 短边目标长度。默认为608。
* **interp** (str): resize的插值方式,与opencv的插值方式对应,取值范围为['NEAREST', 'LINEAR', 'CUBIC', 'AREA', 'LANCZOS4', 'RANDOM']。默认为"LINEAR"。 * **interp** (str): resize的插值方式,与opencv的插值方式对应,取值范围为['NEAREST', 'LINEAR', 'CUBIC', 'AREA', 'LANCZOS4', 'RANDOM']。默认为"LINEAR"。
## RandomHorizontalFlip ## RandomHorizontalFlip
```python ```python
paddlex.det.transforms.RandomHorizontalFlip(prob=0.5) paddlex.det.transforms.RandomHorizontalFlip(prob=0.5)
``` ```
...@@ -65,20 +78,7 @@ paddlex.det.transforms.RandomHorizontalFlip(prob=0.5) ...@@ -65,20 +78,7 @@ paddlex.det.transforms.RandomHorizontalFlip(prob=0.5)
### 参数 ### 参数
* **prob** (float): 随机水平翻转的概率。默认为0.5。 * **prob** (float): 随机水平翻转的概率。默认为0.5。
## Normalize类 ## RandomDistort
```python
paddlex.det.transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
```
对图像进行标准化。
1. 归一化图像到到区间[0.0, 1.0]。
2. 对图像进行减均值除以标准差操作。
### 参数
* **mean** (list): 图像数据集的均值。默认为[0.485, 0.456, 0.406]。
* **std** (list): 图像数据集的标准差。默认为[0.229, 0.224, 0.225]。
## RandomDistort类
```python ```python
paddlex.det.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5, contrast_range=0.5, contrast_prob=0.5, saturation_range=0.5, saturation_prob=0.5, hue_range=18, hue_prob=0.5) paddlex.det.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5, contrast_range=0.5, contrast_prob=0.5, saturation_range=0.5, saturation_prob=0.5, hue_range=18, hue_prob=0.5)
``` ```
...@@ -99,7 +99,7 @@ paddlex.det.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5, ...@@ -99,7 +99,7 @@ paddlex.det.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5,
* **hue_range** (int): 色调因子的范围。默认为18。 * **hue_range** (int): 色调因子的范围。默认为18。
* **hue_prob** (float): 随机调整色调的概率。默认为0.5。 * **hue_prob** (float): 随机调整色调的概率。默认为0.5。
## MixupImage ## MixupImage
```python ```python
paddlex.det.transforms.MixupImage(alpha=1.5, beta=1.5, mixup_epoch=-1) paddlex.det.transforms.MixupImage(alpha=1.5, beta=1.5, mixup_epoch=-1)
``` ```
...@@ -141,7 +141,7 @@ paddlex.det.transforms.RandomExpand(ratio=4., prob=0.5, fill_value=[123.675, 116 ...@@ -141,7 +141,7 @@ paddlex.det.transforms.RandomExpand(ratio=4., prob=0.5, fill_value=[123.675, 116
【注意】该数据增强必须在数据增强Resize、ResizeByShort之前使用。 【注意】该数据增强必须在数据增强Resize、ResizeByShort之前使用。
## RandomCrop ## RandomCrop
```python ```python
paddlex.det.transforms.RandomCrop(aspect_ratio=[.5, 2.], thresholds=[.0, .1, .3, .5, .7, .9], scaling=[.3, 1.], num_attempts=50, allow_no_crop=True, cover_all_box=False) paddlex.det.transforms.RandomCrop(aspect_ratio=[.5, 2.], thresholds=[.0, .1, .3, .5, .7, .9], scaling=[.3, 1.], num_attempts=50, allow_no_crop=True, cover_all_box=False)
``` ```
...@@ -168,14 +168,14 @@ paddlex.det.transforms.RandomCrop(aspect_ratio=[.5, 2.], thresholds=[.0, .1, .3, ...@@ -168,14 +168,14 @@ paddlex.det.transforms.RandomCrop(aspect_ratio=[.5, 2.], thresholds=[.0, .1, .3,
* **allow_no_crop** (bool): 是否允许未进行裁剪。默认值为True。 * **allow_no_crop** (bool): 是否允许未进行裁剪。默认值为True。
* **cover_all_box** (bool): 是否要求所有的真实标注框都必须在裁剪区域内。默认值为False。 * **cover_all_box** (bool): 是否要求所有的真实标注框都必须在裁剪区域内。默认值为False。
## ComposedRCNNTransforms ## ComposedRCNNTransforms
```python ```python
paddlex.det.transforms.ComposedRCNNTransforms(mode, min_max_size=[224, 224], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) paddlex.det.transforms.ComposedRCNNTransforms(mode, min_max_size=[224, 224], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], random_horizontal_flip=True)
``` ```
目标检测FasterRCNN和实例分割MaskRCNN模型中已经组合好的数据处理流程,开发者可以直接使用ComposedRCNNTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomHorizontalFlip](#RandomHorizontalFlip)数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 目标检测FasterRCNN和实例分割MaskRCNN模型中已经组合好的数据处理流程,开发者可以直接使用ComposedRCNNTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomHorizontalFlip](#RandomHorizontalFlip)数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。
ComposedRCNNTransforms共包括以下几个步骤: ComposedRCNNTransforms共包括以下几个步骤:
> 训练阶段: > 训练阶段:
> > 1. 随机以0.5的概率将图像水平翻转 > > 1. 随机以0.5的概率将图像水平翻转, 若random_horizontal_flip为False,则跳过此步骤
> > 2. 将图像进行归一化 > > 2. 将图像进行归一化
> > 3. 图像采用[ResizeByShort](#ResizeByShort)方式,根据min_max_size参数,进行缩入 > > 3. 图像采用[ResizeByShort](#ResizeByShort)方式,根据min_max_size参数,进行缩入
> > 4. 使用[Padding](#Padding)将图像的长和宽分别Padding成32的倍数 > > 4. 使用[Padding](#Padding)将图像的长和宽分别Padding成32的倍数
...@@ -189,6 +189,7 @@ ComposedRCNNTransforms共包括以下几个步骤: ...@@ -189,6 +189,7 @@ ComposedRCNNTransforms共包括以下几个步骤:
* **min_max_size** (list): 输入模型中图像的最短边长度和最长边长度,参考[ResizeByShort](#ResizeByShort)(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练),默认[800, 1333] * **min_max_size** (list): 输入模型中图像的最短边长度和最长边长度,参考[ResizeByShort](#ResizeByShort)(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练),默认[800, 1333]
* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 * **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。
* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 * **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。
* **random_horizontal_flip**(bool): 数据增强,是否以0.5的概率使用随机水平翻转增强,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomHorizontalFlip](#randomhorizontalflip)
### 添加数据增强方式 ### 添加数据增强方式
```python ```python
...@@ -232,19 +233,19 @@ eval_transforms = transforms.Composed([ ...@@ -232,19 +233,19 @@ eval_transforms = transforms.Composed([
``` ```
## ComposedYOLOv3Transforms ## ComposedYOLOv3Transforms
```python ```python
paddlex.det.transforms.ComposedYOLOv3Transforms(mode, shape=[608, 608], mixup_epoch=250, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) paddlex.det.transforms.ComposedYOLOv3Transforms(mode, shape=[608, 608], mixup_epoch=250, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], random_distort=True, random_expand=True, random_crop=True, random_horizontal_flip=True)
``` ```
目标检测YOLOv3模型中已经组合好的数据处理流程,开发者可以直接使用ComposedYOLOv3Transforms,简化手动组合transforms的过程, 该类中已经包含了[MixupImage](#MixupImage)、[RandomDistort](#RandomDistort)、[RandomExpand](#RandomExpand)、[RandomCrop](#RandomCrop)、[RandomHorizontalFlip](#RandomHorizontalFlip)5种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 目标检测YOLOv3模型中已经组合好的数据处理流程,开发者可以直接使用ComposedYOLOv3Transforms,简化手动组合transforms的过程, 该类中已经包含了[MixupImage](#MixupImage)、[RandomDistort](#RandomDistort)、[RandomExpand](#RandomExpand)、[RandomCrop](#RandomCrop)、[RandomHorizontalFlip](#RandomHorizontalFlip)5种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。
ComposedYOLOv3Transforms共包括以下几个步骤: ComposedYOLOv3Transforms共包括以下几个步骤:
> 训练阶段: > 训练阶段:
> > 1. 在前mixup_epoch轮迭代中,使用MixupImage策略 > > 1. 在前mixup_epoch轮迭代中,使用MixupImage策略,若mixup_epoch为-1,则跳过此步骤
> > 2. 对图像进行随机扰动,包括亮度,对比度,饱和度和色调 > > 2. 对图像进行随机扰动,包括亮度,对比度,饱和度和色调,若random_distort为False,则跳过此步骤
> > 3. 随机扩充图像 > > 3. 随机扩充图像,若random_expand为False, 则跳过此步骤
> > 4. 随机裁剪图像 > > 4. 随机裁剪图像,若random_crop为False, 则跳过此步骤
> > 5. 将4步骤的输出图像Resize成shape参数的大小 > > 5. 将4步骤的输出图像Resize成shape参数的大小
> > 6. 随机0.5的概率水平翻转图像 > > 6. 随机0.5的概率水平翻转图像,若random_horizontal_flip为False,则跳过此步骤
> > 7. 图像归一化 > > 7. 图像归一化
> 验证/预测阶段: > 验证/预测阶段:
> > 1. 将图像Resize成shape参数大小 > > 1. 将图像Resize成shape参数大小
...@@ -253,9 +254,13 @@ ComposedYOLOv3Transforms共包括以下几个步骤: ...@@ -253,9 +254,13 @@ ComposedYOLOv3Transforms共包括以下几个步骤:
### 参数 ### 参数
* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' * **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test'
* **shape** (list): 输入模型中图像的大小(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练), 默认[608, 608] * **shape** (list): 输入模型中图像的大小(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练), 默认[608, 608]
* **mixup_epoch**(int): 模型训练过程中,在前mixup_epoch轮迭代中,使用mixup策略,如果为-1,则不使用mixup策略, 默认250。 * **mixup_epoch**(int): 模型训练过程中,在前mixup_epoch轮迭代中,使用mixup策略,如果为-1,则不使用mixup策略, 默认250。底层实现采用[paddlex.det.transforms.MixupImage](#mixupimage)
* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 * **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。
* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 * **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。
* **random_distort**(bool): 数据增强,是否在训练过程中随机扰动图像,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomDistort](#randomdistort)
* **random_expand**(bool): 数据增强,是否在训练过程随机扩张图像,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomExpand](#randomexpand)
* **random_crop**(bool): 数据增强,是否在训练过程中随机裁剪图像,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomCrop](#randomcrop)
* **random_horizontal_flip**(bool): 数据增强,是否在训练过程中随机水平翻转图像,仅在mode为'train'时生效,默认为True。底层实现采用[paddlex.det.transforms.RandomHorizontalFlip](#randomhorizontalflip)
### 添加数据增强方式 ### 添加数据增强方式
```python ```python
......
数据处理-transforms 数据处理与增强
============================ ============================
transforms为PaddleX的模型训练提供了数据的预处理和数据增强接口。 transforms为PaddleX的模型训练提供了数据的预处理和数据增强接口。
......
# 语义分割-seg.transforms # paddlex.seg.transforms
对用于分割任务的数据进行操作。可以利用[Compose](#compose)类将图像预处理/增强操作进行组合。 对用于分割任务的数据进行操作。可以利用[Compose](#compose)类将图像预处理/增强操作进行组合。
## Compose ## Compose
```python ```python
paddlex.seg.transforms.Compose(transforms) paddlex.seg.transforms.Compose(transforms)
``` ```
...@@ -12,7 +12,7 @@ paddlex.seg.transforms.Compose(transforms) ...@@ -12,7 +12,7 @@ paddlex.seg.transforms.Compose(transforms)
* **transforms** (list): 数据预处理/数据增强列表。 * **transforms** (list): 数据预处理/数据增强列表。
## RandomHorizontalFlip ## RandomHorizontalFlip
```python ```python
paddlex.seg.transforms.RandomHorizontalFlip(prob=0.5) paddlex.seg.transforms.RandomHorizontalFlip(prob=0.5)
``` ```
...@@ -21,7 +21,7 @@ paddlex.seg.transforms.RandomHorizontalFlip(prob=0.5) ...@@ -21,7 +21,7 @@ paddlex.seg.transforms.RandomHorizontalFlip(prob=0.5)
* **prob** (float): 随机水平翻转的概率。默认值为0.5。 * **prob** (float): 随机水平翻转的概率。默认值为0.5。
## RandomVerticalFlip ## RandomVerticalFlip
```python ```python
paddlex.seg.transforms.RandomVerticalFlip(prob=0.1) paddlex.seg.transforms.RandomVerticalFlip(prob=0.1)
``` ```
...@@ -30,7 +30,7 @@ paddlex.seg.transforms.RandomVerticalFlip(prob=0.1) ...@@ -30,7 +30,7 @@ paddlex.seg.transforms.RandomVerticalFlip(prob=0.1)
* **prob** (float): 随机垂直翻转的概率。默认值为0.1。 * **prob** (float): 随机垂直翻转的概率。默认值为0.1。
## Resize ## Resize
```python ```python
paddlex.seg.transforms.Resize(target_size, interp='LINEAR') paddlex.seg.transforms.Resize(target_size, interp='LINEAR')
``` ```
...@@ -46,7 +46,7 @@ paddlex.seg.transforms.Resize(target_size, interp='LINEAR') ...@@ -46,7 +46,7 @@ paddlex.seg.transforms.Resize(target_size, interp='LINEAR')
可选的值为['NEAREST', 'LINEAR', 'CUBIC', 'AREA', 'LANCZOS4'],默认为"LINEAR"。 可选的值为['NEAREST', 'LINEAR', 'CUBIC', 'AREA', 'LANCZOS4'],默认为"LINEAR"。
## ResizeByLong ## ResizeByLong
```python ```python
paddlex.seg.transforms.ResizeByLong(long_size) paddlex.seg.transforms.ResizeByLong(long_size)
``` ```
...@@ -55,7 +55,7 @@ paddlex.seg.transforms.ResizeByLong(long_size) ...@@ -55,7 +55,7 @@ paddlex.seg.transforms.ResizeByLong(long_size)
* **long_size** (int): resize后图像的长边大小。 * **long_size** (int): resize后图像的长边大小。
## ResizeRangeScaling ## ResizeRangeScaling
```python ```python
paddlex.seg.transforms.ResizeRangeScaling(min_value=400, max_value=600) paddlex.seg.transforms.ResizeRangeScaling(min_value=400, max_value=600)
``` ```
...@@ -65,7 +65,7 @@ paddlex.seg.transforms.ResizeRangeScaling(min_value=400, max_value=600) ...@@ -65,7 +65,7 @@ paddlex.seg.transforms.ResizeRangeScaling(min_value=400, max_value=600)
* **max_value** (int): 图像长边resize后的最大值。默认值600。 * **max_value** (int): 图像长边resize后的最大值。默认值600。
## ResizeStepScaling ## ResizeStepScaling
```python ```python
paddlex.seg.transforms.ResizeStepScaling(min_scale_factor=0.75, max_scale_factor=1.25, scale_step_size=0.25) paddlex.seg.transforms.ResizeStepScaling(min_scale_factor=0.75, max_scale_factor=1.25, scale_step_size=0.25)
``` ```
...@@ -76,7 +76,7 @@ paddlex.seg.transforms.ResizeStepScaling(min_scale_factor=0.75, max_scale_factor ...@@ -76,7 +76,7 @@ paddlex.seg.transforms.ResizeStepScaling(min_scale_factor=0.75, max_scale_factor
* **scale_step_size** (float), resize尺度范围间隔。默认值0.25。 * **scale_step_size** (float), resize尺度范围间隔。默认值0.25。
## Normalize ## Normalize
```python ```python
paddlex.seg.transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) paddlex.seg.transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
``` ```
...@@ -89,7 +89,7 @@ paddlex.seg.transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) ...@@ -89,7 +89,7 @@ paddlex.seg.transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
* **std** (list): 图像数据集的标准差。默认值[0.5, 0.5, 0.5]。 * **std** (list): 图像数据集的标准差。默认值[0.5, 0.5, 0.5]。
## Padding ## Padding
```python ```python
paddlex.seg.transforms.Padding(target_size, im_padding_value=[127.5, 127.5, 127.5], label_padding_value=255) paddlex.seg.transforms.Padding(target_size, im_padding_value=[127.5, 127.5, 127.5], label_padding_value=255)
``` ```
...@@ -100,7 +100,7 @@ paddlex.seg.transforms.Padding(target_size, im_padding_value=[127.5, 127.5, 127. ...@@ -100,7 +100,7 @@ paddlex.seg.transforms.Padding(target_size, im_padding_value=[127.5, 127.5, 127.
* **label_padding_value** (int): 标注图像padding的值。默认值为255(仅在训练时需要设定该参数)。 * **label_padding_value** (int): 标注图像padding的值。默认值为255(仅在训练时需要设定该参数)。
## RandomPaddingCrop ## RandomPaddingCrop
```python ```python
paddlex.seg.transforms.RandomPaddingCrop(crop_size=512, im_padding_value=[127.5, 127.5, 127.5], label_padding_value=255) paddlex.seg.transforms.RandomPaddingCrop(crop_size=512, im_padding_value=[127.5, 127.5, 127.5], label_padding_value=255)
``` ```
...@@ -111,7 +111,7 @@ paddlex.seg.transforms.RandomPaddingCrop(crop_size=512, im_padding_value=[127.5, ...@@ -111,7 +111,7 @@ paddlex.seg.transforms.RandomPaddingCrop(crop_size=512, im_padding_value=[127.5,
* **label_padding_value** (int): 标注图像padding的值。默认值为255。 * **label_padding_value** (int): 标注图像padding的值。默认值为255。
## RandomBlur ## RandomBlur
```python ```python
paddlex.seg.transforms.RandomBlur(prob=0.1) paddlex.seg.transforms.RandomBlur(prob=0.1)
``` ```
...@@ -120,7 +120,7 @@ paddlex.seg.transforms.RandomBlur(prob=0.1) ...@@ -120,7 +120,7 @@ paddlex.seg.transforms.RandomBlur(prob=0.1)
* **prob** (float): 图像模糊概率。默认为0.1。 * **prob** (float): 图像模糊概率。默认为0.1。
## RandomRotate ## RandomRotate
```python ```python
paddlex.seg.transforms.RandomRotate(rotate_range=15, im_padding_value=[127.5, 127.5, 127.5], label_padding_value=255) paddlex.seg.transforms.RandomRotate(rotate_range=15, im_padding_value=[127.5, 127.5, 127.5], label_padding_value=255)
``` ```
...@@ -134,7 +134,7 @@ paddlex.seg.transforms.RandomRotate(rotate_range=15, im_padding_value=[127.5, 12 ...@@ -134,7 +134,7 @@ paddlex.seg.transforms.RandomRotate(rotate_range=15, im_padding_value=[127.5, 12
* **label_padding_value** (int): 标注图像padding的值。默认为255。 * **label_padding_value** (int): 标注图像padding的值。默认为255。
## RandomScaleAspect ## RandomScaleAspect
```python ```python
paddlex.seg.transforms.RandomScaleAspect(min_scale=0.5, aspect_ratio=0.33) paddlex.seg.transforms.RandomScaleAspect(min_scale=0.5, aspect_ratio=0.33)
``` ```
...@@ -146,7 +146,7 @@ paddlex.seg.transforms.RandomScaleAspect(min_scale=0.5, aspect_ratio=0.33) ...@@ -146,7 +146,7 @@ paddlex.seg.transforms.RandomScaleAspect(min_scale=0.5, aspect_ratio=0.33)
* **aspect_ratio** (float): 裁取图像的宽高比范围,非负值,为0时返回原图。默认为0.33。 * **aspect_ratio** (float): 裁取图像的宽高比范围,非负值,为0时返回原图。默认为0.33。
## RandomDistort ## RandomDistort
```python ```python
paddlex.seg.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5, contrast_range=0.5, contrast_prob=0.5, saturation_range=0.5, saturation_prob=0.5, hue_range=18, hue_prob=0.5) paddlex.seg.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5, contrast_range=0.5, contrast_prob=0.5, saturation_range=0.5, saturation_prob=0.5, hue_range=18, hue_prob=0.5)
``` ```
...@@ -167,26 +167,28 @@ paddlex.seg.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5, ...@@ -167,26 +167,28 @@ paddlex.seg.transforms.RandomDistort(brightness_range=0.5, brightness_prob=0.5,
* **hue_range** (int): 色调因子的范围。默认为18。 * **hue_range** (int): 色调因子的范围。默认为18。
* **hue_prob** (float): 随机调整色调的概率。默认为0.5。 * **hue_prob** (float): 随机调整色调的概率。默认为0.5。
## ComposedSegTransforms ## ComposedSegTransforms
```python ```python
paddlex.det.transforms.ComposedSegTransforms(mode, train_crop_shape=[769, 769], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) paddlex.det.transforms.ComposedSegTransforms(mode, min_max_size=[400, 600], train_crop_shape=[769, 769], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], random_horizontal_flip=True)
``` ```
语义分割DeepLab和UNet模型中已经组合好的数据处理流程,开发者可以直接使用ComposedSegTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomHorizontalFlip](#RandomHorizontalFlip)[ResizeStepScaling](#ResizeStepScaling)[RandomPaddingCrop](#RandomPaddingCrop)3种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。 语义分割DeepLab和UNet模型中已经组合好的数据处理流程,开发者可以直接使用ComposedSegTransforms,简化手动组合transforms的过程, 该类中已经包含了[RandomHorizontalFlip](#RandomHorizontalFlip)[ResizeStepScaling](#ResizeStepScaling)[RandomPaddingCrop](#RandomPaddingCrop)3种数据增强方式,你仍可以通过[add_augmenters函数接口](#add_augmenters)添加新的数据增强方式。
ComposedSegTransforms共包括以下几个步骤: ComposedSegTransforms共包括以下几个步骤:
> 训练阶段: > 训练阶段:
> > 1. 随机对图像以0.5的概率水平翻转 > > 1. 随机对图像以0.5的概率水平翻转,若random_horizontal_flip为False,则跳过此步骤
> > 2. 按不同的比例随机Resize原图 > > 2. 按不同的比例随机Resize原图, 处理方式参考[paddlex.seg.transforms.ResizeRangeScaling](#resizerangescaling)。若min_max_size为None,则跳过此步骤
> > 3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小 > > 3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小
> > 4. 图像归一化 > > 4. 图像归一化
> 预测阶段: > 预测阶段:
> > 1. 将图像的最长边resize至(min_max_size[0] + min_max_size[1])//2, 短边按比例resize。若min_max_size为None,则跳过此步骤
> > 1. 图像归一化 > > 1. 图像归一化
### 参数 ### 参数
* **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test' * **mode** (str): Transforms所处的阶段,包括`train', 'eval'或'test'
* **train_crop_size** (list): 训练过程中随机Crop和Resize后(验证或预测过程中不需配置该参数,自动使用原图大小),输入到模型中图像的大小(与原图大小无关,根据上述几个步骤,会将原图处理成相应大小输入给模型训练), 默认[769, 769] * **min_max_size**(list): 用于对图像进行resize,具体作用参见上述步骤。
* **train_crop_size** (list): 训练过程中随机裁剪原图用于训练,具体作用参见上述步骤。此参数仅在mode为`train`时生效。
* **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。 * **mean** (list): 图像均值, 默认为[0.485, 0.456, 0.406]。
* **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。 * **std** (list): 图像方差,默认为[0.229, 0.224, 0.225]。
* **random_horizontal_flip**(bool): 数据增强,是否随机水平翻转图像,此参数仅在mode为`train`时生效。
### 添加数据增强方式 ### 添加数据增强方式
```python ```python
......
# 可视化-visualize # 预测结果可视化
PaddleX提供了一系列模型预测和结果分析的可视化函数。 PaddleX提供了一系列模型预测和结果分析的可视化函数。
## 目标检测/实例分割预测结果可视化 ## paddlex.det.visualize
> **目标检测/实例分割预测结果可视化**
``` ```
paddlex.det.visualize(image, result, threshold=0.5, save_dir='./') paddlex.det.visualize(image, result, threshold=0.5, save_dir='./')
``` ```
将目标检测/实例分割模型预测得到的Box框和Mask在原图上进行可视化。 将目标检测/实例分割模型预测得到的Box框和Mask在原图上进行可视化。
### 参数 ### 参数
> * **image** (str): 原图文件路径 > * **image** (str|np.ndarray): 原图文件路径或numpy数组(HWC排列,BGR格式)
> * **result** (str): 模型预测结果。 > * **result** (str): 模型预测结果。
> * **threshold**(float): score阈值,将Box置信度低于该阈值的框过滤不进行可视化。默认0.5 > * **threshold**(float): score阈值,将Box置信度低于该阈值的框过滤不进行可视化。默认0.5
> * **save_dir**(str): 可视化结果保存路径。若为None,则表示不保存,该函数将可视化的结果以np.ndarray的形式返回;若设为目录路径,则将可视化结果保存至该目录下。默认值为'./'。 > * **save_dir**(str): 可视化结果保存路径。若为None,则表示不保存,该函数将可视化的结果以np.ndarray的形式返回;若设为目录路径,则将可视化结果保存至该目录下。默认值为'./'。
### 使用示例 ### 使用示例
> 点击下载如下示例中的[模型](https://bj.bcebos.com/paddlex/models/xiaoduxiong_epoch_12.tar.gz)和[测试图片](https://bj.bcebos.com/paddlex/datasets/xiaoduxiong.jpeg) > 点击下载如下示例中的[模型](https://bj.bcebos.com/paddlex/models/xiaoduxiong_epoch_12.tar.gz)
``` ```
import paddlex as pdx import paddlex as pdx
model = pdx.load_model('xiaoduxiong_epoch_12') model = pdx.load_model('xiaoduxiong_epoch_12')
result = model.predict('xiaoduxiong.jpeg') result = model.predict('./xiaoduxiong_epoch_12/xiaoduxiong.jpeg')
pdx.det.visualize('xiaoduxiong.jpeg', result, save_dir='./') pdx.det.visualize('./xiaoduxiong_epoch_12/xiaoduxiong.jpeg', result, save_dir='./')
# 预测结果保存在./visualize_xiaoduxiong.jpeg # 预测结果保存在./visualize_xiaoduxiong.jpeg
``` ```
## paddlex.seg.visualize
> **语义分割模型预测结果可视化**
```
paddlex.seg.visualize(image, result, weight=0.6, save_dir='./')
```
将语义分割模型预测得到的Mask在原图上进行可视化。
## 目标检测/实例分割准确率-召回率可视化 ### 参数
> * **image** (str|np.ndarray): 原图文件路径或numpy数组(HWC排列,BGR格式)。
> * **result** (str): 模型预测结果。
> * **weight**(float): mask可视化结果与原图权重因子,weight表示原图的权重。默认0.6。
> * **save_dir**(str): 可视化结果保存路径。若为None,则表示不保存,该函数将可视化的结果以np.ndarray的形式返回;若设为目录路径,则将可视化结果保存至该目录下。默认值为'./'。
### 使用示例
> 点击下载如下示例中的[模型](https://bj.bcebos.com/paddlex/models/cityscape_deeplab.tar.gz)和[测试图片](https://bj.bcebos.com/paddlex/datasets/city.png)
```
import paddlex as pdx
model = pdx.load_model('cityscape_deeplab')
result = model.predict('city.png')
pdx.det.visualize('city.png', result, save_dir='./')
# 预测结果保存在./visualize_city.png
```
## paddlex.det.draw_pr_curve
> **目标检测/实例分割准确率-召回率可视化**
``` ```
paddlex.det.draw_pr_curve(eval_details_file=None, gt=None, pred_bbox=None, pred_mask=None, iou_thresh=0.5, save_dir='./') paddlex.det.draw_pr_curve(eval_details_file=None, gt=None, pred_bbox=None, pred_mask=None, iou_thresh=0.5, save_dir='./')
``` ```
将目标检测/实例分割模型评估结果中各个类别的准确率和召回率的对应关系进行可视化,同时可视化召回率和置信度阈值的对应关系。 将目标检测/实例分割模型评估结果中各个类别的准确率和召回率的对应关系进行可视化,同时可视化召回率和置信度阈值的对应关系。
> 注:PaddleX在训练过程中保存的模型目录中,均包含`eval_result.json`文件,可将此文件路径传给`eval_details_file`参数,设定`iou_threshold`即可得到对应模型在验证集上的PR曲线图。
### 参数 ### 参数
> * **eval_details_file** (str): 模型评估结果的保存路径,包含真值信息和预测结果。默认值为None。 > * **eval_details_file** (str): 模型评估结果的保存路径,包含真值信息和预测结果。默认值为None。
...@@ -73,29 +99,9 @@ pdx.det.draw_pr_curve(gt=gt, pred_bbox=bbox, save_dir='./insect') ...@@ -73,29 +99,9 @@ pdx.det.draw_pr_curve(gt=gt, pred_bbox=bbox, save_dir='./insect')
预测框的各个类别的准确率和召回率的对应关系、召回率和置信度阈值的对应关系可视化如下: 预测框的各个类别的准确率和召回率的对应关系、召回率和置信度阈值的对应关系可视化如下:
![](./images/insect_bbox_pr_curve(iou-0.5).png) ![](./images/insect_bbox_pr_curve(iou-0.5).png)
## 语义分割预测结果可视化
```
paddlex.seg.visualize(image, result, weight=0.6, save_dir='./')
```
将语义分割模型预测得到的Mask在原图上进行可视化。
### 参数
> * **image** (str): 原图文件路径。
> * **result** (str): 模型预测结果。
> * **weight**(float): mask可视化结果与原图权重因子,weight表示原图的权重。默认0.6。
> * **save_dir**(str): 可视化结果保存路径。若为None,则表示不保存,该函数将可视化的结果以np.ndarray的形式返回;若设为目录路径,则将可视化结果保存至该目录下。默认值为'./'。
### 使用示例 ## paddlex.slim.visualzie
> 点击下载如下示例中的[模型](https://bj.bcebos.com/paddlex/models/cityscape_deeplab.tar.gz)和[测试图片](https://bj.bcebos.com/paddlex/datasets/city.png) > **模型裁剪比例可视化分析**
```
import paddlex as pdx
model = pdx.load_model('cityscape_deeplab')
result = model.predict('city.png')
pdx.det.visualize('city.png', result, save_dir='./')
# 预测结果保存在./visualize_city.png
```
## 模型裁剪比例可视化分析
``` ```
paddlex.slim.visualize(model, sensitivities_file) paddlex.slim.visualize(model, sensitivities_file)
``` ```
...@@ -114,64 +120,11 @@ pdx.slim.visualize(model, 'mobilenetv2.sensitivities', save_dir='./') ...@@ -114,64 +120,11 @@ pdx.slim.visualize(model, 'mobilenetv2.sensitivities', save_dir='./')
# 可视化结果保存在./sensitivities.png # 可视化结果保存在./sensitivities.png
``` ```
## LIME可解释性结果可视化 ## paddlex.transforms.visualize
``` > **数据预处理/增强过程可视化**
paddlex.interpret.lime(img_file,
model,
num_samples=3000,
batch_size=50,
save_dir='./')
```
使用LIME算法将模型预测结果的可解释性可视化。
LIME表示与模型无关的局部可解释性,可以解释任何模型。LIME的思想是以输入样本为中心,在其附近的空间中进行随机采样,每个采样通过原模型得到新的输出,这样得到一系列的输入和对应的输出,LIME用一个简单的、可解释的模型(比如线性回归模型)来拟合这个映射关系,得到每个输入维度的权重,以此来解释模型。
**注意:** 可解释性结果可视化目前只支持分类模型。
### 参数
>* **img_file** (str): 预测图像路径。
>* **model** (paddlex.cv.models): paddlex中的模型。
>* **num_samples** (int): LIME用于学习线性模型的采样数,默认为3000。
>* **batch_size** (int): 预测数据batch大小,默认为50。
>* **save_dir** (str): 可解释性可视化结果(保存为png格式文件)和中间文件存储路径。
### 使用示例
> 对预测可解释性结果可视化的过程可参见[代码](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_weights_file=None)
```
使用NormLIME算法将模型预测结果的可解释性可视化。
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格式文件)和中间文件存储路径。
>* **normlime_weights_file** (str): NormLIME初始化文件名,若不存在,则计算一次,保存于该路径;若存在,则直接载入。
**注意:** dataset`读取的是一个数据集,该数据集不宜过大,否则计算时间会较长,但应包含所有类别的数据。NormLIME可解释性结果可视化目前只支持分类模型。
### 使用示例
> 对预测可解释性结果可视化的过程可参见[代码](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/normlime.py)。
## 数据预处理/增强过程可视化
``` ```
paddlex.transforms.visualize(dataset, paddlex.transforms.visualize(dataset,
img_count=3, img_count=3,
save_dir='vdl_output') save_dir='vdl_output')
``` ```
对数据预处理/增强中间结果进行可视化。 对数据预处理/增强中间结果进行可视化。
...@@ -183,4 +136,4 @@ paddlex.transforms.visualize(dataset, ...@@ -183,4 +136,4 @@ paddlex.transforms.visualize(dataset,
### 参数 ### 参数
>* **dataset** (paddlex.datasets): 数据集读取器。 >* **dataset** (paddlex.datasets): 数据集读取器。
>* **img_count** (int): 需要进行数据预处理/增强的图像数目。默认为3。 >* **img_count** (int): 需要进行数据预处理/增强的图像数目。默认为3。
>* **save_dir** (str): 日志保存的路径。默认为'vdl_output'。 >* **save_dir** (str): 日志保存的路径。默认为'vdl_output'。
\ No newline at end of file
...@@ -8,7 +8,7 @@ Anaconda是一个开源的Python发行版本,其包含了conda、Python等180 ...@@ -8,7 +8,7 @@ Anaconda是一个开源的Python发行版本,其包含了conda、Python等180
### 第二步 安装 ### 第二步 安装
运行下载的安装包(以.exe为后辍),根据引导完成安装, 用户可自行修改安装目录(如下图) 运行下载的安装包(以.exe为后辍),根据引导完成安装, 用户可自行修改安装目录(如下图)
![](../images/anaconda_windows.png) ![](images/anaconda_windows.png)
### 第三步 使用 ### 第三步 使用
- 点击Windows系统左下角的Windows图标,打开:所有程序->Anaconda3/2(64-bit)->Anaconda Prompt - 点击Windows系统左下角的Windows图标,打开:所有程序->Anaconda3/2(64-bit)->Anaconda Prompt
......
# 数据集格式说明
---
## 图像分类ImageNet
图像分类ImageNet数据集包含对应多个标签的图像文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--labelA # 标签为labelA的图像目录
| |--a1.jpg
| |--...
| └--...
|
|--...
|
|--labelZ # 标签为labelZ的图像目录
| |--z1.jpg
| |--...
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,相应的文件名可根据需要自行定义。
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为图像文件对应的标签id(从0开始)。如下所示:
```
labelA/a1.jpg 0
labelZ/z1.jpg 25
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz),下载蔬菜分类分类数据集。
在PaddleX中,使用`paddlex.cv.datasets.ImageNet`([API说明](../apis/datasets/classification.html#imagenet))加载分类数据集。
## 目标检测VOC
目标检测VOC数据集包含图像文件夹、标注信息文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--JPEGImages # 图像目录
| |--xxx1.jpg
| |--...
| └--...
|
|--Annotations # 标注信息目录
| |--xxx1.xml
| |--...
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,相应的文件名可根据需要自行定义。
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为标注文件相对于dataset的相对路径。如下所示:
```
JPEGImages/xxx1.jpg Annotations/xxx1.xml
JPEGImages/xxx2.jpg Annotations/xxx2.xml
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz),下载昆虫检测数据集。
在PaddleX中,使用`paddlex.cv.datasets.VOCDetection`([API说明](../apis/datasets/detection.html#vocdetection))加载目标检测VOC数据集。
## 目标检测和实例分割COCO
目标检测和实例分割COCO数据集包含图像文件夹及图像标注信息文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--JPEGImages # 图像目录
| |--xxx1.jpg
| |--...
| └--...
|
|--train.json # 训练相关信息文件
|
└--val.json # 验证相关信息文件
```
其中,相应的文件名可根据需要自行定义。
`train.json``val.json`存储与标注信息、图像文件相关的信息。如下所示:
```
{
"annotations": [
{
"iscrowd": 0,
"category_id": 1,
"id": 1,
"area": 33672.0,
"image_id": 1,
"bbox": [232, 32, 138, 244],
"segmentation": [[32, 168, 365, 117, ...]]
},
...
],
"images": [
{
"file_name": "xxx1.jpg",
"height": 512,
"id": 267,
"width": 612
},
...
]
"categories": [
{
"name": "labelA",
"id": 1,
"supercategory": "component"
}
]
}
```
其中,每个字段的含义如下所示:
| 域名 | 字段名 | 含义 | 数据类型 | 备注 |
|:-----|:--------|:------------|------|:-----|
| annotations | id | 标注信息id | int | 从1开始 |
| annotations | iscrowd | 标注框是否为一组对象 | int | 只有0、1两种取值 |
| annotations | category_id | 标注框类别id | int | |
| annotations | area | 标注框的面积 | float | |
| annotations | image_id | 当前标注信息所在图像的id | int | |
| annotations | bbox | 标注框坐标 | list | 长度为4,分别代表x,y,w,h |
| annotations | segmentation | 标注区域坐标 | list | list中有至少1个list,每个list由每个小区域坐标点的横纵坐标(x,y)组成 |
| images | id | 图像id | int | 从1开始 |
| images | file_name | 图像文件名 | str | |
| images | height | 图像高度 | int | |
| images | width | 图像宽度 | int | |
| categories | id | 类别id | int | 从1开始 |
| categories | name | 类别标签名 | str | |
| categories | supercategory | 类别父类的标签名 | str | |
[点击这里](https://bj.bcebos.com/paddlex/datasets/garbage_ins_det.tar.gz),下载垃圾实例分割数据集。
在PaddleX中,使用`paddlex.cv.datasets.COCODetection`([API说明](../apis/datasets/detection.html#cocodetection))加载COCO格式数据集。
## 语义分割数据
语义分割数据集包含原图、标注图及相应的文件列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--images # 原图目录
| |--xxx1.png
| |--...
| └--...
|
|--annotations # 标注图目录
| |--xxx1.png
| |--...
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表
```
其中,相应的文件名可根据需要自行定义。
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为标注图像文件相对于dataset的相对路径。如下所示:
```
images/xxx1.png annotations/xxx1.png
images/xxx2.png annotations/xxx2.png
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
background
labelA
labelB
...
```
标注图像为单通道图像,像素值即为对应的类别,像素标注类别需要从0开始递增(一般第一个类别为`background`),
例如0,1,2,3表示有4种类别,标注类别最多为256类。其中可以指定特定的像素值用于表示该值的像素不参与训练和评估(默认为255)。
[点击这里](https://bj.bcebos.com/paddlex/datasets/optic_disc_seg.tar.gz),下载视盘语义分割数据集。
在PaddleX中,使用`paddlex.cv.datasets.SegReader`([API说明](../apis/datasets/semantic_segmentation.html#segdataset))加载语义分割数据集。
## 图像分类EasyDataCls
图像分类EasyDataCls数据集包含存放图像和json文件的文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--easydata # 存放图像和json文件的文件夹
| |--0001.jpg
| |--0001.json
| |--0002.jpg
| |--0002.json
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,图像文件名应与json文件名一一对应。
每个json文件存储于`labels`相关的信息。如下所示:
```
{"labels": [{"name": "labelA"}]}
```
其中,`name`字段代表对应图像的类别。
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为json文件相对于dataset的相对路径。如下所示:
```
easydata/0001.jpg easydata/0001.json
easydata/0002.jpg easydata/0002.json
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://ai.baidu.com/easydata/),可以标注图像分类EasyDataCls数据集。
在PaddleX中,使用`paddlex.cv.datasets.EasyDataCls`([API说明](../apis/datasets/classification.html#easydatacls))加载分类数据集。
## 目标检测和实例分割EasyDataDet
目标检测和实例分割EasyDataDet数据集包含存放图像和json文件的文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录ß
|--easydata # 存放图像和json文件的文件夹
| |--0001.jpg
| |--0001.json
| |--0002.jpg
| |--0002.json
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,图像文件名应与json文件名一一对应。
每个json文件存储于`labels`相关的信息。如下所示:
```
"labels": [{"y1": 18, "x2": 883, "x1": 371, "y2": 404, "name": "labelA",
"mask": "kVfc0`0Zg0<F7J7I5L5K4L4L4L3N3L3N3L3N2N3M2N2N2N2N2N2N1O2N2O1N2N1O2O1N101N1O2O1N101N10001N101N10001N10001O0O10001O000O100000001O0000000000000000000000O1000001O00000O101O000O101O0O101O0O2O0O101O0O2O0O2N2O0O2O0O2N2O1N1O2N2N2O1N2N2N2N2N2N2M3N3M2M4M2M4M3L4L4L4K6K5J7H9E\\iY1"},
{"y1": 314, "x2": 666, "x1": 227, "y2": 676, "name": "labelB",
"mask": "mdQ8g0Tg0:G8I6K5J5L4L4L4L4M2M4M2M4M2N2N2N3L3N2N2N2N2O1N1O2N2N2O1N1O2N2O0O2O1N1O2O0O2O0O2O001N100O2O000O2O000O2O00000O2O000000001N100000000000000000000000000000000001O0O100000001O0O10001N10001O0O101N10001N101N101N101N101N2O0O2N2O0O2N2N2O0O2N2N2N2N2N2N2N2N2N3L3N2N3L3N3L4M2M4L4L5J5L5J7H8H;BUcd<"},
...]}
```
其中,list中的每个元素代表一个标注信息,标注信息中字段的含义如下所示:
| 字段名 | 含义 | 数据类型 | 备注 |
|:--------|:------------|------|:-----|
| x1 | 标注框左下角横坐标 | int | |
| y1 | 标注框左下角纵坐标 | int | |
| x2 | 标注框右上角横坐标 | int | |
| y2 | 标注框右上角纵坐标 | int | |
| name | 标注框中物体类标 | str | |
| mask | 分割区域布尔型numpy编码后的字符串 | str | 该字段可以不存在,当不存在时只能进行目标检测 |
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为json文件相对于dataset的相对路径。如下所示:
```
easydata/0001.jpg easydata/0001.json
easydata/0002.jpg easydata/0002.json
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://ai.baidu.com/easydata/),可以标注图像分类EasyDataDet数据集。
在PaddleX中,使用`paddlex.cv.datasets.EasyDataDet`([API说明](../apis/datasets/detection.html#easydatadet))加载分类数据集。
## 语义分割EasyDataSeg
语义分割EasyDataSeg数据集包含存放图像和json文件的文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录ß
|--easydata # 存放图像和json文件的文件夹
| |--0001.jpg
| |--0001.json
| |--0002.jpg
| |--0002.json
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,图像文件名应与json文件名一一对应。
每个json文件存储于`labels`相关的信息。如下所示:
```
"labels": [{"y1": 18, "x2": 883, "x1": 371, "y2": 404, "name": "labelA",
"mask": "kVfc0`0Zg0<F7J7I5L5K4L4L4L3N3L3N3L3N2N3M2N2N2N2N2N2N1O2N2O1N2N1O2O1N101N1O2O1N101N10001N101N10001N10001O0O10001O000O100000001O0000000000000000000000O1000001O00000O101O000O101O0O101O0O2O0O101O0O2O0O2N2O0O2O0O2N2O1N1O2N2N2O1N2N2N2N2N2N2M3N3M2M4M2M4M3L4L4L4K6K5J7H9E\\iY1"},
{"y1": 314, "x2": 666, "x1": 227, "y2": 676, "name": "labelB",
"mask": "mdQ8g0Tg0:G8I6K5J5L4L4L4L4M2M4M2M4M2N2N2N3L3N2N2N2N2O1N1O2N2N2O1N1O2N2O0O2O1N1O2O0O2O0O2O001N100O2O000O2O000O2O00000O2O000000001N100000000000000000000000000000000001O0O100000001O0O10001N10001O0O101N10001N101N101N101N101N2O0O2N2O0O2N2N2O0O2N2N2N2N2N2N2N2N2N3L3N2N3L3N3L4M2M4L4L5J5L5J7H8H;BUcd<"},
...]}
```
其中,list中的每个元素代表一个标注信息,标注信息中字段的含义如下所示:
| 字段名 | 含义 | 数据类型 | 备注 |
|:--------|:------------|------|:-----|
| x1 | 标注框左下角横坐标 | int | |
| y1 | 标注框左下角纵坐标 | int | |
| x2 | 标注框右上角横坐标 | int | |
| y2 | 标注框右上角纵坐标 | int | |
| name | 标注框中物体类标 | str | |
| mask | 分割区域布尔型numpy编码后的字符串 | str | 该字段必须存在 |
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为json文件相对于dataset的相对路径。如下所示:
```
easydata/0001.jpg easydata/0001.json
easydata/0002.jpg easydata/0002.json
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://ai.baidu.com/easydata/),可以标注图像分类EasyDataSeg数据集。
在PaddleX中,使用`paddlex.cv.datasets.EasyDataSeg`([API说明](../apis/datasets/semantic_segmentation.html#easydataseg))加载分类数据集。
# 数据集转换
当前PaddleX GUI支持ImageNet格式的图像分类数据集、VOC格式的目标检测数据集、COCO格式的实例分割数据集、Seg格式的语义分割的数据集,当使用LabelMe、EasyData、标注精灵这3个工具标注数据时,PaddleX提供了相应接口可将数据转换成与PaddleX GUI想适配的数据集,使用方式如下所示:
```python
import paddlex as pdx
# 该接口实现LabelMe数据集到VOC数据集的转换。
# image_dir为图像文件存放的路径。
# json_dir为与每张图像对应的json文件的存放路径。
# dataset_save_dir为转换后数据集存放路径。
pdx.tools.labelme2voc(image_dir='labelme_imgs',
json_dir='labelme_jsons',
dataset_save_dir='voc_dataset')
```
可替换labelme2voc实现不同数据集间的转换,目前提供的转换接口如下:
| 接口 | 转换关系 |
| :-------- | :------- |
| labelme2voc | LabelMe数据集转换为VOC数据集 |
| labelme2coco | LabelMe数据集转换为COCO数据集 |
| labelme2seg | LabelMe数据集转换为Seg数据集 |
| easydata2imagenet | EasyData数据集转换为ImageNet数据集 |
| easydata2voc | EasyData数据集转换为VOC数据集 |
| easydata2coco | EasyData数据集转换为COCO数据集 |
| easydata2seg | EasyData数据集转换为Seg数据集 |
| jingling2seg | 标注精灵数据集转换为Seg数据集 |
\ No newline at end of file
...@@ -11,6 +11,4 @@ ...@@ -11,6 +11,4 @@
metrics.md metrics.md
interpret.md interpret.md
parameters.md parameters.md
how_to_convert_dataset.md
datasets.md
...@@ -13,7 +13,7 @@ LIME全称Local interpretable model-agnostic explanations,表示一种与模 ...@@ -13,7 +13,7 @@ LIME全称Local interpretable model-agnostic explanations,表示一种与模
LIME的使用方式可参见[代码示例](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/lime.py)[api介绍](../apis/visualize.html#lime)。在使用时,参数中的`num_samples`设置尤为重要,其表示上述步骤2中的随机采样的个数,若设置过小会影响可解释性结果的稳定性,若设置过大则将在上述步骤3耗费较长时间;参数`batch_size`则表示在计算上述步骤3时,预测的batch size,若设置过小将在上述步骤3耗费较长时间,而上限则根据机器配置决定。 LIME的使用方式可参见[代码示例](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/lime.py)[api介绍](../apis/visualize.html#lime)。在使用时,参数中的`num_samples`设置尤为重要,其表示上述步骤2中的随机采样的个数,若设置过小会影响可解释性结果的稳定性,若设置过大则将在上述步骤3耗费较长时间;参数`batch_size`则表示在计算上述步骤3时,预测的batch size,若设置过小将在上述步骤3耗费较长时间,而上限则根据机器配置决定。
最终LIME可解释性算法的可视化结果如下所示: 最终LIME可解释性算法的可视化结果如下所示:
![](../images/lime.png) ![](images/lime.png)
图中绿色区域代表起正向作用的超像素,红色区域代表起反向作用的超像素,"First n superpixels"代表前n个权重比较大的超像素(由上述步骤5计算所得结果)。 图中绿色区域代表起正向作用的超像素,红色区域代表起反向作用的超像素,"First n superpixels"代表前n个权重比较大的超像素(由上述步骤5计算所得结果)。
...@@ -31,12 +31,12 @@ NormLIME是在LIME上的改进,LIME的解释是局部性的,是针对当前 ...@@ -31,12 +31,12 @@ NormLIME是在LIME上的改进,LIME的解释是局部性的,是针对当前
预测的`label`为输出,构建逻辑回归函数`regression_func` 预测的`label`为输出,构建逻辑回归函数`regression_func`
(2) 由`regression_func`可获得每个聚类中心不同类别下的权重,并对权重进行归一化。 (2) 由`regression_func`可获得每个聚类中心不同类别下的权重,并对权重进行归一化。
3. 使用Kmeans模型获取需要可视化图像的每个超像素的聚类中心。 3. 使用Kmeans模型获取需要可视化图像的每个超像素的聚类中心。
4. 对需要可视化的图像的超像素进行随机遮掩构成新的图像。 4. 对需要可视化的图像的超像素进行随机遮掩构成新的图像。
5. 对每张构造的图像使用预测模型预测label。 5. 对每张构造的图像使用预测模型预测label。
6. 根据normlime的权重信息,每个超像素可获不同的权重,选取最高的权重为最终的权重,以此来解释模型。 6. 根据normlime的权重信息,每个超像素可获不同的权重,选取最高的权重为最终的权重,以此来解释模型。
NormLIME的使用方式可参见[代码示例](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/normlime.py)[api介绍](../apis/visualize.html#normlime)。在使用时,参数中的`num_samples`设置尤为重要,其表示上述步骤2中的随机采样的个数,若设置过小会影响可解释性结果的稳定性,若设置过大则将在上述步骤3耗费较长时间;参数`batch_size`则表示在计算上述步骤3时,预测的batch size,若设置过小将在上述步骤3耗费较长时间,而上限则根据机器配置决定;而`dataset`则是由测试集或验证集构造的数据。 NormLIME的使用方式可参见[代码示例](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/interpret/normlime.py)[api介绍](../apis/visualize.html#normlime)。在使用时,参数中的`num_samples`设置尤为重要,其表示上述步骤2中的随机采样的个数,若设置过小会影响可解释性结果的稳定性,若设置过大则将在上述步骤3耗费较长时间;参数`batch_size`则表示在计算上述步骤3时,预测的batch size,若设置过小将在上述步骤3耗费较长时间,而上限则根据机器配置决定;而`dataset`则是由测试集或验证集构造的数据。
最终NormLIME可解释性算法的可视化结果如下所示: 最终NormLIME可解释性算法的可视化结果如下所示:
![](../images/normlime.png) ![](images/normlime.png)
图中绿色区域代表起正向作用的超像素,红色区域代表起反向作用的超像素,"First n superpixels"代表前n个权重比较大的超像素(由上述步骤5计算所得结果)。图中最后一行代表把LIME和NormLIME对应超像素权重相乘的结果。 图中绿色区域代表起正向作用的超像素,红色区域代表起反向作用的超像素,"First n superpixels"代表前n个权重比较大的超像素(由上述步骤5计算所得结果)。图中最后一行代表把LIME和NormLIME对应超像素权重相乘的结果。
\ No newline at end of file
...@@ -6,7 +6,7 @@ PaddleX在模型训练、评估过程中,都会有相应的日志和指标反 ...@@ -6,7 +6,7 @@ PaddleX在模型训练、评估过程中,都会有相应的日志和指标反
PaddleX所有模型在训练过程中,输出的日志信息都包含了6个通用的统计信息,用于辅助用户进行模型训练,例如**分割模型**的训练日志,如下图所示。 PaddleX所有模型在训练过程中,输出的日志信息都包含了6个通用的统计信息,用于辅助用户进行模型训练,例如**分割模型**的训练日志,如下图所示。
![](../images/seg_train.png) ![](images/seg_train.png)
各字段含义如下: 各字段含义如下:
...@@ -26,7 +26,7 @@ PaddleX所有模型在训练过程中,输出的日志信息都包含了6个通 ...@@ -26,7 +26,7 @@ PaddleX所有模型在训练过程中,输出的日志信息都包含了6个通
PaddleX所有模型在训练过程中会根据用户设定的`save_interval_epochs`参数,每间隔一定轮数进行评估和保存。例如**分类模型**的评估日志,如下图所示。 PaddleX所有模型在训练过程中会根据用户设定的`save_interval_epochs`参数,每间隔一定轮数进行评估和保存。例如**分类模型**的评估日志,如下图所示。
![](../images/cls_eval.png) ![](images/cls_eval.png)
上图中第1行表明验证数据集中样本数为240,需要迭代8步才能评估完所有验证数据;第5行用于表明第2轮的模型已经完成保存操作;第6行则表明当前保存的模型中,第2轮的模型在验证集上指标最优(分类任务看`acc1`,此时`acc1`值为0.258333),最优模型会保存在`best_model`目录中。 上图中第1行表明验证数据集中样本数为240,需要迭代8步才能评估完所有验证数据;第5行用于表明第2轮的模型已经完成保存操作;第6行则表明当前保存的模型中,第2轮的模型在验证集上指标最优(分类任务看`acc1`,此时`acc1`值为0.258333),最优模型会保存在`best_model`目录中。
...@@ -38,7 +38,7 @@ PaddleX所有模型在训练过程中会根据用户设定的`save_interval_epoc ...@@ -38,7 +38,7 @@ PaddleX所有模型在训练过程中会根据用户设定的`save_interval_epoc
> 注: acck准确率是针对一张图片进行计算的:把模型在各个类别上的预测得分按从高往低进行排序,取出前k个预测类别,若这k个预测类别包含了真值类,则认为该图片分类正确。 > 注: acck准确率是针对一张图片进行计算的:把模型在各个类别上的预测得分按从高往低进行排序,取出前k个预测类别,若这k个预测类别包含了真值类,则认为该图片分类正确。
![](../images/cls_train.png) ![](images/cls_train.png)
上图中第1行中的`acc1`表示参与当前迭代步数的训练样本的平均top1准确率,值越高代表模型越优;`acc5`表示参与当前迭代步数的训练样本的平均top5(若类别数n少于5,则为topn)准确率,值越高代表模型越优。第4行中的`loss`表示整个训练集的平均损失函数值,`acc1`表示整个训练集的平均top1准确率,`acc5`表示整个训练集的平均top5准确率。 上图中第1行中的`acc1`表示参与当前迭代步数的训练样本的平均top1准确率,值越高代表模型越优;`acc5`表示参与当前迭代步数的训练样本的平均top5(若类别数n少于5,则为topn)准确率,值越高代表模型越优。第4行中的`loss`表示整个训练集的平均损失函数值,`acc1`表示整个训练集的平均top1准确率,`acc5`表示整个训练集的平均top5准确率。
...@@ -46,7 +46,7 @@ PaddleX所有模型在训练过程中会根据用户设定的`save_interval_epoc ...@@ -46,7 +46,7 @@ PaddleX所有模型在训练过程中会根据用户设定的`save_interval_epoc
### 评估日志字段 ### 评估日志字段
![](../images/cls_eval.png) ![](images/cls_eval.png)
上图中第3行中的`acc1`表示整个验证集的平均top1准确率,`acc5`表示整个验证集的平均top5准确率。 上图中第3行中的`acc1`表示整个验证集的平均top1准确率,`acc5`表示整个验证集的平均top5准确率。
...@@ -59,7 +59,7 @@ PaddleX所有模型在训练过程中会根据用户设定的`save_interval_epoc ...@@ -59,7 +59,7 @@ PaddleX所有模型在训练过程中会根据用户设定的`save_interval_epoc
YOLOv3的训练日志只包括训练通用统计信息(见上文训练通用统计信息)。 YOLOv3的训练日志只包括训练通用统计信息(见上文训练通用统计信息)。
![](../images/yolo_train.png) ![](images/yolo_train.png)
上图中第5行`loss`表示整个训练集的平均损失函数loss值。 上图中第5行`loss`表示整个训练集的平均损失函数loss值。
...@@ -75,7 +75,7 @@ FasterRCNN的训练日志除了通用统计信息外,还包括`loss_cls`、`lo ...@@ -75,7 +75,7 @@ FasterRCNN的训练日志除了通用统计信息外,还包括`loss_cls`、`lo
| loss_rpn_bbox | RPN子网络中检测框回归损失函数值 | | loss_rpn_bbox | RPN子网络中检测框回归损失函数值 |
| loss | 所有子网络损失函数值之和 | | loss | 所有子网络损失函数值之和 |
![](../images/faster_train.png) ![](images/faster_train.png)
上图中第1行`loss`, `loss_cls``loss_bbox``loss_rpn_clss``loss_rpn_bbox`都是参与当前迭代步数的训练样本的损失值,而第7行是针整个训练集的损失函数值。 上图中第1行`loss`, `loss_cls``loss_bbox``loss_rpn_clss``loss_rpn_bbox`都是参与当前迭代步数的训练样本的损失值,而第7行是针整个训练集的损失函数值。
...@@ -93,7 +93,7 @@ MaskRCNN的训练日志除了通用统计信息外,还包括`loss_cls`、`loss ...@@ -93,7 +93,7 @@ MaskRCNN的训练日志除了通用统计信息外,还包括`loss_cls`、`loss
| loss_rpn_bbox | RPN子网络中检测框回归损失函数值 | | loss_rpn_bbox | RPN子网络中检测框回归损失函数值 |
| loss | 所有子网络损失函数值之和 | | loss | 所有子网络损失函数值之和 |
![](../images/mask_train.png) ![](images/mask_train.png)
上图中第1行`loss`, `loss_cls``loss_bbox``loss_mask``loss_rpn_clss``loss_rpn_bbox`都是参与当前迭代步数的训练样本的损失值,而第7行是针整个训练集的损失函数值。 上图中第1行`loss`, `loss_cls``loss_bbox``loss_mask``loss_rpn_clss``loss_rpn_bbox`都是参与当前迭代步数的训练样本的损失值,而第7行是针整个训练集的损失函数值。
...@@ -103,7 +103,7 @@ MaskRCNN的训练日志除了通用统计信息外,还包括`loss_cls`、`loss ...@@ -103,7 +103,7 @@ MaskRCNN的训练日志除了通用统计信息外,还包括`loss_cls`、`loss
#### VOC评估标准 #### VOC评估标准
![](../images/voc_eval.png) ![](images/voc_eval.png)
> 注:`map`为平均准确率的平均值,即IoU(Intersection Over Union)取0.5时各个类别的准确率-召回率曲线下面积的平均值。 > 注:`map`为平均准确率的平均值,即IoU(Intersection Over Union)取0.5时各个类别的准确率-召回率曲线下面积的平均值。
...@@ -115,11 +115,11 @@ MaskRCNN的训练日志除了通用统计信息外,还包括`loss_cls`、`loss ...@@ -115,11 +115,11 @@ MaskRCNN的训练日志除了通用统计信息外,还包括`loss_cls`、`loss
COCO格式的数据集不仅可以用于训练目标检测模型,也可以用于训练实例分割模型。在目标检测中,PaddleX主要反馈针对检测框的`bbox_mmAP`指标;在实例分割中,还包括针对Mask的`seg_mmAP`指标。如下所示,第一张日志截图为目标检测的评估结果,第二张日志截图为实例分割的评估结果。 COCO格式的数据集不仅可以用于训练目标检测模型,也可以用于训练实例分割模型。在目标检测中,PaddleX主要反馈针对检测框的`bbox_mmAP`指标;在实例分割中,还包括针对Mask的`seg_mmAP`指标。如下所示,第一张日志截图为目标检测的评估结果,第二张日志截图为实例分割的评估结果。
![](../images/faster_eval.png) ![](images/faster_eval.png)
上图中红框标注的`bbox_mmap`表示整个验证集的检测框平均准确率平均值。 上图中红框标注的`bbox_mmap`表示整个验证集的检测框平均准确率平均值。
![](../images/mask_eval.png) ![](images/mask_eval.png)
上图中红框标注的`bbox_mmap``seg_mmap`分别表示整个验证集的检测框平均准确率平均值、Mask平均准确率平均值。 上图中红框标注的`bbox_mmap``seg_mmap`分别表示整个验证集的检测框平均准确率平均值、Mask平均准确率平均值。
## 分割特有统计信息 ## 分割特有统计信息
...@@ -128,7 +128,7 @@ COCO格式的数据集不仅可以用于训练目标检测模型,也可以用 ...@@ -128,7 +128,7 @@ COCO格式的数据集不仅可以用于训练目标检测模型,也可以用
语义分割的训练日志只包括训练通用统计信息(见上文训练通用统计信息)。 语义分割的训练日志只包括训练通用统计信息(见上文训练通用统计信息)。
![](../images/seg_train.png) ![](images/seg_train.png)
### 评估日志字段 ### 评估日志字段
...@@ -142,4 +142,4 @@ COCO格式的数据集不仅可以用于训练目标检测模型,也可以用 ...@@ -142,4 +142,4 @@ COCO格式的数据集不仅可以用于训练目标检测模型,也可以用
| category_acc | 各类别的准确率,即各类别预测正确的像素数/预测为该类别的总像素数 | | category_acc | 各类别的准确率,即各类别预测正确的像素数/预测为该类别的总像素数 |
| kappa | kappa系数,用于一致性检验 | | kappa | kappa系数,用于一致性检验 |
![](../images/seg_eval.png) ![](images/seg_eval.png)
...@@ -5,53 +5,69 @@ PaddleX所有训练接口中,内置的参数均为根据单GPU卡相应batch_s ...@@ -5,53 +5,69 @@ PaddleX所有训练接口中,内置的参数均为根据单GPU卡相应batch_s
## 1.Epoch数的调整 ## 1.Epoch数的调整
Epoch数是模型训练过程,迭代的轮数,用户可以设置较大的数值,根据模型迭代过程在验证集上的指标表现,来判断模型是否收敛,进而提前终止训练。此外也可以使用`train`接口中的`early_stop`策略,模型在训练过程会自动判断模型是否收敛自动中止。 Epoch数是模型训练过程,迭代的轮数,用户可以设置较大的数值,根据模型迭代过程在验证集上的指标表现,来判断模型是否收敛,进而提前终止训练。此外也可以使用`train`接口中的`early_stop`策略,模型在训练过程会自动判断模型是否收敛自动中止。
## 2.Batch Size的调整 ## 2.batch_size和learning_rate
Batch Size指模型在训练过程中,一次性处理的样本数量, 如若使用多卡训练, batch_size会均分到各张卡上(因此需要让batch size整除卡数)。这个参数跟机器的显存/内存高度相关,`batch_size`越高,所消耗的显存/内存就越高。PaddleX在各个`train`接口中均配置了默认的batch size,如若用户调整batch size,则也注意需要对应调整其它参数,如下表所示展示YOLOv3在训练时的参数配置
| 参数 | 默认值 | 调整比例 | 示例 | > - Batch Size指模型在训练过程中,一次性处理的样本数量
|:---------------- | :------------ | :------------------ | :------------ | > - 如若使用多卡训练, batch_size会均分到各张卡上(因此需要让batch size整除卡数)
| train_batch_size | 8 | 调整为 8*alpha | 16 | > - Batch Size跟机器的显存/内存高度相关,`batch_size`越高,所消耗的显存/内存就越高
| learning_rate | 1.0/8000 | 调整为 alpha/8000 | 2.0/8000 | > - PaddleX在各个`train`接口中均配置了默认的batch size(默认针对单GPU卡),如若训练时提示GPU显存不足,则相应调低BatchSize,如若GPU显存高或使用多张GPU卡时,可相应调高BatchSize。
| warmup_steps | 1000 | 调整为 1000/alpha<br>(该参数也可以自行根据数据情况调整) | 500 | > - **如若用户调整batch size,则也注意需要对应调整其它参数,特别是train接口中默认的learning_rate值**。如在YOLOv3模型中,默认`train_batch_size`为8,`learning_rate`为0.000125,当用户将模型在2卡机器上训练时,可以将`train_batch_size`调整为16, 那么同时`learning_rate`也可以对应调整为0.000125 * 2 = 0.00025
| lr_decay_epochs | [213, 240] | 不变 | [213, 240] |
## 3.warmup_steps和warmup_start_lr
更多训练接口可以参考 在训练模型时,一般都会使用预训练模型,例如检测模型在训练时使用backbone在ImageNet数据集上的预训练权重。但由于在自行训练时,自己的数据与ImageNet数据集存在较大的差异,可能会一开始由于梯度过大使得训练出现问题,因此可以在刚开始训练时,让学习率以一个较小的值,慢慢增长到设定的学习率。因此`warmup_steps``warmup_start_lr`就是这个作用,模型开始训练时,学习率会从`warmup_start_lr`开始,在`warmup_steps`个batch数据迭代后线性增长到设定的学习率。
- [分类模型-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)
## 关于lr_decay_epoch, warmup_steps等参数的说明 > 例如YOLOv3的train接口,默认`train_batch_size`为8,`learning_rate`为0.000125, `warmup_steps`为1000, `warmup_start_lr`为0.0;在此参数配置下表示,模型在启动训练后,在前1000个step(每个step表示一个batch的数据,也就是8个样本)内,学习率会从0.0开始线性增长到设定的0.000125。
在PaddleX或其它深度学习模型的训练过程中,经常见到lr_decay_epoch, warmup_steps, warmup_start_lr等参数设置,下面介绍一些这些参数的作用。 ## 4.lr_decay_epochs和lr_decay_gamma
首先这些参数都是用于控制模型训练过程中学习率的变化方式,例如我们在训练时将learning_rate设为0.1, 通常情况,在模型的训练过程中,学习率一直以0.1不变训练下去, 但为了调出更好的模型效果,我们往往不希望学习率一直保持不变 `lr_decay_epochs`用于让学习率在模型训练后期逐步衰减,它一般是一个list,如[6, 8, 10],表示学习率在第6个epoch时衰减一次,第8个epoch时再衰减一次,第10个epoch时再衰减一次。每次学习率衰减为之前的学习率*lr_decay_gamma
### warmup_steps和warmup_start_lr > 例如YOLOv3的train接口,默认`num_epochs`为270,`learning_rate`为0.000125, `lr_decay_epochs`为[213, 240],`lr_decay_gamma`为0.1;在此参数配置下表示,模型在启动训练后,在前213个epoch中,训练时使用的学习率为0.000125,在第213至240个epoch之间,训练使用的学习率为0.000125x0.1=0.0000125,在240个epoch之后,使用的学习率为0.000125x0.1x0.1=0.00000125
我们在训练模型时,一般都会使用预训练模型,例如检测模型在训练时使用backbone在ImageNet数据集上的预训练权重。但由于在自行训练时,自己的数据与ImageNet数据集存在较大的差异,可能会一开始由于梯度过大使得训练出现问题,因此可以在刚开始训练时,让学习率以一个较小的值,慢慢增长到设定的学习率。因此`warmup_steps``warmup_start_lr`就是这个作用,模型开始训练时,学习率会从`warmup_start_lr`开始,在`warmup_steps`内线性增长到设定的学习率。 ## 5.参数设定时的约束
根据上述几个参数,可以了解到学习率的变化分为WarmUp热身阶段和Decay衰减阶段,
> - Wamup热身阶段:随着训练迭代,学习率从较低的值逐渐线性增长至设定的值,以step为单位
> - Decay衰减阶段:随着训练迭代,学习率逐步衰减,如每次衰减为之前的0.1, 以epoch为单位
> step与epoch的关系:1个epoch由多个step组成,例如训练样本有800张图像,`train_batch_size`为8, 那么每个epoch都要完整用这800张图片训一次模型,而每个epoch总共包含800//8即100个step
### lr_decay_epochs和lr_decay_gamma 在PaddleX中,约束warmup必须在Decay之前结束,因此各参数设置需要满足下面条件
```
warmup_steps <= lr_decay_epochs[0] * num_steps_each_epoch
```
其中`num_steps_each_epoch`计算方式如下,
```
num_steps_each_eposh = num_samples_in_train_dataset // train_batch_size
```
因此,如若你在启动训练时,被提示`warmup_steps should be less than...`时,即表示需要根据上述公式调整你的参数啦,可以调整`lr_decay_epochs`或者是`warmup_steps`
`lr_decay_epochs`用于让学习率在模型训练后期逐步衰减,它一般是一个list,如[6, 8, 10],表示学习率在第6个epoch时衰减一次,第8个epoch时再衰减一次,第10个epoch时再衰减一次。每次学习率衰减为之前的学习率*lr_decay_gamma ## 6.如何使用多GPU卡进行训练
`import paddlex`前配置环境变量,代码如下
```
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0' # 使用第1张GPU卡进行训练
# 注意paddle或paddlex都需要在设置环境变量后再import
import paddlex as pdx
```
### Notice ```
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '' # 不使用GPU,使用CPU进行训练
import paddlex as pdx
```
在PaddleX中,限制warmup需要在第一个学习率decay衰减前结束,因此要满足下面的公式
``` ```
warmup_steps <= lr_decay_epochs[0] * num_steps_each_epoch import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1,3' # 使用第1、2、4张GPU卡进行训练
import paddlex as pdx
``` ```
其中公式中`num_steps_each_epoch = num_samples_in_train_dataset // train_batch_size`
> 因此如若在训练时PaddleX提示`warmup_steps should be less than xxx`时,即可根据上述公式来调整你的`lr_decay_epochs`或者是`warmup_steps`使得两个参数满足上面的条件
> - 图像分类模型 [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#fasterrcnn)
> - YOLOv3 [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/detection.html#yolov3) - 图像分类模型 [train接口](../apis/models/classification.html#train)
> - MaskRCNN [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/instance_segmentation.html#maskrcnn) - FasterRCNN [train接口](../apis/models/detection.html#id1)
> - DeepLab [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#deeplabv3p) - YOLOv3 [train接口](../apis/models/detection.html#train)
> - UNet [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#unet) - MaskRCNN [train接口](../apis/models/instance_segmentation.html#train)
> - HRNet [train接口文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/models/semantic_segmentation.html#hrnet) - DeepLabv3p [train接口](../apis/models/semantic_segmentation.html#train)
# 更新日志
**v1.1.0** 2020.07.12
- 模型更新
> - 新增语义分割模型HRNet、FastSCNN
> - 目标检测FasterRCNN、实例分割MaskRCNN新增backbone HRNet
> - 目标检测/实例分割模型新增COCO数据集预训练模型
> - 集成X2Paddle,PaddleX所有分类模型和语义分割模型支持导出为ONNX协议
- 模型部署更新
> - 模型加密增加支持Windows平台
> - 新增Jetson、PaddleLite模型部署预测方案
> - C++部署代码新增batch批预测,并采用OpenMP对预处理进行并行加速
- 新增2个PaddleX产业案例
> - [人像分割案例]()
> - [工业表计读数案例]()
- 新增数据格式转换功能,LabelMe、精灵标注助手和EasyData平台标注的数据转为PaddleX支持加载的数据格式
- PaddleX文档更新,优化文档结构
**v1.0.0** 2020.05.20
- 增加模型C++部署和Python部署代码
- 增加模型加密部署方案
- 增加分类模型的OpenVINO部署方案
- 增加模型可解释性的接口
**v0.1.8** 2020.05.17
- 修复部分代码Bug
- 新增EasyData平台数据标注格式支持
- 支持imgaug数据增强库的pixel-level算子
...@@ -76,5 +76,4 @@ if not on_rtd: # only import and set the theme if we're building docs locally ...@@ -76,5 +76,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/paddlex.jpg' html_logo = 'paddlex.png'
# PaddleX视觉方案介绍
PaddleX针对图像分类、目标检测、实例分割和语义分割4种视觉任务提供了包含模型选择、压缩策略选择、部署方案选择在内的解决方案。用户根据自己的需求选择合适的模型,选择合适的压缩策略来减小模型的计算量和存储体积、加速模型预测推理,最后选择合适的部署方案将模型部署在移动端或者服务器端。
## 模型选择
### 图像分类
图像分类任务指的是输入一张图片,模型预测图片的类别,如识别为风景、动物、车等。
![](./images/image_classification.png)
对于图像分类任务,针对不同的应用场景,PaddleX提供了百度改进的模型,见下表所示:
> 表中GPU预测速度是使用PaddlePaddle Python预测接口测试得到(测试GPU型号为Nvidia Tesla P40)。
> 表中CPU预测速度 (测试CPU型号为)。
> 表中骁龙855预测速度是使用处理器为骁龙855的手机测试得到。
> 测速时模型输入大小为224 x 224,Top1准确率为ImageNet-1000数据集上评估所得。
| 模型 | 模型特点 | 存储体积 | GPU预测速度(毫秒) | CPU(x86)预测速度(毫秒) | 骁龙855(ARM)预测速度 (毫秒)| Top1准确率 |
| :--------- | :------ | :---------- | :-----------| :------------- | :------------- |:--- |
| MobileNetV3_small_ssld | 轻量高速,适用于追求高速的实时移动端场景 | 12.5MB | 7.08837 | - | 6.546 | 71.3.0% |
| ShuffleNetV2 | 轻量级模型,精度相对偏低,适用于要求更小存储体积的实时移动端场景 | 10.2MB | 15.40 | - | 10.941 | 68.8% |
| MobileNetV3_large_ssld | 轻量级模型,在存储方面优势不大,在速度和精度上表现适中,适合于移动端场景 | 22.8MB | 8.06651 | - | 19.803 | 79.0% |
| MobileNetV2 | 轻量级模型,适用于使用GPU预测的移动端场景 | 15.0MB | 5.92667 | - | 23.318| 72.2 % |
| ResNet50_vd_ssld | 高精度模型,预测时间较短,适用于大多数的服务器端场景 | 103.5MB | 7.79264 | - | - | 82.4% |
| ResNet101_vd_ssld | 超高精度模型,预测时间相对较长,适用于有大数据量时的服务器端场景 | 180.5MB | 13.34580 | - | -| 83.7% |
| Xception65 | 超高精度模型,预测时间更长,在处理较大数据量时有较高的精度,适用于服务器端场景 | 161.6MB | 13.87017 | - | - | 80.3% |
包括上述模型,PaddleX支持近20种图像分类模型,其余模型可参考[PaddleX模型库](../appendix/model_zoo.md)
### 目标检测
目标检测任务指的是输入图像,模型识别出图像中物体的位置(用矩形框框出来,并给出框的位置),和物体的类别,如在手机等零件质检中,用于检测外观上的瑕疵等。
![](./images/object_detection.png)
对于目标检测,针对不同的应用场景,PaddleX提供了主流的YOLOv3模型和Faster-RCNN模型,见下表所示
> 表中GPU预测速度是使用PaddlePaddle Python预测接口测试得到(测试GPU型号为Nvidia Tesla P40)。
> 表中CPU预测速度 (测试CPU型号为)。
> 表中骁龙855预测速度是使用处理器为骁龙855的手机测试得到。
> 测速时YOLOv3的输入大小为608 x 608,FasterRCNN的输入大小为800 x 1333,Box mmAP为COCO2017数据集上评估所得。
| 模型 | 模型特点 | 存储体积 | GPU预测速度 | CPU(x86)预测速度(毫秒) | 骁龙855(ARM)预测速度 (毫秒)| Box mmAP |
| :------- | :------- | :--------- | :---------- | :------------- | :------------- |:--- |
| YOLOv3-MobileNetV3_larget | 适用于追求高速预测的移动端场景 | 100.7MB | 143.322 | - | - | 31.6 |
| YOLOv3-MobileNetV1 | 精度相对偏低,适用于追求高速预测的服务器端场景 | 99.2MB| 15.422 | - | - | 29.3 |
| YOLOv3-DarkNet53 | 在预测速度和模型精度上都有较好的表现,适用于大多数的服务器端场景| 249.2MB | 42.672 | - | - | 38.9 |
| FasterRCNN-ResNet50-FPN | 经典的二阶段检测器,预测速度相对较慢,适用于重视模型精度的服务器端场景 | 167.MB | 83.189 | - | -| 37.2 |
| FasterRCNN-HRNet_W18-FPN | 适用于对图像分辨率较为敏感、对目标细节预测要求更高的服务器端场景 | 115.5MB | 81.592 | - | - | 36 |
| FasterRCNN-ResNet101_vd-FPN | 超高精度模型,预测时间更长,在处理较大数据量时有较高的精度,适用于服务器端场景 | 244.3MB | 156.097 | - | - | 40.5 |
除上述模型外,YOLOv3和Faster RCNN还支持其他backbone,详情可参考[PaddleX模型库](../appendix/model_zoo.md)
### 实例分割
在目标检测中,模型识别出图像中物体的位置和物体的类别。而实例分割则是在目标检测的基础上,做了像素级的分类,将框内的属于目标物体的像素识别出来。
![](./images/instance_segmentation.png)
PaddleX目前提供了实例分割MaskRCNN模型,支持5种不同的backbone网络,详情可参考[PaddleX模型库](../appendix/model_zoo.md)
> 表中GPU预测速度是使用PaddlePaddle Python预测接口测试得到(测试GPU型号为Nvidia Tesla P40)。
> 表中CPU预测速度 (测试CPU型号为)。
> 表中骁龙855预测速度是使用处理器为骁龙855的手机测试得到。
> 测速时MaskRCNN的输入大小为800 x 1333,Box mmAP和Seg mmAP为COCO2017数据集上评估所得。
| 模型 | 模型特点 | 存储体积 | GPU预测速度 | CPU(x86)预测速度(毫秒) | 骁龙855(ARM)预测速度 (毫秒)| Box mmAP | Seg mmAP |
| :---- | :------- | :---------- | :---------- | :----- | :----- | :--- |:--- |
| MaskRCNN-HRNet_W18-FPN | 适用于对图像分辨率较为敏感、对目标细节预测要求更高的服务器端场景 | - | - | - | - | 37.0 | 33.4 |
| MaskRCNN-ResNet50-FPN | 精度较高,适合大多数的服务器端场景| 185.5M | - | - | - | 37.9 | 34.2 |
| MaskRCNN-ResNet101_vd-FPN | 高精度但预测时间更长,在处理较大数据量时有较高的精度,适用于服务器端场景 | 268.6M | - | - | - | 41.4 | 36.8 |
### 语义分割
语义分割用于对图像做像素级的分类,应用在人像分类、遥感图像识别等场景。
![](./images/semantic_segmentation.png)
对于语义分割,PaddleX也针对不同的应用场景,提供了不同的模型选择,如下表所示
> 表中GPU预测速度是使用PaddlePaddle Python预测接口测试得到(测试GPU型号为Nvidia Tesla P40)。
> 表中CPU预测速度 (测试CPU型号为)。
> 表中骁龙855预测速度是使用处理器为骁龙855的手机测试得到。
> 测速时模型的输入大小为1024 x 2048,mIOU为Cityscapes数据集上评估所得。
| 模型 | 模型特点 | 存储体积 | GPU预测速度 | CPU(x86)预测速度(毫秒) | 骁龙855(ARM)预测速度 (毫秒)| mIOU |
| :---- | :------- | :---------- | :---------- | :----- | :----- |:--- |
| DeepLabv3p-MobileNetV2_x1.0 | 轻量级模型,适用于移动端场景| - | - | - | 69.8% |
| HRNet_W18_Small_v1 | 轻量高速,适用于移动端场景 | - | - | - | - |
| FastSCNN | 轻量高速,适用于追求高速预测的移动端或服务器端场景 | - | - | - | 69.64 |
| HRNet_W18 | 高精度模型,适用于对图像分辨率较为敏感、对目标细节预测要求更高的服务器端场景| - | - | - | 79.36 |
| DeepLabv3p-Xception65 | 高精度但预测时间更长,在处理较大数据量时有较高的精度,适用于服务器且背景复杂的场景| - | - | - | 79.3% |
## 压缩策略选择
PaddleX提供包含模型剪裁、定点量化的模型压缩策略来减小模型的计算量和存储体积,加快模型部署后的预测速度。使用不同压缩策略在图像分类、目标检测和语义分割模型上的模型精度和预测速度详见以下内容,用户可以选择根据自己的需求选择合适的压缩策略,进一步优化模型的性能。
| 压缩策略 | 策略特点 |
| :---- | :------- |
| 量化 | 较为显著地减少模型的存储体积,适用于移动端或服务期端TensorRT部署,在移动端对于MobileNet系列模型有明显的加速效果 |
| 剪裁 | 能够去除冗余的参数,达到显著减少参数计算量和模型体积的效果,提升模型的预测性能,适用于CPU部署或移动端部署(GPU上无明显加速效果) |
| 先剪裁后量化 | 可以进一步提升模型的预测性能,适用于移动端或服务器端TensorRT部署 |
### 性能对比
* 表中各指标的格式为XXX/YYY,XXX表示未采取压缩策略时的指标,YYY表示压缩后的指标
* 分类模型的准确率指的是ImageNet-1000数据集上的Top1准确率(模型输入大小为224x224),检测模型的准确率指的是COCO2017数据集上的mmAP(模型输入大小为608x608),分割模型的准确率指的是Cityscapes数据集上mIOU(模型输入大小为769x769)
* 量化策略中,PaddleLiter推理环境为Qualcomm SnapDragon 855 + armv8,速度指标为Thread4耗时
* 剪裁策略中,PaddleLiter推理环境为Qualcomm SnapDragon 845 + armv8,速度指标为Thread4耗时
| 模型 | 压缩策略 | 存储体积(MB) | 准确率(%) | PaddleLite推理耗时(ms) |
| :--: | :------: | :------: | :----: | :----------------: |
| MobileNetV1 | 量化 | 17/4.4 | 70.99/70.18 | 10.0811/4.2934 |
| MobileNetV1 | 剪裁 -30% | 17/12 | 70.99/70.4 | 19.5762/13.6982 |
| YOLOv3-MobileNetV1 | 量化 | 95/25 | 29.3/27.9 | - |
| YOLOv3-MobileNetV1 | 剪裁 -51.77% | 95/25 | 29.3/26 | - |
| Deeplabv3-MobileNetV2 | 量化 | 7.4/1.8 | 63.26/62.03 | 593.4522/484.0018 |
| FastSCNN | 剪裁 -47.60% | 11/5.7 | 69.64/66.68 | 415.664/291.748 |
更多模型在不同设备上压缩前后的指标对比详见[PaddleX压缩模型库](appendix/slim_model_zoo.md)
压缩策略的具体使用流程详见[模型压缩](tutorials/compress)
**注意:PaddleX中全部图像分类模型和语义分割模型都支持量化和剪裁操作,目标检测仅有YOLOv3支持量化和剪裁操作。**
## 模型部署
PaddleX提供服务器端python部署、服务器端c++部署、服务器端加密部署、OpenVINO部署、移动端部署共5种部署方案,用户可以根据自己的需求选择合适的部署方案,点击以下链接了解部署的具体流程。
| 部署方案 | 部署流程 |
| :------: | :------: |
| 服务器端python部署 | [部署流程](tutorials/deploy/deploy_server/deploy_python.html)|
| 服务器端c++部署 | [部署流程](tutorials/deploy/deploy_server/deploy_cpp/) |
| 服务器端加密部署 | [部署流程](tutorials/deploy/deploy_server/encryption.html) |
| OpenVINO部署 | [部署流程](tutorials/deploy/deploy_openvino.html) |
| 移动端部署 | [部署流程](tutorials/deploy/deploy_lite.html) |
# 数据标注工具
PaddleX支持图像分类、目标检测、实例分割和语义分割四大视觉领域常见的任务,对于每类视觉任务,都支持了特定的数据格式。PaddleX目前支持了图像分类的ImageNet格式,目标检测的PascalVOC格式,实例分割的MSCOCO格式(MSCOCO也可以用于目标检测)以及语义分割数据格式。
## 常见标注工具
> 图像分类无需标注工具,用户只需以txt文件记录每张图片的类别标签即可。
> 对于目标检测、实例分割和语义分割,PaddleX已经与主流的标注工具进行了适配,用户可根据自己的需求,选择以下标注工具进行数据标注。
| 标注工具 | 图像分类 | 目标检测 | 实例分割 | 语义分割 | 安装 |
| :--------- | :------- | :------ | :------ | :------- | :----------------------------------------------- |
| Labelme | - | √ | √ | √ | pip install labelme (本地数据标注) |
| 精灵标注 | √ | √* | √ | √ | [官网下载](http://www.jinglingbiaozhu.com/) (本地数据标注) |
| EasyData | √ | √ | √ | √ | [Web页面标注](https://ai.baidu.com/easydata/) (需上传数据进行标注) |
数据标注完成后,参照如下流程,将标注数据转为可用PaddleX模型训练的数据组织格式。
> *注*:精灵标注的目标检测数据可以在工具内部导出为PascalVOC格式,因此paddlex未提供精灵标注数据到PascalVOC格式的转换
## 标注数据格式转换
目前所有标注工具,生成的标注文件,均为与原图同名的json格式文件,如`1.jpg`在标注完成后,则会在标注文件保存的目录生成`1.json`文件。转换时参照以下步骤
> 1. 将所有的原图文件放在同一个目录下,如`pics`目录
> 2. 将所有的标注json文件放在同一个目录下,如`annotations`目录
> 3. 使用如下命令进行转换
> *注*:精灵标注的目标检测数据可以在工具内部导出为PascalVOC格式,因此paddlex未提供精灵标注数据到PascalVOC格式的转换
```
paddlex --data_conversion --source labelme --to PascalVOC --pics ./pics --annotations ./annotations --save_dir ./converted_dataset_dir
```
> `--source`表示数据标注来源,支持`labelme`、`jingling`和`easydata`(分别表示数据来源于LabelMe,精灵标注助手和EasyData)
> `--to`表示数据需要转换成为的格式,支持`ImageNet`(图像分类)、`PascalVOC`(目标检测),`MSCOCO`(实例分割,也可用于目标检测)和`SEG`(语义分割)
> `--pics`指定原图所在的目录路径
> `--annotations`指定标注文件所在的目录路径
# 图像分类ImageNet
## 数据文件夹结构
在PaddleX中,图像分类支持ImageNet数据集格式。数据集目录`data_dir`下包含多个文件夹,每个文件夹中的图像均属于同一个类别,文件夹的命名即为类别名(注意路径中不要包括中文,空格)。
如下为示例结构
```
MyDataset/ # 图像分类数据集根目录
|--dog/ # 当前文件夹所有图片属于dog类别
| |--d1.jpg
| |--d2.jpg
| |--...
| |--...
|
|--...
|
|--snake/ # 当前文件夹所有图片属于snake类别
| |--s1.jpg
| |--s2.jpg
| |--...
| |--...
```
## 划分训练集验证集
**为了用于训练,我们需要在`MyDataset`目录下准备`train_list.txt`, `val_list.txt`和`labels.txt`三个文件**,分别用于表示训练集列表,验证集列表和类别标签列表。[点击下载图像分类示例数据集](https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz)
> 注:也可使用PaddleX自带工具,对数据集进行随机划分,**在数据集按照上面格式组织后**,使用如下命令即可快速完成数据集随机划分,其中split指标训练集的比例,剩余的比例用于验证集。
> ```
> paddlex --split_dataset --from ImageNet --split 0.8 --save_dir ./splited_dataset_dir
> ```
**labels.txt**
labels.txt用于列出所有类别,类别对应行号表示模型训练过程中类别的id(行号从0开始计数),例如labels.txt为以下内容
```
dog
cat
snake
```
即表示该分类数据集中共有3个类别,分别为`dog``cat``snake`,在模型训练中`dog`对应的类别id为0, `cat`对应1,以此类推
**train_list.txt**
train_list.txt列出用于训练时的图片集合,与其对应的类别id,示例如下
```
dog/d1.jpg 0
dog/d2.jpg 0
cat/c1.jpg 1
... ...
snake/s1.jpg 2
```
其中第一列为相对对`MyDataset`的相对路径,第二列为图片对应类别的类别id
**val_list.txt**
val_list列出用于验证时的图片集成,与其对应的类别id,格式与train_list.txt一致
## PaddleX数据集加载
示例代码如下,
```
import paddlex as pdx
from paddlex.cls import transforms
train_transforms = transforms.ComposedClsTransforms(mode='train', crop_size=[224, 224])
eval_transforms = transforms.ComposedClsTransforms(mode='eval', crop_size=[224, 224])
train_dataset = pdx.datasets.ImageNet(
data_dir='./MyDataset',
file_list='./MyDataset/train_list.txt',
label_list='./MyDataset/labels.txt',
transforms=train_transforms)
eval_dataset = pdx.datasets.ImageNet(
data_dir='./MyDataset',
file_list='./MyDataset/eval_list.txt',
label_list='./MyDataset/labels.txt',
transforms=eval_transforms)
```
# 目标检测PascalVOC
## 数据集文件夹结构
在PaddleX中,目标检测支持PascalVOC数据集格式。建议用户将数据集按照如下方式进行组织,原图均放在同一目录,如`JPEGImages`,标注的同名xml文件均放在同一目录,如`Annotations`,示例如下
```
MyDataset/ # 目标检测数据集根目录
|--JPEGImages/ # 原图文件所在目录
| |--1.jpg
| |--2.jpg
| |--...
| |--...
|
|--Annotations/ # 标注文件所在目录
| |--1.xml
| |--2.xml
| |--...
| |--...
```
## 划分训练集验证集
**为了用于训练,我们需要在`MyDataset`目录下准备`train_list.txt`, `val_list.txt`和`labels.txt`三个文件**,分别用于表示训练集列表,验证集列表和类别标签列表。[点击下载目标检测示例数据集](https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz)
> 注:也可使用PaddleX自带工具,对数据集进行随机划分,**在数据集按照上面格式组织后**,使用如下命令即可快速完成数据集随机划分,其中split指标训练集的比例,剩余的比例用于验证集。
> ```
> paddlex --split_dataset --from PascalVOC --pics ./JPEGImages --annotations ./Annotations --split 0.8 --save_dir ./splited_dataset_dir
> ```
**labels.txt**
labels.txt用于列出所有类别,类别对应行号表示模型训练过程中类别的id(行号从0开始计数),例如labels.txt为以下内容
```
dog
cat
snake
```
表示该检测数据集中共有3个目标类别,分别为`dog``cat``snake`,在模型训练中`dog`对应的类别id为0, `cat`对应1,以此类推
**train_list.txt**
train_list.txt列出用于训练时的图片集合,与其对应的标注文件,示例如下
```
JPEGImages/1.jpg Annotations/1.xml
JPEGImages/2.jpg Annotations/2.xml
... ...
```
其中第一列为原图相对`MyDataset`的相对路径,第二列为标注文件相对`MyDataset`的相对路径
**val_list.txt**
val_list列出用于验证时的图片集成,与其对应的标注文件,格式与val_list.txt一致
## PaddleX数据集加载
示例代码如下,
```
import paddlex as pdx
from paddlex.det import transforms
train_transforms = transforms.ComposedYOLOv3Transforms(mode='train', shape=[608, 608])
eval_transforms = transforms.ComposedYOLOv3Transforms(mode='eval', shape=[608, 608])
train_dataset = pdx.datasets.VOCDetection(
data_dir='./MyDataset',
file_list='./MyDataset/train_list.txt',
label_list='./MyDataset/labels.txt',
transforms=train_transforms)
eval_dataset = pdx.datasets.VOCDetection(
data_dir='./MyDataset',
file_list='./MyDataset/val_list.txt',
label_list='MyDataset/labels.txt',
transforms=eval_transforms)
```
模型训练 数据格式说明
========================= =======================================
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 2
:caption: 文档目录:
classification.md classification.md
detection.md detection.md
instance_segmentation.md instance_segmentation.md
segmentation.md segmentation.md
visualdl.md
# 实例分割MSCOCO
## 数据集文件夹结构
在PaddleX中,实例分割支持MSCOCO数据集格式(MSCOCO格式同样也可以用于目标检测)。建议用户将数据集按照如下方式进行组织,原图均放在同一目录,如JPEGImages,标注文件(如annotations.json)放在与JPEGImages所在目录同级目录下,示例结构如下
```
MyDataset/ # 实例分割数据集根目录
|--JPEGImages/ # 原图文件所在目录
| |--1.jpg
| |--2.jpg
| |--...
| |--...
|
|--annotations.json # 标注文件所在目录
```
## 划分训练集验证集
在PaddleX中,为了区分训练集和验证集,在`MyDataset`同级目录,使用不同的json表示数据的划分,例如`train.json``val.json`[点击下载实例分割示例数据集](https://bj.bcebos.com/paddlex/datasets/garbage_ins_det.tar.gz)
> 注:也可使用PaddleX自带工具,对数据集进行随机划分,在数据按照上述示例组织结构后,使用如下命令,即可快速完成数据集随机划分,其中split指定训练集的比例,剩余比例用于验证集。
> ```
> paddlex --split_dataset --from MSCOCO --pics ./JPEGImages --annotations ./annotations.json --split 0.8 --save_dir ./splited_dataset_dir
> ```
MSCOCO数据的标注文件采用json格式,用户可使用Labelme, 精灵标注助手或EasyData等标注工具进行标注,参见[数据标注工具](../annotations.md)
## PaddleX加载数据集
示例代码如下,
```
import paddlex as pdx
from paddlex.det import transforms
train_transforms = transforms.ComposedRCNNTransforms(mode='train', min_max_size=[800, 1333])
eval_transforms = transforms.ComposedRCNNTransforms(mode='eval', min_max_size=[800, 1333])
train_dataset = pdx.dataset.CocoDetection(
data_dir='./MyDataset/JPEGImages',
ann_file='./MyDataset/train.json',
transforms=train_transforms)
eval_dataset = pdx.dataset.CocoDetection(
data_dir='./MyDataset/JPEGImages',
ann_file='./MyDataset/val.json',
transforms=eval_transforms)
```
# 语义分割Seg
## 数据集文件夹结构
在PaddleX中,**标注文件为png文件**。建议用户将数据集按照如下方式进行组织,原图均放在同一目录,如`JPEGImages`,标注的同名png文件均放在同一目录,如`Annotations`,示例如下
```
MyDataset/ # 语义分割数据集根目录
|--JPEGImages/ # 原图文件所在目录
| |--1.jpg
| |--2.jpg
| |--...
| |--...
|
|--Annotations/ # 标注文件所在目录
| |--1.png
| |--2.png
| |--...
| |--...
```
语义分割的标注图像,如1.png,为单通道图像,像素标注类别需要从0开始递增(一般0表示background背景), 例如0, 1, 2, 3表示4种类别,标注类别最多255个类别(其中像素值255不参与训练和评估)。
## 划分训练集验证集
**为了用于训练,我们需要在`MyDataset`目录下准备`train_list.txt`, `val_list.txt`和`labels.txt`三个文件**,分别用于表示训练集列表,验证集列表和类别标签列表。[点击下载语义分割示例数据集](https://bj.bcebos.com/paddlex/datasets/optic_disc_seg.tar.gz)
> 注:也可使用PaddleX自带工具,对数据集进行随机划分,**在数据集按照上面格式组织后**,使用如下命令即可快速完成数据集随机划分,其中split指标训练集的比例,剩余的比例用于验证集。
> ```
> paddlex --split_dataset --from Seg --pics ./JPEGImages --annotations ./Annotations --split 0.8 --save_dir ./splited_dataset_dir
> ```
**labels.txt**
labels.txt用于列出所有类别,类别对应行号表示模型训练过程中类别的id(行号从0开始计数),例如labels.txt为以下内容
```
backgrond
human
car
```
表示该检测数据集中共有3个分割类别,分别为`background``human``car`,在模型训练中`background`对应的类别id为0, `human`对应1,以此类推,如不知具体类别标签,可直接在labels.txt逐行写0,1,2...序列即可。
**train_list.txt**
train_list.txt列出用于训练时的图片集合,与其对应的标注文件,示例如下
```
JPEGImages/1.jpg Annotations/1.png
JPEGImages/2.jpg Annotations/2.png
... ...
```
其中第一列为原图相对`MyDataset`的相对路径,第二列为标注文件相对`MyDataset`的相对路径
**val_list.txt**
val_list列出用于验证时的图片集成,与其对应的标注文件,格式与val_list.txt一致
## PaddleX数据集加载
示例代码如下,
```
import paddlex as pdx
from paddlex.seg import transforms
train_transforms = transforms.ComposedSegTransforms(mode='train', train_crop_size=[512, 512])
eval_transforms = transforms.ComposedSegTransforms(mode='eval', train_crop_size=[512, 512])
train_dataset = pdx.datasets.SegDataset(
data_dir='./MyDataset',
file_list='./MyDataset/train_list.txt',
label_list='./MyDataset/labels.txt',
transforms=train_transforms)
eval_dataset = pdx.datasets.SegDataset(
data_dir='./MyDataset',
file_list='./MyDataset/val_list.txt',
label_list='MyDataset/labels.txt',
transforms=eval_transforms)
```
数据准备
=======================================
.. toctree::
:maxdepth: 2
:caption: 文档目录:
annotation.md
format/index
# 数据集格式说明
该部分内容已迁移至[附录](./appendix/datasets.md)
# 部署模型导出
在服务端部署的模型需要首先将模型导出为inference格式模型,导出的模型将包括`__model__``__params__``model.yml`三个文名,分别为模型的网络结构,模型权重和模型的配置文件(包括数据预处理参数等等)。在安装完PaddleX后,在命令行终端使用如下命令导出模型到当前目录`inferece_model`下。
> 可直接下载小度熊分拣模型测试本文档的流程[xiaoduxiong_epoch_12.tar.gz](https://bj.bcebos.com/paddlex/models/xiaoduxiong_epoch_12.tar.gz)
```
paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./inference_model
```
使用TensorRT预测时,需指定模型的图像输入shape:[w,h]。
**注**
- 分类模型请保持于训练时输入的shape一致。
- 指定[w,h]时,w和h中间逗号隔开,不允许存在空格等其他字符
```
paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./inference_model --fixed_input_shape=[640,960]
```
模型部署
=======================================
.. toctree::
:maxdepth: 2
:caption: 文档目录:
export_model.md
server/index
nvidia-jetson.md
openvino/index
paddlelite/index
# Nvidia-Jetson开发板
## 说明
本文档在 `Linux`平台使用`GCC 4.8.5``GCC 4.9.4`测试过,如果需要使用更高G++版本编译使用,则需要重新编译Paddle预测库,请参考: [NVIDIA Jetson嵌入式硬件预测库源码编译](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html#id12)
## 前置条件
* G++ 4.8.2 ~ 4.9.4
* CUDA 9.0 / CUDA 10.0, CUDNN 7+ (仅在使用GPU版本的预测库时需要)
* CMake 3.0+
请确保系统已经安装好上述基本软件,**下面所有示例以工作目录 `/root/projects/`演示**
### Step1: 下载代码
`git clone https://github.com/PaddlePaddle/PaddleX.git`
**说明**:其中`C++`预测代码在`/root/projects/PaddleX/deploy/cpp` 目录,该目录不依赖任何`PaddleX`下其他目录。
### Step2: 下载PaddlePaddle C++ 预测库 paddle_inference
目前PaddlePaddle为Nvidia-Jetson 提供了一个基于1.6.2版本的C++ 预测库。
| 版本说明 | 预测库(1.6.2版本) |
| ---- | ---- |
| nv-jetson-cuda10-cudnn7.5-trt5 | [paddle_inference](https://paddle-inference-lib.bj.bcebos.com/1.7.1-nv-jetson-cuda10-cudnn7.5-trt5/fluid_inference.tar.gz) |
下载并解压后`/root/projects/fluid_inference`目录包含内容为:
```
fluid_inference
├── paddle # paddle核心库和头文件
|
├── third_party # 第三方依赖库和头文件
|
└── version.txt # 版本和编译信息
```
### Step3: 编译
编译`cmake`的命令在`scripts/jetson_build.sh`中,请根据实际情况修改主要参数,其主要内容说明如下:
```
# 是否使用GPU(即是否使用 CUDA)
WITH_GPU=OFF
# 使用MKL or openblas
WITH_MKL=OFF
# 是否集成 TensorRT(仅WITH_GPU=ON 有效)
WITH_TENSORRT=OFF
# TensorRT 的路径,如果需要集成TensorRT,需修改为您实际安装的TensorRT路径
TENSORRT_DIR=/root/projects/TensorRT/
# Paddle 预测库路径, 请修改为您实际安装的预测库路径
PADDLE_DIR=/root/projects/fluid_inference
# Paddle 的预测库是否使用静态库来编译
# 使用TensorRT时,Paddle的预测库通常为动态库
WITH_STATIC_LIB=OFF
# CUDA 的 lib 路径
CUDA_LIB=/usr/local/cuda/lib64
# CUDNN 的 lib 路径
CUDNN_LIB=/usr/local/cuda/lib64
# 是否加载加密后的模型
WITH_ENCRYPTION=OFF
# OPENCV 路径, 如果使用自带预编译版本可不修改
sh $(pwd)/scripts/jetson_bootstrap.sh # 下载预编译版本的opencv
OPENCV_DIR=$(pwd)/deps/opencv3/
# 以下无需改动
rm -rf build
mkdir -p build
cd build
cmake .. \
-DWITH_GPU=${WITH_GPU} \
-DWITH_MKL=${WITH_MKL} \
-DWITH_TENSORRT=${WITH_TENSORRT} \
-DWITH_ENCRYPTION=${WITH_ENCRYPTION} \
-DTENSORRT_DIR=${TENSORRT_DIR} \
-DPADDLE_DIR=${PADDLE_DIR} \
-DWITH_STATIC_LIB=${WITH_STATIC_LIB} \
-DCUDA_LIB=${CUDA_LIB} \
-DCUDNN_LIB=${CUDNN_LIB} \
-DENCRYPTION_DIR=${ENCRYPTION_DIR} \
-DOPENCV_DIR=${OPENCV_DIR}
make
```
**注意:** linux环境下编译会自动下载OPENCV和YAML,如果编译环境无法访问外网,可手动下载:
- [opencv3_aarch.tgz](https://bj.bcebos.com/paddlex/deploy/tools/opencv3_aarch.tgz)
- [yaml-cpp.zip](https://bj.bcebos.com/paddlex/deploy/deps/yaml-cpp.zip)
opencv3_aarch.tgz文件下载后解压,然后在script/build.sh中指定`OPENCE_DIR`为解压后的路径。
yaml-cpp.zip文件下载后无需解压,在cmake/yaml.cmake中将`URL https://bj.bcebos.com/paddlex/deploy/deps/yaml-cpp.zip` 中的网址,改为下载文件的路径。
修改脚本设置好主要参数后,执行`build`脚本:
```shell
sh ./scripts/jetson_build.sh
```
### Step4: 预测及可视化
**在加载模型前,请检查你的模型目录中文件应该包括`model.yml`、`__model__`和`__params__`三个文件。如若不满足这个条件,请参考[模型导出为Inference文档](export_model.md)将模型导出为部署格式。**
编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifier``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下:
| 参数 | 说明 |
| ---- | ---- |
| model_dir | 导出的预测模型所在路径 |
| image | 要预测的图片文件路径 |
| image_list | 按行存储图片路径的.txt文件 |
| use_gpu | 是否使用 GPU 预测, 支持值为0或1(默认值为0) |
| use_trt | 是否使用 TensorRT 预测, 支持值为0或1(默认值为0) |
| gpu_id | GPU 设备ID, 默认值为0 |
| save_dir | 保存可视化结果的路径, 默认值为"output",**classfier无该参数** |
| key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 |
| batch_size | 预测的批量大小,默认为1 |
| thread_num | 预测的线程数,默认为cpu处理器个数 |
| use_ir_optim | 是否使用图优化策略,支持值为0或1(默认值为1,图像分割默认值为0)|
## 样例
可使用[小度熊识别模型](export_model.md)中导出的`inference_model`和测试图片进行预测,导出到/root/projects,模型路径为/root/projects/inference_model。
`样例一`
不使用`GPU`测试图片 `/root/projects/images/xiaoduxiong.jpeg`
```shell
./build/demo/detector --model_dir=/root/projects/inference_model --image=/root/projects/images/xiaoduxiong.jpeg --save_dir=output
```
图片文件`可视化预测结果`会保存在`save_dir`参数设置的目录下。
`样例二`:
使用`GPU`预测多个图片`/root/projects/image_list.txt`,image_list.txt内容的格式如下:
```
/root/projects/images/xiaoduxiong1.jpeg
/root/projects/images/xiaoduxiong2.jpeg
...
/root/projects/images/xiaoduxiongn.jpeg
```
```shell
./build/demo/detector --model_dir=/root/projects/inference_model --image_list=/root/projects/images_list.txt --use_gpu=1 --save_dir=output --batch_size=2 --thread_num=2
```
图片文件`可视化预测结果`会保存在`save_dir`参数设置的目录下。
OpenVINO部署
=======================================
.. toctree::
:maxdepth: 2
:caption: 文档目录:
windows.md
linux.md
intel_movidius.md
PaddleLite移动端部署
=======================================
.. toctree::
:maxdepth: 2
:caption: 文档目录:
slim/index
android.md
模型压缩 模型压缩
============================ =======================================
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: 文档目录:
prune.md prune.md
quant.md quant.md
服务端C++部署
=======================================
.. toctree::
:maxdepth: 2
:caption: 文档目录:
windows.md
linux.md
...@@ -17,18 +17,18 @@ ...@@ -17,18 +17,18 @@
**说明**:其中`C++`预测代码在`/root/projects/PaddleX/deploy/cpp` 目录,该目录不依赖任何`PaddleX`下其他目录。 **说明**:其中`C++`预测代码在`/root/projects/PaddleX/deploy/cpp` 目录,该目录不依赖任何`PaddleX`下其他目录。
### Step2: 下载PaddlePaddle C++ 预测库 fluid_inference ### Step2: 下载PaddlePaddle C++ 预测库 paddle_inference
PaddlePaddle C++ 预测库针对不同的`CPU``CUDA`,以及是否支持TensorRT,提供了不同的预编译版本,目前PaddleX依赖于Paddle1.8版本,以下提供了多个不同版本的Paddle预测库: PaddlePaddle C++ 预测库针对不同的`CPU``CUDA`,以及是否支持TensorRT,提供了不同的预编译版本,目前PaddleX依赖于Paddle1.8版本,以下提供了多个不同版本的Paddle预测库:
| 版本说明 | 预测库(1.8.2版本) | | 版本说明 | 预测库(1.8.2版本) |
| ---- | ---- | | ---- | ---- |
| ubuntu14.04_cpu_avx_mkl | [fluid_inference.tgz](https://paddle-inference-lib.bj.bcebos.com/1.8.2-cpu-avx-mkl/fluid_inference.tgz) | | ubuntu14.04_cpu_avx_mkl | [paddle_inference](https://paddle-inference-lib.bj.bcebos.com/1.8.2-cpu-avx-mkl/fluid_inference.tgz) |
| ubuntu14.04_cpu_avx_openblas | [fluid_inference.tgz](https://paddle-inference-lib.bj.bcebos.com/1.8.2-cpu-avx-openblas/fluid_inference.tgz) | | ubuntu14.04_cpu_avx_openblas | [paddle_inference](https://paddle-inference-lib.bj.bcebos.com/1.8.2-cpu-avx-openblas/fluid_inference.tgz) |
| ubuntu14.04_cpu_noavx_openblas | [fluid_inference.tgz](https://paddle-inference-lib.bj.bcebos.com/1.8.2-cpu-noavx-openblas/fluid_inference.tgz) | | ubuntu14.04_cpu_noavx_openblas | [paddle_inference](https://paddle-inference-lib.bj.bcebos.com/1.8.2-cpu-noavx-openblas/fluid_inference.tgz) |
| ubuntu14.04_cuda9.0_cudnn7_avx_mkl | [fluid_inference.tgz](https://paddle-inference-lib.bj.bcebos.com/1.8.2-gpu-cuda9-cudnn7-avx-mkl/fluid_inference.tgz) | | ubuntu14.04_cuda9.0_cudnn7_avx_mkl | [paddle_inference](https://paddle-inference-lib.bj.bcebos.com/1.8.2-gpu-cuda9-cudnn7-avx-mkl/fluid_inference.tgz) |
| ubuntu14.04_cuda10.0_cudnn7_avx_mkl | [fluid_inference.tgz](https://paddle-inference-lib.bj.bcebos.com/1.8.2-gpu-cuda10-cudnn7-avx-mkl/fluid_inference.tgz ) | | ubuntu14.04_cuda10.0_cudnn7_avx_mkl | [paddle_inference](https://paddle-inference-lib.bj.bcebos.com/1.8.2-gpu-cuda10-cudnn7-avx-mkl/fluid_inference.tgz ) |
| ubuntu14.04_cuda10.1_cudnn7.6_avx_mkl_trt6 | [fluid_inference.tgz](https://paddle-inference-lib.bj.bcebos.com/1.8.2-gpu-cuda10.1-cudnn7.6-avx-mkl-trt6%2Ffluid_inference.tgz) | | ubuntu14.04_cuda10.1_cudnn7.6_avx_mkl_trt6 | [paddle_inference](https://paddle-inference-lib.bj.bcebos.com/1.8.2-gpu-cuda10.1-cudnn7.6-avx-mkl-trt6%2Ffluid_inference.tgz) |
更多和更新的版本,请根据实际情况下载: [C++预测库下载列表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html) 更多和更新的版本,请根据实际情况下载: [C++预测库下载列表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html)
...@@ -45,7 +45,7 @@ fluid_inference ...@@ -45,7 +45,7 @@ fluid_inference
**注意:** 预编译版本除`nv-jetson-cuda10-cudnn7.5-trt5` 以外其它包都是基于`GCC 4.8.5`编译,使用高版本`GCC`可能存在 `ABI`兼容性问题,建议降级或[自行编译预测库](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html#id12) **注意:** 预编译版本除`nv-jetson-cuda10-cudnn7.5-trt5` 以外其它包都是基于`GCC 4.8.5`编译,使用高版本`GCC`可能存在 `ABI`兼容性问题,建议降级或[自行编译预测库](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html#id12)
### Step4: 编译 ### Step3: 编译
编译`cmake`的命令在`scripts/build.sh`中,请根据实际情况修改主要参数,其主要内容说明如下: 编译`cmake`的命令在`scripts/build.sh`中,请根据实际情况修改主要参数,其主要内容说明如下:
``` ```
...@@ -112,9 +112,9 @@ yaml-cpp.zip文件下载后无需解压,在cmake/yaml.cmake中将`URL https:// ...@@ -112,9 +112,9 @@ yaml-cpp.zip文件下载后无需解压,在cmake/yaml.cmake中将`URL https://
sh ./scripts/build.sh sh ./scripts/build.sh
``` ```
### Step5: 预测及可视化 ### Step4: 预测及可视化
**在加载模型前,请检查你的模型目录中文件应该包括`model.yml`、`__model__`和`__params__`三个文件。如若不满足这个条件,请参考[模型导出为Inference文档](../deploy_python.html#inference)将模型导出为部署格式。** **在加载模型前,请检查你的模型目录中文件应该包括`model.yml`、`__model__`和`__params__`三个文件。如若不满足这个条件,请参考[模型导出为Inference文档](../../export_model.md)将模型导出为部署格式。**
编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifier``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下: 编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifier``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下:
...@@ -130,10 +130,11 @@ yaml-cpp.zip文件下载后无需解压,在cmake/yaml.cmake中将`URL https:// ...@@ -130,10 +130,11 @@ yaml-cpp.zip文件下载后无需解压,在cmake/yaml.cmake中将`URL https://
| key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 | | key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 |
| batch_size | 预测的批量大小,默认为1 | | batch_size | 预测的批量大小,默认为1 |
| thread_num | 预测的线程数,默认为cpu处理器个数 | | thread_num | 预测的线程数,默认为cpu处理器个数 |
| use_ir_optim | 是否使用图优化策略,支持值为0或1(默认值为1,图像分割默认值为0)|
## 样例 ## 样例
可使用[小度熊识别模型](../deploy_python.html#inference)中导出的`inference_model`和测试图片进行预测,导出到/root/projects,模型路径为/root/projects/inference_model。 可使用[小度熊识别模型](../../export_model.md)中导出的`inference_model`和测试图片进行预测,导出到/root/projects,模型路径为/root/projects/inference_model。
`样例一` `样例一`
......
...@@ -24,17 +24,17 @@ git clone https://github.com/PaddlePaddle/PaddleX.git ...@@ -24,17 +24,17 @@ git clone https://github.com/PaddlePaddle/PaddleX.git
**说明**:其中`C++`预测代码在`PaddleX\deploy\cpp` 目录,该目录不依赖任何`PaddleX`下其他目录。 **说明**:其中`C++`预测代码在`PaddleX\deploy\cpp` 目录,该目录不依赖任何`PaddleX`下其他目录。
### Step2: 下载PaddlePaddle C++ 预测库 fluid_inference ### Step2: 下载PaddlePaddle C++ 预测库 paddle_inference
PaddlePaddle C++ 预测库针对是否使用GPU、是否支持TensorRT、以及不同的CUDA版本提供了已经编译好的预测库,目前PaddleX依赖于Paddle 1.8,基于Paddle 1.8的Paddle预测库下载链接如下所示: PaddlePaddle C++ 预测库针对是否使用GPU、是否支持TensorRT、以及不同的CUDA版本提供了已经编译好的预测库,目前PaddleX依赖于Paddle 1.8,基于Paddle 1.8的Paddle预测库下载链接如下所示:
| 版本说明 | 预测库(1.8.2版本) | 编译器 | 构建工具| cuDNN | CUDA | | 版本说明 | 预测库(1.8.2版本) | 编译器 | 构建工具| cuDNN | CUDA |
| ---- | ---- | ---- | ---- | ---- | ---- | | ---- | ---- | ---- | ---- | ---- | ---- |
| cpu_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | | cpu_avx_mkl | [paddle_inference](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 |
| cpu_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/open/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | | cpu_avx_openblas | [paddle_inference](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/open/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 |
| cuda9.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/mkl/post97/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.4.1 | 9.0 | | cuda9.0_cudnn7_avx_mkl | [paddle_inference](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/mkl/post97/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.4.1 | 9.0 |
| cuda9.0_cudnn7_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/open/post97/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.4.1 | 9.0 | | cuda9.0_cudnn7_avx_openblas | [paddle_inference](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/open/post97/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.4.1 | 9.0 |
| cuda10.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/mkl/post107/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.5.0 | 9.0 | | cuda10.0_cudnn7_avx_mkl | [paddle_inference](https://paddle-wheel.bj.bcebos.com/1.8.2/win-infer/mkl/post107/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.5.0 | 9.0 |
请根据实际情况选择下载,如若以上版本不满足您的需求,请至[C++预测库下载列表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/windows_cpp_inference.html)选择符合的版本。 请根据实际情况选择下载,如若以上版本不满足您的需求,请至[C++预测库下载列表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/windows_cpp_inference.html)选择符合的版本。
...@@ -101,7 +101,7 @@ yaml-cpp.zip文件下载后无需解压,在cmake/yaml.cmake中将`URL https:// ...@@ -101,7 +101,7 @@ yaml-cpp.zip文件下载后无需解压,在cmake/yaml.cmake中将`URL https://
### Step5: 预测及可视化 ### Step5: 预测及可视化
**在加载模型前,请检查你的模型目录中文件应该包括`model.yml`、`__model__`和`__params__`三个文件。如若不满足这个条件,请参考[模型导出为Inference文档](../deploy_python.html#inference)将模型导出为部署格式。** **在加载模型前,请检查你的模型目录中文件应该包括`model.yml`、`__model__`和`__params__`三个文件。如若不满足这个条件,请参考[模型导出为Inference文档](../../export_model.md)将模型导出为部署格式。**
上述`Visual Studio 2019`编译产出的可执行文件在`out\build\x64-Release`目录下,打开`cmd`,并切换到该目录: 上述`Visual Studio 2019`编译产出的可执行文件在`out\build\x64-Release`目录下,打开`cmd`,并切换到该目录:
...@@ -123,10 +123,11 @@ cd D:\projects\PaddleX\deploy\cpp\out\build\x64-Release ...@@ -123,10 +123,11 @@ cd D:\projects\PaddleX\deploy\cpp\out\build\x64-Release
| key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 | | key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 |
| batch_size | 预测的批量大小,默认为1 | | batch_size | 预测的批量大小,默认为1 |
| thread_num | 预测的线程数,默认为cpu处理器个数 | | thread_num | 预测的线程数,默认为cpu处理器个数 |
| use_ir_optim | 是否使用图优化策略,支持值为0或1(默认值为1,图像分割默认值为0)|
## 样例 ## 样例
可使用[小度熊识别模型](../deploy_python.md)中导出的`inference_model`和测试图片进行预测, 例如导出到D:\projects,模型路径为D:\projects\inference_model。 可使用[小度熊识别模型](../../export_model.md)中导出的`inference_model`和测试图片进行预测, 例如导出到D:\projects,模型路径为D:\projects\inference_model。
### 样例一:(使用未加密的模型对单张图像做预测) ### 样例一:(使用未加密的模型对单张图像做预测)
......
...@@ -26,9 +26,9 @@ PaddleX提供一个轻量级的模型加密部署方案,通过PaddleX内置的 ...@@ -26,9 +26,9 @@ PaddleX提供一个轻量级的模型加密部署方案,通过PaddleX内置的
> >
> 2)项目集成OpenSSL,使用静态库的形式。 > 2)项目集成OpenSSL,使用静态库的形式。
> >
> 3)实现AES算法接口,借助OpenSSL提供的EVP接口,在EVP接口中指定算法类型,算法使用对称加解密算法中的AES,加解密模式使用AES-GCM, 密钥长度为256位,AES-GCM的实现可以参考官方提供的例子自己进行封装接口:https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption > 3)实现AES算法接口,借助OpenSSL提供的EVP接口,在EVP接口中指定算法类型,算法使用对称加解密算法中的AES,加解密模式使用AES-GCM, 密钥长度为256位,AES-GCM的实现可以参考官方提供的例子自己进行封装接口:[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 > 4)利用OpenSSL库实现SHA256摘要算法,这部分下面有用(可选)。关于SHA256的hash计算可以参考OpenSSL提供的example:[OpenSSL 信息摘要例子](https://wiki.openssl.org/index.php/EVP_Message_Digests)。
> >
> 5)在模型加密环节直接对model文件和params文件的数据内容进行加密后保存到新的文件,为了新的文件能够被区分和可迭代,除了加密后的数据外还添加了头部信息,比如为了判断该文件类型使用固定的魔数作为文件的开头;为了便于后面需求迭代写入版本号以示区别;为了能够在解密时判断是否采用了相同的密钥将加密时的密钥进行SHA256计算后存储;这三部分构成了目前加密后文件的头部信息。加密后的文件包含头部信息 + 密文信息。 > 5)在模型加密环节直接对model文件和params文件的数据内容进行加密后保存到新的文件,为了新的文件能够被区分和可迭代,除了加密后的数据外还添加了头部信息,比如为了判断该文件类型使用固定的魔数作为文件的开头;为了便于后面需求迭代写入版本号以示区别;为了能够在解密时判断是否采用了相同的密钥将加密时的密钥进行SHA256计算后存储;这三部分构成了目前加密后文件的头部信息。加密后的文件包含头部信息 + 密文信息。
> >
...@@ -80,14 +80,14 @@ Windows平台: ...@@ -80,14 +80,14 @@ Windows平台:
.\paddlex-encryption\tool\paddlex_encrypt_tool.exe -model_dir D:\projects\paddlex_inference_model -save_dir D:\projects\paddlex_encrypted_model .\paddlex-encryption\tool\paddlex_encrypt_tool.exe -model_dir D:\projects\paddlex_inference_model -save_dir D:\projects\paddlex_encrypted_model
``` ```
`-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=` `-model_dir`用于指定inference模型路径(参考[导出inference模型](../export_model.md)将模型导出为inference格式模型),可使用[导出小度熊识别模型](../export_model.md)中导出的`inference_model`。加密完成后,加密过的模型会保存至指定的`-save_dir`下,包含`__model__.encrypted``__params__.encrypted``model.yml`三个文件,同时生成密钥信息,命令输出如下图所示,密钥为`kLAl1qOs5uRbFt0/RrIDTZW2+tOf5bzvUIaHGF8lJ1c=`
![](../images/encrypt.png) ![](../images/encrypt.png)
## 2. PaddleX C++加密部署 ## 2. PaddleX C++加密部署
### 2.1 Linux平台使用 ### 2.1 Linux平台使用
参考[Linux平台编译指南](deploy_cpp/deploy_cpp_linux.md)编译C++部署代码。编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifier``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下: 参考[Linux平台编译指南](cpp/linux.md)编译C++部署代码。编译成功后,预测demo的可执行程序分别为`build/demo/detector``build/demo/classifier``build/demo/segmenter`,用户可根据自己的模型类型选择,其主要命令参数说明如下:
| 参数 | 说明 | | 参数 | 说明 |
| ---- | ---- | | ---- | ---- |
...@@ -101,11 +101,12 @@ Windows平台: ...@@ -101,11 +101,12 @@ Windows平台:
| key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 | | key | 加密过程中产生的密钥信息,默认值为""表示加载的是未加密的模型 |
| batch_size | 预测的批量大小,默认为1 | | batch_size | 预测的批量大小,默认为1 |
| thread_num | 预测的线程数,默认为cpu处理器个数 | | thread_num | 预测的线程数,默认为cpu处理器个数 |
| use_ir_optim | 是否使用图优化策略,支持值为0或1(默认值为1,图像分割默认值为0)|
### 样例 ### 样例
可使用[导出小度熊识别模型](deploy_python.md#inference)中的测试图片进行预测。 可使用[导出小度熊识别模型](../export_model.md)中的测试图片进行预测。
#### 样例一: #### 样例一:
...@@ -132,11 +133,11 @@ Windows平台: ...@@ -132,11 +133,11 @@ Windows平台:
`--key`传入加密工具输出的密钥,例如`kLAl1qOs5uRbFt0/RrIDTZW2+tOf5bzvUIaHGF8lJ1c=`, 图片文件`可视化预测结果`会保存在`save_dir`参数设置的目录下。 `--key`传入加密工具输出的密钥,例如`kLAl1qOs5uRbFt0/RrIDTZW2+tOf5bzvUIaHGF8lJ1c=`, 图片文件`可视化预测结果`会保存在`save_dir`参数设置的目录下。
### 2.2 Windows平台使用 ### 2.2 Windows平台使用
参考[Windows平台编译指南](deploy_cpp/deploy_cpp_win_vs2019.md)。需自行下载Windows版PaddleX加密工具压缩包,解压,在编译指南的编译流程基础上,在CMake设置中勾选WITH_ENCRYPTION,ENCRYPTION_DIR填写为加密工具包解压后的目录,再进行编译。参数与Linux版本预测部署一致。预测demo的入口程序为paddlex_inference\detector.exe,paddlex_inference\classifier.exe,paddlex_inference\segmenter.exe。 参考[Windows平台编译指南](cpp/windows.md)。需自行下载Windows版PaddleX加密工具压缩包,解压,在编译指南的编译流程基础上,在CMake设置中勾选WITH_ENCRYPTION,ENCRYPTION_DIR填写为加密工具包解压后的目录,再进行编译。参数与Linux版本预测部署一致。预测demo的入口程序为paddlex_inference\detector.exe,paddlex_inference\classifier.exe,paddlex_inference\segmenter.exe。
### 样例 ### 样例
可使用[导出小度熊识别模型](deploy_python.md#inference)中的测试图片进行预测。 可使用[导出小度熊识别模型](../export_model.md)中的测试图片进行预测。
#### 样例一: #### 样例一:
......
服务端部署 服务端部署
============== =======================================
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: 文档目录:
deploy_python.md python.md
deploy_cpp/index.rst cpp/index
encryption.md encryption.md
# Python部署 # Python部署
PaddleX已经集成了基于Python的高性能预测接口,在安装PaddleX后,可参照如下代码示例,进行预测。相关的接口文档可参考[paddlex.deploy](../../../apis/deploy.md) PaddleX已经集成了基于Python的高性能预测接口,在安装PaddleX后,可参照如下代码示例,进行预测。相关的接口文档可参考[paddlex.deploy](../../../apis/deploy.md)
## 导出inference模型 ## 导出预测模型
可参考[模型导出](../export_model.md)将模型导出为inference格式的模型。
在服务端部署的模型需要首先将模型导出为inference格式模型,导出的模型将包括`__model__``__params__``model.yml`三个文名,分别为模型的网络结构,模型权重和模型的配置文件(包括数据预处理参数等等)。在安装完PaddleX后,在命令行终端使用如下命令导出模型到当前目录`inferece_model`下。
> 可直接下载小度熊分拣模型测试本文档的流程[xiaoduxiong_epoch_12.tar.gz](https://bj.bcebos.com/paddlex/models/xiaoduxiong_epoch_12.tar.gz)
```
paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./inference_model
```
使用TensorRT预测时,需指定模型的图像输入shape:[w,h]。
**注**
- 分类模型请保持于训练时输入的shape一致。
- 指定[w,h]时,w和h中间逗号隔开,不允许存在空格等其他字符
```
paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./inference_model --fixed_input_shape=[640,960]
```
## 预测部署 ## 预测部署
**注意:由于PaddleX代码的持续更新,版本低于1.0.0的模型暂时无法直接用于预测部署,参考[模型版本升级](../upgrade_version.md)对模型版本进行升级。** **注意:由于PaddleX代码的持续更新,版本低于1.0.0的模型暂时无法直接用于预测部署,参考[模型版本升级](../upgrade_version.md)对模型版本进行升级。**
......
人像分割案例
=======================================
这里面写人像分割案例,可根据需求拆分为多个文档
产业案例集
=======================================
.. toctree::
:maxdepth: 2
:caption: 文档目录:
solutions.md
meter_reading/index
human_segmentation/index
remote_sensing/index
工业表计读数案例
=======================================
这里面写表计读数案例,可根据需求拆分为多个文档
遥感分割案例
=======================================
这里面写遥感分割案例,可根据需求拆分为多个文档
# PaddleX模型介绍
PaddleX GUI使用文档 PaddleX GUI
======================================= =======================================
PaddleX GUI是基于PaddleX开发实现的可视化模型训练套件,可以让开发者免去代码开发的步骤,通过点选式地操作就可以快速完成模型的训练开发。PaddleXGUI具有 **数据集可视化分析** 、**模型参数自动推荐** 、**跨平台使用** 三大特点。 PaddleX GUI是基于PaddleX开发实现的可视化模型训练套件,可以让开发者免去代码开发的步骤,通过点选式地操作就可以快速完成模型的训练开发。PaddleXGUI具有 **数据集可视化分析** 、**模型参数自动推荐** 、**跨平台使用** 三大特点。
...@@ -17,9 +17,6 @@ PaddleX GUI是基于PaddleX开发实现的可视化模型训练套件,可以 ...@@ -17,9 +17,6 @@ PaddleX GUI是基于PaddleX开发实现的可视化模型训练套件,可以
:maxdepth: 2 :maxdepth: 2
:caption: 文档目录: :caption: 文档目录:
download.md
how_to_use.md
xx.md
* PaddleX GUI版本: v1.0 * PaddleX GUI版本: v1.0
* 项目官网: http://www.paddlepaddle.org.cn/paddle/paddlex * 项目官网: http://www.paddlepaddle.org.cn/paddle/paddlex
......
...@@ -3,37 +3,18 @@ ...@@ -3,37 +3,18 @@
PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习全流程开发工具。具备 **全流程打通** 、**融合产业实践** 、**易用易集成** 三大特点。 PaddleX是基于飞桨核心框架、开发套件和工具组件的深度学习全流程开发工具。具备 **全流程打通** 、**融合产业实践** 、**易用易集成** 三大特点。
全流程打通
| - **数据准备**: 支持 `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>`_ 可视化分析组件,提供丰富的信息更好地理解模型,优化模型。
| - **多端安全部署**: 内置 `PaddleSlim <https://github.com/PaddlePaddle/PaddleSlim>`_ 模型压缩工具和AES模型加密SDK,结合Paddle Inference和 `Paddle Lite <https://github.com/PaddlePaddle/Paddle-Lite>`_ 便捷完成高性能的多端安全部署。
融合产业实践
| - 精选飞桨产业实践的成熟模型结构,开放案例实践教程,加速开发者产业落地。
易用易集成
| - 统一易用的全流程API,5步完成模型训练,10行代码实现Python/C++高性能部署。
| - 提供以PaddleX为核心集成的跨平台可视化开发工具PaddleX-GUI,更低门槛快速体验飞桨深度学习全流程。
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: 文档目录: :caption: PaddleX使用文档目录
quick_start.md quick_start.md
install.md install.md
tutorials/index.rst data/index
cv_solutions.md train/index
apis/index.rst deploy/index
paddlex_gui/index.rst examples/index
tuning_strategy/index.rst gui/index
update.md apis/index
FAQ.md change_log.md
appendix/index.rst appendix/index
* PaddleX版本: v1.0.0
* 项目官网: http://www.paddlepaddle.org.cn/paddle/paddlex
* 项目GitHub: https://github.com/PaddlePaddle/PaddleX
* 官方QQ用户群: 1045148026
* GitHub Issue反馈: http://www.github.com/PaddlePaddle/PaddleX/issues
# 快速安装 # 快速安装
以下安装过程默认用户已安装好**paddlepaddle-gpu或paddlepaddle(版本大于或等于1.7.1)**,paddlepaddle安装方式参照[飞桨官网](https://www.paddlepaddle.org.cn/install/quick) 以下安装过程默认用户已安装好**paddlepaddle-gpu或paddlepaddle(版本大于或等于1.8.1)**,paddlepaddle安装方式参照[飞桨官网](https://www.paddlepaddle.org.cn/install/quick)
> 推荐使用Anaconda Python环境,Anaconda下安装PaddleX参考文档[Anaconda安装使用](../appendix/anaconda_install.md)
## pip安装 ## pip安装
...@@ -12,8 +10,12 @@ ...@@ -12,8 +10,12 @@
pip install paddlex -i https://mirror.baidu.com/pypi/simple pip install paddlex -i https://mirror.baidu.com/pypi/simple
``` ```
## Anaconda安装
Anaconda是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。使用Anaconda可以通过创建多个独立的Python环境,避免用户的Python环境安装太多不同版本依赖导致冲突。
- 参考[Anaconda安装PaddleX文档](appendix/anaconda_install.md)
## 代码安装
## Github代码安装
github代码会跟随开发进度不断更新 github代码会跟随开发进度不断更新
``` ```
...@@ -24,18 +26,17 @@ python setup.py install ...@@ -24,18 +26,17 @@ python setup.py install
``` ```
## 安装问题 ## pycocotools安装问题
### 1. pycocotools安装问题
> PaddleX依赖pycocotools包,如安装pycocotools失败,可参照如下方式安装pycocotools > PaddleX依赖pycocotools包,如安装pycocotools失败,可参照如下方式安装pycocotools
**Windows** > Windows安装时可能会提示缺少`Microsoft Visual C++ 2015 build tools`,[点击下载VC build tools](https://go.microsoft.com/fwlink/?LinkId=691126)安装再执行如下pip命令
> Windows安装时可能会提示缺少`Microsoft Visual C++ 2015 build tools`,[点击下载](https://go.microsoft.com/fwlink/?LinkId=691126)安装再执行如下pip命令
``` ```
pip install cython pip install cython
pip install git+https://gitee.com/jiangjiajun/philferriere-cocoapi.git#subdirectory=PythonAPI pip install git+https://gitee.com/jiangjiajun/philferriere-cocoapi.git#subdirectory=PythonAPI
``` ```
**Linux/Mac安装** > Linux/Mac系统下,直接使用pip安装如下两个依赖即可
``` ```
pip install cython pip install cython
pip install pycocotools pip install pycocotools
......
本页面已移至 [这里](./appendix/metrics.md)
本页面已移至 [这里](./appendix/model_zoo.md)
## <a name="2">PaddleX GUI安装</a>
PaddleX GUI是提升项目开发效率的核心模块,开发者可快速完成深度学习模型全流程开发。我们诚挚地邀请您前往 [官网](https://www.paddlepaddle.org.cn/paddle/paddleX)下载试用PaddleX GUI可视化前端,并获得您宝贵的意见或开源项目贡献。
#### <a name="1">安装推荐环境</a>
* **操作系统**
* Windows7/8/10(推荐Windows 10);
* Mac OS 10.13+;
* Ubuntu 18.04+;
***注:处理器需为x86_64架构,支持MKL。***
* **训练硬件**
* **GPU**(仅Windows及Linux系统):
推荐使用支持CUDA的NVIDIA显卡,例如:GTX 1070+以上性能的显卡;
Windows系统X86_64驱动版本>=411.31;
Linux系统X86_64驱动版本>=410.48;
显存8G以上;
* **CPU**
PaddleX当前支持您用本地CPU进行训练,但推荐使用GPU以获得更好的开发体验。
* **内存**:建议8G以上
* **硬盘空间**:建议SSD剩余空间1T以上(非必须)
***注:PaddleX在Windows及Mac OS系统只支持单卡模型。Windows系统暂不支持NCCL。***
# PaddleX GUI使用文档
飞桨全流程开发工具,集飞桨核心框架、模型库、工具及组件等深度学习开发全流程所需能力于一身,易用易集成,是开发者快速入门深度学习、提升深度学习项目开发效率的最佳辅助工具。
PaddleX GUI是一个应用PaddleX实现的一个图形化开发客户端产品,它使得开发者通过键入式输入即可完成深度学习模型全流程开发,可大幅度提升项目开发效率。飞桨团队期待各位开发者基于PaddleX,实现出各种符合自己产业实际需求的产品。
我们诚挚地邀请您前往 [官网](https://www.paddlepaddle.org.cn/paddlex)下载试用PaddleX GUI,并获得您宝贵的意见或开源项目贡献。
## 目录
* **产品特性**
* **PaddleX GUI可视化前端**
* **FAQ**
## 产品特性
\- **全流程打通**
将深度学习开发全流程打通,并提供可视化开发界面, 省去了对各环节API的熟悉过程及重复的代码开发,极大地提升了开发效率。
\- **易用易集成**
提供功能最全、最灵活的Python API开发模式,完全开源开放,易于集成和二次开发。键入式输入的图形化开发界面,使得非专业算法人员也可快速进行业务POC。
\- **融合产业实践经验**
融合飞桨产业落地经验,精选高质量的视觉模型方案,开放实际的案例教学,手把手带您实现产业需求落地。
\- **教程与服务**
从数据集准备到上线部署,为您提供业务开发全流程的文档说明及技术服务。开发者可以通过QQ群、微信群、GitHub社区等多种形式与飞桨团队及同业合作伙伴交流沟通。
## PaddleX GUI 可视化前端
**第一步:准备数据**
在开始模型训练前,您需要根据不同的任务类型,将数据标注为相应的格式。目前PaddleX支持【图像分类】、【目标检测】、【语义分割】、【实例分割】四种任务类型。不同类型任务的数据处理方式可查看[数据标注方式](https://paddlex.readthedocs.io/zh_CN/latest/appendix/datasets.html)
**第二步:导入我的数据集**
①数据标注完成后,您需要根据不同的任务,将数据和标注文件,按照客户端提示更名并保存到正确的文件中。
②在客户端新建数据集,选择与数据集匹配的任务类型,并选择数据集对应的路径,将数据集导入。
![](images/datasets1.jpg)
③选定导入数据集后,客户端会自动校验数据及标注文件是否合规,校验成功后,您可根据实际需求,将数据集按比例划分为训练集、验证集、测试集。
④您可在「数据分析」模块按规则预览您标注的数据集,双击单张图片可放大查看。
![](images/dataset2.jpg)
**第三步:创建项目**
① 在完成数据导入后,您可以点击「新建项目」创建一个项目。
② 您可根据实际任务需求选择项目的任务类型,需要注意项目所采用的数据集也带有任务类型属性,两者需要进行匹配。
![](images/project3.jpg)
**第四步:项目开发**
**数据选择**:项目创建完成后,您需要选择已载入客户端并校验后的数据集,并点击下一步,进入参数配置页面。
![](images/project1.jpg)
**参数配置**:主要分为**模型参数****训练参数****优化策略**三部分。您可根据实际需求选择模型结构、骨架网络及对应的训练参数、优化策略,使得任务效果最佳。
![](images/project2.jpg)
参数配置完成后,点击启动训练,模型开始训练并进行效果评估。
**训练可视化**:在训练过程中,您可通过VisualDL查看模型训练过程参数变化、日志详情,及当前最优的训练集和验证集训练指标。模型在训练过程中通过点击"中止训练"随时中止训练过程。
![](images/visualization1.jpg)
模型训练结束后,可选择进入『模型剪裁分析』或者直接进入『模型评估』。
![](images/visualization2.jpg)
**模型裁剪**:如果开发者希望减少模型的体积、计算量,提升模型在设备上的预测性能,可以采用PaddleX提供的模型裁剪策略。裁剪过程将对模型各卷积层的敏感度信息进行分析,根据各参数对模型效果的影响进行不同比例的裁剪,再进行精调训练获得最终裁剪后的模型。
![](images/visualization3.jpg)
**模型评估**:在模型评估页面,您可查看训练后的模型效果。评估方法包括混淆矩阵、精度、召回率等。
![](images/visualization4.jpg)
您还可以选择『数据集切分』时留出的『测试数据集』或从本地文件夹中导入一张/多张图片,将训练后的模型进行测试。根据测试结果,您可决定是否将训练完成的模型保存为预训练模型并进入模型发布页面,或返回先前步骤调整参数配置重新进行训练。
![](images/visualization5.jpg)
**第五步:模型发布**
当模型效果满意后,您可根据实际的生产环境需求,选择将模型发布为需要的版本。
![](images/publish.jpg)
## FAQ
1. **为什么训练速度这么慢?**
PaddleX完全采用您本地的硬件进行计算,深度学习任务确实对算力要求较高,为了使您能快速体验应用PaddleX进行开发,我们适配了CPU硬件,但强烈建议您使用GPU以提升训练速度和开发体验。
2. **我可以在服务器或云平台上部署PaddleX么?**
PaddleX GUI是一个适配本地单机安装的客户端,无法在服务器上直接进行部署,您可以直接使用PaddleX API,或采用飞桨核心框架进行服务器上的部署。如果您希望使用公有算力,强烈建议您尝试飞桨产品系列中的 [EasyDL](https://ai.baidu.com/easydl/)[AI Studio](https://aistudio.baidu.com/aistudio/index)进行开发。
3. **PaddleX支持EasyData标注的数据吗?**
支持,PaddleX可顺畅读取EasyData标注的数据。但当前版本的PaddleX GUI暂时无法支持直接导入EasyData数据格式,您可以参照文档,将[数据集进行转换](https://paddlex.readthedocs.io/zh_CN/latest/appendix/how_to_convert_dataset.html)再导入PaddleX GUI进行后续开发。
同时,我们也在紧密开发PaddleX GUI可直接导入EasyData数据格式的功能。
4. **为什么模型裁剪分析耗时这么长?**
模型裁剪分析过程是对模型各卷积层的敏感度信息进行分析,根据各参数对模型效果的影响进行不同比例的裁剪。此过程需要重复多次直至FLOPS满足要求,最后再进行精调训练获得最终裁剪后的模型,因此耗时较长。有关模型裁剪的原理,可参见文档[剪裁原理介绍](https://paddlepaddle.github.io/PaddleSlim/algo/algo.html#2-%E5%8D%B7%E7%A7%AF%E6%A0%B8%E5%89%AA%E8%A3%81%E5%8E%9F%E7%90%86)
5. **如何调用后端代码?**
PaddleX 团队为您整理了相关的API接口文档,方便您学习和使用。具体请参见[PaddleX API说明文档](https://paddlex.readthedocs.io/zh_CN/latest/apis/index.html)
**如果您有更多问题或建议,欢迎以issue的形式,或加入PaddleX官方QQ群(1045148026)直接反馈您的问题和需求**
![](images/QR.jpg)
...@@ -2,30 +2,39 @@ ...@@ -2,30 +2,39 @@
本文档在一个小数据集上展示了如何通过PaddleX进行训练,您可以阅读PaddleX的**使用教程**来了解更多模型任务的训练使用方式。本示例同步在AIStudio上,可直接[在线体验模型训练](https://aistudio.baidu.com/aistudio/projectdetail/439860) 本文档在一个小数据集上展示了如何通过PaddleX进行训练,您可以阅读PaddleX的**使用教程**来了解更多模型任务的训练使用方式。本示例同步在AIStudio上,可直接[在线体验模型训练](https://aistudio.baidu.com/aistudio/projectdetail/439860)
PaddleX中的所有模型训练跟随以下3个步骤,即可快速完成训练代码开发!
## 1. 安装PaddleX | 步骤 | |说明 |
| :--- | :--------------- | :-------------- |
| 第1步| <a href=#定义训练验证图像处理流程transforms>定义transforms</a> | 用于定义模型训练、验证、预测过程中,<br>输入图像的预处理和数据增强操作 |
| 第2步| <a href="#定义dataset加载图像分类数据集">定义datasets</a> | 用于定义模型要加载的训练、验证数据集 |
| 第3步| <a href="#使用MoibleNetV3_small_ssld模型开始训练">定义模型开始训练</a> | 选择需要的模型,进行训练 |
> **注意**:不同模型的transforms、datasets和训练参数都有较大差异,更多模型训练,可直接根据文档教程获取更多模型的训练代码。[模型训练教程](train/index.html)
PaddleX的其它用法
- <a href="#加载训练保存的模型预测">加载训练保存的模型进行预测</a>
- [使用VisualDL查看训练过程中的指标变化]()
<a name="安装PaddleX"></a>
**1. 安装PaddleX**
> 安装相关过程和问题可以参考PaddleX的[安装文档](./install.md)。 > 安装相关过程和问题可以参考PaddleX的[安装文档](./install.md)。
``` ```
pip install paddlex -i https://mirror.baidu.com/pypi/simple pip install paddlex -i https://mirror.baidu.com/pypi/simple
``` ```
## 2. 准备蔬菜分类数据集 <a name="准备蔬菜分类数据集"></a>
**2. 准备蔬菜分类数据集**
``` ```
wget https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz wget https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz
tar xzvf vegetables_cls.tar.gz tar xzvf vegetables_cls.tar.gz
``` ```
## 3. 训练代码开发 <a name="定义训练验证图像处理流程transforms"></a>
PaddleX的所有模型训练和预测均只涉及到5个API接口,分别是 **3. 定义训练/验证图像处理流程transforms**
> - [transforms](apis/transforms/index.html) 图像数据处理
> - [datasets](apis/datasets/classification.md) 数据集加载
> - [models](apis/models/classification.md) 模型类型定义
> - [train](apis/models/classification.html#train) 开始训练
> - [predict](apis/models/classification.html#predict) 模型预测
在本示例,通过如下`train.py`代码进行训练, 训练环境为1张Tesla P40 GPU卡。
### 3.1 定义`transforms`数据处理流程
由于训练时数据增强操作的加入,因此模型在训练和验证过程中,数据处理流程需要分别进行定义。如下所示,代码在`train_transforms`中加入了[RandomCrop](apis/transforms/cls_transforms.html#RandomCrop)[RandomHorizontalFlip](apis/transforms/cls_transforms.html#RandomHorizontalFlip)两种数据增强方式, 更多方法可以参考[数据增强文档](apis/transforms/augment.md) 由于训练时数据增强操作的加入,因此模型在训练和验证过程中,数据处理流程需要分别进行定义。如下所示,代码在`train_transforms`中加入了[RandomCrop](apis/transforms/cls_transforms.html#RandomCrop)[RandomHorizontalFlip](apis/transforms/cls_transforms.html#RandomHorizontalFlip)两种数据增强方式, 更多方法可以参考[数据增强文档](apis/transforms/augment.md)
``` ```
from paddlex.cls import transforms from paddlex.cls import transforms
...@@ -41,8 +50,13 @@ eval_transforms = transforms.Compose([ ...@@ -41,8 +50,13 @@ eval_transforms = transforms.Compose([
]) ])
``` ```
### 3.2 定义`dataset`加载数据集 <a name="定义dataset加载图像分类数据集"></a>
定义数据集,`pdx.datasets.ImageNet`表示读取ImageNet格式的分类数据集, 更多数据集细节可以查阅[数据集格式说明](datasets.md)[ImageNet接口文档](apis/datasets/classification.md) **4. 定义`dataset`加载图像分类数据集**
定义数据集,`pdx.datasets.ImageNet`表示读取ImageNet格式的分类数据集
- [paddlex.datasets.ImageNet接口说明](apis/datasets/classification.md)
- [ImageNet数据格式说明](data/format/classification.md)
``` ```
train_dataset = pdx.datasets.ImageNet( train_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls', data_dir='vegetables_cls',
...@@ -57,53 +71,53 @@ eval_dataset = pdx.datasets.ImageNet( ...@@ -57,53 +71,53 @@ eval_dataset = pdx.datasets.ImageNet(
transforms=eval_transforms) transforms=eval_transforms)
``` ```
### 3.3 定义分类模型 <a name="使用MoibleNetV3_small_ssld模型开始训练"></a>
**5. 使用MobileNetV3_small_ssld模型开始训练**
本文档中使用百度基于蒸馏方法得到的MobileNetV3预训练模型,模型结构与MobileNetV3一致,但精度更高。PaddleX内置了20多种分类模型,查阅[PaddleX模型库](appendix/model_zoo.md)了解更多分类模型。 本文档中使用百度基于蒸馏方法得到的MobileNetV3预训练模型,模型结构与MobileNetV3一致,但精度更高。PaddleX内置了20多种分类模型,查阅[PaddleX模型库](appendix/model_zoo.md)了解更多分类模型。
``` ```
num_classes = len(train_dataset.labels) num_classes = len(train_dataset.labels)
model = pdx.cls.MobileNetV3_small_ssld(num_classes=num_classes) model = pdx.cls.MobileNetV3_small_ssld(num_classes=num_classes)
```
### 3.4 定义训练参数 model.train(num_epochs=20,
定义好模型后,即可直接调用`train`接口,定义训练时的参数,分类模型内置了`piecewise_decay`学习率衰减策略,相关参数见[分类train接口文档](apis/models/classification.html#train)
```
model.train(num_epochs=10,
train_dataset=train_dataset, train_dataset=train_dataset,
train_batch_size=32, train_batch_size=32,
eval_dataset=eval_dataset, eval_dataset=eval_dataset,
lr_decay_epochs=[4, 6, 8], lr_decay_epochs=[4, 6, 8],
learning_rate=0.025, save_dir='output/mobilenetv3_small_ssld',
save_dir='output/mobilenetv2',
use_vdl=True) use_vdl=True)
``` ```
## 4. 模型开始训练 <a name="训练过程使用VisualDL查看训练指标变化"></a>
`train.py`与解压后的数据集目录`vegetables_cls`放在同一目录下,在此目录下运行`train.py`即可开始训练。如果您的电脑上有GPU,这将会在10分钟内训练完成,如果为CPU也大概会在30分钟内训练完毕。 **6. 训练过程使用VisualDL查看训练指标变化**
```
python train.py
```
## 5. 训练过程中查看训练指标 模型在训练过程中,训练指标和在验证集上的指标,均会以标准输出流形式,输出到命令终端。在用户设定`use_vdl=True`的前提下,也会使用VisualDL格式打点到`save_dir`目录下的`vdl_log`文件夹,用户可都终端通过如下命令启动visualdl,查看可视化的指标变化趋势。
模型在训练过程中,所有的迭代信息将以标注输出流的形式,输出到命令执行的终端上,用户也可通过visualdl以可视化的方式查看训练指标的变化,通过如下方式启动visualdl后,在浏览器打开https://0.0.0.0:8001 (或 https://localhost:8001)即可。
``` ```
visualdl --logdir output/mobilenetv2/vdl_log --port 8001 visualdl --logdir output/mobilenetv3_small_ssld --port 8001
``` ```
![](./images/vdl1.jpg) 服务启动后,通过浏览器打开https://0.0.0.0:8001或https://localhost:8001即可。
> 如果您使用的是AIStudio平台进行训练,不能通过此方式启动visualdl,请参考AIStudio VisualDL启动教程使用
<a name="加载训练保存的模型预测"></a>
**7. 加载训练保存的模型预测**
## 6. 训练完成使用模型进行测试 模型在训练过程中,会每间隔一定轮数保存一次模型,在验证集上评估效果最好的一轮会保存在`save_dir`目录下的`best_model`文件夹。通过如下方式可加载模型,进行预测。
如下代码使用训练过程中第8轮保存的模型进行测试。 - [load_model接口说明](apis/load_model.md)
- [分类模型predict接口说明](apis/models/classification.html#predict)
``` ```
import paddlex as pdx import paddlex as pdx
model = pdx.load_model('output/mobilenetv2/epoch_8') model = pdx.load_model('output/mobilenetv3_small_ssld/best_model')
result = model.predict('vegetables_cls/bocai/100.jpg', topk=3) result = model.predict('vegetables_cls/bocai/100.jpg')
print("Predict Result:", result) print("Predict Result: ", result)
``` ```
> 预测结果输出如下,预测按score进行排序,得到前三分类结果 预测结果输出如下,
``` ```
Predict Result: Predict Result: [{'score': 0.9999393, 'category': 'bocai', 'category_id': 0}, {'score': 6.010089e-05, 'category': 'hongxiancai', 'category_id': 2}, {'score': 5.593914e-07, 'category': 'xilanhua', 'category_id': 5}] Predict Result: Predict Result: [{'score': 0.9999393, 'category': 'bocai', 'category_id': 0}]
``` ```
## 其它推荐 <a name="更多使用教程"></a>
**更多使用教程**
- 1.[目标检测模型训练](tutorials/train/detection.md) - 1.[目标检测模型训练](tutorials/train/detection.md)
- 2.[语义分割模型训练](tutorials/train/segmentation.md) - 2.[语义分割模型训练](tutorials/train/segmentation.md)
- 3.[实例分割模型训练](tutorials/train/instance_segmentation.md) - 3.[实例分割模型训练](tutorials/train/instance_segmentation.md)
......
# 模型裁剪
## 原理介绍
模型裁剪用于减小模型的计算量和体积,可以加快模型部署后的预测速度,是一种减小模型大小和降低模型计算复杂度的常用方式,通过裁剪卷积层中Kernel输出通道的大小及其关联层参数大小来实现,其关联裁剪的原理可参见[PaddleSlim相关文档](https://paddlepaddle.github.io/PaddleSlim/algo/algo.html#id16)**一般而言,在同等模型精度前提下,数据复杂度越低,模型可以被裁剪的比例就越高**
## 裁剪方法
PaddleX提供了两种方式:
**1.用户自行计算裁剪配置(推荐),整体流程包含三个步骤,**
> **第一步**: 使用数据集训练原始模型
> **第二步**:利用第一步训练好的模型,在验证数据集上计算模型中各个参数的敏感度,并将敏感度信息存储至本地文件
> **第三步**:使用数据集训练裁剪模型(与第一步差异在于需要在`train`接口中,将第二步计算得到的敏感信息文件传给接口的`sensitivities_file`参数)
> 在如上三个步骤中,**相当于模型共需要训练两遍**,分别对应第一步和第三步,但其中第三步训练的是裁剪后的模型,因此训练速度较第一步会更快。
> 第二步会遍历模型中的部分裁剪参数,分别计算各个参数裁剪后对于模型在验证集上效果的影响,**因此会反复在验证集上评估多次**。
**2.使用PaddleX内置的裁剪方案**
> PaddleX内置的模型裁剪方案是**基于标准数据集**上计算得到的参数敏感度信息,由于不同数据集特征分布会有较大差异,所以该方案相较于第1种方案训练得到的模型**精度一般而言会更低**(**且用户自定义数据集与标准数据集特征分布差异越大,导致训练的模型精度会越低**),仅在用户想节省时间的前提下可以参考使用,使用方式只需一步,
> **一步**: 使用数据集训练裁剪模型,在训练调用`train`接口时,将接口中的`sensitivities_file`参数设置为'DEFAULT'字符串
> 注:各模型内置的裁剪方案分别依据的数据集为: 图像分类——ImageNet数据集、目标检测——PascalVOC数据集、语义分割——CityScape数据集
## 裁剪实验
基于上述两种方案,我们在PaddleX上使用样例数据进行了实验,在Tesla P40上实验指标如下所示,
### 图像分类
实验背景:使用MobileNetV2模型,数据集为蔬菜分类示例数据,见[使用教程-模型压缩-图像分类](../tutorials/compress/classification.md)
| 模型 | 裁剪情况 | 模型大小 | Top1准确率(%) |GPU预测速度 | CPU预测速度 |
| :-----| :--------| :-------- | :---------- |:---------- |:----------|
|MobileNetV2 | 无裁剪(原模型)| 13.0M | 97.50|6.47ms |47.44ms |
|MobileNetV2 | 方案一(eval_metric_loss=0.10) | 2.1M | 99.58 |5.03ms |20.22ms |
|MobileNetV2 | 方案二(eval_metric_loss=0.10) | 6.0M | 99.58 |5.42ms |29.06ms |
### 目标检测
实验背景:使用YOLOv3-MobileNetV1模型,数据集为昆虫检测示例数据,见[使用教程-模型压缩-目标检测](../tutorials/compress/detection.md)
| 模型 | 裁剪情况 | 模型大小 | MAP(%) |GPU预测速度 | CPU预测速度 |
| :-----| :--------| :-------- | :---------- |:---------- | :---------|
|YOLOv3-MobileNetV1 | 无裁剪(原模型)| 139M | 67.57| 14.88ms |976.42ms |
|YOLOv3-MobileNetV1 | 方案一(eval_metric_loss=0.10) | 34M | 75.49 |10.60ms |558.49ms |
|YOLOv3-MobileNetV1 | 方案二(eval_metric_loss=0.05) | 29M | 50.27| 9.43ms |360.46ms |
### 语义分割
实验背景:使用UNet模型,数据集为视盘分割示例数据, 见[使用教程-模型压缩-语义分割](../tutorials/compress/segmentation.md)
| 模型 | 裁剪情况 | 模型大小 | mIOU(%) |GPU预测速度 | CPU预测速度 |
| :-----| :--------| :-------- | :---------- |:---------- | :---------|
|UNet | 无裁剪(原模型)| 77M | 91.22 |33.28ms |9523.55ms |
|UNet | 方案一(eval_metric_loss=0.10) |26M | 90.37 |21.04ms |3936.20ms |
|UNet | 方案二(eval_metric_loss=0.10) |23M | 91.21 |18.61ms |3447.75ms |
# 模型量化
## 原理介绍
为了满足低内存带宽、低功耗、低计算资源占用以及低模型存储等需求,定点量化被提出。为此我们提供了训练后量化,该量化使用KL散度确定量化比例因子,将FP32模型转成INT8模型,且不需要重新训练,可以快速得到量化模型。
## 使用PaddleX量化模型
PaddleX提供了`export_quant_model`接口,让用户以接口的形式完成模型以post_quantization方式量化并导出。点击查看[量化接口使用文档](../apis/slim.md)
## 量化性能对比
模型量化后的性能对比指标请查阅[PaddleSlim模型库](https://paddlepaddle.github.io/PaddleSlim/model_zoo.html)
// 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共提供了20+的图像分类模型,可满足开发者不同场景的需求下的使用。
- **Top1精度**: 模型在ImageNet数据集上的测试精度
- **预测速度**:单张图片的预测用时(不包括预处理和后处理)
- "-"表示指标暂未更新
| 模型(点击获取代码) | Top1精度 | 模型大小 | GPU预测速度 | Arm预测速度 | 备注 |
| :---------------- | :------- | :------- | :--------- | :--------- | :----- |
| [MobileNetV3_small_ssld](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/mobilenetv3_small_ssld.py) | 71.3% | 21.0MB | 6.809ms | - | 模型小,预测速度快,适用于低性能或移动端设备 |
| [MobileNetV2](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/mobilenetv2.py) | 72.2% | 14.0MB | 4.546ms | - | 模型小,预测速度快,适用于低性能或移动端设备 |
| [ShuffleNetV2](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/shufflenetv2.py) | 68.8% | 9.0MB | 6.101ms | - | 模型体积小,预测速度快,适用于低性能或移动端设备 |
| [ResNet50_vd_ssld](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/resnet50_vd_ssld.py) | 82.4% | 102.8MB | 9.058ms | - | 模型精度高,适用于服务端部署 |
## 开始训练
> 代码保存到本地后,即可直接训练,**训练代码会自动下载训练数据开始训练**
> > 如保存为`mobilenetv3_small_ssld.py`,如下命令即可开始训练
> > ```
> > python mobilenetv3_small_ssld.py
> > ```
## 相关文档
-**重要**】针对自己的机器环境和数据,调整训练参数?先了解下PaddleX中训练参数作用。[——>>传送门](../appendix/parameters.md)
-**有用**】没有机器资源?使用AIStudio免费的GPU资源在线训练模型。[——>>传送门](https://aistudio.baidu.com/aistudio/projectdetail/450925)
-**拓展**】更多图像分类模型,查阅[PaddleX模型库](../appendix/model_zoo.md)[API使用文档](../apis/models/index.html)
模型训练
=======================================
PaddleX目前集成了XX模型,涵盖视觉领域的图像分类、目标检测、实例分割和语义分割四大主流任务
.. toctree::
:maxdepth: 1
:caption: 文档目录:
classification.md
object_detection.md
instance_segmentation.md
semantic_segmentation.md
prediction.md
# 实例分割
## 介绍
PaddleX目前提供了MaskRCNN实例分割模型结构,多种backbone模型,可满足开发者不同场景和性能的需求。
- **Box MMAP/Seg MMAP**: 模型在COCO数据集上的测试精度
- **预测速度**:单张图片的预测用时(不包括预处理和后处理)
- "-"表示指标暂未更新
| 模型(点击获取代码) | Box MMAP/Seg MMAP | 模型大小 | GPU预测速度 | Arm预测速度 | 备注 |
| :---------------- | :------- | :------- | :--------- | :--------- | :----- |
| [MaskRCNN-ResNet50-FPN](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/instance_segmentation/mask_r50_fpn.py) | -/- | 136.0MB | 197.715ms | - | 模型精度高,适用于服务端部署 |
| [MaskRCNN-ResNet18-FPN](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/instance_segmentation/mask_r18_fpn.py) | -/- | - | - | - | 模型精度高,适用于服务端部署 |
| [MaskRCNN-HRNet-FPN](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/instance_segmentation/mask_hrnet_fpn.py) | -/- | 115.MB | 81.592ms | - | 模型精度高,预测速度快,适用于服务端部署 |
## 开始训练
> 代码保存到本地后,即可直接训练,**训练代码会自动下载训练数据开始训练**
> > 如保存为`mask_r50_fpn.py`,如下命令即可开始训练
> > ```
> > python mask_r50_fpn.py
> > ```
## 相关文档
-**重要**】针对自己的机器环境和数据,调整训练参数?先了解下PaddleX中训练参数作用。[——>>传送门](../appendix/parameters.md)
-**有用**】没有机器资源?使用AIStudio免费的GPU资源在线训练模型。[——>>传送门](https://aistudio.baidu.com/aistudio/projectdetail/450925)
-**拓展**】更多图像分类模型,查阅[PaddleX模型库](../appendix/model_zoo.md)[API使用文档](../apis/models/index.html)
# 目标检测
## 介绍
PaddleX目前提供了FasterRCNN和YOLOv3两种检测结构,多种backbone模型,可满足开发者不同场景和性能的需求。
- **Box MMAP**: 模型在COCO数据集上的测试精度
- **预测速度**:单张图片的预测用时(不包括预处理和后处理)
- "-"表示指标暂未更新
| 模型(点击获取代码) | Box MMAP | 模型大小 | GPU预测速度 | Arm预测速度 | 备注 |
| :---------------- | :------- | :------- | :--------- | :--------- | :----- |
| [YOLOv3-MobileNetV1](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/yolov3_mobilenetv1.py) | 29.3% | 99.2MB | 15.442ms | - | 模型小,预测速度快,适用于低性能或移动端设备 |
| [YOLOv3-MobileNetV3](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/yolov3_mobilenetv3.py) | 31.6% | 100.7MB | 143.322ms | - | 模型小,移动端上预测速度有优势 |
| [YOLOv3-DarkNet53](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/yolov3_darknet53.py) | 38.9 | 249.2MB | 42.672ms | - | 模型较大,预测速度快,适用于服务端 |
| [FasterRCNN-ResNet50-FPN](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/faster_r50_fpn.py) | 37.2% | 136.0MB | 197.715ms | - | 模型精度高,适用于服务端部署 |
| [FasterRCNN-ResNet18-FPN](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/faster_r18_fpn.py) | - | - | - | - | 模型精度高,适用于服务端部署 |
| [FasterRCNN-HRNet-FPN](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/faster_hrnet_fpn.py) | 36.0% | 115.MB | 81.592ms | - | 模型精度高,预测速度快,适用于服务端部署 |
## 开始训练
> 代码保存到本地后,即可直接训练,**训练代码会自动下载训练数据开始训练**
> > 如保存为`yolov3_mobilenetv1.py`,如下命令即可开始训练
> > ```
> > python yolov3_mobilenetv1.py
> > ```
## 相关文档
-**重要**】针对自己的机器环境和数据,调整训练参数?先了解下PaddleX中训练参数作用。[——>>传送门](../appendix/parameters.md)
-**有用**】没有机器资源?使用AIStudio免费的GPU资源在线训练模型。[——>>传送门](https://aistudio.baidu.com/aistudio/projectdetail/450925)
-**拓展**】更多图像分类模型,查阅[PaddleX模型库](../appendix/model_zoo.md)[API使用文档](../apis/models/index.html)
# 加载模型预测
PaddleX可以使用`load_model`接口加载模型(包括训练过程中保存的模型,导出的部署模型,量化模型以及裁剪的模型)进行预测,同时PaddleX中也内置了一系列的可视化工具函数,帮助用户方便地检查模型的效果。
## 图像分类
```
import paddlex as pdx
model = pdx.load_model('./mobilenetv2')
result = model.predict('./mobilenetv2/test.jpg')
print("Predict Result: ", result)
```
## 目标检测和实例分割
```
import paddlex as pdx
test_jpg = './xiaoduxiong_epoch_12/test.jpg'
model = pdx.load_model('./xiaoduxiong_epoch_12')
result = model.predict(test_jpg)
pdx.det.visualize(test_jpg, result, thresh=0.5, save_dir='./')
```
在上述示例代码中,通过调用`paddlex.det.visualize`可以对目标检测/实例分割的预测结果进行可视化,可视化的结果保存在`save_dir`下。
> 注意:目标检测和实例分割模型在调用`predict`接口得到的结果需用户自行过滤低置信度结果,在`paddlex.det.visualize`接口中,我们提供了`thresh`用于过滤,置信度低于此值的结果将被过滤,不会可视化。
## 语义分割
```
import paddlex as pdx
test_jpg = './deeplabv3p_mobilenetv2_coco/test.jpg'
model = pdx.load_model('./deeplabv3p_mobilenetv2_coco')
result = model.predict(test_jpg)
pdx.seg.visualize(test_jpg, result, weight=0.0, save_dir='./')
```
在上述示例代码中,通过调用`paddlex.seg.visualize`可以对语义分割的预测结果进行可视化,可视化的结果保存在`save_dir`下。其中`weight`参数用于调整预测结果和原图结果融合展现时的权重,0.0时只展示预测结果mask的可视化,1.0时只展示原图可视化。
PaddleX的`load_model`接口可以满足用户一般的模型调研需求,如若为更高性能的预测部署,可以参考如下文档
- [服务端Python部署]()
- [服务端C++部署]()
# 语义分割
## 介绍
PaddleX目前提供了DeepLabv3p、UNet、HRNet和FastSCNN四种语义分割结构,多种backbone模型,可满足开发者不同场景和性能的需求。
- **mIOU**: 模型在COCO数据集上的测试精度
- **预测速度**:单张图片的预测用时(不包括预处理和后处理)
- "-"表示指标暂未更新
| 模型(点击获取代码) | Box MMAP | 模型大小 | GPU预测速度 | Arm预测速度 | 备注 |
| :---------------- | :------- | :------- | :--------- | :--------- | :----- |
| [DeepLabv3p-MobileNetV2-x0.25](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/yolov3_mobilenetv1.py) | 29.3% | 99.2MB | 15.442ms | - | 模型小,预测速度快,适用于低性能或移动端设备 |
| [DeepLabv3p-MobileNetV2-x1.0](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/yolov3_mobilenetv1.py) | 29.3% | 99.2MB | 15.442ms | - | 模型小,预测速度快,适用于低性能或移动端设备 |
| [DeepLabv3p-Xception65](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/yolov3_mobilenetv3.py) | 31.6% | 100.7MB | 143.322ms | - | 模型小,移动端上预测速度有优势 |
| [UNet](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/yolov3_darknet53.py) | 38.9 | 249.2MB | 42.672ms | - | 模型较大,预测速度快,适用于服务端 |
| [HRNet](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/faster_r50_fpn.py) | 37.2% | 136.0MB | 197.715ms | - | 模型精度高,适用于服务端部署 |
| [FastSCNN](https://github.com/PaddlePaddle/PaddleX/blob/doc/tutorials/train/image_classification/faster_r18_fpn.py) | - | - | - | - | 模型精度高,适用于服务端部署 |
## 开始训练
> 代码保存到本地后,即可直接训练,**训练代码会自动下载训练数据开始训练**
> > 如保存为`deeplabv3p_mobilenetv2_x0.25.py`,如下命令即可开始训练
> > ```
> > python deeplabv3p_mobilenetv2_x0.25.py
> > ```
## 相关文档
-**重要**】针对自己的机器环境和数据,调整训练参数?先了解下PaddleX中训练参数作用。[——>>传送门](../appendix/parameters.md)
-**有用**】没有机器资源?使用AIStudio免费的GPU资源在线训练模型。[——>>传送门](https://aistudio.baidu.com/aistudio/projectdetail/450925)
-**拓展**】更多图像分类模型,查阅[PaddleX模型库](../appendix/model_zoo.md)[API使用文档](../apis/models/index.html)
目标检测
============================
PaddleX针对目标检测任务提供了通过负样本学习降低误检率的策略,用户可根据需求及应用场景使用该策略对模型进行调优。
.. toctree::
:maxdepth: 1
negatives_training.md
# 通过负样本学习降低误检率
## 应用场景
在背景和目标相似的场景下,模型容易把背景误检成目标。为了降低误检率,可以通过负样本学习来降低误检率,即在训练过程中把无目标真值的图片加入训练。
## 效果对比
* 与基准模型相比,通过负样本学习后的模型**mmAP有3.6%的提升,mAP有0.1%的提升**
* 与基准模型相比,通过负样本学习后的模型在背景图片上的图片级别**误检率降低了49.68%**
表1 违禁品验证集上**框级别精度**对比
||mmAP(AP@IoU=0.5:0.95)| mAP (AP@IoU=0.5)|
|:---|:---|:---|
|基准模型 | 45.8% | 83% |
|通过负样本学习后的模型 | 49.4% | 83.1% |
表2 违禁品验证集上**图片级别的召回率**、无违禁品验证集上**图片级别的误检率**对比
||违禁品图片级别的召回率| 无违禁品图片级别的误检率|
|:---|:--------------------|:------------------------|
|基准模型 | 98.97% | 55.27% |
|通过负样本学习后的模型 | 97.75% | 5.59% |
【名词解释】
* 图片级别的召回率:只要在有目标的图片上检测出目标(不论框的个数),该图片被认为召回。批量有目标图片中被召回图片所占的比例,即为图片级别的召回率。
* 图片级别的误检率:只要在无目标的图片上检测出目标(不论框的个数),该图片被认为误检。批量无目标图片中被误检图片所占的比例,即为图片级别的误检率。
## 使用方法
在定义训练所用的数据集之后,使用数据集类的成员函数`add_negative_samples`将无目标真值的背景图片所在路径传入给训练集。代码示例如下:
```
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from paddlex.det import transforms
import paddlex as pdx
# 定义训练和验证时的transforms
train_transforms = transforms.ComposedRCNNTransforms(
mode='train', min_max_size=[600, 1000])
eval_transforms = transforms.ComposedRCNNTransforms(
mode='eval', min_max_size=[600, 1000])
# 定义训练所用的数据集
train_dataset = pdx.datasets.CocoDetection(
data_dir='jinnan2_round1_train_20190305/restricted/',
ann_file='jinnan2_round1_train_20190305/train.json',
transforms=train_transforms,
shuffle=True,
num_workers=2)
# 训练集中加入无目标背景图片
train_dataset.add_negative_samples(
'jinnan2_round1_train_20190305/normal_train_back/')
# 定义验证所用的数据集
eval_dataset = pdx.datasets.CocoDetection(
data_dir='jinnan2_round1_train_20190305/restricted/',
ann_file='jinnan2_round1_train_20190305/val.json',
transforms=eval_transforms,
num_workers=2)
# 初始化模型,并进行训练
model = pdx.det.FasterRCNN(num_classes=len(train_dataset.labels) + 1)
model.train(
num_epochs=17,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
train_batch_size=8,
learning_rate=0.01,
lr_decay_epochs=[13, 16],
save_dir='./output')
```
## 实验细则
(1) 数据集
我们使用X光违禁品数据集对通过负样本学习降低误检率的策略有效性进行了实验验证。该数据集中背景比较繁杂,很多背景物体与目标物体较为相似。
* 检测铁壳打火机、黑钉打火机 、刀具、电源和电池、剪刀5种违禁品。
* 训练集有883张违禁品图片,验证集有98张违禁品图片。
* 无违禁品的X光图片有2540张。
(2) 基准模型
使用FasterRCNN-ResNet50作为检测模型,除了水平翻转外没有使用其他的数据增强方式,只使用违禁品训练集进行训练。模型在违禁品验证集上的精度见表1,mmAP有45.8%,mAP达到83%。
(3) 通过负样本学习后的模型
把无违禁品的X光图片按1:1分成无违禁品训练集和无违禁品验证集。我们将基准模型在无违禁品验证集进行测试,发现图片级别的误检率高达55.27%。为了降低该误检率,将基准模型在无违禁品训练集进行测试,挑选出被误检图片共663张,将这663张图片加入训练,训练参数配置与基准模型训练时一致。
通过负样本学习后的模型在违禁品验证集上的精度见表1,mmAP有49.4%,mAP达到83.1%。与基准模型相比,**mmAP有3.6%的提升,mAP有0.1%的提升**。通过负样本学习后的模型在无违禁品验证集的误检率仅有5.58%,与基准模型相比,**误检率降低了49.68%**
此外,还测试了两个模型在有违禁品验证集上图片级别的召回率,见表2,与基准模型相比,通过负样本学习后的模型仅漏检了1张图片,召回率几乎是无损的。
PaddleX调优策略介绍
============================
.. toctree::
:maxdepth: 2
detection/index.rst
# 分类模型裁剪
---
本文档训练代码可直接在PaddleX的Repo中下载,[代码tutorials/compress/classification](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/classification)
本文档按如下方式对模型进行了裁剪
> 第一步:在训练数据集上训练MobileNetV2
> 第二步:在验证数据集上计算模型中各个参数的敏感度信息
> 第三步:根据第二步计算的敏感度,设定`eval_metric_loss`,对模型裁剪后重新在训练数据集上训练
## 步骤一 训练MobileNetV2
> 模型训练使用文档可以直接参考[分类模型训练](../train/classification.md),本文档在该代码基础上添加了部分参数选项,用户可直接下载模型训练代码[tutorials/compress/classification/mobilenetv2.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/classification/mobilenetv2.py)
> 使用如下命令开始模型训练
```
python mobilenetv2.py
```
## 步骤二 计算参数敏感度
> 参数敏感度的计算可以直接使用PaddleX提供的API`paddlex.slim.cal_params_sensitivities`,使用代码如下, 敏感度信息文件会保存至`save_file`
```
import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import paddlex as pdx
model_dir = './output/mobilenetv2/best_model'
model = pdx.load_model(model_dir)
# 定义验证所用的数据集
eval_dataset = pdx.datasets.ImageNet(
data_dir=dataset,
file_list=os.path.join(dataset, 'val_list.txt'),
label_list=os.path.join(dataset, 'labels.txt'),
transforms=model.eval_transforms)
pdx.slim.cal_params_sensitivities(model,
save_file,
eval_dataset,
batch_size=8)
```
> 本步骤代码已整理至[tutorials/compress/classification/cal_sensitivities_file.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/classification/cal_sensitivities_file.py),用户可直接下载使用
> 使用如下命令开始计算敏感度
```
python cal_sensitivities_file.py --model_dir output/mobilenetv2/best_model --dataset vegetables_cls --save_file sensitivities.data
```
## 步骤三 开始裁剪训练
> 本步骤代码与步骤一使用同一份代码文件,使用如下命令开始裁剪训练
```
python mobilenetv2.py --model_dir output/mobilenetv2/best_model --sensitivities_file sensitivities.data --eval_metric_loss 0.10
```
## 实验效果
本教程的实验效果可以查阅[模型压缩文档](../../slim/prune.md)
# 检测模型裁剪
---
本文档训练代码可直接在PaddleX的Repo中下载,[代码tutorials/compress/detection](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/detection)
本文档按如下方式对模型进行了裁剪
> 第一步:在训练数据集上训练YOLOv3
> 第二步:在验证数据集上计算模型中各个参数的敏感度信息
> 第三步:根据第二步计算的敏感度,设定`eval_metric_loss`,对模型裁剪后重新在训练数据集上训练
## 步骤一 训练YOLOv3
> 模型训练使用文档可以直接参考[检测模型训练](../train/detection.md),本文档在该代码基础上添加了部分参数选项,用户可直接下载模型训练代码[tutorials/compress/detection/yolov3_mobilnet.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/detection/yolov3_mobilenet.py)
> 使用如下命令开始模型训练
```
python yolov3_mobilenet.py
```
## 步骤二 计算参数敏感度
> 参数敏感度的计算可以直接使用PaddleX提供的API`paddlex.slim.cal_params_sensitivities`,使用代码如下, 敏感度信息文件会保存至`save_file`
```
import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import paddlex as pdx
model = pdx.load_model(model_dir)
# 定义验证所用的数据集
eval_dataset = pdx.datasets.ImageNet(
data_dir=dataset,
file_list=os.path.join(dataset, 'val_list.txt'),
label_list=os.path.join(dataset, 'labels.txt'),
transforms=model.eval_transforms)
pdx.slim.cal_params_sensitivities(model,
save_file,
eval_dataset,
batch_size=8)
```
> 本步骤代码已整理至[tutorials/compress/detection/cal_sensitivities_file.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/detection/cal_sensitivities_file.py),用户可直接下载使用
> 使用如下命令开始计算敏感度
```
python cal_sensitivities_file.py --model_dir output/yolov3_mobile/best_model --dataset insect_det --save_file sensitivities.data
```
## 步骤三 开始裁剪训练
> 本步骤代码与步骤一使用同一份代码文件,使用如下命令开始裁剪训练
```
python yolov3_mobilenet.py --model_dir output/yolov3_mobile/best_model --sensitivities_file sensitivities.data --eval_metric_loss 0.10
```
## 实验效果
本教程的实验效果可以查阅[模型压缩文档](../../slim/prune.md)
模型压缩
=========================
.. toctree::
:maxdepth: 1
classification.md
detection.md
segmentation.md
# 分割模型裁剪
---
本文档训练代码可直接在PaddleX的Repo中下载,[代码tutorials/compress/segmentation](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/segmentation)
本文档按如下方式对模型进行了裁剪
> 第一步:在训练数据集上训练UNet
> 第二步:在验证数据集上计算模型中各个参数的敏感度信息
> 第三步:根据第二步计算的敏感度,设定`eval_metric_loss`,对模型裁剪后重新在训练数据集上训练
## 步骤一 训练UNet
> 模型训练使用文档可以直接参考[检测模型训练](../train/segmentation.md),本文档在该代码基础上添加了部分参数选项,用户可直接下载模型训练代码[tutorials/compress/segmentation/unet.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/segmentation/unet.py)
> 使用如下命令开始模型训练
```
python unet.py
```
## 步骤二 计算参数敏感度
> 参数敏感度的计算可以直接使用PaddleX提供的API`paddlex.slim.cal_params_sensitivities`,使用代码如下, 敏感度信息文件会保存至`save_file`
```
import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import paddlex as pdx
model = pdx.load_model(model_dir)
# 定义验证所用的数据集
eval_dataset = pdx.datasets.ImageNet(
data_dir=dataset,
file_list=os.path.join(dataset, 'val_list.txt'),
label_list=os.path.join(dataset, 'labels.txt'),
transforms=model.eval_transforms)
pdx.slim.cal_params_sensitivities(model,
save_file,
eval_dataset,
batch_size=8)
```
> 本步骤代码已整理至[tutorials/compress/detection/cal_sensitivities_file.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/compress/segmentation/cal_sensitivities_file.py),用户可直接下载使用
> 使用如下命令开始计算敏感度
```
python cal_sensitivities_file.py --model_dir output/unet/best_model --dataset optic_disc_seg --save_file sensitivities.data
```
## 步骤三 开始裁剪训练
> 本步骤代码与步骤一使用同一份代码文件,使用如下命令开始裁剪训练
```
python unet.py --model_dir output/unet/best_model --sensitivities_file sensitivities.data --eval_metric_loss 0.10
```
## 实验效果
本教程的实验效果可以查阅[模型压缩文档](../../slim/prune.md)
模型压缩
============================
.. toctree::
:maxdepth: 2
prune.md
quant.md
# 模型裁剪
## 原理介绍
模型裁剪用于减小模型的计算量和体积,可以加快模型部署后的预测速度,是一种减小模型大小和降低模型计算复杂度的常用方式,通过裁剪卷积层中Kernel输出通道的大小及其关联层参数大小来实现,其关联裁剪的原理可参见[PaddleSlim相关文档](https://paddlepaddle.github.io/PaddleSlim/algo/algo.html#id16)**一般而言,在同等模型精度前提下,数据复杂度越低,模型可以被裁剪的比例就越高**
## 裁剪方法
PaddleX提供了两种方式:
**1.用户自行计算裁剪配置(推荐),整体流程包含三个步骤,**
> **第一步**: 使用数据集训练原始模型
> **第二步**:利用第一步训练好的模型,在验证数据集上计算模型中各个参数的敏感度,并将敏感度信息存储至本地文件
> **第三步**:使用数据集训练裁剪模型(与第一步差异在于需要在`train`接口中,将第二步计算得到的敏感信息文件传给接口的`sensitivities_file`参数)
> 在如上三个步骤中,**相当于模型共需要训练两遍**,分别对应第一步和第三步,但其中第三步训练的是裁剪后的模型,因此训练速度较第一步会更快。
> 第二步会遍历模型中的部分裁剪参数,分别计算各个参数裁剪后对于模型在验证集上效果的影响,**因此会反复在验证集上评估多次**。
**2.使用PaddleX内置的裁剪方案**
> PaddleX内置的模型裁剪方案是**基于标准数据集**上计算得到的参数敏感度信息,由于不同数据集特征分布会有较大差异,所以该方案相较于第1种方案训练得到的模型**精度一般而言会更低**(**且用户自定义数据集与标准数据集特征分布差异越大,导致训练的模型精度会越低**),仅在用户想节省时间的前提下可以参考使用,使用方式只需一步,
> **一步**: 使用数据集训练裁剪模型,在训练调用`train`接口时,将接口中的`sensitivities_file`参数设置为'DEFAULT'字符串
> 注:各模型内置的裁剪方案分别依据的数据集为: 图像分类——ImageNet数据集、目标检测——PascalVOC数据集、语义分割——CityScape数据集
## 裁剪实验
基于上述两种方案,我们在PaddleX上使用样例数据进行了实验,在Tesla P40上实验指标如下所示,
### 图像分类
实验背景:使用MobileNetV2模型,数据集为蔬菜分类示例数据,见[使用教程-模型压缩-图像分类](../tutorials/compress/classification.md)
| 模型 | 裁剪情况 | 模型大小 | Top1准确率(%) |GPU预测速度 | CPU预测速度 |
| :-----| :--------| :-------- | :---------- |:---------- |:----------|
|MobileNetV2 | 无裁剪(原模型)| 13.0M | 97.50|6.47ms |47.44ms |
|MobileNetV2 | 方案一(eval_metric_loss=0.10) | 2.1M | 99.58 |5.03ms |20.22ms |
|MobileNetV2 | 方案二(eval_metric_loss=0.10) | 6.0M | 99.58 |5.42ms |29.06ms |
### 目标检测
实验背景:使用YOLOv3-MobileNetV1模型,数据集为昆虫检测示例数据,见[使用教程-模型压缩-目标检测](../tutorials/compress/detection.md)
| 模型 | 裁剪情况 | 模型大小 | MAP(%) |GPU预测速度 | CPU预测速度 |
| :-----| :--------| :-------- | :---------- |:---------- | :---------|
|YOLOv3-MobileNetV1 | 无裁剪(原模型)| 139M | 67.57| 14.88ms |976.42ms |
|YOLOv3-MobileNetV1 | 方案一(eval_metric_loss=0.10) | 34M | 75.49 |10.60ms |558.49ms |
|YOLOv3-MobileNetV1 | 方案二(eval_metric_loss=0.05) | 29M | 50.27| 9.43ms |360.46ms |
### 语义分割
实验背景:使用UNet模型,数据集为视盘分割示例数据, 见[使用教程-模型压缩-语义分割](../tutorials/compress/segmentation.md)
| 模型 | 裁剪情况 | 模型大小 | mIOU(%) |GPU预测速度 | CPU预测速度 |
| :-----| :--------| :-------- | :---------- |:---------- | :---------|
|UNet | 无裁剪(原模型)| 77M | 91.22 |33.28ms |9523.55ms |
|UNet | 方案一(eval_metric_loss=0.10) |26M | 90.37 |21.04ms |3936.20ms |
|UNet | 方案二(eval_metric_loss=0.10) |23M | 91.21 |18.61ms |3447.75ms |
# 模型量化
## 原理介绍
为了满足低内存带宽、低功耗、低计算资源占用以及低模型存储等需求,定点量化被提出。为此我们提供了训练后量化,该量化使用KL散度确定量化比例因子,将FP32模型转成INT8模型,且不需要重新训练,可以快速得到量化模型。
## 使用PaddleX量化模型
PaddleX提供了`export_quant_model`接口,让用户以接口的形式完成模型以post_quantization方式量化并导出。点击查看[量化接口使用文档](../apis/slim.md)
## 量化性能对比
模型量化后的性能对比指标请查阅[PaddleSlim模型库](https://paddlepaddle.github.io/PaddleSlim/model_zoo.html)
# 数据准备
该部分内容已迁移至[附录](../appendix/datasets.md)
# 数据集格式说明
---
## 图像分类ImageNet
图像分类ImageNet数据集包含对应多个标签的图像文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--labelA # 标签为labelA的图像目录
| |--a1.jpg
| |--...
| └--...
|
|--...
|
|--labelZ # 标签为labelZ的图像目录
| |--z1.jpg
| |--...
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,相应的文件名可根据需要自行定义。
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为图像文件对应的标签id(从0开始)。如下所示:
```
labelA/a1.jpg 0
labelZ/z1.jpg 25
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz),下载蔬菜分类分类数据集。
在PaddleX中,使用`paddlex.cv.datasets.ImageNet`([API说明](./apis/datasets.html#imagenet))加载分类数据集。
## 目标检测VOC
目标检测VOC数据集包含图像文件夹、标注信息文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--JPEGImages # 图像目录
| |--xxx1.jpg
| |--...
| └--...
|
|--Annotations # 标注信息目录
| |--xxx1.xml
| |--...
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,相应的文件名可根据需要自行定义。
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为标注文件相对于dataset的相对路径。如下所示:
```
JPEGImages/xxx1.jpg Annotations/xxx1.xml
JPEGImages/xxx2.jpg Annotations/xxx2.xml
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz),下载昆虫检测数据集。
在PaddleX中,使用`paddlex.cv.datasets.VOCDetection`([API说明](./apis/datasets.html#vocdetection))加载目标检测VOC数据集。
## 目标检测和实例分割COCO
目标检测和实例分割COCO数据集包含图像文件夹及图像标注信息文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--JPEGImages # 图像目录
| |--xxx1.jpg
| |--...
| └--...
|
|--train.json # 训练相关信息文件
|
└--val.json # 验证相关信息文件
```
其中,相应的文件名可根据需要自行定义。
`train.json``val.json`存储与标注信息、图像文件相关的信息。如下所示:
```
{
"annotations": [
{
"iscrowd": 0,
"category_id": 1,
"id": 1,
"area": 33672.0,
"image_id": 1,
"bbox": [232, 32, 138, 244],
"segmentation": [[32, 168, 365, 117, ...]]
},
...
],
"images": [
{
"file_name": "xxx1.jpg",
"height": 512,
"id": 267,
"width": 612
},
...
]
"categories": [
{
"name": "labelA",
"id": 1,
"supercategory": "component"
}
]
}
```
其中,每个字段的含义如下所示:
| 域名 | 字段名 | 含义 | 数据类型 | 备注 |
|:-----|:--------|:------------|------|:-----|
| annotations | id | 标注信息id | int | 从1开始 |
| annotations | iscrowd | 标注框是否为一组对象 | int | 只有0、1两种取值 |
| annotations | category_id | 标注框类别id | int | |
| annotations | area | 标注框的面积 | float | |
| annotations | image_id | 当前标注信息所在图像的id | int | |
| annotations | bbox | 标注框坐标 | list | 长度为4,分别代表x,y,w,h |
| annotations | segmentation | 标注区域坐标 | list | list中有至少1个list,每个list由每个小区域坐标点的横纵坐标(x,y)组成 |
| images | id | 图像id | int | 从1开始 |
| images | file_name | 图像文件名 | str | |
| images | height | 图像高度 | int | |
| images | width | 图像宽度 | int | |
| categories | id | 类别id | int | 从1开始 |
| categories | name | 类别标签名 | str | |
| categories | supercategory | 类别父类的标签名 | str | |
[点击这里](https://bj.bcebos.com/paddlex/datasets/garbage_ins_det.tar.gz),下载垃圾实例分割数据集。
在PaddleX中,使用`paddlex.cv.datasets.COCODetection`([API说明](./apis/datasets.html#cocodetection))加载COCO格式数据集。
## 语义分割数据
语义分割数据集包含原图、标注图及相应的文件列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--images # 原图目录
| |--xxx1.png
| |--...
| └--...
|
|--annotations # 标注图目录
| |--xxx1.png
| |--...
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表
```
其中,相应的文件名可根据需要自行定义。
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为标注图像文件相对于dataset的相对路径。如下所示:
```
images/xxx1.png annotations/xxx1.png
images/xxx2.png annotations/xxx2.png
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
background
labelA
labelB
...
```
标注图像为单通道图像,像素值即为对应的类别,像素标注类别需要从0开始递增(一般第一个类别为`background`),
例如0,1,2,3表示有4种类别,标注类别最多为256类。其中可以指定特定的像素值用于表示该值的像素不参与训练和评估(默认为255)。
[点击这里](https://bj.bcebos.com/paddlex/datasets/optic_disc_seg.tar.gz),下载视盘语义分割数据集。
在PaddleX中,使用`paddlex.cv.datasets.SegReader`([API说明](./apis/datasets.html#segreader))加载语义分割数据集。
## 图像分类EasyDataCls
图像分类EasyDataCls数据集包含存放图像和json文件的文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录
|--easydata # 存放图像和json文件的文件夹
| |--0001.jpg
| |--0001.json
| |--0002.jpg
| |--0002.json
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,图像文件名应与json文件名一一对应。
每个json文件存储于`labels`相关的信息。如下所示:
```
{"labels": [{"name": "labelA"}]}
```
其中,`name`字段代表对应图像的类别。
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为json文件相对于dataset的相对路径。如下所示:
```
easydata/0001.jpg easydata/0001.json
easydata/0002.jpg easydata/0002.json
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://ai.baidu.com/easydata/),可以标注图像分类EasyDataCls数据集。
在PaddleX中,使用`paddlex.cv.datasets.EasyDataCls`([API说明](./apis/datasets.html#easydatacls))加载分类数据集。
## 目标检测和实例分割EasyDataDet
目标检测和实例分割EasyDataDet数据集包含存放图像和json文件的文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录ß
|--easydata # 存放图像和json文件的文件夹
| |--0001.jpg
| |--0001.json
| |--0002.jpg
| |--0002.json
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,图像文件名应与json文件名一一对应。
每个json文件存储于`labels`相关的信息。如下所示:
```
"labels": [{"y1": 18, "x2": 883, "x1": 371, "y2": 404, "name": "labelA",
"mask": "kVfc0`0Zg0<F7J7I5L5K4L4L4L3N3L3N3L3N2N3M2N2N2N2N2N2N1O2N2O1N2N1O2O1N101N1O2O1N101N10001N101N10001N10001O0O10001O000O100000001O0000000000000000000000O1000001O00000O101O000O101O0O101O0O2O0O101O0O2O0O2N2O0O2O0O2N2O1N1O2N2N2O1N2N2N2N2N2N2M3N3M2M4M2M4M3L4L4L4K6K5J7H9E\\iY1"},
{"y1": 314, "x2": 666, "x1": 227, "y2": 676, "name": "labelB",
"mask": "mdQ8g0Tg0:G8I6K5J5L4L4L4L4M2M4M2M4M2N2N2N3L3N2N2N2N2O1N1O2N2N2O1N1O2N2O0O2O1N1O2O0O2O0O2O001N100O2O000O2O000O2O00000O2O000000001N100000000000000000000000000000000001O0O100000001O0O10001N10001O0O101N10001N101N101N101N101N2O0O2N2O0O2N2N2O0O2N2N2N2N2N2N2N2N2N3L3N2N3L3N3L4M2M4L4L5J5L5J7H8H;BUcd<"},
...]}
```
其中,list中的每个元素代表一个标注信息,标注信息中字段的含义如下所示:
| 字段名 | 含义 | 数据类型 | 备注 |
|:--------|:------------|------|:-----|
| x1 | 标注框左下角横坐标 | int | |
| y1 | 标注框左下角纵坐标 | int | |
| x2 | 标注框右上角横坐标 | int | |
| y2 | 标注框右上角纵坐标 | int | |
| name | 标注框中物体类标 | str | |
| mask | 分割区域布尔型numpy编码后的字符串 | str | 该字段可以不存在,当不存在时只能进行目标检测 |
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为json文件相对于dataset的相对路径。如下所示:
```
easydata/0001.jpg easydata/0001.json
easydata/0002.jpg easydata/0002.json
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://ai.baidu.com/easydata/),可以标注图像分类EasyDataDet数据集。
在PaddleX中,使用`paddlex.cv.datasets.EasyDataDet`([API说明](./apis/datasets.html#easydatadet))加载分类数据集。
## 语义分割EasyDataSeg
语义分割EasyDataSeg数据集包含存放图像和json文件的文件夹、标签文件及图像列表文件。
参考数据文件结构如下:
```
./dataset/ # 数据集根目录ß
|--easydata # 存放图像和json文件的文件夹
| |--0001.jpg
| |--0001.json
| |--0002.jpg
| |--0002.json
| └--...
|
|--train_list.txt # 训练文件列表文件
|
|--val_list.txt # 验证文件列表文件
|
└--labels.txt # 标签列表文件
```
其中,图像文件名应与json文件名一一对应。
每个json文件存储于`labels`相关的信息。如下所示:
```
"labels": [{"y1": 18, "x2": 883, "x1": 371, "y2": 404, "name": "labelA",
"mask": "kVfc0`0Zg0<F7J7I5L5K4L4L4L3N3L3N3L3N2N3M2N2N2N2N2N2N1O2N2O1N2N1O2O1N101N1O2O1N101N10001N101N10001N10001O0O10001O000O100000001O0000000000000000000000O1000001O00000O101O000O101O0O101O0O2O0O101O0O2O0O2N2O0O2O0O2N2O1N1O2N2N2O1N2N2N2N2N2N2M3N3M2M4M2M4M3L4L4L4K6K5J7H9E\\iY1"},
{"y1": 314, "x2": 666, "x1": 227, "y2": 676, "name": "labelB",
"mask": "mdQ8g0Tg0:G8I6K5J5L4L4L4L4M2M4M2M4M2N2N2N3L3N2N2N2N2O1N1O2N2N2O1N1O2N2O0O2O1N1O2O0O2O0O2O001N100O2O000O2O000O2O00000O2O000000001N100000000000000000000000000000000001O0O100000001O0O10001N10001O0O101N10001N101N101N101N101N2O0O2N2O0O2N2N2O0O2N2N2N2N2N2N2N2N2N3L3N2N3L3N3L4M2M4L4L5J5L5J7H8H;BUcd<"},
...]}
```
其中,list中的每个元素代表一个标注信息,标注信息中字段的含义如下所示:
| 字段名 | 含义 | 数据类型 | 备注 |
|:--------|:------------|------|:-----|
| x1 | 标注框左下角横坐标 | int | |
| y1 | 标注框左下角纵坐标 | int | |
| x2 | 标注框右上角横坐标 | int | |
| y2 | 标注框右上角纵坐标 | int | |
| name | 标注框中物体类标 | str | |
| mask | 分割区域布尔型numpy编码后的字符串 | str | 该字段必须存在 |
`train_list.txt``val_list.txt`文本以空格为分割符分为两列,第一列为图像文件相对于dataset的相对路径,第二列为json文件相对于dataset的相对路径。如下所示:
```
easydata/0001.jpg easydata/0001.json
easydata/0002.jpg easydata/0002.json
...
```
`labels.txt`: 每一行为一个单独的类别,相应的行号即为类别对应的id(行号从0开始),如下所示:
```
labelA
labelB
...
```
[点击这里](https://ai.baidu.com/easydata/),可以标注图像分类EasyDataSeg数据集。
在PaddleX中,使用`paddlex.cv.datasets.EasyDataSeg`([API说明](./apis/datasets.html#easydataseg))加载分类数据集。
# 移动端部署
PaddleX的移动端部署由PaddleLite实现,部署的流程如下,首先将训练好的模型导出为inference model,然后使用PaddleLite的python接口对模型进行优化,最后使用PaddleLite的预测库进行部署,
PaddleLite的详细介绍和使用可参考:[PaddleLite文档](https://paddle-lite.readthedocs.io/zh/latest/)
> PaddleX --> Inference Model --> PaddleLite Opt --> PaddleLite Inference
以下介绍如何将PaddleX导出为inference model,然后使用PaddleLite的OPT模块对模型进行优化:
step 1: 安装PaddleLite
```
pip install paddlelite
```
step 2: 将PaddleX模型导出为inference模型
参考[导出inference模型](deploy_server/deploy_python.html#inference)将模型导出为inference格式模型。
**注意:由于PaddleX代码的持续更新,版本低于1.0.0的模型暂时无法直接用于预测部署,参考[模型版本升级](./upgrade_version.md)对模型版本进行升级。**
step 3: 将inference模型转换成PaddleLite模型
```
python /path/to/PaddleX/deploy/lite/export_lite.py --model_dir /path/to/inference_model --save_file /path/to/lite_model --place place/to/run
```
| 参数 | 说明 |
| ---- | ---- |
| model_dir | 预测模型所在路径,包含"__model__", "__params__"文件 |
| save_file | 模型输出的名称,默认为"paddlex.nb" |
| place | 运行的平台,可选:arm|opencl|x86|npu|xpu|rknpu|apu |
step 4: 预测
Lite模型预测正在集成中,即将开源...
# 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* 16.04 (64-bit) with GCC* 4.8.5
* CMake 3.12
* Python 2.7 or higher
请确保系统已经安装好上述基本软件,**下面所有示例以工作目录 `/root/projects/`演示**
```
git clone https://github.com/PaddlePaddle/PaddleX.git
```
**说明**:其中`C++`预测代码在`/root/projects/PaddleX/deploy/openvino` 目录,该目录不依赖任何`PaddleX`下其他目录。
### Step1: 软件依赖
- openvino:
[编译文档](https://github.com/openvinotoolkit/openvino/blob/2020/build-instruction.md#build-steps)
- gflags:
[编译文档](https://gflags.github.io/gflags/#download)
- opencv:
[编译文档](https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html)
说明:/root/projects/PaddleX/deploy/openvino/scripts/bootstrap.sh提供了预编译版本下载,也可自行编译。
- ngraph:
说明:openvino编译的过程中会生成ngraph的lib文件,位于{openvino根目录}/bin/intel64/Release/lib/下。
### Step2: 编译
编译`cmake`的命令在`scripts/build.sh`中,请根据Step1中编译软件的实际情况修改主要参数,其主要内容说明如下:
```
# openvino预编译库的路径
OPENVINO_DIR=/path/to/inference_engine/
# gflags预编译库的路径
GFLAGS_DIR=/path/to/gflags
# ngraph lib的路径,编译openvino时通常会生成
NGRAPH_LIB=/path/to/ngraph/lib/
# opencv预编译库的路径, 如果使用自带预编译版本可不修改
OPENCV_DIR=$(pwd)/deps/opencv3gcc4.8/
# 下载自带预编译版本
sh $(pwd)/scripts/bootstrap.sh
rm -rf build
mkdir -p build
cd build
cmake .. \
-DOPENCV_DIR=${OPENCV_DIR} \
-DGFLAGS_DIR=${GFLAGS_DIR} \
-DOPENVINO_DIR=${OPENVINO_DIR} \
-DNGRAPH_LIB=${NGRAPH_LIB}
make
```
修改脚本设置好主要参数后,执行`build`脚本:
```shell
sh ./scripts/build.sh
```
### Step3: 模型转换
将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: 预测
编译成功后,分类任务的预测可执行程序为`classifier`,其主要命令参数说明如下:
| 参数 | 说明 |
| ---- | ---- |
| --model_dir | Model Optimizer生成的.xml文件路径,请保证Model Optimizer生成的三个文件在同一路径下|
| --image | 要预测的图片文件路径 |
| --image_list | 按行存储图片路径的.txt文件 |
| --device | 运行的平台, 默认值为"CPU" |
#### 样例
`样例一`
测试图片 `/path/to/xiaoduxiong.jpeg`
```shell
./build/classifier --model_dir=/path/to/openvino_model --image=/path/to/xiaoduxiong.jpeg
```
`样例二`:
预测多个图片`/path/to/image_list.txt`,image_list.txt内容的格式如下:
```
/path/to/images/xiaoduxiong1.jpeg
/path/to/images/xiaoduxiong2.jpeg
...
/path/to/images/xiaoduxiongn.jpeg
```
```shell
./build/classifier --model_dir=/path/to/models/openvino_model --image_list=/root/projects/images_list.txt
```
C++部署
==============
C++部署方案位于目录PaddleX/deploy/cpp/下,且独立于PaddleX其他模块。该方案支持在 Windows 和 Linux 完成编译、二次开发集成和部署运行,支持在Linux上完成加密部署。
.. toctree::
:maxdepth: 1
deploy_cpp_win_vs2019.md
deploy_cpp_linux.md
多端安全部署
==============
本文档指引用户如何采用更高性能地方式来部署使用PaddleX训练的模型。本文档模型部署采用Paddle Inference高性能部署方式,在模型运算过程中,对模型计算图进行优化,同时减少内存操作,具体各模型性能对比见服务端Python部署的预测性能对比章节。
同时结合产业实践开发者对模型知识产权的保护需求,提供了轻量级模型加密部署的方案,提升深度学习模型部署的安全性。
.. toctree::
:maxdepth: 2
deploy_server/index.rst
deploy_openvino.md
deploy_lite.md
PaddleX全流程开发教程
=========================
.. toctree::
:maxdepth: 1
dataset_prepare.md
train/index.rst
compress/index.rst
deploy/index.rst
# 训练图像分类模型
---
本文档训练代码可参考PaddleX的[代码tutorial/train/classification/mobilenetv2.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/classification/mobilenetv2.py)
**1.下载并解压训练所需的数据集**
> 使用1张显卡训练并指定使用0号卡。
```python
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import paddlex as pdx
```
> 这里使用蔬菜数据集,训练集、验证集和测试集共包含6189个样本,18个类别。
```python
veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz'
pdx.utils.download_and_decompress(veg_dataset, path='./')
```
**2.定义训练和验证过程中的数据处理和增强操作**
> transforms用于指定训练和验证过程中的数据处理和增强操作流程,如下代码在训练过程中使用了`RandomCrop`和`RandomHorizontalFlip`进行数据增强,transforms的使用见[paddlex.cls.transforms](../../apis/transforms/cls_transforms.html#paddlex-cls-transforms)
```python
from paddlex.cls import transforms
train_transforms = transforms.Compose([
transforms.RandomCrop(crop_size=224),
transforms.RandomHorizontalFlip(),
transforms.Normalize()
])
eval_transforms = transforms.Compose([
transforms.ResizeByShort(short_size=256),
transforms.CenterCrop(crop_size=224),
transforms.Normalize()
])
```
**3.创建数据集读取器,并绑定相应的数据预处理流程**
> 通过不同的数据集读取器可以加载不同格式的数据集,数据集API的介绍见文档[paddlex.datasets](../../apis/datasets.md)
```python
train_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls',
file_list='vegetables_cls/train_list.txt',
label_list='vegetables_cls/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls',
file_list='vegetables_cls/val_list.txt',
label_list='vegetables_cls/labels.txt',
transforms=eval_transforms)
```
**4.创建模型进行训练**
> 模型训练会默认自动下载和使用imagenet图像数据集上的预训练模型,用户也可自行指定`pretrain_weights`参数来设置预训练权重。模型训练过程每间隔`save_interval_epochs`轮会保存一次模型在`save_dir`目录下,同时在保存的过程中也会在验证数据集上计算相关指标。
> 分类模型的接口可见文档[paddlex.cls.models](../../apis/models.md)
```python
model = pdx.cls.MobileNetV2(num_classes=len(train_dataset.labels))
model.train(
num_epochs=10,
train_dataset=train_dataset,
train_batch_size=32,
eval_dataset=eval_dataset,
lr_decay_epochs=[4, 6, 8],
learning_rate=0.025,
save_dir='output/mobilenetv2',
use_vdl=True)
```
> 将`use_vdl`设置为`True`时可使用VisualDL查看训练指标。按以下方式启动VisualDL后,浏览器打开 https://0.0.0.0:8001即可。其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP。
```shell
visualdl --logdir output/mobilenetv2/vdl_log --port 8001
```
**5.验证或测试**
> 利用训练完的模型可继续在验证集上进行验证。
```python
eval_metrics = model.evaluate(eval_dataset, batch_size=8)
print("eval_metrics:", eval_metrics)
```
> 结果输出:
```
eval_metrics: OrderedDict([('acc1', 0.9895916733386709), ('acc5', 0.9983987189751802)])
```
> 训练完用模型对图片进行测试。
```python
predict_result = model.predict('./vegetables_cls/bocai/IMG_00000839.jpg', topk=5)
print("predict_result:", predict_result)
```
> 结果输出:
```
predict_result: [{'category_id': 13, 'category': 'bocai', 'score': 0.8607276},
{'category_id': 11, 'category': 'kongxincai', 'score': 0.06386806},
{'category_id': 2, 'category': 'suanmiao', 'score': 0.03736042},
{'category_id': 12, 'category': 'heiqiezi', 'score': 0.007879922},
{'category_id': 17, 'category': 'huluobo', 'score': 0.006327283}]
```
# 训练目标检测模型
------
更多检测模型在VOC数据集或COCO数据集上的训练代码可参考[代码tutorials/train/detection/faster_rcnn_r50_fpn.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/faster_rcnn_r50_fpn.py)[代码tutorials/train/detection/yolov3_darknet53.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/yolov3_darknet53.py)
**1.下载并解压训练所需的数据集**
> 使用1张显卡训练并指定使用0号卡。
```python
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import paddlex as pdx
```
> 这里使用昆虫数据集,训练集、验证集和测试集共包含217个样本,6个类别。
```python
insect_dataset = 'https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz'
pdx.utils.download_and_decompress(insect_dataset, path='./')
```
**2.定义训练和验证过程中的数据处理和增强操作**
> 在训练过程中使用`RandomHorizontalFlip`进行数据增强,由于接下来选择的模型是带FPN结构的Faster RCNN,所以使用`Padding`将输入图像的尺寸补齐到32的倍数,以保证FPN中两个需做相加操作的特征层的尺寸完全相同。transforms的使用见[paddlex.det.transforms](../../apis/transforms/det_transforms.md)
```python
from paddlex.det import transforms
train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.Normalize(),
transforms.ResizeByShort(short_size=800, max_size=1333),
transforms.Padding(coarsest_stride=32)
])
eval_transforms = transforms.Compose([
transforms.Normalize(),
transforms.ResizeByShort(short_size=800, max_size=1333),
transforms.Padding(coarsest_stride=32),
])
```
**3.创建数据集读取器,并绑定相应的数据预处理流程**
> 数据集读取器的介绍见文档[paddlex.datasets](../../apis/datasets.md)
```python
train_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det',
file_list='insect_det/train_list.txt',
label_list='insect_det/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det',
file_list='insect_det/val_list.txt',
label_list='insect_det/labels.txt',
transforms=eval_transforms)
```
**4.创建Faster RCNN模型,并进行训练**
> 创建带FPN结构的Faster RCNN模型,`num_classes` 需要设置为包含背景类的类别数,即: 目标类别数量(6) + 1
```python
num_classes = len(train_dataset.labels) + 1
model = pdx.det.FasterRCNN(num_classes=num_classes)
```
> 模型训练默认下载并使用在ImageNet数据集上训练得到的Backone,用户也可自行指定`pretrain_weights`参数来设置预训练权重。训练过程每间隔`save_interval_epochs`会在`save_dir`保存一次模型,与此同时也会在验证数据集上计算指标。检测模型的接口可见文档[paddlex.cv.models](../../apis/models.md#fasterrcnn)
```python
model.train(
num_epochs=12,
train_dataset=train_dataset,
train_batch_size=2,
eval_dataset=eval_dataset,
learning_rate=0.0025,
lr_decay_epochs=[8, 11],
save_dir='output/faster_rcnn_r50_fpn',
use_vdl=True)
```
> 将`use_vdl`设置为`True`时可使用VisualDL查看训练指标。按以下方式启动VisualDL后,浏览器打开 https://0.0.0.0:8001即可。其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP。
```shell
visualdl --logdir output/faster_rcnn_r50_fpn/vdl_log --port 8001
```
**5.验证或测试**
> 训练完利用模型可继续在验证集上进行验证。
```python
eval_metrics = model.evaluate(eval_dataset, batch_size=2)
print("eval_metrics:", eval_metrics)
```
> 结果输出:
```python
eval_metrics: {'bbox_map': 76.085371}
```
> 训练完用模型对图片进行测试。
```python
predict_result = model.predict('./insect_det/JPEGImages/1968.jpg')
```
> 可视化测试结果:
```python
pdx.det.visualize('./insect_det/JPEGImages/1968.jpg', predict_result, threshold=0.5, save_dir='./output/faster_rcnn_r50_fpn')
```
![](../../images/visualized_fasterrcnn.jpg)
# 训练实例分割模型
------
本文档训练代码可直接下载[代码tutorials/train/detection/mask_rcnn_r50_fpn.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/detection/mask_rcnn_r50_fpn.py)
**1.下载并解压训练所需的数据集**
> 使用1张显卡训练并指定使用0号卡。
```python
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import paddlex as pdx
```
> 这里使用小度熊分拣数据集,训练集、验证集和测试共包含21个样本,1个类别。
```python
xiaoduxiong_dataset = 'https://bj.bcebos.com/paddlex/datasets/xiaoduxiong_ins_det.tar.gz'
pdx.utils.download_and_decompress(xiaoduxiong_dataset, path='./')
```
**2.定义训练和验证过程中的数据处理和增强操作**
> 在训练过程中使用`RandomHorizontalFlip`进行数据增强,由于接下来选择的模型是带FPN结构的Mask RCNN,所以使用`PaddingImage`将输入图像的尺寸补齐到32的倍数,以保证FPN中两个需做相加操作的特征层的尺寸完全相同。transforms的使用见[paddlex.cv.transforms](../../apis/transforms/det_transforms.md)
```python
from paddlex.det import transforms
train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.Normalize(),
transforms.ResizeByShort(short_size=800, max_size=1333),
transforms.Padding(coarsest_stride=32)
])
eval_transforms = transforms.Compose([
transforms.Normalize(),
transforms.ResizeByShort(short_size=800, max_size=1333),
transforms.Padding(coarsest_stride=32)
])
```
**3.创建数据集读取器,并绑定相应的数据预处理流程**
> 数据集读取器的介绍见文档[paddlex.datasets](../../apis/datasets.md)
```python
train_dataset = pdx.datasets.CocoDetection(
data_dir='xiaoduxiong_ins_det/JPEGImages',
ann_file='xiaoduxiong_ins_det/train.json',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.CocoDetection(
data_dir='xiaoduxiong_ins_det/JPEGImages',
ann_file='xiaoduxiong_ins_det/val.json',
transforms=eval_transforms)
```
**4.创建Mask RCNN模型,并进行训练**
> 创建带FPN结构的Mask RCNN模型,`num_classes` 需要设置为包含背景类的类别数,即: 目标类别数量(1) + 1。
```python
num_classes = len(train_dataset.labels)
model = pdx.det.MaskRCNN(num_classes=num_classes
```
> 模型训练默认下载并使用在ImageNet数据集上训练得到的Backone,用户也可自行指定`pretrain_weights`参数来设置预训练权重。训练过程每间隔`save_interval_epochs`会在`save_dir`保存一次模型,与此同时也会在验证数据集上计算指标。检测模型的接口可见文档[paddlex.det.models](../../apis/models.md)。
```python
model.train(
num_epochs=12,
train_dataset=train_dataset,
train_batch_size=1,
eval_dataset=eval_dataset,
learning_rate=0.00125,
warmup_steps=10,
lr_decay_epochs=[8, 11],
save_dir='output/mask_rcnn_r50_fpn',
use_vdl=True)
```
> 将`use_vdl`设置为`True`时可使用VisualDL查看训练指标。按以下方式启动VisualDL后,浏览器打开 https://0.0.0.0:8001即可。其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP。
```shell
visualdl --logdir output/faster_rcnn_r50_fpn/vdl_log --port 8001
```
**5.验证或测试**
> 训练完利用模型可继续在验证集上进行验证。
```python
eval_metrics = model.evaluate(eval_dataset, batch_size=1)
print("eval_metrics:", eval_metrics)
```
> 结果输出:
```python
eval_metrics: OrderedDict([('bbox_mmap', 0.5038283828382838), ('segm_mmap', 0.7025202520252025)])
```
> 训练完用模型对图片进行测试。
```python
predict_result = model.predict('./xiaoduxiong_ins_det/JPEGImages/WechatIMG114.jpeg')
```
> 可视化测试结果:
```python
pdx.det.visualize('./xiaoduxiong_ins_det/JPEGImages/WechatIMG114.jpeg', predict_result, threshold=0.7, save_dir='./output/mask_rcnn_r50_fpn')
```
![](../../images/visualized_maskrcnn.jpeg)
# 训练语义分割模型
---
更多语义分割模型在视盘数据集上的训练代码可参考[代码tutorials/train/segmentation/deeplabv3p.py](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/segmentation/deeplabv3p.py)
**1.下载并解压训练所需的数据集**
> 使用1张显卡训练并指定使用0号卡。
```python
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import paddlex as pdx
```
> 这里使用视盘分割数据集,训练集、验证集和测试集共包含343个样本,2个类别。
```python
optic_dataset = 'https://bj.bcebos.com/paddlex/datasets/optic_disc_seg.tar.gz'
pdx.utils.download_and_decompress(optic_dataset, path='./')
```
**2.定义训练和验证过程中的数据处理和增强操作**
> 在训练过程中使用`RandomHorizontalFlip`和`RandomPaddingCrop`进行数据增强,transforms的使用见[paddlex.seg.transforms](../../apis/transforms/seg_transforms.md)
```python
train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.Resize(target_size=512),
transforms.RandomPaddingCrop(crop_size=500),
transforms.Normalize()
])
eval_transforms = transforms.Compose([
transforms.Resize(512),
transforms.Normalize()
])
```
**3.创建数据集读取器,并绑定相应的数据预处理流程**
> 数据集读取器的介绍见文档[paddlex.cv.datasets](../../apis/datasets.md)
```python
train_dataset = pdx.datasets.SegDataset(
data_dir='optic_disc_seg',
file_list='optic_disc_seg/train_list.txt',
label_list='optic_disc_seg/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.SegDataset(
data_dir='optic_disc_seg',
file_list='optic_disc_seg/val_list.txt',
label_list='optic_disc_seg/labels.txt',
transforms=eval_transforms)
```
**4.创建DeepLabv3+模型,并进行训练**
> 创建DeepLabv3+模型,`num_classes` 需要设置为不包含背景类的类别数,即: 目标类别数量(1),详细代码可参见[demo](https://github.com/PaddlePaddle/PaddleX/blob/develop/tutorials/train/segmentation/deeplabv3p.py#L44)。
```python
num_classes = num_classes
model = pdx.seg.DeepLabv3p(num_classes=num_classes)
```
> 模型训练默认下载并使用在ImageNet数据集上训练得到的Backone,用户也可自行指定`pretrain_weights`参数来设置预训练权重。
训练过程每间隔`save_interval_epochs`会在`save_dir`保存一次模型,与此同时也会在验证数据集上计算指标。
检测模型的接口可见文档[paddlex.seg.models](../../apis/models.md)
```python
model.train(
num_epochs=40,
train_dataset=train_dataset,
train_batch_size=4,
eval_dataset=eval_dataset,
learning_rate=0.01,
save_dir='output/deeplab',
use_vdl=True)
```
> 将`use_vdl`设置为`True`时可使用VisualDL查看训练指标。按以下方式启动VisualDL后,浏览器打开 https://0.0.0.0:8001即可。其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP。
```shell
visualdl --logdir output/deeplab/vdl_log --port 8001
```
**5.验证或测试**
> 训练完利用模型可继续在验证集上进行验证。
```python
eval_metrics = model.evaluate(eval_dataset, batch_size=2)
print("eval_metrics:", eval_metrics)
```
> 结果输出:
```python
eval_metrics: {'miou': 0.8915175875548873, 'category_iou': [0.9956445981924432, 0.7873905769173314], 'macc': 0.9957137358816046, 'category_acc': [0.9975360650317765, 0.8948120441157331], 'kappa': 0.8788684558629085}
```
> 训练完用模型对图片进行测试。
```python
image_name = 'optic_disc_seg/JPEGImages/H0005.jpg'
predict_result = model.predict(image_name)
```
> 可视化测试结果:
```python
import paddlex as pdx
pdx.seg.visualize(image_name, predict_result, weight=0.4)
```
![](../../images/visualized_deeplab.jpg)
# VisualDL可视化训练指标
在使用PaddleX训练模型过程中,各个训练指标和评估指标会直接输出到标准输出流,同时也可通过VisualDL对训练过程中的指标进行可视化,只需在调用`train`函数时,将`use_vdl`参数设为`True`即可,如下代码所示,
```
model = paddlex.cls.ResNet50(num_classes=1000)
model.train(num_epochs=120, train_dataset=train_dataset,
train_batch_size=32, eval_dataset=eval_dataset,
log_interval_steps=10, save_interval_epochs=10,
save_dir='./output', use_vdl=True)
```
模型在训练过程中,会在`save_dir`下生成`vdl_log`目录,通过在命令行终端执行以下命令,启动VisualDL。
```
visualdl --logdir=output/vdl_log --port=8008
```
在浏览器打开`http://0.0.0.0:8008`便可直接查看随训练迭代动态变化的各个指标(0.0.0.0表示启动VisualDL所在服务器的IP,本机使用0.0.0.0即可)。
在训练分类模型过程中,使用VisualDL进行可视化的示例图如下所示。
> 训练过程中每个Step的`Loss`和相应`Top1准确率`变化趋势:
![](../../images/vdl1.jpg)
> 训练过程中每个Step的`学习率lr`和相应`Top5准确率`变化趋势:
![](../../images/vdl2.jpg)
> 训练过程中,每次保存模型时,模型在验证数据集上的`Top1准确率`和`Top5准确率`:
![](../../images/vdl3.jpg)
# 更新日志
- 2020.05.20
> - 发布正式版 v1.0
> - 增加模型C++部署和Python部署代码
> - 增加模型加密部署方案
> - 增加分类模型的OpenVINO部署方案
> - 增加模型可解释性的接口
- 2020.05.17
> - 发布v0.1.8 pip更新
> - 修复部分代码Bug
> - 新增EasyData平台数据标注格式支持
> - 支持imgaug数据增强库的pixel-level算子
...@@ -50,6 +50,36 @@ def arg_parser(): ...@@ -50,6 +50,36 @@ def arg_parser():
action="store_true", action="store_true",
default=False, default=False,
help="export onnx model for deployment") help="export onnx model for deployment")
parser.add_argument(
"--data_conversion",
"-dc",
action="store_true",
default=False,
help="convert the dataset to the standard format")
parser.add_argument(
"--source",
"-se",
type=_text_type,
default=None,
help="define dataset format before the conversion")
parser.add_argument(
"--to",
"-to",
type=_text_type,
default=None,
help="define dataset format after the conversion")
parser.add_argument(
"--pics",
"-p",
type=_text_type,
default=None,
help="define pictures directory path")
parser.add_argument(
"--annotations",
"-a",
type=_text_type,
default=None,
help="define annotations directory path")
parser.add_argument( parser.add_argument(
"--fixed_input_shape", "--fixed_input_shape",
"-fs", "-fs",
...@@ -105,6 +135,24 @@ def main(): ...@@ -105,6 +135,24 @@ def main():
"paddlex --export_inference --model_dir model_path --save_dir infer_model" "paddlex --export_inference --model_dir model_path --save_dir infer_model"
) )
pdx.convertor.export_onnx_model(model, args.save_dir) pdx.convertor.export_onnx_model(model, args.save_dir)
if args.data_conversion:
assert args.source is not None, "--source should be defined while converting dataset"
assert args.to is not None, "--to should be defined to confirm the taregt dataset format"
assert args.pics is not None, "--pics should be defined to confirm the pictures path"
assert args.annotations is not None, "--annotations should be defined to confirm the annotations path"
assert args.save_dir is not None, "--save_dir should be defined to store taregt dataset"
if args.source == 'labelme' and args.to == 'ImageNet':
logging.error(
"The labelme dataset can not convert to the ImageNet dataset.",
exit=False)
if args.source == 'jingling' and args.to == 'PascalVOC':
logging.error(
"The jingling dataset can not convert to the PascalVOC dataset.",
exit=False)
pdx.tools.convert.dataset_conversion(args.source, args.to,
args.pics, args.annotations, args.save_dir )
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -46,7 +46,7 @@ def is_valid(sample): ...@@ -46,7 +46,7 @@ def is_valid(sample):
return False return False
elif isinstance(s, np.ndarray) and s.size == 0: elif isinstance(s, np.ndarray) and s.size == 0:
return False return False
elif isinstance(s, collections.Sequence) and len(s) == 0: elif isinstance(s, collections.abc.Sequence) and len(s) == 0:
return False return False
return True return True
...@@ -55,6 +55,7 @@ def get_encoding(path): ...@@ -55,6 +55,7 @@ def get_encoding(path):
f = open(path, 'rb') f = open(path, 'rb')
data = f.read() data = f.read()
file_encoding = chardet.detect(data).get('encoding') file_encoding = chardet.detect(data).get('encoding')
f.close()
return file_encoding return file_encoding
......
...@@ -18,6 +18,7 @@ import random ...@@ -18,6 +18,7 @@ import random
import copy import copy
import json import json
import paddlex.utils.logging as logging import paddlex.utils.logging as logging
from paddlex.utils import path_normalization
from .imagenet import ImageNet from .imagenet import ImageNet
from .dataset import is_pic from .dataset import is_pic
from .dataset import get_encoding from .dataset import get_encoding
...@@ -68,6 +69,8 @@ class EasyDataCls(ImageNet): ...@@ -68,6 +69,8 @@ class EasyDataCls(ImageNet):
for line in f: for line in f:
img_file, json_file = [osp.join(data_dir, x) \ img_file, json_file = [osp.join(data_dir, x) \
for x in line.strip().split()[:2]] for x in line.strip().split()[:2]]
img_file = path_normalization(img_file)
json_file = path_normalization(json_file)
if not is_pic(img_file): if not is_pic(img_file):
continue continue
if not osp.isfile(json_file): if not osp.isfile(json_file):
......
...@@ -20,6 +20,7 @@ import json ...@@ -20,6 +20,7 @@ import json
import cv2 import cv2
import numpy as np import numpy as np
import paddlex.utils.logging as logging import paddlex.utils.logging as logging
from paddlex.utils import path_normalization
from .voc import VOCDetection from .voc import VOCDetection
from .dataset import is_pic from .dataset import is_pic
from .dataset import get_encoding from .dataset import get_encoding
...@@ -87,6 +88,8 @@ class EasyDataDet(VOCDetection): ...@@ -87,6 +88,8 @@ class EasyDataDet(VOCDetection):
for line in f: for line in f:
img_file, json_file = [osp.join(data_dir, x) \ img_file, json_file = [osp.join(data_dir, x) \
for x in line.strip().split()[:2]] for x in line.strip().split()[:2]]
img_file = path_normalization(img_file)
json_file = path_normalization(json_file)
if not is_pic(img_file): if not is_pic(img_file):
continue continue
if not osp.isfile(json_file): if not osp.isfile(json_file):
......
...@@ -20,6 +20,7 @@ import json ...@@ -20,6 +20,7 @@ import json
import cv2 import cv2
import numpy as np import numpy as np
import paddlex.utils.logging as logging import paddlex.utils.logging as logging
from paddlex.utils import path_normalization
from .dataset import Dataset from .dataset import Dataset
from .dataset import get_encoding from .dataset import get_encoding
from .dataset import is_pic from .dataset import is_pic
...@@ -71,6 +72,8 @@ class EasyDataSeg(Dataset): ...@@ -71,6 +72,8 @@ class EasyDataSeg(Dataset):
for line in f: for line in f:
img_file, json_file = [osp.join(data_dir, x) \ img_file, json_file = [osp.join(data_dir, x) \
for x in line.strip().split()[:2]] for x in line.strip().split()[:2]]
img_file = path_normalization(img_file)
json_file = path_normalization(json_file)
if not is_pic(img_file): if not is_pic(img_file):
continue continue
if not osp.isfile(json_file): if not osp.isfile(json_file):
......
...@@ -17,6 +17,7 @@ import os.path as osp ...@@ -17,6 +17,7 @@ import os.path as osp
import random import random
import copy import copy
import paddlex.utils.logging as logging import paddlex.utils.logging as logging
from paddlex.utils import path_normalization
from .dataset import Dataset from .dataset import Dataset
from .dataset import is_pic from .dataset import is_pic
from .dataset import get_encoding from .dataset import get_encoding
...@@ -66,6 +67,7 @@ class ImageNet(Dataset): ...@@ -66,6 +67,7 @@ class ImageNet(Dataset):
with open(file_list, encoding=get_encoding(file_list)) as f: with open(file_list, encoding=get_encoding(file_list)) as f:
for line in f: for line in f:
items = line.strip().split() items = line.strip().split()
items[0] = path_normalization(items[0])
if not is_pic(items[0]): if not is_pic(items[0]):
continue continue
full_path = osp.join(data_dir, items[0]) full_path = osp.join(data_dir, items[0])
......
...@@ -17,6 +17,7 @@ import os.path as osp ...@@ -17,6 +17,7 @@ import os.path as osp
import random import random
import copy import copy
import paddlex.utils.logging as logging import paddlex.utils.logging as logging
from paddlex.utils import path_normalization
from .dataset import Dataset from .dataset import Dataset
from .dataset import get_encoding from .dataset import get_encoding
from .dataset import is_pic from .dataset import is_pic
...@@ -61,10 +62,11 @@ class SegDataset(Dataset): ...@@ -61,10 +62,11 @@ class SegDataset(Dataset):
for line in f: for line in f:
item = line.strip() item = line.strip()
self.labels.append(item) self.labels.append(item)
with open(file_list, encoding=get_encoding(file_list)) as f: with open(file_list, encoding=get_encoding(file_list)) as f:
for line in f: for line in f:
items = line.strip().split() items = line.strip().split()
items[0] = path_normalization(items[0])
items[1] = path_normalization(items[1])
if not is_pic(items[0]): if not is_pic(items[0]):
continue continue
full_path_im = osp.join(data_dir, items[0]) full_path_im = osp.join(data_dir, items[0])
......
...@@ -22,6 +22,7 @@ import numpy as np ...@@ -22,6 +22,7 @@ import numpy as np
from collections import OrderedDict from collections import OrderedDict
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import paddlex.utils.logging as logging import paddlex.utils.logging as logging
from paddlex.utils import path_normalization
from .dataset import Dataset from .dataset import Dataset
from .dataset import is_pic from .dataset import is_pic
from .dataset import get_encoding from .dataset import get_encoding
...@@ -92,6 +93,8 @@ class VOCDetection(Dataset): ...@@ -92,6 +93,8 @@ class VOCDetection(Dataset):
break break
img_file, xml_file = [osp.join(data_dir, x) \ img_file, xml_file = [osp.join(data_dir, x) \
for x in line.strip().split()[:2]] for x in line.strip().split()[:2]]
img_file = path_normalization(img_file)
xml_file = path_normalization(xml_file)
if not is_pic(img_file): if not is_pic(img_file):
continue continue
if not osp.isfile(xml_file): if not osp.isfile(xml_file):
......
# 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.
...@@ -28,7 +28,7 @@ def visualize_detection(image, result, threshold=0.5, save_dir='./'): ...@@ -28,7 +28,7 @@ def visualize_detection(image, result, threshold=0.5, save_dir='./'):
""" """
if isinstance(image, np.ndarray): if isinstance(image, np.ndarray):
image_name = str(int(time.time())) + '.jpg' image_name = str(int(time.time() * 1000)) + '.jpg'
else: else:
image_name = os.path.split(image)[-1] image_name = os.path.split(image)[-1]
image = cv2.imread(image) image = cv2.imread(image)
...@@ -64,7 +64,7 @@ def visualize_segmentation(image, result, weight=0.6, save_dir='./'): ...@@ -64,7 +64,7 @@ def visualize_segmentation(image, result, weight=0.6, save_dir='./'):
if isinstance(image, np.ndarray): if isinstance(image, np.ndarray):
im = image im = image
image_name = str(int(time.time())) + '.jpg' image_name = str(int(time.time() * 1000)) + '.jpg'
else: else:
image_name = os.path.split(image)[-1] image_name = os.path.split(image)[-1]
im = cv2.imread(image) im = cv2.imread(image)
...@@ -145,8 +145,8 @@ def draw_bbox_mask(image, results, threshold=0.5): ...@@ -145,8 +145,8 @@ def draw_bbox_mask(image, results, threshold=0.5):
assert brightness_factor >= -1.0 and brightness_factor <= 1.0 assert brightness_factor >= -1.0 and brightness_factor <= 1.0
color = mplc.to_rgb(color) color = mplc.to_rgb(color)
polygon_color = colorsys.rgb_to_hls(*mplc.to_rgb(color)) polygon_color = colorsys.rgb_to_hls(*mplc.to_rgb(color))
modified_lightness = polygon_color[1] + ( modified_lightness = polygon_color[1] + (brightness_factor *
brightness_factor * polygon_color[1]) polygon_color[1])
modified_lightness = 0.0 if modified_lightness < 0.0 else modified_lightness modified_lightness = 0.0 if modified_lightness < 0.0 else modified_lightness
modified_lightness = 1.0 if modified_lightness > 1.0 else modified_lightness modified_lightness = 1.0 if modified_lightness > 1.0 else modified_lightness
modified_color = colorsys.hls_to_rgb( modified_color = colorsys.hls_to_rgb(
...@@ -161,8 +161,7 @@ def draw_bbox_mask(image, results, threshold=0.5): ...@@ -161,8 +161,7 @@ def draw_bbox_mask(image, results, threshold=0.5):
dpi = fig.get_dpi() dpi = fig.get_dpi()
fig.set_size_inches( fig.set_size_inches(
(width * scale + 1e-2) / dpi, (width * scale + 1e-2) / dpi,
(height * scale + 1e-2) / dpi, (height * scale + 1e-2) / dpi, )
)
canvas = FigureCanvasAgg(fig) canvas = FigureCanvasAgg(fig)
ax = fig.add_axes([0.0, 0.0, 1.0, 1.0]) ax = fig.add_axes([0.0, 0.0, 1.0, 1.0])
ax.axis("off") ax.axis("off")
...@@ -208,8 +207,7 @@ def draw_bbox_mask(image, results, threshold=0.5): ...@@ -208,8 +207,7 @@ def draw_bbox_mask(image, results, threshold=0.5):
edgecolor=color, edgecolor=color,
linewidth=linewidth * scale, linewidth=linewidth * scale,
alpha=0.8, alpha=0.8,
linestyle="-", linestyle="-", ))
))
# draw mask # draw mask
if 'mask' in dt: if 'mask' in dt:
...@@ -232,23 +230,22 @@ def draw_bbox_mask(image, results, threshold=0.5): ...@@ -232,23 +230,22 @@ def draw_bbox_mask(image, results, threshold=0.5):
fill=True, fill=True,
facecolor=mplc.to_rgb(color) + (alpha, ), facecolor=mplc.to_rgb(color) + (alpha, ),
edgecolor=edge_color, edgecolor=edge_color,
linewidth=max(default_font_size // 15 * scale, 1), linewidth=max(default_font_size // 15 * scale, 1), )
)
ax.add_patch(polygon) ax.add_patch(polygon)
# draw label # draw label
text_pos = (xmin, ymin) text_pos = (xmin, ymin)
horiz_align = "left" horiz_align = "left"
instance_area = w * h instance_area = w * h
if (instance_area < _SMALL_OBJECT_AREA_THRESH * scale if (instance_area < _SMALL_OBJECT_AREA_THRESH * scale or
or h < 40 * scale): h < 40 * scale):
if ymin >= height - 5: if ymin >= height - 5:
text_pos = (xmin, ymin) text_pos = (xmin, ymin)
else: else:
text_pos = (xmin, ymax) text_pos = (xmin, ymax)
height_ratio = h / np.sqrt(height * width) height_ratio = h / np.sqrt(height * width)
font_size = (np.clip((height_ratio - 0.02) / 0.08 + 1, 1.2, 2) * 0.5 * font_size = (np.clip((height_ratio - 0.02) / 0.08 + 1, 1.2,
default_font_size) 2) * 0.5 * default_font_size)
text = "{} {:.2f}".format(cname, score) text = "{} {:.2f}".format(cname, score)
color = np.maximum(list(mplc.to_rgb(color)), 0.2) color = np.maximum(list(mplc.to_rgb(color)), 0.2)
color[np.argmax(color)] = max(0.8, np.max(color)) color[np.argmax(color)] = max(0.8, np.max(color))
...@@ -269,8 +266,7 @@ def draw_bbox_mask(image, results, threshold=0.5): ...@@ -269,8 +266,7 @@ def draw_bbox_mask(image, results, threshold=0.5):
horizontalalignment=horiz_align, horizontalalignment=horiz_align,
color=color, color=color,
zorder=10, zorder=10,
rotation=0, rotation=0, )
)
s, (width, height) = canvas.print_to_buffer() s, (width, height) = canvas.print_to_buffer()
buffer = np.frombuffer(s, dtype="uint8") buffer = np.frombuffer(s, dtype="uint8")
...@@ -408,8 +404,8 @@ def draw_pr_curve(eval_details_file=None, ...@@ -408,8 +404,8 @@ def draw_pr_curve(eval_details_file=None,
plt.plot(x, sr_array, color=color, label=nm, linewidth=1) plt.plot(x, sr_array, color=color, label=nm, linewidth=1)
plt.legend(loc="lower left", fontsize=5) plt.legend(loc="lower left", fontsize=5)
plt.savefig( plt.savefig(
os.path.join(save_dir, "./{}_pr_curve(iou-{}).png".format( os.path.join(save_dir,
style, iou_thresh)), "./{}_pr_curve(iou-{}).png".format(style, iou_thresh)),
dpi=800) dpi=800)
plt.close() plt.close()
......
...@@ -1104,20 +1104,21 @@ class ArrangeSegmenter(SegTransform): ...@@ -1104,20 +1104,21 @@ class ArrangeSegmenter(SegTransform):
class ComposedSegTransforms(Compose): class ComposedSegTransforms(Compose):
""" 语义分割模型(UNet/DeepLabv3p)的图像处理流程,具体如下 """ 语义分割模型(UNet/DeepLabv3p)的图像处理流程,具体如下
训练阶段: 训练阶段:
1. 随机对图像以0.5的概率水平翻转 1. 随机对图像以0.5的概率水平翻转,若random_horizontal_flip为False,则跳过此步骤
2. 按不同的比例随机Resize原图 2. 按不同的比例随机Resize原图, 处理方式参考[paddlex.seg.transforms.ResizeRangeScaling](#resizerangescaling)。若min_max_size为None,则跳过此步骤
3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小 3. 从原图中随机crop出大小为train_crop_size大小的子图,如若crop出来的图小于train_crop_size,则会将图padding到对应大小
4. 图像归一化 4. 图像归一化
预测阶段: 预测阶段:
1. 图像归一化 1. 将图像的最长边resize至(min_max_size[0] + min_max_size[1])//2, 短边按比例resize。若min_max_size为None,则跳过此步骤
2. 图像归一化
Args: Args:
mode(str): 图像处理所处阶段,训练/验证/预测,分别对应'train', 'eval', 'test' mode(str): Transforms所处的阶段,包括`train', 'eval'或'test'
min_max_size(list): 训练过程中,图像的最长边会随机resize至此区间(短边按比例相应resize);预测阶段,图像最长边会resize至此区间中间值,即(min_size+max_size)/2。默认为[400, 600] min_max_size(list): 用于对图像进行resize,具体作用参见上述步骤。
train_crop_size(list): 仅在mode为'train`时生效,训练过程中,随机从图像中裁剪出对应大小的子图(如若原图小于此大小,则会padding到此大小),默认为[400, 600] train_crop_size(list): 训练过程中随机裁剪原图用于训练,具体作用参见上述步骤。此参数仅在mode为`train`时生效。
mean(list): 图像均值 mean(list): 图像均值, 默认为[0.485, 0.456, 0.406]。
std(list): 图像方差 std(list): 图像方差,默认为[0.229, 0.224, 0.225]。
random_horizontal_flip(bool): 数据增强方式,仅在mode为`train`时生效,表示训练过程是否随机水平翻转图像,默认为True random_horizontal_flip(bool): 数据增强,是否随机水平翻转图像,此参数仅在mode为`train`时生效。
""" """
def __init__(self, def __init__(self,
...@@ -1129,19 +1130,29 @@ class ComposedSegTransforms(Compose): ...@@ -1129,19 +1130,29 @@ class ComposedSegTransforms(Compose):
random_horizontal_flip=True): random_horizontal_flip=True):
if mode == 'train': if mode == 'train':
# 训练时的transforms,包含数据增强 # 训练时的transforms,包含数据增强
transforms = [ if min_max_size is None:
ResizeRangeScaling( transforms = [
min_value=min(min_max_size), max_value=max(min_max_size)), RandomPaddingCrop(crop_size=train_crop_size), Normalize(
RandomPaddingCrop(crop_size=train_crop_size), Normalize( mean=mean, std=std)
mean=mean, std=std) ]
] else:
transforms = [
ResizeRangeScaling(
min_value=min(min_max_size),
max_value=max(min_max_size)),
RandomPaddingCrop(crop_size=train_crop_size), Normalize(
mean=mean, std=std)
]
if random_horizontal_flip: if random_horizontal_flip:
transforms.insert(0, RandomHorizontalFlip()) transforms.insert(0, RandomHorizontalFlip())
else: else:
# 验证/预测时的transforms # 验证/预测时的transforms
long_size = (min(min_max_size) + max(min_max_size)) // 2 if min_max_size is None:
transforms = [ transforms = [Normalize(mean=mean, std=std)]
ResizeByLong(long_size=long_size), Normalize( else:
mean=mean, std=std) long_size = (min(min_max_size) + max(min_max_size)) // 2
] transforms = [
ResizeByLong(long_size=long_size), Normalize(
mean=mean, std=std)
]
super(ComposedSegTransforms, self).__init__(transforms) super(ComposedSegTransforms, self).__init__(transforms)
...@@ -40,4 +40,5 @@ def get_encoding(path): ...@@ -40,4 +40,5 @@ def get_encoding(path):
f = open(path, 'rb') f = open(path, 'rb')
data = f.read() data = f.read()
file_encoding = chardet.detect(data).get('encoding') file_encoding = chardet.detect(data).get('encoding')
f.close()
return file_encoding return file_encoding
\ No newline at end of file
...@@ -15,8 +15,10 @@ ...@@ -15,8 +15,10 @@
# limitations under the License. # limitations under the License.
from .x2imagenet import EasyData2ImageNet from .x2imagenet import EasyData2ImageNet
from .x2imagenet import JingLing2ImageNet
from .x2coco import LabelMe2COCO from .x2coco import LabelMe2COCO
from .x2coco import EasyData2COCO from .x2coco import EasyData2COCO
from .x2coco import JingLing2COCO
from .x2voc import LabelMe2VOC from .x2voc import LabelMe2VOC
from .x2voc import EasyData2VOC from .x2voc import EasyData2VOC
from .x2seg import JingLing2Seg from .x2seg import JingLing2Seg
...@@ -24,10 +26,34 @@ from .x2seg import LabelMe2Seg ...@@ -24,10 +26,34 @@ from .x2seg import LabelMe2Seg
from .x2seg import EasyData2Seg from .x2seg import EasyData2Seg
easydata2imagenet = EasyData2ImageNet().convert easydata2imagenet = EasyData2ImageNet().convert
jingling2imagenet = JingLing2ImageNet().convert
labelme2coco = LabelMe2COCO().convert labelme2coco = LabelMe2COCO().convert
easydata2coco = EasyData2COCO().convert easydata2coco = EasyData2COCO().convert
jingling2coco = JingLing2COCO().convert
labelme2voc = LabelMe2VOC().convert labelme2voc = LabelMe2VOC().convert
easydata2voc = EasyData2VOC().convert easydata2voc = EasyData2VOC().convert
jingling2seg = JingLing2Seg().convert jingling2seg = JingLing2Seg().convert
labelme2seg = LabelMe2Seg().convert labelme2seg = LabelMe2Seg().convert
easydata2seg = EasyData2Seg().convert easydata2seg = EasyData2Seg().convert
def dataset_conversion(source, to, pics, anns, save_dir):
if source == 'labelme' and to == 'PascalVOC':
labelme2voc(pics, anns, save_dir)
elif source == 'labelme' and to == 'MSCOCO':
labelme2coco(pics, anns, save_dir)
elif source == 'labelme' and to == 'SEG':
labelme2seg(pics, anns, save_dir)
elif source == 'jingling' and to == 'ImageNet':
jingling2imagenet(pics, anns, save_dir)
elif source == 'jingling' and to == 'MSCOCO':
jingling2coco(pics, anns, save_dir)
elif source == 'jingling' and to == 'SEG':
jingling2seg(pics, anns, save_dir)
elif source == 'easydata' and to == 'ImageNet':
easydata2imagenet(pics, anns, save_dir)
elif source == 'easydata' and to == 'PascalVOC':
easydata2voc(pics, anns, save_dir)
elif source == 'easydata' and to == 'MSCOCO':
easydata2coco(pics, anns, save_dir)
elif source == 'easydata' and to == 'SEG':
easydata2seg(pics, anns, save_dir)
\ No newline at end of file
...@@ -22,6 +22,7 @@ import shutil ...@@ -22,6 +22,7 @@ import shutil
import numpy as np import numpy as np
import PIL.ImageDraw import PIL.ImageDraw
from .base import MyEncoder, is_pic, get_encoding from .base import MyEncoder, is_pic, get_encoding
from paddlex.utils import path_normalization
class X2COCO(object): class X2COCO(object):
...@@ -100,6 +101,7 @@ class LabelMe2COCO(X2COCO): ...@@ -100,6 +101,7 @@ class LabelMe2COCO(X2COCO):
image["height"] = json_info["imageHeight"] image["height"] = json_info["imageHeight"]
image["width"] = json_info["imageWidth"] image["width"] = json_info["imageWidth"]
image["id"] = image_id + 1 image["id"] = image_id + 1
json_info["imagePath"] = path_normalization(json_info["imagePath"])
image["file_name"] = osp.split(json_info["imagePath"])[-1] image["file_name"] = osp.split(json_info["imagePath"])[-1]
return image return image
...@@ -144,7 +146,7 @@ class LabelMe2COCO(X2COCO): ...@@ -144,7 +146,7 @@ class LabelMe2COCO(X2COCO):
img_name_part = osp.splitext(img_file)[0] img_name_part = osp.splitext(img_file)[0]
json_file = osp.join(json_dir, img_name_part + ".json") json_file = osp.join(json_dir, img_name_part + ".json")
if not osp.exists(json_file): if not osp.exists(json_file):
os.remove(os.remove(osp.join(image_dir, img_file))) os.remove(osp.join(image_dir, img_file))
continue continue
image_id = image_id + 1 image_id = image_id + 1
with open(json_file, mode='r', \ with open(json_file, mode='r', \
...@@ -187,6 +189,7 @@ class EasyData2COCO(X2COCO): ...@@ -187,6 +189,7 @@ class EasyData2COCO(X2COCO):
image["height"] = img.shape[0] image["height"] = img.shape[0]
image["width"] = img.shape[1] image["width"] = img.shape[1]
image["id"] = image_id + 1 image["id"] = image_id + 1
img_path = path_normalization(img_path)
image["file_name"] = osp.split(img_path)[-1] image["file_name"] = osp.split(img_path)[-1]
return image return image
...@@ -216,7 +219,7 @@ class EasyData2COCO(X2COCO): ...@@ -216,7 +219,7 @@ class EasyData2COCO(X2COCO):
img_name_part = osp.splitext(img_file)[0] img_name_part = osp.splitext(img_file)[0]
json_file = osp.join(json_dir, img_name_part + ".json") json_file = osp.join(json_dir, img_name_part + ".json")
if not osp.exists(json_file): if not osp.exists(json_file):
os.remove(os.remove(osp.join(image_dir, img_file))) os.remove(osp.join(image_dir, img_file))
continue continue
image_id = image_id + 1 image_id = image_id + 1
with open(json_file, mode='r', \ with open(json_file, mode='r', \
...@@ -255,3 +258,108 @@ class EasyData2COCO(X2COCO): ...@@ -255,3 +258,108 @@ class EasyData2COCO(X2COCO):
self.annotations_list.append( self.annotations_list.append(
self.generate_polygon_anns_field(points, segmentation, label, image_id, object_id, self.generate_polygon_anns_field(points, segmentation, label, image_id, object_id,
label_to_num)) label_to_num))
class JingLing2COCO(X2COCO):
"""将使用EasyData标注的检测或分割数据集转换为COCO数据集。
"""
def __init__(self):
super(JingLing2COCO, self).__init__()
def generate_images_field(self, json_info, image_id):
image = {}
image["height"] = json_info["size"]["height"]
image["width"] = json_info["size"]["width"]
image["id"] = image_id + 1
json_info["path"] = path_normalization(json_info["path"])
image["file_name"] = osp.split(json_info["path"])[-1]
return image
def generate_polygon_anns_field(self, height, width,
points, label, image_id,
object_id, label_to_num):
annotation = {}
annotation["segmentation"] = [list(np.asarray(points).flatten())]
annotation["iscrowd"] = 0
annotation["image_id"] = image_id + 1
annotation["bbox"] = list(map(float, self.get_bbox(height, width, points)))
annotation["area"] = annotation["bbox"][2] * annotation["bbox"][3]
annotation["category_id"] = label_to_num[label]
annotation["id"] = object_id + 1
return annotation
def get_bbox(self, height, width, points):
polygons = points
mask = np.zeros([height, width], dtype=np.uint8)
mask = PIL.Image.fromarray(mask)
xy = list(map(tuple, polygons))
PIL.ImageDraw.Draw(mask).polygon(xy=xy, outline=1, fill=1)
mask = np.array(mask, dtype=bool)
index = np.argwhere(mask == 1)
rows = index[:, 0]
clos = index[:, 1]
left_top_r = np.min(rows)
left_top_c = np.min(clos)
right_bottom_r = np.max(rows)
right_bottom_c = np.max(clos)
return [
left_top_c, left_top_r, right_bottom_c - left_top_c,
right_bottom_r - left_top_r
]
def parse_json(self, img_dir, json_dir):
image_id = -1
object_id = -1
labels_list = []
label_to_num = {}
for img_file in os.listdir(img_dir):
img_name_part = osp.splitext(img_file)[0]
json_file = osp.join(json_dir, img_name_part + ".json")
if not osp.exists(json_file):
os.remove(osp.join(image_dir, img_file))
continue
image_id = image_id + 1
with open(json_file, mode='r', \
encoding=get_encoding(json_file)) as j:
json_info = json.load(j)
img_info = self.generate_images_field(json_info, image_id)
self.images_list.append(img_info)
anns_type = "bndbox"
for i, obj in enumerate(json_info["outputs"]["object"]):
if i == 0:
if "polygon" in obj:
anns_type = "polygon"
else:
if anns_type not in obj:
continue
object_id = object_id + 1
label = obj["name"]
if label not in labels_list:
self.categories_list.append(\
self.generate_categories_field(label, labels_list))
labels_list.append(label)
label_to_num[label] = len(labels_list)
if anns_type == "polygon":
points = []
for j in range(int(len(obj["polygon"]) / 2.0)):
points.append([obj["polygon"]["x" + str(j + 1)],
obj["polygon"]["y" + str(j + 1)]])
self.annotations_list.append(
self.generate_polygon_anns_field(json_info["size"]["height"],
json_info["size"]["width"],
points,
label,
image_id,
object_id,
label_to_num))
if anns_type == "bndbox":
points = []
points.append([obj["bndbox"]["xmin"], obj["bndbox"]["ymin"]])
points.append([obj["bndbox"]["xmax"], obj["bndbox"]["ymax"]])
points.append([obj["bndbox"]["xmin"], obj["bndbox"]["ymax"]])
points.append([obj["bndbox"]["xmax"], obj["bndbox"]["ymin"]])
self.annotations_list.append(
self.generate_rectangle_anns_field(points, label, image_id,
object_id, label_to_num))
\ No newline at end of file
...@@ -22,9 +22,8 @@ import shutil ...@@ -22,9 +22,8 @@ import shutil
import numpy as np import numpy as np
from .base import MyEncoder, is_pic, get_encoding from .base import MyEncoder, is_pic, get_encoding
class EasyData2ImageNet(object):
"""将使用EasyData标注的分类数据集转换为COCO数据集。 class X2ImageNet(object):
"""
def __init__(self): def __init__(self):
pass pass
...@@ -46,8 +45,8 @@ class EasyData2ImageNet(object): ...@@ -46,8 +45,8 @@ class EasyData2ImageNet(object):
continue continue
with open(json_file, mode="r", \ with open(json_file, mode="r", \
encoding=get_encoding(json_file)) as j: encoding=get_encoding(json_file)) as j:
json_info = json.load(j) json_info = self.get_json_info(j)
for output in json_info['labels']: for output in json_info:
cls_name = output['name'] cls_name = output['name']
new_image_dir = osp.join(dataset_save_dir, cls_name) new_image_dir = osp.join(dataset_save_dir, cls_name)
if not osp.exists(new_image_dir): if not osp.exists(new_image_dir):
...@@ -55,4 +54,28 @@ class EasyData2ImageNet(object): ...@@ -55,4 +54,28 @@ class EasyData2ImageNet(object):
if is_pic(img_name): if is_pic(img_name):
shutil.copyfile( shutil.copyfile(
osp.join(image_dir, img_name), osp.join(image_dir, img_name),
osp.join(new_image_dir, img_name)) osp.join(new_image_dir, img_name))
\ No newline at end of file
class EasyData2ImageNet(X2ImageNet):
"""将使用EasyData标注的分类数据集转换为ImageNet数据集。
"""
def __init__(self):
super(EasyData2ImageNet, self).__init__()
def get_json_info(self, json_file):
json_info = json.load(json_file)
json_info = json_info['labels']
return json_info
class JingLing2ImageNet(X2ImageNet):
"""将使用标注精灵标注的分类数据集转换为ImageNet数据集。
"""
def __init__(self):
super(X2ImageNet, self).__init__()
def get_json_info(self, json_file):
json_info = json.load(json_file)
json_info = json_info['outputs']['object']
return json_info
\ No newline at end of file
...@@ -17,6 +17,7 @@ from . import logging ...@@ -17,6 +17,7 @@ from . import logging
from . import utils from . import utils
from . import save from . import save
from .utils import seconds_to_hms from .utils import seconds_to_hms
from .utils import path_normalization
from .download import download from .download import download
from .download import decompress from .download import decompress
from .download import download_and_decompress from .download import download_and_decompress
...@@ -20,6 +20,7 @@ import numpy as np ...@@ -20,6 +20,7 @@ import numpy as np
import six import six
import yaml import yaml
import math import math
import platform
from . import logging from . import logging
...@@ -49,18 +50,26 @@ def get_environ_info(): ...@@ -49,18 +50,26 @@ def get_environ_info():
info['num'] = fluid.core.get_cuda_device_count() info['num'] = fluid.core.get_cuda_device_count()
return info return info
def path_normalization(path):
win_sep = "\\"
other_sep = "/"
if platform.system() == "Windows":
path = win_sep.join(path.split(other_sep))
else:
path = other_sep.join(path.split(win_sep))
return path
def parse_param_file(param_file, return_shape=True): def parse_param_file(param_file, return_shape=True):
from paddle.fluid.proto.framework_pb2 import VarType from paddle.fluid.proto.framework_pb2 import VarType
f = open(param_file, 'rb') f = open(param_file, 'rb')
version = np.fromstring(f.read(4), dtype='int32') version = np.frombuffer(f.read(4), dtype='int32')
lod_level = np.fromstring(f.read(8), dtype='int64') lod_level = np.frombuffer(f.read(8), dtype='int64')
for i in range(int(lod_level)): for i in range(int(lod_level)):
_size = np.fromstring(f.read(8), dtype='int64') _size = np.frombuffer(f.read(8), dtype='int64')
_ = f.read(_size) _ = f.read(_size)
version = np.fromstring(f.read(4), dtype='int32') version = np.frombuffer(f.read(4), dtype='int32')
tensor_desc = VarType.TensorDesc() tensor_desc = VarType.TensorDesc()
tensor_desc_size = np.fromstring(f.read(4), dtype='int32') tensor_desc_size = np.frombuffer(f.read(4), dtype='int32')
tensor_desc.ParseFromString(f.read(int(tensor_desc_size))) tensor_desc.ParseFromString(f.read(int(tensor_desc_size)))
tensor_shape = tuple(tensor_desc.dims) tensor_shape = tuple(tensor_desc.dims)
if return_shape: if return_shape:
......
import os import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import paddle.fluid as fluid
from paddlex.cls import transforms from paddlex.cls import transforms
import paddlex as pdx import paddlex as pdx
...@@ -11,13 +7,13 @@ veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz' ...@@ -11,13 +7,13 @@ veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz'
pdx.utils.download_and_decompress(veg_dataset, path='./') pdx.utils.download_and_decompress(veg_dataset, path='./')
# 定义训练和验证时的transforms # 定义训练和验证时的transforms
train_transforms = transforms.Compose( train_transforms = transforms.Compose([
[transforms.RandomCrop(crop_size=224), transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(),
transforms.Normalize()]) transforms.Normalize()
])
eval_transforms = transforms.Compose([ eval_transforms = transforms.Compose([
transforms.ResizeByShort(short_size=256), transforms.ResizeByShort(short_size=256),
transforms.CenterCrop(crop_size=224), transforms.CenterCrop(crop_size=224), transforms.Normalize()
transforms.Normalize()
]) ])
# 定义训练和验证所用的数据集 # 定义训练和验证所用的数据集
...@@ -33,26 +29,20 @@ eval_dataset = pdx.datasets.ImageNet( ...@@ -33,26 +29,20 @@ eval_dataset = pdx.datasets.ImageNet(
label_list='vegetables_cls/labels.txt', label_list='vegetables_cls/labels.txt',
transforms=eval_transforms) transforms=eval_transforms)
# PaddleX支持自定义构建优化器
step_each_epoch = train_dataset.num_samples // 32
learning_rate = fluid.layers.cosine_decay(
learning_rate=0.025, step_each_epoch=step_each_epoch, epochs=10)
optimizer = fluid.optimizer.Momentum(
learning_rate=learning_rate,
momentum=0.9,
regularization=fluid.regularizer.L2Decay(4e-5))
# 初始化模型,并进行训练 # 初始化模型,并进行训练
# 可使用VisualDL查看训练指标 # 可使用VisualDL查看训练指标
# VisualDL启动方式: visualdl --logdir output/resnet50/vdl_log --port 8001 # VisualDL启动方式: visualdl --logdir output/mobilenetv2/vdl_log --port 8001
# 浏览器打开 https://0.0.0.0:8001即可 # 浏览器打开 https://0.0.0.0:8001即可
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP # 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
model = pdx.cls.ResNet50(num_classes=len(train_dataset.labels)) model = pdx.cls.AlexNet(num_classes=len(train_dataset.labels))
# AlexNet需要指定确定的input_shape
model.fixed_input_shape = [224, 224]
model.train( model.train(
num_epochs=10, num_epochs=10,
train_dataset=train_dataset, train_dataset=train_dataset,
train_batch_size=32, train_batch_size=32,
eval_dataset=eval_dataset, eval_dataset=eval_dataset,
optimizer=optimizer, lr_decay_epochs=[4, 6, 8],
save_dir='output/resnet50', learning_rate=0.0025,
save_dir='output/alexnet',
use_vdl=True) use_vdl=True)
import os import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from paddlex.cls import transforms from paddlex.cls import transforms
import paddlex as pdx import paddlex as pdx
...@@ -11,14 +8,12 @@ pdx.utils.download_and_decompress(veg_dataset, path='./') ...@@ -11,14 +8,12 @@ pdx.utils.download_and_decompress(veg_dataset, path='./')
# 定义训练和验证时的transforms # 定义训练和验证时的transforms
train_transforms = transforms.Compose([ train_transforms = transforms.Compose([
transforms.RandomCrop(crop_size=224), transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(),
transforms.RandomHorizontalFlip(),
transforms.Normalize() transforms.Normalize()
]) ])
eval_transforms = transforms.Compose([ eval_transforms = transforms.Compose([
transforms.ResizeByShort(short_size=256), transforms.ResizeByShort(short_size=256),
transforms.CenterCrop(crop_size=224), transforms.CenterCrop(crop_size=224), transforms.Normalize()
transforms.Normalize()
]) ])
# 定义训练和验证所用的数据集 # 定义训练和验证所用的数据集
......
import os
from paddlex.cls import transforms
import paddlex as pdx
# 下载和解压蔬菜分类数据集
veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz'
pdx.utils.download_and_decompress(veg_dataset, path='./')
# 定义训练和验证时的transforms
train_transforms = transforms.Compose([
transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(),
transforms.Normalize()
])
eval_transforms = transforms.Compose([
transforms.ResizeByShort(short_size=256),
transforms.CenterCrop(crop_size=224), transforms.Normalize()
])
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls',
file_list='vegetables_cls/train_list.txt',
label_list='vegetables_cls/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls',
file_list='vegetables_cls/val_list.txt',
label_list='vegetables_cls/labels.txt',
transforms=eval_transforms)
# 初始化模型,并进行训练
# 可使用VisualDL查看训练指标
# VisualDL启动方式: visualdl --logdir output/mobilenetv2/vdl_log --port 8001
# 浏览器打开 https://0.0.0.0:8001即可
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
model = pdx.cls.MobileNetV3_small_ssld(num_classes=len(train_dataset.labels))
model.train(
num_epochs=10,
train_dataset=train_dataset,
train_batch_size=32,
eval_dataset=eval_dataset,
lr_decay_epochs=[4, 6, 8],
learning_rate=0.025,
save_dir='output/mobilenetv3_small_ssld',
use_vdl=True)
import os
from paddlex.cls import transforms
import paddlex as pdx
# 下载和解压蔬菜分类数据集
veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz'
pdx.utils.download_and_decompress(veg_dataset, path='./')
# 定义训练和验证时的transforms
train_transforms = transforms.Compose([
transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(),
transforms.Normalize()
])
eval_transforms = transforms.Compose([
transforms.ResizeByShort(short_size=256),
transforms.CenterCrop(crop_size=224), transforms.Normalize()
])
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls',
file_list='vegetables_cls/train_list.txt',
label_list='vegetables_cls/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls',
file_list='vegetables_cls/val_list.txt',
label_list='vegetables_cls/labels.txt',
transforms=eval_transforms)
# 初始化模型,并进行训练
# 可使用VisualDL查看训练指标
# VisualDL启动方式: visualdl --logdir output/mobilenetv2/vdl_log --port 8001
# 浏览器打开 https://0.0.0.0:8001即可
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
model = pdx.cls.ResNet50_vd_ssld(num_classes=len(train_dataset.labels))
model.train(
num_epochs=10,
train_dataset=train_dataset,
train_batch_size=32,
eval_dataset=eval_dataset,
lr_decay_epochs=[4, 6, 8],
learning_rate=0.025,
save_dir='output/resnet50_vd_ssld',
use_vdl=True)
import os
from paddlex.cls import transforms
import paddlex as pdx
# 下载和解压蔬菜分类数据集
veg_dataset = 'https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz'
pdx.utils.download_and_decompress(veg_dataset, path='./')
# 定义训练和验证时的transforms
train_transforms = transforms.Compose([
transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(),
transforms.Normalize()
])
eval_transforms = transforms.Compose([
transforms.ResizeByShort(short_size=256),
transforms.CenterCrop(crop_size=224), transforms.Normalize()
])
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls',
file_list='vegetables_cls/train_list.txt',
label_list='vegetables_cls/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.ImageNet(
data_dir='vegetables_cls',
file_list='vegetables_cls/val_list.txt',
label_list='vegetables_cls/labels.txt',
transforms=eval_transforms)
# 初始化模型,并进行训练
# 可使用VisualDL查看训练指标
# VisualDL启动方式: visualdl --logdir output/mobilenetv2/vdl_log --port 8001
# 浏览器打开 https://0.0.0.0:8001即可
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
model = pdx.cls.ShuffleNetV2(num_classes=len(train_dataset.labels))
model.train(
num_epochs=10,
train_dataset=train_dataset,
train_batch_size=32,
eval_dataset=eval_dataset,
lr_decay_epochs=[4, 6, 8],
learning_rate=0.025,
save_dir='output/shufflenetv2',
use_vdl=True)
import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from paddlex.det import transforms
import paddlex as pdx
# 下载和解压小度熊分拣数据集
xiaoduxiong_dataset = 'https://bj.bcebos.com/paddlex/datasets/xiaoduxiong_ins_det.tar.gz'
pdx.utils.download_and_decompress(xiaoduxiong_dataset, path='./')
# 定义训练和验证时的transforms
train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(), transforms.Normalize(),
transforms.ResizeByShort(
short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32)
])
eval_transforms = transforms.Compose([
transforms.Normalize(),
transforms.ResizeByShort(
short_size=800, max_size=1333),
transforms.Padding(coarsest_stride=32),
])
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.CocoDetection(
data_dir='xiaoduxiong_ins_det/JPEGImages',
ann_file='xiaoduxiong_ins_det/train.json',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.CocoDetection(
data_dir='xiaoduxiong_ins_det/JPEGImages',
ann_file='xiaoduxiong_ins_det/val.json',
transforms=eval_transforms)
# 初始化模型,并进行训练
# 可使用VisualDL查看训练指标
# VisualDL启动方式: visualdl --logdir output/mask_rcnn_r50_fpn/vdl_log --port 8001
# 浏览器打开 https://0.0.0.0:8001即可
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
# num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1
num_classes = len(train_dataset.labels) + 1
model = pdx.det.MaskRCNN(num_classes=num_classes, backbone='HRNet_W18')
model.train(
num_epochs=12,
train_dataset=train_dataset,
train_batch_size=1,
eval_dataset=eval_dataset,
learning_rate=0.00125,
warmup_steps=10,
lr_decay_epochs=[8, 11],
save_dir='output/mask_rcnn_hrnet_fpn',
use_vdl=True)
...@@ -11,16 +11,16 @@ pdx.utils.download_and_decompress(xiaoduxiong_dataset, path='./') ...@@ -11,16 +11,16 @@ pdx.utils.download_and_decompress(xiaoduxiong_dataset, path='./')
# 定义训练和验证时的transforms # 定义训练和验证时的transforms
train_transforms = transforms.Compose([ train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(), transforms.RandomHorizontalFlip(), transforms.Normalize(),
transforms.Normalize(), transforms.ResizeByShort(
transforms.ResizeByShort(short_size=800, max_size=1333), short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32)
transforms.Padding(coarsest_stride=32)
]) ])
eval_transforms = transforms.Compose([ eval_transforms = transforms.Compose([
transforms.Normalize(), transforms.Normalize(),
transforms.ResizeByShort(short_size=800, max_size=1333), transforms.ResizeByShort(
transforms.Padding(coarsest_stride=32) short_size=800, max_size=1333),
transforms.Padding(coarsest_stride=32),
]) ])
# 定义训练和验证所用的数据集 # 定义训练和验证所用的数据集
...@@ -41,7 +41,7 @@ eval_dataset = pdx.datasets.CocoDetection( ...@@ -41,7 +41,7 @@ eval_dataset = pdx.datasets.CocoDetection(
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP # 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
# num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1 # num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1
num_classes = len(train_dataset.labels) + 1 num_classes = len(train_dataset.labels) + 1
model = pdx.det.MaskRCNN(num_classes=num_classes) model = pdx.det.MaskRCNN(num_classes=num_classes, backbone='ResNet50_vd')
model.train( model.train(
num_epochs=12, num_epochs=12,
train_dataset=train_dataset, train_dataset=train_dataset,
......
import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from paddlex.det import transforms
import paddlex as pdx
# 下载和解压昆虫检测数据集
insect_dataset = 'https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz'
pdx.utils.download_and_decompress(insect_dataset, path='./')
# 定义训练和验证时的transforms
train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(), transforms.Normalize(),
transforms.ResizeByShort(
short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32)
])
eval_transforms = transforms.Compose([
transforms.Normalize(),
transforms.ResizeByShort(
short_size=800, max_size=1333),
transforms.Padding(coarsest_stride=32),
])
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det',
file_list='insect_det/train_list.txt',
label_list='insect_det/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det',
file_list='insect_det/val_list.txt',
label_list='insect_det/labels.txt',
transforms=eval_transforms)
# 初始化模型,并进行训练
# 可使用VisualDL查看训练指标
# VisualDL启动方式: visualdl --logdir output/faster_rcnn_r50_fpn/vdl_log --port 8001
# 浏览器打开 https://0.0.0.0:8001即可
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
# num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1
num_classes = len(train_dataset.labels) + 1
model = pdx.det.FasterRCNN(num_classes=num_classes, backbone='HRNet_W18')
model.train(
num_epochs=12,
train_dataset=train_dataset,
train_batch_size=2,
eval_dataset=eval_dataset,
learning_rate=0.0025,
lr_decay_epochs=[8, 11],
save_dir='output/faster_rcnn_hrnet_fpn',
use_vdl=True)
import os import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from paddlex.det import transforms from paddlex.det import transforms
import paddlex as pdx import paddlex as pdx
...@@ -11,18 +8,17 @@ pdx.utils.download_and_decompress(insect_dataset, path='./') ...@@ -11,18 +8,17 @@ pdx.utils.download_and_decompress(insect_dataset, path='./')
# 定义训练和验证时的transforms # 定义训练和验证时的transforms
train_transforms = transforms.Compose([ train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(), transforms.RandomHorizontalFlip(), transforms.Normalize(),
transforms.Normalize(), transforms.ResizeByShort(
transforms.ResizeByShort(short_size=800, max_size=1333), short_size=800, max_size=1333), transforms.Padding(coarsest_stride=32)
transforms.Padding(coarsest_stride=32)
]) ])
eval_transforms = transforms.Compose([ eval_transforms = transforms.Compose([
transforms.Normalize(), transforms.Normalize(),
transforms.ResizeByShort(short_size=800, max_size=1333), transforms.ResizeByShort(
short_size=800, max_size=1333),
transforms.Padding(coarsest_stride=32), transforms.Padding(coarsest_stride=32),
]) ])
# 定义训练和验证所用的数据集 # 定义训练和验证所用的数据集
train_dataset = pdx.datasets.VOCDetection( train_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det', data_dir='insect_det',
...@@ -43,7 +39,7 @@ eval_dataset = pdx.datasets.VOCDetection( ...@@ -43,7 +39,7 @@ eval_dataset = pdx.datasets.VOCDetection(
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP # 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
# num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1 # num_classes 需要设置为包含背景类的类别数,即: 目标类别数量 + 1
num_classes = len(train_dataset.labels) + 1 num_classes = len(train_dataset.labels) + 1
model = pdx.det.FasterRCNN(num_classes=num_classes) model = pdx.det.FasterRCNN(num_classes=num_classes, backbone='ResNet50_vd')
model.train( model.train(
num_epochs=12, num_epochs=12,
train_dataset=train_dataset, train_dataset=train_dataset,
......
import os import os
# 选择使用0号卡
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from paddlex.det import transforms from paddlex.det import transforms
import paddlex as pdx import paddlex as pdx
...@@ -15,13 +12,15 @@ train_transforms = transforms.Compose([ ...@@ -15,13 +12,15 @@ train_transforms = transforms.Compose([
transforms.RandomDistort(), transforms.RandomDistort(),
transforms.RandomExpand(), transforms.RandomExpand(),
transforms.RandomCrop(), transforms.RandomCrop(),
transforms.Resize(target_size=608, interp='RANDOM'), transforms.Resize(
target_size=608, interp='RANDOM'),
transforms.RandomHorizontalFlip(), transforms.RandomHorizontalFlip(),
transforms.Normalize(), transforms.Normalize(),
]) ])
eval_transforms = transforms.Compose([ eval_transforms = transforms.Compose([
transforms.Resize(target_size=608, interp='CUBIC'), transforms.Resize(
target_size=608, interp='CUBIC'),
transforms.Normalize(), transforms.Normalize(),
]) ])
......
import os
from paddlex.det import transforms
import paddlex as pdx
# 下载和解压昆虫检测数据集
insect_dataset = 'https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz'
pdx.utils.download_and_decompress(insect_dataset, path='./')
# 定义训练和验证时的transforms
train_transforms = transforms.Compose([
transforms.MixupImage(mixup_epoch=250),
transforms.RandomDistort(),
transforms.RandomExpand(),
transforms.RandomCrop(),
transforms.Resize(
target_size=608, interp='RANDOM'),
transforms.RandomHorizontalFlip(),
transforms.Normalize(),
])
eval_transforms = transforms.Compose([
transforms.Resize(
target_size=608, interp='CUBIC'),
transforms.Normalize(),
])
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det',
file_list='insect_det/train_list.txt',
label_list='insect_det/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det',
file_list='insect_det/val_list.txt',
label_list='insect_det/labels.txt',
transforms=eval_transforms)
# 初始化模型,并进行训练
# 可使用VisualDL查看训练指标
# VisualDL启动方式: visualdl --logdir output/yolov3_darknet/vdl_log --port 8001
# 浏览器打开 https://0.0.0.0:8001即可
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
num_classes = len(train_dataset.labels)
model = pdx.det.YOLOv3(num_classes=num_classes, backbone='MobileNetV1')
model.train(
num_epochs=270,
train_dataset=train_dataset,
train_batch_size=8,
eval_dataset=eval_dataset,
learning_rate=0.000125,
lr_decay_epochs=[210, 240],
save_dir='output/yolov3_mobilenetv1',
use_vdl=True)
import os
from paddlex.det import transforms
import paddlex as pdx
# 下载和解压昆虫检测数据集
insect_dataset = 'https://bj.bcebos.com/paddlex/datasets/insect_det.tar.gz'
pdx.utils.download_and_decompress(insect_dataset, path='./')
# 定义训练和验证时的transforms
train_transforms = transforms.Compose([
transforms.MixupImage(mixup_epoch=250),
transforms.RandomDistort(),
transforms.RandomExpand(),
transforms.RandomCrop(),
transforms.Resize(
target_size=608, interp='RANDOM'),
transforms.RandomHorizontalFlip(),
transforms.Normalize(),
])
eval_transforms = transforms.Compose([
transforms.Resize(
target_size=608, interp='CUBIC'),
transforms.Normalize(),
])
# 定义训练和验证所用的数据集
train_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det',
file_list='insect_det/train_list.txt',
label_list='insect_det/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.VOCDetection(
data_dir='insect_det',
file_list='insect_det/val_list.txt',
label_list='insect_det/labels.txt',
transforms=eval_transforms)
# 初始化模型,并进行训练
# 可使用VisualDL查看训练指标
# VisualDL启动方式: visualdl --logdir output/yolov3_darknet/vdl_log --port 8001
# 浏览器打开 https://0.0.0.0:8001即可
# 其中0.0.0.0为本机访问,如为远程服务, 改成相应机器IP
num_classes = len(train_dataset.labels)
model = pdx.det.YOLOv3(num_classes=num_classes, backbone='MobileNetV3_large')
model.train(
num_epochs=270,
train_dataset=train_dataset,
train_batch_size=8,
eval_dataset=eval_dataset,
learning_rate=0.000125,
lr_decay_epochs=[210, 240],
save_dir='output/yolov3_mobilenetv3',
use_vdl=True)
...@@ -11,14 +11,14 @@ pdx.utils.download_and_decompress(optic_dataset, path='./') ...@@ -11,14 +11,14 @@ pdx.utils.download_and_decompress(optic_dataset, path='./')
# 定义训练和验证时的transforms # 定义训练和验证时的transforms
train_transforms = transforms.Compose([ train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(), transforms.RandomHorizontalFlip(), transforms.ResizeRangeScaling(),
transforms.Resize(target_size=512), transforms.RandomPaddingCrop(crop_size=512), transforms.Normalize()
transforms.RandomPaddingCrop(crop_size=500),
transforms.Normalize()
]) ])
eval_transforms = transforms.Compose( eval_transforms = transforms.Compose([
[transforms.Resize(512), transforms.Normalize()]) transforms.ResizeByLong(long_size=512), transforms.Padding(target_size=512),
transforms.Normalize()
])
# 定义训练和验证所用的数据集 # 定义训练和验证所用的数据集
train_dataset = pdx.datasets.SegDataset( train_dataset = pdx.datasets.SegDataset(
...@@ -46,5 +46,5 @@ model.train( ...@@ -46,5 +46,5 @@ model.train(
train_batch_size=4, train_batch_size=4,
eval_dataset=eval_dataset, eval_dataset=eval_dataset,
learning_rate=0.01, learning_rate=0.01,
save_dir='output/deeplab', save_dir='output/deeplabv3p_mobilenetv2',
use_vdl=True) use_vdl=True)
...@@ -11,9 +11,15 @@ pdx.utils.download_and_decompress(optic_dataset, path='./') ...@@ -11,9 +11,15 @@ pdx.utils.download_and_decompress(optic_dataset, path='./')
# 定义训练和验证时的transforms # 定义训练和验证时的transforms
# API说明: https://paddlex.readthedocs.io/zh_CN/latest/apis/transforms/seg_transforms.html#composedsegtransforms # API说明: https://paddlex.readthedocs.io/zh_CN/latest/apis/transforms/seg_transforms.html#composedsegtransforms
train_transforms = transforms.ComposedSegTransforms( train_transforms = transforms.Compose([
mode='train', train_crop_size=[769, 769]) transforms.RandomHorizontalFlip(), transforms.ResizeRangeScaling(),
eval_transforms = transforms.ComposedSegTransforms(mode='eval') transforms.RandomPaddingCrop(crop_size=512), transforms.Normalize()
])
eval_transforms = transforms.Compose([
transforms.ResizeByLong(long_size=512), transforms.Padding(target_size=512),
transforms.Normalize()
])
# 定义训练和验证所用的数据集 # 定义训练和验证所用的数据集
# API说明: https://paddlex.readthedocs.io/zh_CN/latest/apis/datasets/semantic_segmentation.html#segdataset # API说明: https://paddlex.readthedocs.io/zh_CN/latest/apis/datasets/semantic_segmentation.html#segdataset
......
...@@ -16,8 +16,8 @@ train_transforms = transforms.Compose([ ...@@ -16,8 +16,8 @@ train_transforms = transforms.Compose([
]) ])
eval_transforms = transforms.Compose([ eval_transforms = transforms.Compose([
transforms.ResizeByLong(long_size=512), transforms.ResizeByLong(long_size=512), transforms.Padding(target_size=512),
transforms.Padding(target_size=512), transforms.Normalize() transforms.Normalize()
]) ])
# 定义训练和验证所用的数据集 # 定义训练和验证所用的数据集
......
...@@ -11,15 +11,12 @@ pdx.utils.download_and_decompress(optic_dataset, path='./') ...@@ -11,15 +11,12 @@ pdx.utils.download_and_decompress(optic_dataset, path='./')
# 定义训练和验证时的transforms # 定义训练和验证时的transforms
train_transforms = transforms.Compose([ train_transforms = transforms.Compose([
transforms.RandomHorizontalFlip(), transforms.RandomHorizontalFlip(), transforms.ResizeRangeScaling(),
transforms.ResizeRangeScaling(), transforms.RandomPaddingCrop(crop_size=512), transforms.Normalize()
transforms.RandomPaddingCrop(crop_size=512),
transforms.Normalize()
]) ])
eval_transforms = transforms.Compose([ eval_transforms = transforms.Compose([
transforms.ResizeByLong(long_size=512), transforms.ResizeByLong(long_size=512), transforms.Padding(target_size=512),
transforms.Padding(target_size=512),
transforms.Normalize() transforms.Normalize()
]) ])
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册