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

Merge pull request #1346 from TingquanGao/dev/update_docs

Dev/update docs
# 图像分类任务数据集说明
本文档将介绍 PaddleClas 所使用的数据集格式,以及图像分类任务的主要数据集,包括 ImageNet1k 和 flowers102 的介绍。
---
## 1. 数据集格式说明
PaddleClas 使用 `txt` 格式文件指定训练集和测试集,以 `ImageNet1k` 数据集为例,其中 `train_list.txt``val_list.txt` 的格式形如:
```shell
# 每一行采用"空格"分隔图像路径与标注
# 下面是train_list.txt中的格式样例
train/n01440764/n01440764_10026.JPEG 0
...
# 下面是val_list.txt中的格式样例
val/ILSVRC2012_val_00000001.JPEG 65
...
```
## 2. ImageNet1k 数据集
数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注|
:------:|:---------------:|:---------------------:|:-----------:|:-----------:
[ImageNet1k](http://www.image-net.org/challenges/LSVRC/2012/)|1.2M| 50k | 1000 |
从官方下载数据后,按如下组织数据
```bash
PaddleClas/dataset/ILSVRC2012/
|_ train/
| |_ n01440764
| | |_ n01440764_10026.JPEG
| | |_ ...
| |_ ...
| |
| |_ n15075141
| |_ ...
| |_ n15075141_9993.JPEG
|_ val/
| |_ ILSVRC2012_val_00000001.JPEG
| |_ ...
| |_ ILSVRC2012_val_00050000.JPEG
|_ train_list.txt
|_ val_list.txt
```
## 3. Flowers102 数据集
数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注|
:------:|:---------------:|:---------------------:|:-----------:|:-----------:
[flowers102](https://www.robots.ox.ac.uk/~vgg/data/flowers/102/)|1k | 6k | 102 |
将下载的数据解压后,可以看到以下目录
```shell
jpg/
setid.mat
imagelabels.mat
```
将以上文件放置在 `PaddleClas/dataset/flowers102/`
通过运行 `generate_flowers102_list.py` 生成 `train_list.txt``val_list.txt`
```shell
python generate_flowers102_list.py jpg train > train_list.txt
python generate_flowers102_list.py jpg valid > val_list.txt
```
按照如下结构组织数据:
```shell
PaddleClas/dataset/flowers102/
|_ jpg/
| |_ image_03601.jpg
| |_ ...
| |_ image_02355.jpg
|_ train_list.txt
|_ val_list.txt
```
# 服务器端C++预测
本教程将介绍在服务器端部署PaddleClas模型的详细步骤。
---
## 1. 准备环境
- Linux 环境,推荐使用 docker。
- Windows 环境,目前支持基于 `Visual Studio 2019 Community` 进行编译;此外,如果您希望通过生成 `sln解决方案` 的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681)
* 该文档主要介绍基于 Linux 环境下的 PaddleClas C++ 预测流程,如果需要在 Windows 环境下使用预测库进行 C++ 预测,具体编译方法请参考 [Windows下编译教程](./docs/windows_vs2019_build.md)
### 1.1 编译opencv库
* 首先需要从 opencv 官网上下载在 Linux 环境下源码编译的包,以 3.4.7 版本为例,下载及解压缩命令如下:
```
wget https://github.com/opencv/opencv/archive/3.4.7.tar.gz
tar -xvf 3.4.7.tar.gz
```
执行完成上述命令后,会在当前目录下生成 `opencv-3.4.7/` 的目录。
* 编译 opencv,首先设置 opencv 源码路径(`root_path`)以及安装路径(`install_path`),`root_path` 为下载的 opencv 源码路径,`install_path` 为 opencv 的安装路径。在本例中,源码路径即为当前目录下的 `opencv-3.4.7/`
```shell
cd ./opencv-3.4.7
export root_path=$PWD
export install_path=${root_path}/opencv3
```
* 然后在 opencv 源码路径下,按照下面的命令进行编译:
```shell
rm -rf build
mkdir build
cd build
cmake .. \
-DCMAKE_INSTALL_PREFIX=${install_path} \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DWITH_IPP=OFF \
-DBUILD_IPP_IW=OFF \
-DWITH_LAPACK=OFF \
-DWITH_EIGEN=OFF \
-DCMAKE_INSTALL_LIBDIR=lib64 \
-DWITH_ZLIB=ON \
-DBUILD_ZLIB=ON \
-DWITH_JPEG=ON \
-DBUILD_JPEG=ON \
-DWITH_PNG=ON \
-DBUILD_PNG=ON \
-DWITH_TIFF=ON \
-DBUILD_TIFF=ON
make -j
make install
```
* 执行完成上述命令后,会生成 opencv 头文件和库文件,用于后面的 PaddleClas 代码编译。
以 opencv3.4.7 版本为例,最终在安装路径下的文件结构如下所示。**注意**:不同的 opencv 版本,下述的文件结构可能不同。
```
opencv3/
|-- bin
|-- include
|-- lib64
|-- share
```
### 1.2 获取 Paddle 预测库
* 有 2 种方式获取 Paddle 预测库,下面进行详细介绍。
#### 1.2.1 预测库源码编译
如果希望获取最新预测库特性,可以从 GitHub 上克隆 Paddle 最新代码,从源码编译预测库。对于不同平台的编译流程,请参考[Paddle预测库官网](https://paddleinference.paddlepaddle.org.cn/v2.1/user_guides/source_compile.html)的说明。编译示例如下:
1. 使用Git获取源代码:
```shell
git clone https://github.com/PaddlePaddle/Paddle.git
cd Paddle
```
2. 进入 `Paddle` 目录后,开始进行编译:
```shell
rm -rf build
mkdir build
cd build
cmake .. \
-DWITH_CONTRIB=OFF \
-DWITH_MKL=ON \
-DWITH_MKLDNN=ON \
-DWITH_TESTING=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DWITH_INFERENCE_API_TEST=OFF \
-DON_INFER=ON \
-DWITH_PYTHON=ON
make -j
make inference_lib_dist
```
关于编译参数选项可以参考 Paddle C++ 预测库官网:[编译选项表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/install/Tables.html#bianyixuanxiangbiao)
3. 编译完成之后,可以在 `./build/paddle_inference_install_dir/` 文件下看到以下文件及目录:
```
build/paddle_inference_install_dir/
|-- CMakeCache.txt
|-- paddle
|-- third_party
|-- version.txt
```
#### 1.2.2 直接下载安装
[Paddle预测库官网](https://paddleinference.paddlepaddle.org.cn/v2.1/user_guides/download_lib.html#c) 上提供了不同版本的 Paddle 预测库,包括多个操作系统平台和GPU、CPU等多个硬件平台的预编译库,可以在官网查找并选择合适的预测库版本进行下载,建议选择 `2.1.1` 版本。
**注意**:在选择预测库时,所选预测库版本需要与后续编译选项一致:
* CPU 预测库仅可用于 GPU 预测,具体又分为 `mkl``openblas`,分别对应其低层实现基于 `MKL` 数学运算库 和 `OpenBLAS` 数学运算库;
* GPU 预测库支持 GPU 预测和 CPU 预测,其 GPU 预测功能底层实现基于 CUDA、cuDNN,CPU 预测功能底层基于 `MKL` 实现。
`manylinux_cuda10.2_cudnn8.1_avx_mkl_trt7_gcc8.2``2.1.1` 版本为例,可使用下述命令下载并解压:
```shell
wget https://paddle-inference-lib.bj.bcebos.com/2.1.1-gpu-cuda10.2-cudnn8.1-mkl-gcc8.2/paddle_inference.tgz
tar -xf paddle_inference.tgz
```
上述命令会在当前目录下生成 `paddle_inference/` 目录。
## 2. 开始编译
<a name="2.1"></a>
### 2.1 编译 PaddleClas C++ 预测 demo
编译命令如下,其中 Paddle C++ 预测库、OpenCV 等依赖库的路径需要根据机器上的实际位置进行修改。
```shell
sh tools/build_demo.sh
```
具体地,`tools/build_demo.sh`中内容如下:
```shell
OpenCV_DIR=path/to/opencv
PADDLE_LIB_DIR=path/to/paddle
CUDA_LIB_DIR=path/to/cuda
CUDNN_LIB_DIR=path/to/cudnn
TENSORRT_LIB_DIR=path/to/tensorrt
CONFIG_LIB_PATH=path/to/config/library
CLS_LIB_PATH=path/to/cls/library
CMP_STATIC=ON
BUILD_DIR=build
rm -rf ${BUILD_DIR}
mkdir ${BUILD_DIR}
cd ${BUILD_DIR}
cmake .. \
-DWITH_MKL=ON \
-DWITH_GPU=ON \
-DWITH_TENSORRT=OFF \
-DWITH_STATIC_LIB=OFF \
-DOpenCV_DIR=${OpenCV_DIR} \
-DPADDLE_LIB=${PADDLE_LIB_DIR} \
-DCUDA_LIB=${CUDA_LIB_DIR} \
-DCUDNN_LIB=${CUDNN_LIB_DIR} \
-DCONFIG_LIB=${CONFIG_LIB_PATH} \
-DCLS_LIB=${CLS_LIB_PATH} \
-DCMP_STATIC=OFF \
make -j
```
上述命令中,各个编译选项的具体说明如下:
* `DWITH_MKL`:是否使用 MKL 数学运算库,默认为 `ON`,注意需要与下载的预测库版本一致。如为 `OpenBLAS` 版本预测库,则需设置为 `OFF`
* `DWITH_GPU`:使用使用 GPU 预测库,默认为 `OFF`,当下载预测库版本为 GPU 预测库时,可置为 `ON`,同时请设置 `DCUDA_LIB``DCUDNN_LIB`,否则请设置为 `OFF`
* `DWITH_TENSORRT`:是否使用 TensorRT,默认为 `OFF`,当 `DWITH_GPU` 设置为 `ON` 时有效,同时请设置 `DTENSORRT_LIB`
* `DWITH_STATIC_LIB`:是否使用 Paddle 预测库中的静态链接库,默认为 `OFF`
* `DOpenCV_DIR`:OpenCV 编译库的路径,本例中为 `opencv-3.4.7/opencv3/share/OpenCV`,注意该路径下需要有 `OpenCVConfig.cmake` 文件;
* `DPADDLE_LIB`:Paddle 预测库路径,一般使用下载并解压的预编译库路径 `paddle_inference` 即可,或编译生成的预测库的路径 `build/paddle_inference_install_dir`,注意该路径下需要有 `paddle``third_party` 两个子路径;
* `DCUDA_LIB`:CUDA 库路径,当 `DWITH_GPU` 设置为 `ON` 时有效,在 docker 中通常为 `/usr/local/cuda/lib64`
* `DCUDNN_LIB`:cuDNN 库路径,当 `DWITH_GPU` 设置为 `ON` 时有效,在 docker 中通常为 `/usr/lib/x86_64-linux-gnu/`
* `DTENSORRT_LIB`:TensorRT 库路径,当 `DWITH_GPU``DUSE_TENSORRT` 均设置为 `ON` 时有效,在 dokcer 中通常为 `/usr/local/TensorRT6-cuda10.0-cudnn7/`
* `DCONFIG_LIB`:如需使用已编译好的 `config lib`,请设置为 `config lib` 的路径,否则请删除该选项;
* `DCLS_LIB`:如需使用已编译好的 `cls lib`,请设置为 `cls lib` 的路径,否则请删除该选项;
* `DCMP_STATIC`:是否将 `config lib``cls lib` 编译为静态链接库,默认为 `ON`,如需编译为动态链接库,请设置为 `OFF`
在执行上述命令,编译完成之后,会在当前路径下生成 `build` 目录,其中有可执行文件 `clas_system`。并且,如未设置 `DCONFIG_LIB``DCLS_LIB`,则会在 `.\lib\` 路径下生成 `config lib` 和 `cls lib` 两个库文件,根据 `DCMP_STATIC` 的设置,两个库文件将被编译为静态链接库(`libconfig.a`、`libcls.a`)或动态链接库(`libconfig.so`、`libcls.so`)。
### 2.2 编译 config lib 预测库与 cls lib 预测库
除了可以直接编译 demo,也同样可以仅编译 config lib 和 cls lib 预测库,只需运行如下命令:
```shell
sh tools/build_lib.sh
```
具体地,`tools/build_lib.sh`中内容如下:
```shell
OpenCV_DIR=path/to/opencv
PADDLE_LIB_DIR=path/to/paddle
BUILD_DIR=./lib/build
rm -rf ${BUILD_DIR}
mkdir ${BUILD_DIR}
cd ${BUILD_DIR}
cmake .. \
-DOpenCV_DIR=${OpenCV_DIR} \
-DPADDLE_LIB=${PADDLE_LIB_DIR} \
-DCMP_STATIC=ON \
make
```
上述命令中,各个编译选项的具体说明如下:
* `DOpenCV_DIR`:OpenCV 编译库的路径,本例中为 `opencv-3.4.7/opencv3/share/OpenCV`,注意该路径下需要有 `OpenCVConfig.cmake` 文件;
* `DPADDLE_LIB`:Paddle 预测库路径,一般使用下载并解压的预编译库路径 `paddle_inference` 即可,或编译生成的预测库的路径 `build/paddle_inference_install_dir`,注意该路径下需要有 `paddle` 和 `third_party` 两个子路径;
* `DCMP_STATIC`:是否将 `config lib` 和 `cls lib` 编译为静态链接库(`.a`),默认为 `ON`,如需编译为动态链接库(`.so`),请设置为 `OFF`。
执行上述命令后,将在目录 `./lib/` 下生成 `config lib` 和 `cls lib` 的动态链接库(`libcls.so` 和 `libconfig.so`)或静态链接库(`libcls.a` 和 `libconfig.a`)。在[编译 PaddleClas C++ 预测 demo](#2.1)中,可以通过指定编译选项 `DCLS_LIB` 和 `DCONFIG_LIB` 指定已有链接库的路径,链接库同样也可用于二次开发。
## 3. 运行 demo
### 3.1 准备 inference model
首先需要准备 inference model,关于将模型导出为 inference model 的具体步骤,可以参考[模型导出](../../docs/zh_CN/tutorials/getting_started.md#4-使用inference模型进行模型推理)文档。假设导出的预测模型文件放在`./inference`目录下,则目录结构如下。
```
inference/
|--inference.pdmodel
|--inference.pdiparams
```
**注意**:上述文件中,`cls_infer.pdmodel` 文件存储了模型网络结构信息,`cls_infer.pdiparams` 文件存储了模型参数权重信息。在运行预测时,注意两个文件的路径需要分别设置为配置文件 `tools/config.txt` 中的字段 `cls_model_path` 和 `cls_params_path` 的值。
### 3.2 运行 demo
首先修改 `tools/config.txt` 中对应字段:
* use_gpu:是否使用GPU;
* gpu_id:使用的GPU卡号;
* gpu_mem:显存;
* cpu_math_library_num_threads:底层科学计算库所用线程的数量;
* use_mkldnn:是否使用MKLDNN加速;
* use_tensorrt: 是否使用tensorRT进行加速;
* use_fp16:是否使用半精度浮点数进行计算,该选项仅在use_tensorrt为true时有效;
* cls_model_path:预测模型结构文件路径;
* cls_params_path:预测模型参数文件路径;
* resize_short_size:预处理时图像缩放大小;
* crop_size:预处理时图像裁剪后的大小。
然后修改`tools/run.sh`:
* `./build/clas_system ./tools/config.txt ./docs/imgs/ILSVRC2012_val_00000666.JPEG`
* 上述命令中分别为:编译得到的可执行文件 `clas_system`;运行时的配置文件 `config.txt`;待预测的图像。
* 最后执行以下命令,完成对一幅图像的分类。
```shell
sh tools/run.sh
```
* 最终屏幕上会输出结果,如下图所示。
<div align="center">
<img src="./docs/imgs/cpp_infer_result.png" width="600">
</div>
其中`class id`表示置信度最高的类别对应的id,score表示图片属于该类别的概率。
# 基于 Visual Studio 2019 Community CMake 编译指南
PaddleClas 在 Windows 平台下基于 `Visual Studio 2019 Community` 进行了测试。微软从 `Visual Studio 2017` 开始即支持直接管理 `CMake` 跨平台编译项目,但是直到 `2019` 版才提供了稳定和完全的支持,所以如果你想使用 CMake 管理项目编译构建,我们推荐使用 `Visual Studio 2019`。如果您希望通过生成 `sln解决方案` 的方式进行编译,可以参考该文档:[https://zhuanlan.zhihu.com/p/145446681](https://zhuanlan.zhihu.com/p/145446681)
## 1. 前置条件
* Visual Studio 2019
* CUDA 9.0 / CUDA 10.0,cudnn 7.6+ (仅在使用GPU版本的预测库时需要)
* CMake 3.0+
请确保系统已经正确安装并配置好上述基本软件,其中:
* 在安装 `Visual Studio 2019` 时,`工作负载` 需要勾选 `使用C++的桌面开发`
* CUDA需要正确安装并设置系统环境变量;
* CMake需要正确安装并将路径添加到系统环境变量中。
以下示例基于 `Visual Studio 2019 Community` 版本,以工作目录为 `D:\projects` 进行演示。
### 1.1 下载 PaddlePaddle C++ 预测库 paddle_inference_install_dir
PaddlePaddle C++ 预测库针对不同的 `CPU ``CUDA` 版本提供了不同的预编译版本,请根据实际情况下载: [C++预测库下载列表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/windows_cpp_inference.html),建议选择 `2.1.1` 版本。
**注意**:在选择预测库时,所选预测库版本需要与后续编译选项一致:
* CPU 预测库仅可用于 GPU 预测,具体又分为 `mkl``openblas`,分别对应其低层实现基于 `MKL` 数学运算库 和 `OpenBLAS` 数学运算库;
* GPU 预测库支持 GPU 预测和 CPU 预测,其 GPU 预测功能底层实现基于 CUDA、cuDNN,CPU 预测功能底层基于 `MKL` 实现。
下载并解压后,目录 `D:\projects\paddle_inference_install_dir` 包含内容为:
```
paddle_inference_install_dir
├── paddle # paddle核心库和头文件
├── third_party # 第三方依赖库和头文件
└── version.txt # 版本和编译信息
```
**注意**:需要将 `Paddle预测库` 的路径(`D:\projects\paddle_inference_install_dir\paddle\lib`)添加到系统环境变量 `Path` 中。
### 1.2 安装配置 OpenCV
1. 在 OpenCV 官网下载适用于 Windows 平台的 3.4.6 版本,[下载地址](https://sourceforge.net/projects/opencvlibrary/files/3.4.6/opencv-3.4.6-vc14_vc15.exe/download)
2. 运行下载的可执行文件,将 OpenCV 解压至指定目录,如 `D:\projects\opencv`
3. 配置环境变量,如下流程所示:
* 此电脑(我的电脑)-> 属性 -> 高级系统设置 -> 环境变量;
* 在系统变量中找到 Path(如没有,自行创建),并双击编辑;
* 新建,将 OpenCV 路径填入并保存,如 `D:\projects\opencv\build\x64\vc14\bin`
<a name="2"></a>
## 2. 使用 Visual Studio 2019 编译
1. 打开 Visual Studio 2019 Community,点击 `继续但无需代码`
![step2](../../images/inference_deployment/vs2019_step1.png)
2. 点击:`文件`->`打开`->`CMake`
![step2.1](../../images/inference_deployment/vs2019_step2.png)
选择项目代码所在路径,并打开`CMakeList.txt`
![step2.2](../../images/inference_deployment/vs2019_step3.png)
3. 点击:`项目`->`CMake设置`
![step3](../../images/inference_deployment/vs2019_step4.png)
4. 请设置以下参数的值
| 名称 | 值 | 保存到 JSON |
| ----------------------------- | ------------------ | ----------- |
| CMAKE_BACKWARDS_COMPATIBILITY | 3.17 | [√] |
| CMAKE_BUILD_TYPE | RelWithDebInfo | [√] |
| CUDA_LIB | CUDA的库路径 | [√] |
| CUDNN_LIB | CUDNN的库路径 | [√] |
| OpenCV_DIR | OpenCV的安装路径 | [√] |
| PADDLE_LIB | Paddle预测库的路径 | [√] |
| WITH_GPU | [√] | [√] |
| WITH_MKL | [√] | [√] |
| WITH_STATIC_LIB | [√] | [√] |
除上述选项外,还有以下两个选项可依据具体情况设置:
* `DCONFIG_LIB`:如需使用已编译好的 `config lib`,请设置为 `config lib` 的路径,否则请删除该选项;
* `DCLS_LIB`:如需使用已编译好的 `cls lib`,请设置为 `cls lib` 的路径,否则请删除该选项;
**注意**
* `CMAKE_BACKWARDS_COMPATIBILITY` 的值请根据自己 `cmake` 版本设置,`cmake` 版本可以通过命令:`cmake --version` 查询;
* `CUDA_LIB``CUDNN_LIB` 的值仅需在使用**GPU版本**预测库时指定,其中CUDA库版本尽量对齐,**使用9.0、10.0版本,不使用9.2、10.1等版本CUDA库**
* 在设置 `CUDA_LIB``CUDNN_LIB``OPENCV_DIR``PADDLE_LIB` 时,点击 `浏览`,分别设置相应的路径;
* `CUDA_LIB``CUDNN_LIB`:该路径取决于CUDA与CUDNN的安装位置。
* `OpenCV_DIR`:该路径下需要有`.cmake`文件,一般为`opencv/build/`
* `PADDLE_LIB`:该路径下需要有`CMakeCache.txt`文件,一般为`paddle_inference_install_dir/`
* 在使用 `CPU` 版预测库时,请不要勾选 `WITH_GPU` - `保存到 JSON`
![step4](../../images/inference_deployment/vs2019_step5.png)
设置完成后,点击上图中 `保存并生成CMake缓存以加载变量`
5. 点击`生成`->`全部生成`
![step6](../../images/inference_deployment/vs2019_step6.png)
在编译完成后,会生成可执行文件 `clas_system.exe`。并且,如未设置 `DCONFIG_LIB``DCLS_LIB`,则会在 `.\lib\` 目录下生成 `config lib` 和 `cls lib` 两个静态链接库文件(`libconfig.a`、`libcls.a`)。类似地,你也可以仅编译生成 `config lib` 和 `cls lib` 两个静态链接库文件,只需打开路径为 `D:\projects\PaddleClas\deploy\cpp\lib\CMakeList.txt` 的 `CMake` 文件并进行编译即可,具体参考[使用 Visual Studio 2019 编译](#2),完成编译后,同样可在 `.\lib\` 目录下生成静态链接库文件,静态链接库文件可用于二次开发。
## 3. 预测
### 3.1 准备 inference model
首先需要准备 inference model,关于将模型导出为 inference model 的具体步骤,可以参考[模型导出](../../docs/zh_CN/tutorials/getting_started.md#4-使用inference模型进行模型推理)文档。假设导出的预测模型文件放在`./inference`目录下,则目录结构如下。
```
inference/
|--inference.pdmodel
|--inference.pdiparams
```
**注意**:上述文件中,`cls_infer.pdmodel` 文件存储了模型网络结构信息,`cls_infer.pdiparams` 文件存储了模型参数权重信息。在运行预测时,注意两个文件的路径需要分别设置为配置文件 `tools/config.txt` 中的字段 `cls_model_path``cls_params_path` 的值。
### 3.2 运行预测
首先修改 `tools/config.txt` 中对应字段:
* use_gpu:是否使用GPU;
* gpu_id:使用的GPU卡号;
* gpu_mem:显存;
* cpu_math_library_num_threads:底层科学计算库所用线程的数量;
* use_mkldnn:是否使用MKLDNN加速;
* use_tensorrt: 是否使用tensorRT进行加速;
* use_fp16:是否使用半精度浮点数进行计算,该选项仅在use_tensorrt为true时有效;
* cls_model_path:预测模型结构文件路径;
* cls_params_path:预测模型参数文件路径;
* resize_short_size:预处理时图像缩放大小;
* crop_size:预处理时图像裁剪后的大小。
`Visual Studio 2019` 编译产出的可执行文件 `clas_system.exe``out\build\x64-Release` 目录下,打开 `cmd`,并切换到该目录:
```shell
cd D:\projects\PaddleClas\deploy\cpp\out\build\x64-Release
```
可执行文件 `clas_system.exe` 即为编译产出的的预测程序,运行下述命令即可执行预测:
```shell
.\clas_system.exe D:\projects\PaddleClas\deploy\cpp\tools\config.txt .\docs\ILSVRC2012_val_00008306.JPEG
```
上述命令中,第一个参数(`D:\projects\PaddleClas\deploy\cpp\tools\config.txt`)为配置文件路径,第二个参数(`.\docs\ILSVRC2012_val_00008306.JPEG`)为需要预测的图片路径。
注意,需要在配置文件中正确设置预测参数,包括所用模型文件的路径(`cls_model_path``cls_params_path`)。
### 4. 注意事项
* 在 Windows 下的终端中执行文件 exe 时,可能会发生乱码的现象,此时需要在终端中输入 `CHCP 65001`,将终端的编码方式由 GBK 编码(默认)改为 UTF-8 编码,更加具体的解释可以参考这篇博客:[https://blog.csdn.net/qq_35038153/article/details/78430359](https://blog.csdn.net/qq_35038153/article/details/78430359)
* 如果需要使用 CPU 预测,PaddlePaddle 在 Windows 上仅支持 avx 的 CPU 预测,目前不支持 noavx 的 CPU 预测;
* 在使用生成的 `clas_system.exe` 进行预测时,如提示 `由于找不到paddle_fluid.dll,无法继续执行代码。重新安装程序可能会解决此问题`,请检查是否将 Paddle 预测库路径添加到系统环境变量,详见[Step1: 下载PaddlePaddle C++ 预测库 paddle_inference_install_dir](#step1-下载paddlepaddle-c-预测库-paddle_inference_install_dir)
# 模型导出
PaddlePaddle 支持导出 inference 模型用于部署推理场景,相比于训练调优场景,inference 模型会将网络权重与网络结构进行持久化存储,并且 PaddlePaddle 支持使用预测引擎加载 inference 模型进行预测推理。
---
## 1. 环境准备
首先请参考文档[安装PaddlePaddle](../installation/install_paddle.md)和文档[安装PaddleClas](../installation/install_paddleclas.md)配置运行环境。
## 2. 分类模型导出
进入 PaddleClas 目录下:
```shell
cd /path/to/PaddleClas
```
以 ResNet50_vd 分类模型为例,下载预训练模型:
```shell
wget -P ./cls_pretrain/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/legendary_models/ResNet50_vd_pretrained.pdparams
```
上述模型是使用 ResNet50_vd 在 ImageNet 上训练的模型,使用的配置文件为 `ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml`,将该模型转为 inference 模型只需运行如下命令:
```shell
python tools/export_model.py \
-c ./ppcls/configs/ImageNet/ResNet/ResNet50_vd.yaml \
-o Global.pretrained_model=./cls_pretrain/ResNet50_vd_pretrained \
-o Global.save_inference_dir=./deploy/models/class_ResNet50_vd_ImageNet_infer
```
## 3. 识别模型导出
进入 PaddleClas 目录下:
```shell
cd /path/to/PaddleClas
```
以商品识别特征提取模型为例,下载预训练模型:
```shell
wget -P ./product_pretrain/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/product_ResNet50_vd_Aliproduct_v1.0_pretrained.pdparams
```
上述模型是 ResNet50_vd 在 AliProduct 上训练的模型,训练使用的配置文件为 `ppcls/configs/Products/ResNet50_vd_Aliproduct.yaml`,将该模型转为 inference 模型只需运行如下命令:
```shell
python3 tools/export_model.py \
-c ./ppcls/configs/Products/ResNet50_vd_Aliproduct.yaml \
-o Global.pretrained_model=./product_pretrain/product_ResNet50_vd_Aliproduct_v1.0_pretrained \
-o Global.save_inference_dir=./deploy/models/product_ResNet50_vd_aliproduct_v1.0_infer
```
注意,此处保存的 inference 模型在 embedding 特征层做了截断,即导出后模型最终的输出为 n 维 embedding 特征。
## 4. 命令参数说明
在上述模型导出命令中,所使用的配置文件需要与该模型的训练文件相同,在配置文件中有以下字段用于配置模型导出参数:
* `Global.image_shape`:用于指定模型的输入数据尺寸,该尺寸不包含 batch 维度;
* `Global.save_inference_dir`:用于指定导出的 inference 模型的保存位置;
* `Global.pretrained_model`:用于指定训练过程中保存的模型权重文件路径,该路径无需包含模型权重文件后缀名 `.pdparams`。。
上述命令将生成以下三个文件:
* `inference.pdmodel`:用于存储网络结构信息;
* `inference.pdiparams`:用于存储网络权重信息;
* `inference.pdiparams.info`:用于存储模型的参数信息,在分类模型和识别模型中可忽略。
导出的 inference 模型文件可用于预测引擎进行推理部署,根据不同的部署方式/平台,可参考:
* [Python 预测](./python_deploy.md)
* [C++ 预测](./cpp_deploy.md)(目前仅支持分类模型)
* [Python Whl 预测](./whl_deploy.md)(目前仅支持分类模型)
* [PaddleHub Serving 部署](./paddle_hub_serving_deploy.md)(目前仅支持分类模型)
* [PaddleServing 部署](./paddle_serving_deploy.md)(目前仅支持分类模型)
* [PaddleLite 部署](./paddle_lite_deploy.md)(目前仅支持分类模型)
# 基于PaddleHub Serving的服务部署
PaddleClas 支持通过 PaddleHub 快速进行服务化部署。
---
## 1. 简介
hubserving 服务部署配置服务包 `clas` 下包含 3 个必选文件,目录如下:
```
hubserving/clas/
└─ __init__.py 空文件,必选
└─ config.json 配置文件,可选,使用配置启动服务时作为参数传入
└─ module.py 主模块,必选,包含服务的完整逻辑
└─ params.py 参数文件,必选,包含模型路径、前后处理参数等参数
```
## 2. 准备环境
```shell
# 安装paddlehub,请安装2.0版本
pip3 install paddlehub==2.1.0 --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple
```
## 3. 下载推理模型
安装服务模块前,需要准备推理模型并放到正确路径,默认模型路径为:
* 分类推理模型结构文件:`PaddleClas/inference/inference.pdmodel`
* 分类推理模型权重文件:`PaddleClas/inference/inference.pdiparams`
**注意**
* 模型文件路径可在 `PaddleClas/deploy/hubserving/clas/params.py` 中查看和修改:
```python
"inference_model_dir": "../inference/"
```
需要注意,
* 模型文件(包括 `.pdmodel``.pdiparams`)名称必须为`inference`
* 我们也提供了大量基于ImageNet-1k数据集的预训练模型,模型列表及下载地址详见[模型库概览](../../docs/zh_CN/models/models_intro.md),也可以使用自己训练转换好的模型。
## 4. 安装服务模块
针对 Linux 环境和 Windows 环境,安装命令如下。
* 在Linux环境下,安装示例如下:
```shell
cd PaddleClas/deploy
# 安装服务模块:
hub install hubserving/clas/
```
* 在Windows环境下(文件夹的分隔符为`\`),安装示例如下:
```shell
cd PaddleClas\deploy
# 安装服务模块:
hub install hubserving\clas\
```
## 5. 启动服务
### 5.1 命令行命令启动
该方式仅支持使用 CPU 预测。启动命令:
```shell
$ hub serving start --modules Module1==Version1 \
--port XXXX \
--use_multiprocess \
--workers \
```
**参数说明**:
|参数|用途|
|-|-|
|--modules/-m| [**必选**] PaddleHub Serving预安装模型,以多个Module==Version键值对的形式列出<br>*`当不指定Version时,默认选择最新版本`*|
|--port/-p| [**可选**] 服务端口,默认为8866|
|--use_multiprocess| [**可选**] 是否启用并发方式,默认为单进程方式,推荐多核CPU机器使用此方式<br>*`Windows操作系统只支持单进程方式`*|
|--workers| [**可选**] 在并发方式下指定的并发任务数,默认为`2*cpu_count-1`,其中`cpu_count`为CPU核数|
如按默认参数启动服务:```hub serving start -m clas_system```
这样就完成了一个服务化 API 的部署,使用默认端口号 8866。
### 5.2 配置文件启动
该方式仅支持使用 CPU 或 GPU 预测。启动命令:
```hub serving start -c config.json```
其中,`config.json`格式如下:
```json
{
"modules_info": {
"clas_system": {
"init_args": {
"version": "1.0.0",
"use_gpu": true,
"enable_mkldnn": false
},
"predict_args": {
}
}
},
"port": 8866,
"use_multiprocess": false,
"workers": 2
}
```
**参数说明**:
* `init_args`中的可配参数与`module.py`中的`_initialize`函数接口一致。其中,
- 当`use_gpu`为`true`时,表示使用GPU启动服务。
- 当`enable_mkldnn`为`true`时,表示使用MKL-DNN加速。
* `predict_args`中的可配参数与`module.py`中的`predict`函数接口一致。
**注意**:
* 使用配置文件启动服务时,将使用配置文件中的参数设置,其他命令行参数将被忽略;
* 如果使用 GPU 预测(即,`use_gpu`置为`true`),则需要在启动服务之前,设置 `CUDA_VISIBLE_DEVICES` 环境变量来指定所使用的 GPU 卡号,如:`export CUDA_VISIBLE_DEVICES=0`;
* **`use_gpu` 不可与 `use_multiprocess` 同时为 `true`**;
* **`use_gpu` 与 `enable_mkldnn` 同时为 `true` 时,将忽略 `enable_mkldnn`,而使用 GPU**。
如使用 GPU 3号卡启动服务:
```shell
cd PaddleClas/deploy
export CUDA_VISIBLE_DEVICES=3
hub serving start -c hubserving/clas/config.json
```
## 6. 发送预测请求
配置好服务端后,可使用以下命令发送预测请求,获取预测结果:
```shell
cd PaddleClas/deploy
python hubserving/test_hubserving.py server_url image_path
```
**脚本参数说明**:
* **server_url**:服务地址,格式为
`http://[ip_address]:[port]/predict/[module_name]`
* **image_path**:测试图像路径,可以是单张图片路径,也可以是图像集合目录路径。
* **batch_size**:[**可选**] 以`batch_size`大小为单位进行预测,默认为`1`。
* **resize_short**:[**可选**] 预处理时,按短边调整大小,默认为`256`。
* **crop_size**:[**可选**] 预处理时,居中裁剪的大小,默认为`224`。
* **normalize**:[**可选**] 预处理时,是否进行`normalize`,默认为`True`。
* **to_chw**:[**可选**] 预处理时,是否调整为`CHW`顺序,默认为`True`。
**注意**:如果使用`Transformer`系列模型,如`DeiT_***_384`, `ViT_***_384`等,请注意模型的输入数据尺寸,需要指定`--resize_short=384 --crop_size=384`。
访问示例:
```shell
python hubserving/test_hubserving.py --server_url http://127.0.0.1:8866/predict/clas_system --image_file ./hubserving/ILSVRC2012_val_00006666.JPEG --batch_size 8
```
**返回结果格式说明**:
返回结果为列表(list),包含 top-k 个分类结果,以及对应的得分,还有此图片预测耗时,具体如下:
```
list: 返回结果
└─ list: 第一张图片结果
└─ list: 前k个分类结果,依score递减排序
└─ list: 前k个分类结果对应的score,依score递减排序
└─ float: 该图分类耗时,单位秒
```
## 7. 自定义修改服务模块
如果需要修改服务逻辑,需要进行以下操作:
1. 停止服务
```hub serving stop --port/-p XXXX```
2. 到相应的`module.py`和`params.py`等文件中根据实际需求修改代码。`module.py`修改后需要重新安装(`hub install hubserving/clas/`)并部署。在进行部署前,可通过`python hubserving/clas/module.py`测试已安装服务模块。
3. 卸载旧服务包
```hub uninstall clas_system```
4. 安装修改后的新服务包
```hub install hubserving/clas/```
5.重新启动服务
```hub serving start -m clas_system```
**注意**:
常用参数可在 [params.py](./clas/params.py) 中修改:
* 更换模型,需要修改模型文件路径参数:
```python
"inference_model_dir":
```
* 更改后处理时返回的`top-k`结果数量:
```python
'topk':
```
* 更改后处理时的lable与class id对应映射文件:
```python
'class_id_map_file':
```
为了避免不必要的延时以及能够以 batch_size 进行预测,数据预处理逻辑(包括 `resize`、`crop` 等操作)均在客户端完成,因此需要在 [test_hubserving.py](./test_hubserving.py#L35-L52) 中修改。
# PaddleLite推理部署
本教程将介绍基于[Paddle Lite](https://github.com/PaddlePaddle/Paddle-Lite)在移动端部署 PaddleClas 分类模型的详细步骤。
Paddle Lite是飞桨轻量化推理引擎,为手机、IOT端提供高效推理能力,并广泛整合跨平台硬件,为端侧部署及应用落地问题提供轻量化的部署方案。如果希望直接测试速度,可以参考[Paddle-Lite移动端benchmark测试教程](../../docs/zh_CN/extension/paddle_mobile_inference.md)
---
## 1. 准备环境
Paddle Lite 目前支持以下平台部署:
* 电脑(编译Paddle Lite)
* 安卓手机(armv7或armv8)
### 1.1 准备交叉编译环境
交叉编译环境用于编译 Paddle Lite 和 PaddleClas 的 C++ demo。
支持多种开发环境,不同开发环境的编译流程请参考对应文档。
1. [Docker](https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_env.html#docker)
2. [Linux](https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_env.html#linux)
3. [MAC OS](https://paddle-lite.readthedocs.io/zh/latest/source_compile/compile_env.html#mac-os)
### 1.2 准备预测库
预测库有两种获取方式:
1. [建议]直接下载,预测库下载链接如下:
|平台|预测库下载链接|
|-|-|
|Android|[arm7](https://paddlelite-data.bj.bcebos.com/Release/2.8-rc/Android/gcc/inference_lite_lib.android.armv7.gcc.c++_static.with_extra.with_cv.tar.gz) / [arm8](https://paddlelite-data.bj.bcebos.com/Release/2.8-rc/Android/gcc/inference_lite_lib.android.armv8.gcc.c++_static.with_extra.with_cv.tar.gz)|
|iOS|[arm7](https://paddlelite-data.bj.bcebos.com/Release/2.8-rc/iOS/inference_lite_lib.ios.armv7.with_cv.with_extra.tiny_publish.tar.gz) / [arm8](https://paddlelite-data.bj.bcebos.com/Release/2.8-rc/iOS/inference_lite_lib.ios.armv8.with_cv.with_extra.tiny_publish.tar.gz)|
**注**:
1. 如果是从 Paddle-Lite [官方文档](https://paddle-lite.readthedocs.io/zh/latest/quick_start/release_lib.html#android-toolchain-gcc)下载的预测库,
注意选择 `with_extra=ON,with_cv=ON` 的下载链接。
2. 如果使用量化的模型部署在端侧,建议使用 Paddle-Lite develop 分支编译预测库。
2. 编译 Paddle-Lite 得到预测库,Paddle-Lite 的编译方式如下:
```shell
git clone https://github.com/PaddlePaddle/Paddle-Lite.git
cd Paddle-Lite
# 如果使用编译方式,建议使用develop分支编译预测库
git checkout develop
./lite/tools/build_android.sh --arch=armv8 --with_cv=ON --with_extra=ON
```
**注意**:编译Paddle-Lite获得预测库时,需要打开`--with_cv=ON --with_extra=ON`两个选项,`--arch`表示`arm`版本,这里指定为armv8,更多编译命令介绍请参考[链接](https://paddle-lite.readthedocs.io/zh/latest/user_guides/Compile/Android.html#id2)
直接下载预测库并解压后,可以得到`inference_lite_lib.android.armv8/`文件夹,通过编译Paddle-Lite得到的预测库位于`Paddle-Lite/build.lite.android.armv8.gcc/inference_lite_lib.android.armv8/`文件夹下。
预测库的文件目录如下:
```
inference_lite_lib.android.armv8/
|-- cxx C++ 预测库和头文件
| |-- include C++ 头文件
| | |-- paddle_api.h
| | |-- paddle_image_preprocess.h
| | |-- paddle_lite_factory_helper.h
| | |-- paddle_place.h
| | |-- paddle_use_kernels.h
| | |-- paddle_use_ops.h
| | `-- paddle_use_passes.h
| `-- lib C++预测库
| |-- libpaddle_api_light_bundled.a C++静态库
| `-- libpaddle_light_api_shared.so C++动态库
|-- java Java预测库
| |-- jar
| | `-- PaddlePredictor.jar
| |-- so
| | `-- libpaddle_lite_jni.so
| `-- src
|-- demo C++和Java示例代码
| |-- cxx C++ 预测库demo
| `-- java Java 预测库demo
```
## 2. 开始运行
### 2.1 模型优化
Paddle-Lite 提供了多种策略来自动优化原始的模型,其中包括量化、子图融合、混合精度、Kernel 优选等方法,使用 Paddle-Lite 的 `opt` 工具可以自动对 inference 模型进行优化,目前支持两种优化方式,优化后的模型更轻量,模型运行速度更快。在进行模型优化前,需要先准备 `opt` 优化工具,有以下两种方式。
**注意**:如果已经准备好了 `.nb` 结尾的模型文件,可以跳过此步骤。
#### 2.1.1 [建议]pip安装paddlelite并进行转换
Python下安装 `paddlelite`,目前最高支持 `Python3.7`
**注意**`paddlelite` whl包版本必须和预测库版本对应。
```shell
pip install paddlelite==2.8
```
之后使用 `paddle_lite_opt` 工具可以进行 inference 模型的转换。`paddle_lite_opt` 的部分参数如下
|选项|说明|
|-|-|
|--model_dir|待优化的PaddlePaddle模型(非combined形式)的路径|
|--model_file|待优化的PaddlePaddle模型(combined形式)的网络结构文件路径|
|--param_file|待优化的PaddlePaddle模型(combined形式)的权重文件路径|
|--optimize_out_type|输出模型类型,目前支持两种类型:protobuf和naive_buffer,其中naive_buffer是一种更轻量级的序列化/反序列化实现。若您需要在mobile端执行模型预测,请将此选项设置为naive_buffer。默认为protobuf|
|--optimize_out|优化模型的输出路径|
|--valid_targets|指定模型可执行的backend,默认为arm。目前可支持x86、arm、opencl、npu、xpu,可以同时指定多个backend(以空格分隔),Model Optimize Tool将会自动选择最佳方式。如果需要支持华为NPU(Kirin 810/990 Soc搭载的达芬奇架构NPU),应当设置为npu, arm|
|--record_tailoring_info|当使用 根据模型裁剪库文件 功能时,则设置该选项为true,以记录优化后模型含有的kernel和OP信息,默认为false|
`--model_file` 表示 inference 模型的 model 文件地址,`--param_file` 表示 inference 模型的 param 文件地址;`optimize_out` 用于指定输出文件的名称(不需要添加 `.nb` 的后缀)。直接在命令行中运行 `paddle_lite_opt`,也可以查看所有参数及其说明。
#### 2.1.2 源码编译Paddle-Lite生成opt工具
模型优化需要 Paddle-Lite 的 `opt` 可执行文件,可以通过编译 Paddle-Lite 源码获得,编译步骤如下:
```shell
# 如果准备环境时已经clone了Paddle-Lite,则不用重新clone Paddle-Lite
git clone https://github.com/PaddlePaddle/Paddle-Lite.git
cd Paddle-Lite
git checkout develop
# 启动编译
./lite/tools/build.sh build_optimize_tool
```
编译完成后,`opt` 文件位于 `build.opt/lite/api/` 下,可通过如下方式查看 `opt` 的运行选项和使用方式:
```shell
cd build.opt/lite/api/
./opt
```
`opt` 的使用方式与参数与上面的 `paddle_lite_opt` 完全一致。
<a name="2.1.3"></a>
#### 2.1.3 转换示例
下面以PaddleClas的 `MobileNetV3_large_x1_0` 模型为例,介绍使用 `paddle_lite_opt` 完成预训练模型到inference模型,再到 Paddle-Lite 优化模型的转换。
```shell
# 进入PaddleClas根目录
cd PaddleClas_root_path
# 下载并解压inference模型
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/inference/MobileNetV3_large_x1_0_infer.tar
tar -xf MobileNetV3_large_x1_0_infer.tar
# 将inference模型转化为Paddle-Lite优化模型
paddle_lite_opt --model_file=./MobileNetV3_large_x1_0_infer/inference.pdmodel --param_file=./MobileNetV3_large_x1_0_infer/inference.pdiparams --optimize_out=./MobileNetV3_large_x1_0
```
最终在当前文件夹下生成 `MobileNetV3_large_x1_0.nb` 的文件。
**注意**`--optimize_out` 参数为优化后模型的保存路径,无需加后缀 `.nb``--model_file` 参数为模型结构信息文件的路径,`--param_file` 参数为模型权重信息文件的路径,请注意文件名。
### 2.2 与手机联调
首先需要进行一些准备工作。
1. 准备一台 arm8 的安卓手机,如果编译的预测库和 opt 文件是 armv7,则需要 arm7 的手机,并修改 Makefile 中 `ARM_ABI = arm7`
2. 电脑上安装 ADB 工具,用于调试。 ADB安装方式如下:
* MAC电脑安装ADB:
```shell
brew cask install android-platform-tools
```
* Linux安装ADB
```shell
sudo apt update
sudo apt install -y wget adb
```
* Window安装ADB
win上安装需要去谷歌的安卓平台下载ADB软件包进行安装:[链接](https://developer.android.com/studio)
3. 手机连接电脑后,开启手机 `USB调试` 选项,选择 `文件传输` 模式,在电脑终端中输入:
```shell
adb devices
```
如果有 device 输出,则表示安装成功,如下所示:
```
List of devices attached
744be294 device
```
4. 准备优化后的模型、预测库文件、测试图像和类别映射文件。
```shell
cd PaddleClas_root_path
cd deploy/lite/
# 运行prepare.sh
# prepare.sh 会将预测库文件、测试图像和使用的字典文件放置在预测库中的demo/cxx/clas文件夹下
sh prepare.sh /{lite prediction library path}/inference_lite_lib.android.armv8
# 进入lite demo的工作目录
cd /{lite prediction library path}/inference_lite_lib.android.armv8/
cd demo/cxx/clas/
# 将C++预测动态库so文件复制到debug文件夹中
cp ../../../cxx/lib/libpaddle_light_api_shared.so ./debug/
```
`prepare.sh``PaddleClas/deploy/lite/imgs/tabby_cat.jpg` 作为测试图像,将测试图像复制到 `demo/cxx/clas/debug/` 文件夹下。
`paddle_lite_opt` 工具优化后的模型文件放置到 `/{lite prediction library path}/inference_lite_lib.android.armv8/demo/cxx/clas/debug/` 文件夹下。本例中,使用 [2.1.3](#2.1.3) 生成的 `MobileNetV3_large_x1_0.nb` 模型文件。
执行完成后,clas 文件夹下将有如下文件格式:
```
demo/cxx/clas/
|-- debug/
| |--MobileNetV3_large_x1_0.nb 优化后的分类器模型文件
| |--tabby_cat.jpg 待测试图像
| |--imagenet1k_label_list.txt 类别映射文件
| |--libpaddle_light_api_shared.so C++预测库文件
| |--config.txt 分类预测超参数配置
|-- config.txt 分类预测超参数配置
|-- image_classfication.cpp 图像分类代码文件
|-- Makefile 编译文件
```
#### 注意:
* 上述文件中,`imagenet1k_label_list.txt` 是 ImageNet1k 数据集的类别映射文件,如果使用自定义的类别,需要更换该类别映射文件。
* `config.txt` 包含了分类器的超参数,如下:
```shell
clas_model_file ./MobileNetV3_large_x1_0.nb # 模型文件地址
label_path ./imagenet1k_label_list.txt # 类别映射文本文件
resize_short_size 256 # resize之后的短边边长
crop_size 224 # 裁剪后用于预测的边长
visualize 0 # 是否进行可视化,如果选择的话,会在当前文件夹下生成名为clas_result.png的图像文件。
```
5. 启动调试,上述步骤完成后就可以使用ADB将文件夹 `debug/` push 到手机上运行,步骤如下:
```shell
# 执行编译,得到可执行文件clas_system
make -j
# 将编译得到的可执行文件移动到debug文件夹中
mv clas_system ./debug/
# 将上述debug文件夹push到手机上
adb push debug /data/local/tmp/
adb shell
cd /data/local/tmp/debug
export LD_LIBRARY_PATH=/data/local/tmp/debug:$LD_LIBRARY_PATH
# clas_system可执行文件的使用方式为:
# ./clas_system 配置文件路径 测试图像路径
./clas_system ./config.txt ./tabby_cat.jpg
```
如果对代码做了修改,则需要重新编译并 push 到手机上。
运行效果如下:
<div align="center">
<img src="./imgs/lite_demo_result.png" width="600">
</div>
## FAQ
Q1:如果想更换模型怎么办,需要重新按照流程走一遍吗?
A1:如果已经走通了上述步骤,更换模型只需要替换 `.nb` 模型文件即可,同时要注意修改下配置文件中的 `.nb` 文件路径以及类别映射文件(如有必要)。
Q2:换一个图测试怎么做?
A2:替换 debug 下的测试图像为你想要测试的图像,使用 ADB 再次 push 到手机上即可。
# 模型服务化部署
## 1. 简介
[Paddle Serving](https://github.com/PaddlePaddle/Serving) 旨在帮助深度学习开发者轻松部署在线预测服务,支持一键部署工业级的服务能力、客户端和服务端之间高并发和高效通信、并支持多种编程语言开发客户端。
该部分以 HTTP 预测服务部署为例,介绍怎样在 PaddleClas 中使用 PaddleServing 部署模型服务。
## 2. Serving安装
Serving 官网推荐使用 docker 安装并部署 Serving 环境。首先需要拉取 docker 环境并创建基于 Serving 的 docker。
```shell
nvidia-docker pull hub.baidubce.com/paddlepaddle/serving:0.2.0-gpu
nvidia-docker run -p 9292:9292 --name test -dit hub.baidubce.com/paddlepaddle/serving:0.2.0-gpu
nvidia-docker exec -it test bash
```
进入 docker 后,需要安装 Serving 相关的 python 包。
```shell
pip install paddlepaddle-gpu
pip install paddle-serving-client
pip install paddle-serving-server-gpu
```
* 如果安装速度太慢,可以通过 `-i https://pypi.tuna.tsinghua.edu.cn/simple` 更换源,加速安装过程。
* 如果希望部署 CPU 服务,可以安装 serving-server 的 cpu 版本,安装命令如下。
```shell
pip install paddle-serving-server
```
## 3. 导出模型
使用 `tools/export_serving_model.py` 脚本导出 Serving 模型,以 `ResNet50_vd` 为例,使用方法如下。
```shell
python tools/export_serving_model.py -m ResNet50_vd -p ./pretrained/ResNet50_vd_pretrained/ -o serving
```
最终在 serving 文件夹下会生成 `ppcls_client_conf``ppcls_model` 两个文件夹,分别存储了 client 配置、模型参数与结构文件。
## 4. 服务部署与请求
* 使用下面的方式启动 Serving 服务。
```shell
python tools/serving/image_service_gpu.py serving/ppcls_model workdir 9292
```
其中 `serving/ppcls_model` 为刚才保存的 Serving 模型地址,`workdir` 为工作目录,`9292` 为服务的端口号。
* 使用下面的脚本向 Serving 服务发送识别请求,并返回结果。
```
python tools/serving/image_http_client.py 9292 ./docs/images/logo.png
```
`9292` 为发送请求的端口号,需要与服务启动时的端口号保持一致,`./docs/images/logo.png` 为待识别的图像文件。最终返回 Top1 识别结果的类别 ID 以及概率值。
* 更多的服务部署类型,如 `RPC预测服务` 等,可以参考 Serving 的 github 官网:[https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imagenet](https://github.com/PaddlePaddle/Serving/tree/develop/python/examples/imagenet)
# Python 预测推理
---
首先请参考文档[安装PaddlePaddle](../installation/install_paddle.md)和文档[安装PaddleClas](../installation/install_paddleclas.md)配置运行环境。
## 1. 图像分类推理
首先请参考文档[模型导出](./export_model.md)准备 inference 模型,然后进入 PaddleClas 的 `deploy` 目录下:
```shell
cd /path/to/PaddleClas/deploy
```
使用以下命令进行预测:
```shell
python python/predict_cls.py -c configs/inference_cls.yaml
```
在配置文件 `configs/inference_cls.yaml` 中有以下字段用于配置预测参数:
* `Global.infer_imgs`:待预测的图片文件路径;
* `Global.inference_model_dir`:inference 模型文件所在目录,该目录下需要有文件 `inference.pdmodel``inference.pdiparams` 两个文件;
* `Global.use_tensorrt`:是否使用 TesorRT 预测引擎,默认为 `False`
* `Global.use_gpu`:是否使用 GPU 预测,默认为 `True`
* `Global.enable_mkldnn`:是否启用 `MKL-DNN` 加速库,默认为 `False`。注意 `enable_mkldnn``use_gpu` 同时为 `True` 时,将忽略 `enable_mkldnn`,而使用 GPU 预测;
* `Global.use_fp16`:是否启用 `FP16` ,默认为 `False`
* `PreProcess`:用于数据预处理配置;
* `PostProcess`:由于后处理配置;
* `PostProcess.Topk.class_id_map_file`:数据集 label 的映射文件,默认为 `./utils/imagenet1k_label_list.txt`,该文件为 PaddleClas 所使用的 ImageNet 数据集 label 映射文件。
**注意**:
* 如果使用 VisionTransformer 系列模型,如 `DeiT_***_384`, `ViT_***_384` 等,请注意模型的输入数据尺寸,部分模型需要修改参数: `PreProcess.resize_short=384`, `PreProcess.resize=384`
* 如果你希望提升评测模型速度,使用gpu评测时,建议开启TensorRT加速预测,使用cpu评测时,建议开启MKL-DNN加速预测。
## 2. 主体检测模型推理
进入 PaddleClas 的 `deploy` 目录下:
```shell
cd /path/to/PaddleClas/deploy
```
准备 PaddleClas 提供的主体检测 inference 模型:
```shell
mkdir -p models
# 下载通用检测 inference 模型并解压
wget -P ./models/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar
tar -xf ./models/ppyolov2_r50vd_dcn_mainbody_v1.0_infer.tar -C ./models/
```
使用以下命令进行预测:
```shell
python python/predict_det.py -c configs/inference_det.yaml
```
在配置文件 `configs/inference_det.yaml` 中有以下字段用于配置预测参数:
* `Global.infer_imgs`:待预测的图片文件路径;
* `Global.use_gpu`: 是否使用 GPU 预测,默认为 `True`
## 3. 特征提取模型推理
下面以商品特征提取为例,介绍特征提取模型推理。首先进入 PaddleClas 的 `deploy` 目录下:
```shell
cd /path/to/PaddleClas/deploy
```
准备 PaddleClas 提供的商品特征提取 inference 模型:
```shell
mkdir -p models
# 下载商品特征提取 inference 模型并解压
wget -P ./models/ https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/product_ResNet50_vd_aliproduct_v1.0_infer.tar
tar -xf ./models/product_ResNet50_vd_aliproduct_v1.0_infer.tar -C ./models/
```
上述预测命令可以得到一个 512 维的特征向量,直接输出在在命令行中。
## 4. 主体检测、特征提取和向量检索串联
主体检测、特征提取和向量检索的串联预测,可以参考图像识别[快速体验](../quick_start/quick_start_recognition.md)
# PaddleClas Whl 使用说明
PaddleClas 支持 Python Whl 包方式进行预测,目前 Whl 包方式仅支持图像分类,暂不支持主体检测、特征提取及向量检索。
---
## 1. 安装
* pip安装
```bash
pip3 install paddleclas==2.2.1
```
* 本地构建并安装
```bash
python3 setup.py bdist_wheel
pip3 install dist/*
```
## 2. 快速开始
* 使用`ResNet50`模型,以下图(`'docs/images/whl/demo.jpg'`)为例进行说明。
<div align="center">
<img src="../images/whl/demo.jpg" width = "400" />
</div>
* 在Python代码中使用
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50')
infer_imgs='docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
**注意**`PaddleClas.predict()` 为可迭代对象(`generator`),因此需要使用 `next()` 函数或 `for` 循环对其迭代调用。每次调用将以 `batch_size` 为单位进行一次预测,并返回预测结果。返回结果示例如下:
```
>>> result
[{'class_ids': [8, 7, 136, 80, 84], 'scores': [0.79368, 0.16329, 0.01853, 0.00959, 0.00239], 'label_names': ['hen', 'cock', 'European gallinule, Porphyrio porphyrio', 'black grouse', 'peacock']}]
```
* 在命令行中使用
```bash
paddleclas --model_name=ResNet50 --infer_imgs="docs/images/whl/demo.jpg"
```
```
>>> result
filename: docs/images/whl/demo.jpg, top-5, class_ids: [8, 7, 136, 80, 84], scores: [0.79368, 0.16329, 0.01853, 0.00959, 0.00239], label_names: ['hen', 'cock', 'European gallinule, Porphyrio porphyrio', 'black grouse', 'peacock']
Predict complete!
```
## 3. 参数解释
以下参数可在命令行方式使用中通过参数指定,或在Python代码中实例化PaddleClas对象时作为构造函数的参数使用。
* model_name(str): 模型名称,使用PaddleClas提供的基于ImageNet1k的预训练模型。
* inference_model_dir(str): 本地模型文件目录,当未指定 `model_name` 时该参数有效。该目录下需包含 `inference.pdmodel``inference.pdiparams` 两个模型文件。
* infer_imgs(str): 待预测图片文件路径,或包含图片文件的目录,或网络图片的URL。
* use_gpu(bool): 是否使用GPU,默认为 `True`
* gpu_mem(int): 使用的GPU显存大小,当 `use_gpu``True` 时有效,默认为8000。
* use_tensorrt(bool): 是否开启TensorRT预测,可提升GPU预测性能,需要使用带TensorRT的预测库,默认为 `False`
* enable_mkldnn(bool): 是否开启MKLDNN,当 `use_gpu``False` 时有效,默认 `False`
* cpu_num_threads(int): cpu预测时的线程数,当 `use_gpu``False``enable_mkldnn``True` 时有效,默认值为 `10`
* batch_size(int): 预测时每个batch的样本数量,默认为 `1`
* resize_short(int): 按图像较短边进行等比例缩放,默认为 `256`
* crop_size(int): 将图像裁剪到指定大小,默认为 `224`
* topk(int): 打印(返回)预测结果的前 `topk` 个类别和对应的分类概率,默认为 `5`
* class_id_map_file(str): `class id``label` 的映射关系文件。默认使用 `ImageNet1K` 数据集的映射关系。
* save_dir(str): 将预测结果作为预标注数据保存的路径,默认为 `None`,即不保存。
**注意**: 如果使用`Transformer`系列模型,如`DeiT_***_384`, `ViT_***_384`等,请注意模型的输入数据尺寸,需要设置参数`resize_short=384`, `crop_size=384`,如下所示。
* 命令行中
```bash
from paddleclas import PaddleClas, get_default_confg
paddleclas --model_name=ViT_base_patch16_384 --infer_imgs='docs/images/whl/demo.jpg' --resize_short=384 --crop_size=384
```
* Python代码中
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ViT_base_patch16_384', resize_short=384, crop_size=384)
```
## 4. 使用示例
PaddleClas提供两种使用方式:
1. Python代码中使用;
2. 命令行中使用。
### 4.1 查看帮助信息
* CLI
```bash
paddleclas -h
```
### 4.2 使用PaddleClas提供的预训练模型进行预测
可以使用PaddleClas提供的预训练模型来预测,并通过参数`model_name`指定。此时PaddleClas会根据`model_name`自动下载指定模型,并保存在目录`~/.paddleclas/`下。
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50')
infer_imgs = 'docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/demo.jpg'
```
### 4.3 使用本地模型文件预测
可以使用本地的模型文件进行预测,通过参数`inference_model_dir`指定模型文件目录即可。需要注意,模型文件目录下必须包含`inference.pdmodel``inference.pdiparams`两个文件。
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(inference_model_dir='./inference/')
infer_imgs = 'docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --inference_model_dir='./inference/' --infer_imgs='docs/images/whl/demo.jpg'
```
### 4.4 批量预测
当参数 `infer_imgs` 为包含图片文件的目录时,可以对图片进行批量预测,只需通过参数 `batch_size` 指定batch大小。
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50', batch_size=2)
infer_imgs = 'docs/images/'
result=clas.predict(infer_imgs)
for r in result:
print(r)
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/' --batch_size 2
```
### 4.5 对网络图片进行预测
可以对网络图片进行预测,只需通过参数`infer_imgs`指定图片`url`。此时图片会下载并保存在`~/.paddleclas/images/`目录下。
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50')
infer_imgs = 'https://raw.githubusercontent.com/paddlepaddle/paddleclas/release/2.2/docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='https://raw.githubusercontent.com/paddlepaddle/paddleclas/release/2.2/docs/images/whl/demo.jpg'
```
### 4.6 对`NumPy.ndarray`格式数据进行预测
在Python中,可以对`Numpy.ndarray`格式的图像数据进行预测,只需通过参数`infer_imgs`指定即可。注意该图像数据必须为三通道图像数据。
* python
```python
import cv2
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50')
infer_imgs = cv2.imread("docs/images/whl/demo.jpg")
result=clas.predict(infer_imgs)
print(next(result))
```
### 4.7 保存预测结果
可以指定参数`pre_label_out_dir='./output_pre_label/'`,将图片按其top1预测结果保存到`pre_label_out_dir`目录下对应类别的文件夹中。
* python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50', save_dir='./output_pre_label/')
infer_imgs = 'docs/images/whl/' # it can be infer_imgs folder path which contains all of images you want to predict.
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/' --save_dir='./output_pre_label/'
```
### 4.8 指定label name
可以通过参数`class_id_map_file`指定`class id``lable`的对应关系。PaddleClas默认使用ImageNet1K的label_name(`ppcls/utils/imagenet1k_label_list.txt`)。
`class_id_map_file`文件内容格式应为:
```
class_id<space>class_name<\n>
```
例如:
```
0 tench, Tinca tinca
1 goldfish, Carassius auratus
2 great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias
......
```
* Python
```python
from paddleclas import PaddleClas
clas = PaddleClas(model_name='ResNet50', class_id_map_file='./ppcls/utils/imagenet1k_label_list.txt')
infer_imgs = 'docs/images/whl/demo.jpg'
result=clas.predict(infer_imgs)
print(next(result))
```
* CLI
```bash
paddleclas --model_name='ResNet50' --infer_imgs='docs/images/whl/demo.jpg' --class_id_map_file='./ppcls/utils/imagenet1k_label_list.txt'
```
# 安装 PaddlePaddle
---
目前, **PaddleClas** 要求 **PaddlePaddle** 版本 `>=2.0`。建议使用我们提供的 Docker 运行 PaddleClas,有关 Docker、nvidia-docker 的相关使用教程可以参考[链接](https://www.runoob.com/Docker/Docker-tutorial.html)。如果不使用 Docker,可以直接跳过 [2.1](#2.1) 部分内容,从 [2.2](#2.2) 部分开始。
## 1. 环境要求
**版本要求**
- python 3.x
- CUDA >= 10.1 (如果使用 `paddlepaddle-gpu`)
- cuDNN >= 7.6.4 (如果使用 `paddlepaddle-gpu`)
- nccl >= 2.1.2 (如果使用分布式训练/评估)
- gcc >= 8.2
**建议**
* 当 CUDA 版本为 10.1 时,显卡驱动版本 `>= 418.39`
* 当 CUDA 版本为 10.2 时,显卡驱动版本 `>= 440.33`
* 更多 CUDA 版本与要求的显卡驱动版本可以参考[链接](https://docs.nvidia.com/deploy/cuda-compatibility/index.html)
## 2.(建议)使用 Docker 环境
* 切换到工作目录下
```shell
cd /home/Projects
```
* 创建 docker 容器
下述命令会创建一个名为 ppcls 的 Docker 容器,并将当前工作目录映射到容器内的 `/paddle` 目录。
```shell
# 对于GPU用户
sudo nvidia-docker run --name ppcls -v $PWD:/paddle --shm-size=8G --network=host -it paddlepaddle/paddle:2.1.0-gpu-cuda10.2-cudnn7 /bin/bash
# 对于CPU用户
sudo docker run --name ppcls -v $PWD:/paddle --shm-size=8G --network=host -it paddlepaddle/paddle:2.1.0 /bin/bash
```
**注意**
* 首次使用该镜像时,下述命令会自动下载该镜像文件,下载需要一定的时间,请耐心等待;
* 下述命令会创建一个 Docker 容器,之后再次使用该容器时无需再次运行该命令;
* 参数 `--shm-size=8G` 将设置容器的共享内存为8G,如机器环境允许,建议将该参数设置较大,如 `64G`
* 您也可以访问 [DockerHub](https://hub.Docker.com/r/paddlepaddle/paddle/tags/)获取与您机器适配的镜像。
* 退出/进入 docker 容器
在进入 Docker 容器后,可使用组合键 `Ctrl + P + Q` 退出当前容器,同时不关闭该容器。如需再次进入容器,可使用下述命令:
```shell
sudo Docker exec -it ppcls /bin/bash
```
## 3. 通过 pip 安装 PaddlePaddle
可运行下面的命令,通过 pip 安装最新版本 PaddlePaddle:
```bash
# 对于CPU用户
pip3 install paddlepaddle --upgrade -i https://mirror.baidu.com/pypi/simple
# 对于GPU用户
pip3 install paddlepaddle-gpu --upgrade -i https://mirror.baidu.com/pypi/simple
```
**注意:**
* 如果先安装了 CPU 版本的 PaddlePaddle,之后想切换到 GPU 版本,那么需要使用 pip 先卸载 CPU 版本的 PaddlePaddle,再安装 GPU 版本的 PaddlePaddle,否则容易导致 PaddlePaddle 冲突。
* 您也可以从源码编译安装 PaddlePaddle,请参照[PaddlePaddle 安装文档](http://www.paddlepaddle.org.cn/install/quick)中的说明进行操作。
## 4. 验证安装
使用以下命令可以验证 PaddlePaddle 是否安装成功。
```python
import paddle
paddle.utils.run_check()
```
查看 PaddlePaddle 版本的命令如下:
```bash
python -c "import paddle; print(paddle.__version__)"
```
**注意**
- 从源码编译的 PaddlePaddle 版本号为 `0.0.0`,请确保使用了 PaddlePaddle 2.0 及之后的源码编译;
- PaddleClas 基于 PaddlePaddle 高性能的分布式训练能力,若您从源码编译,请确保打开编译选项 `WITH_DISTRIBUTE=ON`。具体编译选项参考[编译选项表](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/install/Tables.html#id3)
- 在 Docker 中运行时,为保证 Docker 容器有足够的共享内存用于 Paddle 的数据读取加速,在创建Docker 容器时,请设置参数 `--shm_size=8g`,条件允许的话可以设置为更大的值。
# 安装 PaddleClas
---
## 1. 克隆 PaddleClas
从 GitHub 下载:
```shell
git clone https://github.com/PaddlePaddle/PaddleClas.git -b release/2.3
```
如果访问 GitHub 网速较慢,可以从 Gitee 下载,命令如下:
```shell
git clone https://gitee.com/paddlepaddle/PaddleClas.git -b release/2.3
```
## 2. 安装 Python 依赖库
PaddleClas 的 Python 依赖库在 `requirements.txt` 中给出,可通过如下命令安装:
```shell
pip install --upgrade -r requirements.txt -i https://mirror.baidu.com/pypi/simple
```
# 30分钟玩转PaddleClas(尝鲜版)
此教程主要针对初级用户,即深度学习相关理论知识处于入门阶段,具有一定的 Python 基础,能够阅读简单代码的用户。此内容主要包括使用 PaddleClas 进行图像分类网络训练及模型预测。
---
## 1. 基础知识
图像分类顾名思义就是一个模式分类问题,是计算机视觉中最基础的任务,它的目标是将不同的图像,划分到不同的类别。以下会对整个模型训练过程中需要了解到的一些概念做简单的解释,希望能够对初次体验 PaddleClas 的你有所帮助:
- train/val/test dataset 分别代表模型的训练集、验证集和测试集:
- 训练集(train dataset):用来训练模型,使模型能够识别不同类型的特征;
- 验证集(val dataset):训练过程中的测试集,方便训练过程中查看模型训练程度;
- 测试集(test dataset):训练模型结束后,用于评价模型结果的测试集。
- 预训练模型
使用在某个较大的数据集训练好的预训练模型,即被预置了参数的权重,可以帮助模型在新的数据集上更快收敛。尤其是对一些训练数据比较稀缺的任务,在神经网络参数十分庞大的情况下,仅仅依靠任务自身的训练数据可能无法训练充分,加载预训练模型的方法可以认为是让模型基于一个更好的初始状态进行学习,从而能够达到更好的性能。
- 迭代轮数(epoch)
模型训练迭代的总轮数,模型对训练集全部样本过一遍即为一个 epoch。当测试错误率和训练错误率相差较小时,可认为当前迭代轮数合适;当测试错误率先变小后变大时,则说明迭代轮数过大,需要减小迭代轮数,否则容易出现过拟合。
- 损失函数(Loss Function)
训练过程中,衡量模型输出(预测值)与真实值之间的差异
- 准确率(Acc):表示预测正确的样本数占总数据的比例
- Top1 Acc:预测结果中概率最大的所在分类正确,则判定为正确;
- Top5 Acc:预测结果中概率排名前 5 中有分类正确,则判定为正确;
## 2. 环境安装与配置
具体安装步骤可详看[Paddle 安装文档](../installation/install_paddle.md)[PaddleClas 安装文档](../installation/install_paddleclas.md)
## 3. 数据的准备与处理
进入PaddleClas目录:
```shell
# linux or mac, $path_to_PaddleClas表示PaddleClas的根目录,用户需要根据自己的真实目录修改
cd $path_to_PaddleClas
```
进入 `dataset/flowers102` 目录,下载并解压 flowers102 数据集:
```shell
# linux or mac
cd dataset/flowers102
# 如果希望从浏览器中直接下载,可以复制该链接并访问,然后下载解压即可
wget https://paddle-imagenet-models-name.bj.bcebos.com/data/flowers102.zip
# 解压
unzip flowers102.zip
```
没有安装 `wget` 命令或者在 Windows 中下载的话,需要将地址拷贝到浏览器中下载,并进行解压到 PaddleClas 的根目录即可。
解压完成后,在文件夹下已经生成用于训练和测试的三个 `.txt` 文件:`train_list.txt`(训练集,1020张图)、`val_list.txt`(验证集,1020张图)、`train_extra_list.txt`(更大的训练集,7169张图)。文件中每行格式:**图像相对路径** **图像的label_id**(注意:中间有空格)。
此时flowers102数据集存放在**dataset/flowers102/jpg** 文件夹中,图像示例如下:
<div align="center">
<img src="../../images/quick_start/Examples-Flower-102.png" width = "800" />
</div>
返回 `PaddleClas` 根目录:
```shell
# linux or mac
cd ../../
# windoes直接打开PaddleClas根目录即可
```
## 4. 模型训练
### 4.1 使用CPU进行模型训练
由于使用CPU来进行模型训练,计算速度较慢,因此,此处以 ShuffleNetV2_x0_25 为例。此模型计算量较小,在 CPU 上计算速度较快。但是也因为模型较小,训练好的模型精度也不会太高。
#### 4.1.1 不使用预训练模型
```shell
# windows在cmd中进入PaddleClas根目录,执行此命令
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml
```
- `-c` 参数是指定训练的配置文件路径,训练的具体超参数可查看`yaml`文件
- `yaml``Global.device` 参数设置为`cpu`,即使用CPU进行训练(若不设置,此参数默认为`True`
- `yaml`文件中`epochs`参数设置为20,说明对整个数据集进行20个epoch迭代,预计训练20分钟左右(不同CPU,训练时间略有不同),此时训练模型不充分。若提高训练模型精度,请将此参数设大,如**40**,训练时间也会相应延长
#### 4.1.2 使用预训练模型
```shell
python tools/train.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml -o Arch.pretrained=True
```
- `-o` 参数可以选择为 `True``False`,也可以是预训练模型存放路径,当选择为 `True` 时,预训练权重会自动下载到本地。注意:若为预训练模型路径,则不要加上:`.pdparams`
可以使用将使用与不使用预训练模型训练进行对比,观察 loss 的下降情况。
### 4.2 使用GPU进行模型训练
由于 GPU 训练速度更快,可以使用更复杂模型,因此以 ResNet50_vd 为例。与 ShuffleNetV2_x0_25 相比,此模型计算量较大,训练好的模型精度也会更高。
首先要设置环境变量,使用 0 号 GPU 进行训练:
- 对于 Linux 用户
```shell
export CUDA_VISIBLE_DEVICES=0
```
- 对于 Windows 用户
```shell
set CUDA_VISIBLE_DEVICES=0
```
#### 不使用预训练模型
```shell
python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml
```
训练完成后,验证集的`Top1 Acc`曲线如下所示,最高准确率为0.2735。训练精度曲线下图所示
<div align="center">
<img src="../../images/quick_start/r50_vd_acc.png" width = "800" />
</div>
#### 4.2.1 使用预训练模型进行训练
基于 ImageNet1k 分类预训练模型进行微调,训练脚本如下所示
```shell
python3 tools/train.py -c ./ppcls/configs/quick_start/ResNet50_vd.yaml -o Arch.pretrained=True
```
**注**:此训练脚本使用 GPU,如使用 CPU 可按照上文中[使用CPU进行模型训练](#使用CPU进行模型训练)所示,进行修改。
验证集的 `Top1 Acc` 曲线如下所示,最高准确率为 `0.9402`,加载预训练模型之后,flowers102 数据集精度大幅提升,绝对精度涨幅超过 65%。
<div align="center">
<img src="../../images/quick_start/r50_vd_pretrained_acc.png" width = "800" />
</div>
## 5. 模型预测
训练完成后预测代码如下:
```shell
cd $path_to_PaddleClas
python3 tools/infer.py -c ./ppcls/configs/quick_start/new_user/ShuffleNetV2_x0_25.yaml -o Infer.infer_imgs=dataset/flowers102/jpg/image_00001.jpg -o Global.pretrained_model=output/ShuffleNetV2_x0_25/best_model
```
`-i` 输入为单张图像路径,运行成功后,示例结果如下:
`[{'class_ids': [76, 65, 34, 9, 69], 'scores': [0.91762, 0.01801, 0.00833, 0.0071, 0.00669], 'file_name': 'dataset/flowers102/jpg/image_00001.jpg', 'label_names': []}]`
`-i` 输入为图像集所在目录,运行成功后,示例结果如下:
```txt
[{'class_ids': [76, 65, 34, 9, 69], 'scores': [0.91762, 0.01801, 0.00833, 0.0071, 0.00669], 'file_name': 'dataset/flowers102/jpg/image_00001.jpg', 'label_names': []}, {'class_ids': [76, 69, 34, 28, 9], 'scores': [0.77122, 0.06295, 0.02537, 0.02531, 0.0251], 'file_name': 'dataset/flowers102/jpg/image_00002.jpg', 'label_names': []}, {'class_ids': [99, 76, 81, 85, 16], 'scores': [0.26374, 0.20423, 0.07818, 0.06042, 0.05499], 'file_name': 'dataset/flowers102/jpg/image_00003.jpg', 'label_names': []}, {'class_ids': [9, 37, 34, 24, 76], 'scores': [0.17784, 0.16651, 0.14539, 0.12096, 0.04816], 'file_name': 'dataset/flowers102/jpg/image_00004.jpg', 'label_names': []}, {'class_ids': [76, 66, 91, 16, 13], 'scores': [0.95494, 0.00688, 0.00596, 0.00352, 0.00308], 'file_name': 'dataset/flowers102/jpg/image_00005.jpg', 'label_names': []}, {'class_ids': [76, 66, 34, 8, 43], 'scores': [0.44425, 0.07487, 0.05609, 0.05609, 0.03667], 'file_name': 'dataset/flowers102/jpg/image_00006.jpg', 'label_names': []}, {'class_ids': [86, 93, 81, 22, 21], 'scores': [0.44714, 0.13582, 0.07997, 0.0514, 0.03497], 'file_name': 'dataset/flowers102/jpg/image_00007.jpg', 'label_names': []}, {'class_ids': [13, 76, 81, 18, 97], 'scores': [0.26771, 0.1734, 0.06576, 0.0451, 0.03986], 'file_name': 'dataset/flowers102/jpg/image_00008.jpg', 'label_names': []}, {'class_ids': [34, 76, 8, 5, 9], 'scores': [0.67224, 0.31896, 0.00241, 0.00227, 0.00102], 'file_name': 'dataset/flowers102/jpg/image_00009.jpg', 'label_names': []}, {'class_ids': [76, 34, 69, 65, 66], 'scores': [0.95185, 0.01101, 0.00875, 0.00452, 0.00406], 'file_name': 'dataset/flowers102/jpg/image_00010.jpg', 'label_names': []}]
```
其中,列表的长度为 batch_size 的大小。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册