## PP-ShiTu V2图像识别系统 ## 目录 - [1. PP-ShiTu V2模型和应用场景介绍](#1-pp-shituv2模型和应用场景介绍) - [2. 模型快速体验](#2-模型快速体验) - [2.1 PP-ShiTu android demo 快速体验](#21-pp-shitu-android-demo-快速体验) - [2.2 命令行代码快速体验](#22-命令行代码快速体验) - [3 模块介绍与训练](#3-模块介绍与训练) - [3.1 主体检测](#31-主体检测) - [3.2 特征提取](#32-特征提取) - [3.3 向量检索](#33-向量检索) - [4. 推理部署](#4-推理部署) - [4.1 推理模型准备](#41-推理模型准备) - [4.1.1 基于训练得到的权重导出 inference 模型](#411-基于训练得到的权重导出-inference-模型) - [4.1.2 直接下载 inference 模型](#412-直接下载-inference-模型) - [4.2 测试数据准备](#42-测试数据准备) - [4.3 基于 Python 预测引擎推理](#43-基于-python-预测引擎推理) - [4.3.1 预测单张图像](#431-预测单张图像) - [4.3.2 基于文件夹的批量预测](#432-基于文件夹的批量预测) - [4.4 基于 C++ 预测引擎推理](#44-基于-c-预测引擎推理) - [4.5 服务化部署](#45-服务化部署) - [4.6 端侧部署](#46-端侧部署) - [4.7 Paddle2ONNX 模型转换与预测](#47-paddle2onnx-模型转换与预测) - [参考文献](#参考文献) ## 1. PP-ShiTuV2模型和应用场景介绍 PP-ShiTuV2 是基于 PP-ShiTuV1 改进的一个实用轻量级通用图像识别系统,由主体检测、特征提取、向量检索三个模块构成,相比 PP-ShiTuV1 具有更高的识别精度、更强的泛化能力以及相近的推理速度*。主要针对训练数据集、特征提取两个部分进行优化,使用了更优的骨干网络、损失函数与训练策略,使得 PP-ShiTuV2 在多个实际应用场景上的检索性能有显著提升。 **本文档提供了用户使用 PaddleClas 的 PP-ShiTuV2 图像识别方案进行快速构建轻量级、高精度、可落地的图像识别pipeline。该pipeline可以广泛应用于商场商品识别场景、安防人脸或行人识别场景、海量图像检索过滤等场景中。**
下表列出了 PP-ShiTuV2 用不同的模型结构与训练策略所得到的相关指标, | 模型 | 存储(主体检测+特征提取) | product | | :--------- | :---------------------- | :------------------ | | | | recall@1 | | PP-ShiTuV1 | 64(30+34)MB | 66.8% | | PP-ShiTuV2 | 49(30+19)MB | 73.8% | **注:** - recall及mAP指标的介绍可以参考 [常用指标](../algorithm_introduction/reid.md#22-常用指标)。 - 延时是基于 Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz 测试得到,开启 MKLDNN 加速策略,线程数为10。 ## 2. 模型快速体验 ### 2.1 PP-ShiTu android demo 快速体验 可以通过扫描二维码或者 [点击链接](https://paddle-imagenet-models-name.bj.bcebos.com/demos/PP-ShiTu.apk) 下载并安装APP
然后将以下体验图片保存到手机上:
打开安装好的APP,点击下方“**本地识别**”按钮,选择上面这张保存的图片,再点击确定,就能得到如下识别结果:
更详细的说明参考[PP-ShiTu android demo功能说明](https://github.com/weisy11/PaddleClas/blob/develop/docs/zh_CN/quick_start/quick_start_recognition.md) ### 2.2 命令行代码快速体验 - 首先按照以下命令,安装paddlepaddle和faiss ```shell # 如果您的机器安装的是 CUDA9 或 CUDA10,请运行以下命令安装 python3.7 -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple # 如果您的机器是CPU,请运行以下命令安装 python3.7 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple # 安装 faiss 库 python3.7 -m pip install faiss-cpu==1.7.1post2 ``` - 然后按照以下命令,安装paddleclas whl包 ```shell # 进入到PaddleClas根目录下 cd PaddleClas # 安装paddleclas python3.7 setup.py install ``` - 然后执行以下命令下载并解压好demo数据,最后执行一行命令体验图像识别 ```shell # 下载并解压demo数据 wget -nc https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/drink_dataset_v2.0.tar && tar -xf drink_dataset_v2.0.tar # 执行识别命令 paddleclas \ --model_name=PP-ShiTuV2 \ --infer_imgs=./drink_dataset_v2.0/test_images/100.jpeg \ --index_dir=./drink_dataset_v2.0/index/ \ --data_file=./drink_dataset_v2.0/gallery/drink_label.txt ``` ## 3 模块介绍与训练 ### 3.1 主体检测 主体检测是目前应用非常广泛的一种检测技术,它指的是检测出图片中一个或者多个主体的坐标位置,然后将图像中的对应区域裁剪下来进行识别。主体检测是识别任务的前序步骤,输入图像经过主体检测后再进行识别,可以过滤复杂背景,有效提升识别精度。 考虑到检测速度、模型大小、检测精度等因素,最终选择 PaddleDetection 自研的轻量级模型 `PicoDet-LCNet_x2_5` 作为 PP-ShiTuV2 的主体检测模型 主体检测模型的数据集、训练、评估、推理等详细信息可以参考文档:[picodet_lcnet_x2_5_640_mainbody](../image_recognition_pipeline/mainbody_detection.md)。 ### 3.2 特征提取 特征提取是图像识别中的关键一环,它的作用是将输入的图片转化为固定维度的特征向量,用于后续的 [向量检索](./vector_search.md) 。考虑到特征提取模型的速度、模型大小、特征提取性能等因素,最终选择 PaddleClas 自研的 [`PPLCNetV2_base`](../models/PP-LCNetV2.md) 作为特征提取网络。相比 PP-ShiTuV1 所使用的 `PPLCNet_x2_5`, `PPLCNetV2_base` 基本保持了较高的分类精度,并减少了40%的推理时间*。 **注:** *推理环境基于 Intel(R) Xeon(R) Gold 6271C CPU @ 2.60GHz 硬件平台,OpenVINO 推理平台。 在实验过程中我们也发现可以对 `PPLCNetV2_base` 进行适当的改进,在保持速度基本不变的情况下,让其在识别任务中得到更高的性能,包括:去掉 `PPLCNetV2_base` 末尾的 `ReLU` 和 `FC`、将最后一个 stage(RepDepthwiseSeparable) 的 stride 改为1。 特征提取模型的数据集、训练、评估、推理等详细信息可以参考文档:[PPLCNetV2_base_ShiTu](../image_recognition_pipeline/feature_extraction.md)。 ### 3.3 向量检索 向量检索技术在图像识别、图像检索中应用比较广泛。其主要目标是对于给定的查询向量,在已经建立好的向量库中进行特征向量的相似度或距离计算,返回候选向量的相似度排序结果。 在 PP-ShiTuV2 识别系统中,我们使用了 [Faiss](https://github.com/facebookresearch/faiss) 向量检索开源库对此部分进行支持,其具有适配性好、安装方便、算法丰富、同时支持CPU与GPU的优点。 PP-ShiTuV2 系统中关于 Faiss 向量检索库的安装及使用可以参考文档:[vector search](../image_recognition_pipeline/vector_search.md)。 ## 4. 推理部署 ### 4.1 推理模型准备 Paddle Inference 是飞桨的原生推理库, 作用于服务器端和云端,提供高性能的推理能力。相比于直接基于预训练模型进行预测,Paddle Inference可使用 MKLDNN、CUDNN、TensorRT 进行预测加速,从而实现更优的推理性能。更多关于 Paddle Inference 推理引擎的介绍,可以参考 [Paddle Inference官网教程](https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/infer/inference/inference_cn.html)。 当使用 Paddle Inference 推理时,加载的模型类型为 inference 模型。本案例提供了两种获得 inference 模型的方法,如果希望得到和文档相同的结果,请选择 [直接下载 inference 模型](#412-直接下载-inference-模型) 的方式。 #### 4.1.1 基于训练得到的权重导出 inference 模型 - 主体检测模型权重导出请参考文档 [主体检测推理模型准备](../image_recognition_pipeline/mainbody_detection.md#41-推理模型准备),或者参照 [4.1.2](#412-直接下载-inference-模型) 直接下载解压即可。 - 特征提取模型权重导出可以参考以下命令: ```shell python3.7 tools/export_model.py \ -c ./ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml \ -o Global.pretrained_model="https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/PPShiTuV2/general_PPLCNetV2_base_pretrained_v1.0.pdparams" \ -o Global.save_inference_dir=deploy/models/GeneralRecognitionV2_PPLCNetV2_base` ``` 执行完该脚本后会在 `deploy/models/` 下生成 `GeneralRecognitionV2_PPLCNetV2_base` 文件夹,具有如下文件结构: ```log deploy/models/ ├── GeneralRecognitionV2_PPLCNetV2_base │ ├── inference.pdiparams │ ├── inference.pdiparams.info │ └── inference.pdmodel ``` #### 4.1.2 直接下载 inference 模型 [4.1.1 小节](#411-基于训练得到的权重导出-inference-模型) 提供了导出 inference 模型的方法,此处提供我们导出好的 inference 模型,可以按以下命令,下载模型到指定位置解压进行体验。 ```shell cd deploy/models # 下载主体检测inference模型并解压 wget -nc https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar && tar -xf picodet_PPLCNet_x2_5_mainbody_lite_v1.0_infer.tar # 下载特征提取inference模型并解压 wget -nc https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/inference/PP-ShiTuV2/general_PPLCNetV2_base_pretrained_v1.0_infer.tar && tar -xf general_PPLCNetV2_base_pretrained_v1. ``` ### 4.2 测试数据准备 准备好主体检测、特征提取模型之后,还需要准备作为输入的测试数据,可以执行以下命令下载并解压测试数据。 ```shell # 返回deploy cd ../ # 下载测试数据drink_dataset_v2.0,并解压 wget -nc https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/drink_dataset_v2.0.tar && tar -xf drink_dataset_v2.0.tar ``` ### 4.3 基于 Python 预测引擎推理 #### 4.3.1 预测单张图像 然后执行以下命令对单张图像 `./drink_dataset_v2.0/test_images/100.jpeg` 进行识别。 ```shell # 执行下面的命令使用 GPU 进行预测 python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.infer_imgs="./drink_dataset_v2.0/test_images/100.jpeg" # 执行下面的命令使用 CPU 进行预测 python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.infer_imgs="./drink_dataset_v2.0/test_images/100.jpeg" -o Global.use_gpu=False ``` 最终输出结果如下。 ```log [{'bbox': [437, 71, 660, 728], 'rec_docs': '元气森林', 'rec_scores': 0.7740249}, {'bbox': [221, 72, 449, 701], 'rec_docs': '元气森林', 'rec_scores': 0.6950992}, {'bbox': [794, 104, 979, 652], 'rec_docs': '元气森林', 'rec_scores': 0.6305153}] ``` #### 4.3.2 基于文件夹的批量预测 如果希望预测文件夹内的图像,可以直接修改配置文件中的 Global.infer_imgs 字段,也可以通过下面的 -o 参数修改对应的配置。 ```shell # 使用下面的命令使用 GPU 进行预测 python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.infer_imgs="./drink_dataset_v2.0/test_images" # 使用下面的命令使用 CPU 进行预测 python3.7 python/predict_system.py -c configs/inference_general.yaml -o Global.infer_imgs="./drink_dataset_v2.0/test_images" -o Global.use_gpu=False ``` 终端中会输出该文件夹内所有图像的分类结果,如下所示。 ```log ... [{'bbox': [0, 0, 600, 600], 'rec_docs': '红牛-强化型', 'rec_scores': 0.74081033}] Inference: 120.39852142333984 ms per batch image [{'bbox': [0, 0, 514, 436], 'rec_docs': '康师傅矿物质水', 'rec_scores': 0.6918598}] Inference: 32.045602798461914 ms per batch image [{'bbox': [138, 40, 573, 1198], 'rec_docs': '乐虎功能饮料', 'rec_scores': 0.68214047}] Inference: 113.41428756713867 ms per batch image [{'bbox': [328, 7, 467, 272], 'rec_docs': '脉动', 'rec_scores': 0.60406065}] Inference: 122.04337120056152 ms per batch image [{'bbox': [242, 82, 498, 726], 'rec_docs': '味全_每日C', 'rec_scores': 0.5428652}] Inference: 37.95266151428223 ms per batch image [{'bbox': [437, 71, 660, 728], 'rec_docs': '元气森林', 'rec_scores': 0.7740249}, {'bbox': [221, 72, 449, 701], 'rec_docs': '元气森林', 'rec_scores': 0.6950992}, {'bbox': [794, 104, 979, 652], 'rec_docs': '元气森林', 'rec_scores': 0.6305153}] ... ``` 其中 `bbox` 表示检测出的主体所在位置,`rec_docs` 表示索引库中与检测框最为相似的类别,`rec_scores` 表示对应的相似度。 ### 4.4 基于 C++ 预测引擎推理 PaddleClas 提供了基于 C++ 预测引擎推理的示例,您可以参考 [服务器端 C++ 预测](../../../deploy/cpp_shitu/readme.md) 来完成相应的推理部署。如果您使用的是 Windows 平台,可以参考 [基于 Visual Studio 2019 Community CMake 编译指南](../inference_deployment/cpp_deploy_on_windows.md) 完成相应的预测库编译和模型预测工作。 ### 4.5 服务化部署 Paddle Serving 提供高性能、灵活易用的工业级在线推理服务。Paddle Serving 支持 RESTful、gRPC、bRPC 等多种协议,提供多种异构硬件和多种操作系统环境下推理解决方案。更多关于Paddle Serving 的介绍,可以参考 [Paddle Serving 代码仓库](https://github.com/PaddlePaddle/Serving)。 PaddleClas 提供了基于 Paddle Serving 来完成模型服务化部署的示例,您可以参考 [模型服务化部署](../inference_deployment/recognition_serving_deploy.md) 来完成相应的部署工作。 ### 4.6 端侧部署 Paddle Lite 是一个高性能、轻量级、灵活性强且易于扩展的深度学习推理框架,定位于支持包括移动端、嵌入式以及服务器端在内的多硬件平台。更多关于 Paddle Lite 的介绍,可以参考 [Paddle Lite 代码仓库](https://github.com/PaddlePaddle/Paddle-Lite)。 ### 4.7 Paddle2ONNX 模型转换与预测 Paddle2ONNX 支持将 PaddlePaddle 模型格式转化到 ONNX 模型格式。通过 ONNX 可以完成将 Paddle 模型到多种推理引擎的部署,包括TensorRT/OpenVINO/MNN/TNN/NCNN,以及其它对 ONNX 开源格式进行支持的推理引擎或硬件。更多关于 Paddle2ONNX 的介绍,可以参考 [Paddle2ONNX 代码仓库](https://github.com/PaddlePaddle/Paddle2ONNX)。 PaddleClas 提供了基于 Paddle2ONNX 来完成 inference 模型转换 ONNX 模型并作推理预测的示例,您可以参考 [Paddle2ONNX 模型转换与预测](../../../deploy/paddle2onnx/readme.md) 来完成相应的部署工作。 ## 参考文献 1. Schall, Konstantin, et al. "GPR1200: A Benchmark for General-Purpose Content-Based Image Retrieval." International Conference on Multimedia Modeling. Springer, Cham, 2022. 2. Luo, Hao, et al. "A strong baseline and batch normalization neck for deep person re-identification." IEEE Transactions on Multimedia 22.10 (2019): 2597-2609.