PaddleClas PULC 行人属性识别模型:基于 PP-LCNet 的轻量级多标签分类实战指南
PaddleClas PULC 行人属性识别模型:基于 PP-LCNet 的轻量级多标签分类实战指南
导读
本文围绕 PaddleClas 仓库中 PULC(Practical Ultra Lightweight image Classification,实用超轻量图像分类)方案下的行人属性识别(Person Attribute)模型展开,系统讲解如何基于 PPLCNet_x1_0.yaml 完成从数据准备、训练、评估、知识蒸馏到推理部署的完整链路。读完本文,你将掌握:行人属性多标签分类的标签编码与后处理规则、PULC 训练配置中 EDA(数据增强)与 SKL-UGI 蒸馏策略的具体用法、超参数搜索方法,以及 Paddle Inference / Paddle Serving / Paddle-Lite / ONNX 等多端部署的实操命令。本文主体基于 PULC_person_attribute_en.md,并辅以仓库源码与配置进行纵深印证。
1. 模型概述与精度-速度权衡
行人属性识别是行人分析(Pedestrian Analysis)、行人跟踪(Pedestrian Tracking)等场景中的核心能力,需要从单张行人图像中同时输出性别、年龄、朝向、配饰、背包、上下装款式、鞋靴等多维属性。PaddleClas PULC 方案的目标是在保证实用精度的前提下,将模型做到极致轻量。
下表列出了 PULC 行人属性模型的指标演进(ma 为多标签平均准确率,Latency 为 CPU 单图延迟,Size 为模型体积):
| Backbone | ma(%) | Latency(ms) | Size(M) | Training Strategy |
|---|---|---|---|---|
| Res2Net200_vd_26w_4s | 81.25 | 77.51 | 293 | using ImageNet pretrained |
| SwinTransformer_tiny | 80.17 | 89.51 | 111 | using ImageNet pretrained |
| MobileNetV3_small_x0_35 | 70.79 | 2.90 | 1.7 | using ImageNet pretrained |
| PPLCNet_x1_0 | 76.31 | 2.01 | 7.1 | using ImageNet pretrained |
| PPLCNet_x1_0 | 77.31 | 2.01 | 7.1 | using SSLD pretrained |
| PPLCNet_x1_0 | 77.71 | 2.01 | 7.1 | using SSLD pretrained + EDA strategy |
| PPLCNet_x1_0 | 78.59 | 2.01 | 7.1 | using SSLD pretrained + EDA strategy + SKL-UGI knowledge distillation strategy |
从上表可以清晰看到 PULC 方案的精度-速度权衡路径:
- 大模型(Res2Net200_vd_26w_4s、SwinTransformer_tiny)ma 最高,但延迟高达 77~90ms,不适合端侧或高吞吐场景;
- 直接换用轻量主干 MobileNetV3_small_x0_35 虽快(2.90ms),但 ma 掉到 70.79%;
- 换用 PPLCNet_x1_0 后,ma 比 MobileNetV3_small_x0_35 高出 5.5 个百分点以上,且速度还快 20% 以上;
- 叠加 SSLD 预训练,ma 提升约 1 个百分点(不增加推理开销);
- 再叠加 EDA 策略,ma 再提升 0.4 个百分点;
- 最后叠加 SKL-UGI 知识蒸馏,ma 再提升 0.88 个百分点。
最终 PPLCNet_x1_0 的 ma(78.59%)与 SwinTransformer_tiny(80.17%)仅差 1.58 个百分点,但推理速度是后者的 44 倍以上——这正是 PULC 轻量实用路线的价值所在。
注意:表中的 Latency 测试环境为 Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz,开启 MKLDNN,线程数为 10。关于 PP-LCNet 更多信息可参考 PP-LCNet 介绍。
2. 快速开始
2.1 安装 PaddlePaddle
根据本机环境二选一执行:
# CUDA9 / CUDA10 环境,安装 GPU 版本
python3 -m pip install paddlepaddle-gpu -i https://mirror.baidu.com/pypi/simple
# 无 GPU 环境,安装 CPU 版本
python3 -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
其他版本(如不同 CUDA 版本)的安装方式请参考 PaddlePaddle 官方安装文档。
2.2 安装 PaddleClas wheel 包
pip3 install paddleclas
PaddleClas 以 wheel 包形式提供开箱即用的推理接口,模型权重会自动下载,无需手动准备模型文件。
2.3 预测
首先下载演示图片并解压:
wget https://paddleclas.bj.bcebos.com/data/PULC/pulc_demo_imgs.zip && unzip pulc_demo_imgs.zip
CLI 方式
paddleclas --model_name=person_attribute --infer_imgs=pulc_demo_imgs/person_attribute/090004.jpg
输出示例:
>>> result
attributes: ['Male', 'Age18-60', 'Back', 'Glasses: False', 'Hat: False', 'HoldObjectsInFront: False', 'Backpack', 'Upper: LongSleeve UpperPlaid', 'Lower: Trousers', 'No boots'], output: [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1], filename: pulc_demo_imgs/person_attribute/090004.jpg
Predict complete!
--infer_imgs 同时支持单张图片路径与图片目录路径,目录内所有图片会被依次预测。
Python 方式
import paddleclas
model = paddleclas.PaddleClas(model_name="person_attribute")
result = model.predict(input_data="pulc_demo_imgs/person_attribute/090004.jpg")
print(next(result))
注意:model.predict() 返回的是生成器(generator),需要用 next() 或 for 循环逐批获取结果;每批大小由 batch_size 决定,默认为 1,实例化时可指定,例如 model = paddleclas.PaddleClas(model_name="person_attribute", batch_size=2)。输出示例:
[{'attributes': ['Male', 'Age18-60', 'Back', 'Glasses: False', 'Hat: False', 'HoldObjectsInFront: False', 'Backpack', 'Upper: LongSleeve UpperPlaid', 'Lower: Trousers', 'No boots'], 'output': [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1], 'filename': 'pulc_demo_imgs/person_attribute/090004.jpg'}]
2.4 输出向量与属性标签的对应关系
output 是一个长度为 26 的 0/1 向量(模型 class_num 为 26),其索引含义为:索引 0 表示是否戴帽子,索引 1 表示是否戴眼镜,索引 2-7 表示上衣款式,索引 8-13 表示下装款式,索引 14 表示是否穿靴子,索引 15-17 表示背包类型,索引 18 表示胸前是否持有物品,索引 19-21 表示年龄段,索引 22 表示性别,索引 23-25 表示朝向。完整编码逻辑可查看 ppcls/data/postprocess/attr_rec.py 中的 PersonAttribute 类实现。
行人属性具体包含以下类别:
- Gender: Male Female
- Age: AgeLess18, Age18-60, AgeOver60
- Direction: Front, Side, Back
- Accessories: glasses, hat, none
- Front holding: yes, no
- Bags: Backpack, Shoulder, Handbag
- Upper styles: UpperStride, UpperLogo, UpperPlaid, UpperSplice
- Lower style: LowerStripe, LowerPattern
- Short sleeved: yes, no
- Long sleeved: yes, no
- Long coat: yes, no
- Trousers: yes, no
- Shorts: yes, no
- Skirts & Skirts: Yes, No
- Wear boots: yes, no
值得说明的是,26 维输出并非全部是独立二分类:性别、朝向、包类、年龄段内部是互斥多选一(后处理中取 argmax),而上下装款式等是多标签可叠加输出(逐一与阈值比较)。这一点在 PersonAttribute 后处理实现 中可以清晰看到:age_list、direct_list、bag_list 分别对 19:22、23:26、15:18 区间取 argmax,而上衣、下装则在阈值之上逐一拼接。
3. 训练、评估与推理
3.1 安装
PaddleClas 源码安装方式请参考 安装说明。
3.2 数据集
3.2.1 数据集简介
本案例使用 PA100K 数据集(行人属性公开数据集)。PaddleClas 已将其转换为可直接下载的多标签(multi-label)可读数据格式。
3.2.2 获取数据集
进入仓库根目录后,在 dataset/ 下下载并解压:
cd dataset
wget https://paddleclas.bj.bcebos.com/data/PULC/pa100k.tar
tar -xf pa100k.tar
cd ../
解压后的 pa100k 目录结构如下:
pa100k
├── train
│ ├── 000001.jpg
│ ├── 000002.jpg
...
├── val
│ ├── 080001.jpg
│ ├── 080002.jpg
...
├── test
│ ├── 090001.jpg
│ ├── 090002.jpg
...
├── train_list.txt
├── train_val_list.txt
├── val_list.txt
├── test_list.txt
其中 train/、val/、test/ 分别为训练集、验证集、测试集;train_list.txt、val_list.txt、test_list.txt 为对应划分的标签文件。本案例暂时不使用 test_list.txt。
3.3 训练
训练配置位于 ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml,训练命令如下:
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml
验证集最优 ma 约为 77.71%(数据集较小,通常会在 0.3% 左右波动)。
训练配置逐段解读
结合仓库源码,对该配置文件的关键段落说明如下:
- Global 段:
epochs: 20、image_shape: [3, 256, 192](注意 PaddleClas 中为 HWC 语义下的 [H, W] = [256, 192],输入为 192×256 分辨率)、use_multilabel: True(标志多标签任务,驱动数据集与损失函数走多标签分支); - Arch 段:
name: "PPLCNet_x1_0"、pretrained: True、use_ssld: True(使用 SSLD 蒸馏得到的 PP-LCNet 预训练权重,对应表格中第 5 行的效果来源)、class_num: 26(与 26 维属性向量一一对应); - Loss 段:训练与评估均使用
MultiLabelLoss,并开启weight_ratio: True(利用标签文件中携带的类别正样本比例做加权)与size_sum: True。其底层实现在 ppcls/loss/multilabelloss.py:_binary_crossentropy中调用F.binary_cross_entropy_with_logits,weight_ratio开启时通过ratio2weight函数根据正负样本比例构造指数形式的样本权重,缓解行人属性数据集的类别不均衡问题; - Optimizer 段:Momentum(momentum=0.9)+ Cosine 学习率(初始 0.01,前 5 个 epoch warmup)+ L2 正则(coeff 0.0005);
- DataLoader.Train 段:
MultiLabelDataset,label_ratio: True(标签文件附带每类正样本比例)。预处理链依次为DecodeImage→ResizeImage([192, 256])→TimmAutoAugment(概率 0.8,rand-m9-mstd0.5-inc1策略,bicubic 插值)→Padv2(先 pad 到 212×276,mode 1,填充 0)→RandomCropImage([192, 256])→RandFlipImage(水平翻转)→NormalizeImage(ImageNet 均值方差)→RandomErasing(EPSILON 0.4,即 erasing 概率)。其中 TimmAutoAugment、RandomErasing 等组合即文档所述的 EDA(Enhanced Data Augmentation)策略,是 77.31%→77.71% 那 0.4 个百分点的来源; - Infer 段:
infer_imgs默认指向deploy/images/PULC/person_attribute/090004.jpg;PostProcess.name: PersonAttribute,并设置了三个阈值:默认threshold: 0.5、眼镜专用glasses_threshold: 0.3(眼镜正例偏少,放宽阈值召回)、胸前持有物专用hold_threshold: 0.6(降低误报)。这三个阈值会在 PersonAttribute 后处理 中被分别用于对应属性; - Metric 段:
ATTRMetric,其实现位于 ppcls/metric/metrics.py,内部封装AttrMeter计算多标签准确率(即 ma),用于评估阶段输出与最优模型选择。
3.4 评估
python3 tools/eval.py \
-c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml \
-o Global.pretrained_model="output/PPLCNet_x1_0/best_model"
其中 -o Global.pretrained_model="output/PPLCNet_x1_0/best_model" 指定最优权重路径,可按需替换为其他路径。
3.5 推理
python3 tools/infer.py \
-c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml \
-o Global.pretrained_model=output/PPLCNet_x1_0/best_model
结果示例:
[{'attributes': ['Male', 'Age18-60', 'Back', 'Glasses: False', 'Hat: False', 'HoldObjectsInFront: False', 'Backpack', 'Upper: LongSleeve UpperPlaid', 'Lower: Trousers', 'No boots'], 'output': [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1]}]
注意:默认测试图为 deploy/images/PULC/person_attribute/090004.jpg;测试其他图片只需指定 -o Infer.infer_imgs=path_to_test_image。
4. 模型压缩:SKL-UGI 知识蒸馏
SKL-UGI 是 PaddleClas 提出的一种简单但有效的知识蒸馏算法(SKL 指 Soft/Kernel Label 软标签蒸馏,UGI 指 UN-Used-Image 无标签图片数据的利用)。行人属性 PULC 方案采用 ResNet101_vd 作为教师模型、PPLCNet_x1_0 作为学生模型 的组合。
4.1 教师模型训练
教师模型沿用 PPLCNet_x1_0.yaml 的超参数,仅通过 -o Arch.name=ResNet101_vd 替换主干:
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml \
-o Arch.name=ResNet101_vd
验证集最优 ma 约为 80.10%,最优教师权重保存在 output/ResNet101_vd/best_model.pdparams。
4.2 知识蒸馏训练
蒸馏训练配置位于 ppcls/configs/PULC/person_attribute/PPLCNet_x1_0_Distillation.yaml,命令如下:
export CUDA_VISIBLE_DEVICES=0,1,2,3
python3 -m paddle.distributed.launch \
--gpus="0,1,2,3" \
tools/train.py \
-c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0_Distillation.yaml \
-o Arch.models.0.Teacher.pretrained=output/ResNet101_vd/best_model
验证集最优 ma 约为 78.5%,最优学生权重保存在 output/DistillationModel/best_model_student.pdparams。
蒸馏配置要点
从蒸馏配置文件中可以提炼出 SKL-UGI 在 PULC 行人属性场景的工程化要点:
- Arch 段:
name: "DistillationModel",models列表内依次定义Teacher(ResNet101_vd,蒸馏时加载已训好的教师权重)与Student(PPLCNet_x1_0,pretrained: True+use_ssld: True);freeze_params_list: [True, False]表示冻结教师参数、只训练学生;infer_model_name: "Student"指明导出/推理时使用学生分支; - Loss 段:训练时同时使用
DistillationDMLLoss(教师与学生 logits 之间的 DML 蒸馏损失,实现见 ppcls/loss/distillationloss.py 的DistillationDMLLoss类,其model_name_pairs: [["Student", "Teacher"]]指定配对关系)与DistillationMultiLabelLoss(学生分支自身接多标签 BCE 损失),二者权重均为 1.0;评估时仍用标准MultiLabelLoss; - 其余 Global / Optimizer / DataLoader / Infer 段与普通训练配置一致,即蒸馏在相同数据与增强策略下进行。
5. 超参数搜索(可选)
第 3.2 节与 4.1 节所使用的超参数,来自 PaddleClas 的 Hyperparameters Searching(SHAS) 机制。若要在自有数据集上获得更优结果,可参考 PULC 训练文档 中的搜索章节。
注意:本节可选执行。搜索过程耗时较长,请根据实际情况决定是否运行;若未更换数据集,可跳过本节。
仓库中已附带行人属性场景的搜索配置 ppcls/configs/PULC/person_attribute/search.yaml,其结构展示了 SHAS 的搜索维度:
base_config_file/distill_config_file:普通训练与蒸馏训练的基配置;gpus: 0,1,2,3、output_dir: output/search_attr、search_times: 1:搜索资源与轮次;search_dict定义了五个搜索维度及其候选值:lrs:初始学习率,候选[0.0001, 0.005, 0.01, 0.02, 0.05];resolutions:训练分辨率,候选[[192, 256]],同时联动修改ResizeImage.size、RandomCropImage.size、TimmAutoAugment.img_size三处;ra_probs:TimmAutoAugment 概率,候选[0.0, 0.2, 0.4, 0.6, 0.8, 1.0];re_probs:RandomErasing 概率(EPSILON),候选[0.0, 0.2, 0.4, 0.6, 0.8, 1.0];lr_mult_list:PP-LCNet 各 stage 的层间学习率倍率,候选三组不同分布;
teacher段:教师模型候选ResNet101_vd、ResNet50_vd,并指定蒸馏时需移除的键(如Arch.lr_mult_list);final_replace:将搜索得到的学生lr_mult_list回填到蒸馏配置的Arch.models.1.Student.lr_mult_list。
配套的 PPLCNet_x1_0_search.yaml 即为搜索基配置(其中 TimmAutoAugment.prob: 0.0、RandomErasing.EPSILON: 0.0 表示搜索起点为不启用增强)。
6. 推理部署
Paddle Inference 是 PaddlePaddle 官方推理库,相比直接加载预训练模型,推理模型可借助算子融合、IR 优化等工具加速,获得更好的服务端推理性能。
6.1 获取 Paddle Inference 模型
6.1.1 导出推理模型
python3 tools/export_model.py \
-c ./ppcls/configs/PULC/person_attribute/PPLCNet_x1_0.yaml \
-o Global.pretrained_model=output/DistillationModel/best_model_student \
-o Global.save_inference_dir=deploy/models/PPLCNet_x1_0_person_attribute_infer
执行后推理模型保存在指定目录:
├── PPLCNet_x1_0_person_attribute_infer
│ ├── inference.pdiparams
│ ├── inference.pdiparams.info
│ └── inference.pdmodel
注意:上述命令加载的是蒸馏训练得到的最优学生权重;若未做蒸馏训练,应使用 output/PPLCNet_x1_0/best_model.pdparams。
6.1.2 直接下载推理模型
也可以跳过导出,直接下载 PaddleClas 提供的推理模型:
cd deploy/models
wget https://paddleclas.bj.bcebos.com/models/PULC/person_attribute_infer.tar && tar -xf person_attribute_infer.tar
解压后 deploy/models/person_attribute_infer/ 下包含 inference.pdmodel、inference.pdiparams、inference.pdiparams.info 三个文件。
6.2 Python 预测(Paddle Inference)
回到 deploy 目录后,使用 deploy/python/predict_cls.py 配合部署配置 deploy/configs/PULC/person_attribute/inference_person_attribute.yaml 进行预测。
6.2.1 单图预测
# GPU 预测
python3.7 python/predict_cls.py -c configs/PULC/person_attribute/inference_person_attribute.yaml -o Global.use_gpu=True
# CPU 预测
python3.7 python/predict_cls.py -c configs/PULC/person_attribute/inference_person_attribute.yaml -o Global.use_gpu=False
输出示例:
090004.jpg: {'attributes': ['Male', 'Age18-60', 'Back', 'Glasses: False', 'Hat: False', 'HoldObjectsInFront: False', 'Backpack', 'Upper: LongSleeve UpperPlaid', 'Lower: Trousers', 'No boots'], 'output': [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1]}
6.2.2 目录批量预测
将 Global.infer_imgs 指定为目录路径即可批量预测:
python3.7 python/predict_cls.py -c configs/PULC/person_attribute/inference_person_attribute.yaml -o Global.infer_imgs="./images/PULC/person_attribute/"
输出示例:
090004.jpg: {'attributes': ['Male', 'Age18-60', 'Back', ...]}
090007.jpg: {'attributes': ['Female', 'Age18-60', 'Side', 'Glasses: False', 'Hat: False', 'HoldObjectsInFront: False', 'No bag', 'Upper: ShortSleeve', 'Lower: Skirt&Dress', 'No boots'], 'output': [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0]}
(原文档此处将 someone/nobody 描述为图中是否有人,实际 PULC 人属性输出为 attributes 与 26 维 output 向量。)
部署配置关键参数
inference_person_attribute.yaml 中值得关注的参数:
Global段:inference_model_dir: "./models/person_attribute_infer"(指向下载或导出的推理模型目录)、use_gpu、enable_mkldnn: True+cpu_num_threads: 10(CPU 场景开启 MKLDNN 并设定线程数)、ir_optim: True(IR 优化)、use_tensorrt/use_fp16/gpu_mem(GPU 加速选项);PreProcess段:推理预处理只需ResizeImage([192, 256])→NormalizeImage→ToCHWImage,不含训练时的数据增强,与训练配置中Infer.transforms一致;PostProcess段:main_indicator: PersonAttribute,并保留threshold: 0.5、glasses_threshold: 0.3、hold_threshold: 0.6三个后处理阈值。
从 predict_cls.py 的实现可以看到完整调用链:ClsPredictor 按 PreProcess.transform_ops 构造预处理算子链、按 PostProcess 构建后处理器,预测时将批量图像预处理后送入 Paddle Inference predictor,输出经 build_postprocess 构造的 PersonAttribute 后处理转为属性文本与 0/1 向量,最后在 main() 中按批打印结果。
6.3 C++ 部署
PaddleClas 提供了 C++ 部署示例,详见 C++ 部署文档(对应仓库 deploy/cpp 中的实现)。
6.4 服务化部署(Paddle Serving)
Paddle Serving 是灵活的机器学习模型高性能服务化载体,支持 RESTful、gRPC、bRPC 等多种协议,可为多种异构硬件与操作系统环境提供部署方案。PaddleClas 提供了基于 Paddle Serving 的服务化部署示例,详见 分类服务化部署文档(对应 deploy/paddleserving)。
6.5 移动端部署(Paddle-Lite)
Paddle-Lite 是面向移动端、嵌入式与 IoT 设备的开源深度学习推理框架。PaddleClas 提供了 Paddle-Lite 移动端部署示例,详见 Paddle-Lite 部署文档(对应 deploy/lite)。
6.6 转 ONNX 并部署
Paddle2ONNX 可将 Paddle Inference 模型转换为 ONNX 模型,进而部署到 TensorRT、OpenVINO、MNN/TNN、NCNN 等不同推理引擎。转换与 ONNX 推理细节参见 deploy/paddle2onnx/readme_en.md。
7. 总结:从配置到落地的完整路径
PULC 行人属性识别方案的完整落地路径可归纳为四步:
- 数据:下载 PA100K 多标签格式数据(
train_list.txt等标签文件需附带类别比例,供MultiLabelLoss的weight_ratio加权使用); - 训练:以 PPLCNet_x1_0.yaml 为基线,依次叠加 SSLD 预训练、EDA 增强与 SKL-UGI 蒸馏(PPLCNet_x1_0_Distillation.yaml),可参考 search.yaml 在自有数据集上搜索更优超参;
- 导出:用
tools/export_model.py将学生模型导出为 Paddle Inference 格式(inference.pdmodel/inference.pdiparams); - 部署:按算力与场景选择 Python(predict_cls.py)、C++、Paddle Serving、Paddle-Lite 或 ONNX 任一通道,统一复用 inference_person_attribute.yaml 中的预处理与阈值配置。
最终效果是:在保持 7.1M 模型体积、2.01ms CPU 延迟的同时,将行人属性识别 ma 提升至 78.59%,与大模型(SwinTransformer_tiny,80.17%)精度仅差 1.58 个百分点——这正是 PULC 方案面向真实业务场景的工程价值所在。