16 KiB
目标检测全流程教程
本教程以路标数据集为例,使用YOLOv3算法详细说明了PaddleDetection全流程使用教程,包括:准备数据、选择模型、训练模型、评估、预测、模型压缩和模型部署。
目录
准备数据
PaddleDetection默认支持COCO和Pascal VOC 和WIDER-FACE 数据。
详细的数据准备文档请参考如何准备训练数据。
如果您的数据为VOC标注形式,最终数据集文件组织结构如下。
├── annotations
│ ├── road0.xml
│ ├── road1.xml
│ ├── road10.xml
│ | ...
├── images
│ ├── road0.jpg
│ ├── road1.jpg
│ ├── road2.jpg
│ | ...
├── label_list.txt
├── train.txt
└── valid.txt
各个文件说明
# label_list.txt 是类别名称列表,指定了类别名称和类别id的映射关系
>>cat label_list.txt
classname1
classname2
...
# train.txt 是训练数据文件列表,每一行包括一条图像路径和图像对应标注xml文件路径(路径是相对于data_dir的路径或者全局路径),中间以空格隔开
>>cat train.txt
./images/xxx1.jpg ./annotations/xxx1.xml
./images/xxx2.jpg ./annotations/xxx2.xml
...
# valid.txt 是验证数据文件列表
>>cat valid.txt
./images/xxx3.jpg ./annotations/xxx3.xml
...
如果您的数据为COCO标注形式,最终数据集文件组织结构为:
dataset/xxx/
├── annotations
│ ├── train.json # 训练集标注文件
│ ├── valid.json # 验证集标注文件
├── images
│ ├── xxx1.jpg
│ ├── xxx2.jpg
│ ├── xxx3.jpg
│ | ...
...
本教程以Kaggle数据集 比赛数据为例,包含877张图像,数据类别4类:speedlimit,crosswalk,trafficlight,stop。
我们将数据集划分为训练集(701张图)和测试集(176张图),下载连接为:VOC标注roadsign_voc 和 COCO标注roadsign_coco 。
路标数据集示例图:
注意:
(1)数据集中路径名、文件名不要包含空格,尽量不要使用中文
(2)用户数据,建议在训练前仔细检查 数据,避免因数据标注格式错误或图像数据不完整造成训练过程中的中断
(2)如果图像尺寸太大的话,在不限制读入数据尺寸情况下,占用内存较多,会造成内存/显存溢出,请合理设置batch_size,可从小到大尝试
模型选择
PaddleDetection中提供了丰富的模型库,具体可在模型库中查看各个模型的指标,您可依据实际部署算力的情况,选择合适的模型。
本教程选用YOLOv3作为训练模型。
选择和修改配置文件
您可以在模型库中找到模型的指标,以及模型的配置文件(配置文件存放在configs/
文件夹下)和预训练权重地址。
关于配置文件中参数详细解释,请参考:
配置文件设计思路请参考文档 配置模块设计与介绍
如何新增模型请参考文档 新增模型算法
配置文件中部分参数介绍
-
1、max_iters
max_iters为最大迭代次数,而一个iter会运行batch_size * device_num
张图片。 注意:
(1)LearningRate.schedulers.milestones
需要随max_iters
变化而变化。 (2)milestones
设置的是在PiecewiseDecay学习率调整策略中,在训练轮数达到milestones
中设置的轮数时,学习率以gamma
倍数衰减变化。
(3) 1x表示训练12个epoch,1个epoch是将所有训练数据训练一轮。由于YOLO系列算法收敛比较慢,在COCO数据集上YOLO系列算法换算后约为270 epoch,PP-YOLO约380 epoch。 -
2、pretrain_weights
pretrain_weights 参数用于设置预训练模型路径,可以设置为本地路径,也可以设置为远程路径。
pretrain_weights 可以是:- 在ImageNet数据集上的预训练的分类模型权重,各个模型请参考PaddleModels
- 在VOC或COCO数据集上的预训练的检测模型权重,各个模型请参考 检测模型库
注意:加载模型时网络结构中和预训练模型中形状不匹配的参数将自动被忽略。
-
3、save_dir
save_dir 参数用于设置训练时模型保存文件夹,PaddleDetection会在save_dir
文件夹下新建一个与指定的配置文件同名的子文件夹,并将模型存在这个子文件夹下。当开启--eval
,会在这个子文件夹下保存名为best_model
的模型文件。
注意:
(1) 老版本模型权重文件是以.tar
为后缀的文件,新版本模型权重文件是以.pdparams
为后缀的文件。
(2) 新版Paddle在训练过程中会保存2个文件:
- 优化相关:xxx.pdopt
- 模型权重:xxx.pdparams
-
4、weights
weights 参数用于设置评估预测使用的模型路径,这里可以是远程路径。
本地路径是指以pdparams
为后缀的模型权重文件。 -
5、metric 评估度量方式 mAP的metric评估方式可以选择COCO和VOC或WIDERFACE,其中VOC有
11point
和integral
两种评估方法 -
6、num_classes 模型中分类数 num_classes 模型中分类数量。注意在FasterRCNN中,需要将
with_background=true 且 num_classes=数据num_classes + 1
-
7、dataset路径设置
dataset_dir
: 数据路径设置image_dir
: 图像文件夹路径,相对于dataset_dir
的相对路径,也可以设置为全局路径。anno_path
:- 训练和评估时,表示标注文件路径,相对于
dataset_dir
的相对路径,也可以设置为全局路径。 - 测试时,表示类别映射文件路径,相对于
dataset_dir
的相对路径,也可以设置为全局路径。VOC
数据中是lable_list.txt
文件路径,COCO
数据中是包含类别的json
文件路径。
- 训练和评估时,表示标注文件路径,相对于
图像路径 =
os.path.join(dataset_dir, image_dir, image_path)
,image_path
来自train.txt
中 xml标注文件路径 =os.path.join(dataset_dir, image_dir, xml_path)
,xml_path
来自train.txt
中 -
8、with_background with_background 用于设置是否包含背景类。注意在FasterRCNN中,需要将
with_background=true 且 num_classes+1
-
9、inputs_def 设置 inputs_def 请参各个算法的配置文件设置
-
10、base_lr base_lr 配合 batch_size调整,参考 学习率调整策略
在使用ImageNet的预训练模型时,训练时使用1张卡,单卡batch_size=1, base_lr=0.00125,base_lr随着(batch_size * GPU卡数)
等比例变化。
若loss出现nan,请将学习率再设置小一些试试。 -
11、batch_size 请根据硬件设置batch_size大小。若需要设置内存使用量请参考如何设置内存使用量
-
12、sample_transforms and batch_transforms
sample_transforms是针对单张图像的操作,batch_transforms是针对一个batch数据的操作。文档请参考数据处理模块.
configs中的sample_transforms
,各个函数说明请参考ppdet/data/transform/operators.py
configs中的batch_transforms
,各个函数说明请参考ppdet/data/transform/batch_operators.py
训练
可以通过命令行tools/train.py
设置参数,其中的-o
参数可以覆盖设置配置文件里的参数。
tools/train.py
训练参数列表
以下列表可以通过--help
查看
FLAG | 支持脚本 | 用途 | 默认值 | 备注 |
---|---|---|---|---|
-c | ALL | 指定配置文件 | None | 配置模块说明请参考配置模块 |
-o | ALL | 设置配置文件里的参数内容 | None | 使用-o配置相较于-c选择的配置文件具有更高的优先级。例如:-o use_gpu=False max_iter=10000 |
-r/--resume_checkpoint | train | 从某一检查点恢复训练 | None | -r output/faster_rcnn_r50_1x/10000 |
--eval | train | 是否边训练边测试 | False | |
--output_eval | train/eval | 编辑评测保存json路径 | 当前路径 | --output_eval ./json_result |
--fp16 | train | 是否使用混合精度训练模式 | False | 需使用GPU训练 |
--loss_scale | train | 设置混合精度训练模式中损失值的缩放比例 | 8.0 | 需先开启--fp16 后使用 |
--json_eval | eval | 是否通过已存在的bbox.json或者mask.json进行评估 | False | json文件路径在--output_eval 中设置 |
--output_dir | infer | 输出预测后可视化文件 | ./output |
--output_dir output |
--draw_threshold | infer | 可视化时分数阈值 | 0.5 | --draw_threshold 0.7 |
--infer_dir | infer | 用于预测的图片文件夹路径 | None | |
--infer_img | infer | 用于预测的图片路径 | None | 相较于--infer_dir 具有更高优先级 |
--use_vdl | train/infer | 是否使用VisualDL 记录数据,进而在VisualDL面板中显示 | False | VisualDL需Python>=3.5 |
--vdl_log_dir | train/infer | 指定 VisualDL 记录数据的存储路径 | train:vdl_log_dir/scalar infer: vdl_log_dir/image |
VisualDL需Python>=3.5 |
注意:
参数设置优先级, 命令行 -o 选项参数设置的优先级 > 配置文件参数设置优先级 > 配置文件中的__READER__.yml
中的参数设置优先级,高优先级会覆盖低优先级的参数设置
开始训练
python tools/train.py -c configs/yolov3_mobilenet_v1_roadsign.yml -o use_gpu=true --eval
通过visualdl命令实时查看变化曲线
# 设置visualdl参数
python tools/train.py -c configs/yolov3_mobilenet_v1_roadsign.yml --eval -o use_gpu=true --use_vdl=True --vdl_log_dir=vdl_dir/scalar
# 打开visualdl
visualdl --logdir vdl_dir/scalar/ --host <host_IP> --port <port_num>
分布式训练
PaddleDetection还支持分布式训练,并行训练方式速度较快,可以使用tools/train_multi_machine.py
可以启动分布式训练。
目前同时支持单机单卡、单机多卡与多机多卡的训练过程,其训练参数与tools/train.py
完全一致。
如单机多卡训练:
python -m paddle.distributed.launch \
--selected_gpus 0,1,2,3,4,5,6,7 \
tools/train_multi_machine.py \
-c configs/yolov3_mobilenet_v1_roadsign.yml
详细请参考文档分布式训练.
评估和预测
评估
- 使用配置文件中
weights
参数设定的权重文件进行评估
# 默认使用训练过程中保存的best_model,评估需使用单卡评估
CUDA_VISIBLE_DEVICES=0 python tools/eval.py -c configs/yolov3_mobilenet_v1_roadsign.yml -o use_gpu=true
- 通过
weights
参数指定权重文件进行评估
# 指定模型评估
CUDA_VISIBLE_DEVICES=0 python tools/eval.py -c configs/yolov3_mobilenet_v1_roadsign.yml -o use_gpu=true weights=output/yolov3_mobilenet_v1_roadsign/best_model
- 通过设置
save_prediction_only
参数保存评估结果,生成bbox.json
文件
# 设置 save_prediction_only=true,会在当前文件夹下生成预测结果文件bbox.json
CUDA_VISIBLE_DEVICES=0 python tools/eval.py -c configs/yolov3_mobilenet_v1_roadsign.yml -o use_gpu=true save_prediction_only=true
预测
# 预测结束后会在output文件夹中生成一张画有预测结果的同名图像
python tools/infer.py -c configs/yolov3_mobilenet_v1_roadsign.yml --infer_img=demo/road554.png
推理部署
在模型部署之前,如果您需要对模型进行压缩,PaddleDetection
提供了基于PaddleSlim 进行模型压缩的完整教程和实验结果,详细请参考:量化、剪枝、蒸馏、搜索 。
PaddleDetection
目前支持以下部署方式:
详细部署文档请参考PaddleDetection预测部署文档。这里以PaddleServing部署方式为例说明。
安装paddle-serving-client
和paddle-serving-server
# 安装 paddle-serving-client
pip install paddle-serving-client -i https://mirror.baidu.com/pypi/simple
# 安装 paddle-serving-server
pip install paddle-serving-server -i https://mirror.baidu.com/pypi/simple
# 安装 paddle-serving-server-gpu
pip install paddle-serving-server-gpu -i https://mirror.baidu.com/pypi/simple
导出模型
python tools/export_serving_model.py -c configs/yolov3_mobilenet_v1_roadsign.yml -o use_gpu=true weights=output/yolov3_mobilenet_v1_roadsign/best_model --output_dir=./inference_model
以上命令会在./inference_model文件夹下生成一个yolov3_mobilenet_v1_roadsign
文件夹:
inference_model
│ ├── yolov3_mobilenet_v1_roadsign
│ │ ├── infer_cfg.yml
│ │ ├── serving_client
│ │ │ ├── serving_client_conf.prototxt
│ │ │ ├── serving_client_conf.stream.prototxt
│ │ ├── serving_server
│ │ │ ├── conv1_bn_mean
│ │ │ ├── conv1_bn_offset
│ │ │ ├── conv1_bn_scale
│ │ │ ├── ...
serving_client
文件夹下serving_client_conf.prototxt
详细说明了模型输入输出信息
serving_client_conf.prototxt
文件内容为:
feed_var {
name: "image"
alias_name: "image"
is_lod_tensor: false
feed_type: 1
shape: 3
shape: 608
shape: 608
}
feed_var {
name: "im_size"
alias_name: "im_size"
is_lod_tensor: false
feed_type: 2
shape: 2
}
fetch_var {
name: "multiclass_nms_0.tmp_0"
alias_name: "multiclass_nms_0.tmp_0"
is_lod_tensor: true
fetch_type: 1
shape: -1
}
启动PaddleServing服务
cd inference_model/yolov3_mobilenet_v1_roadsign/
# GPU
python -m paddle_serving_server_gpu.serve --model serving_server --port 9393 --gpu_ids 0
# CPU
python -m paddle_serving_server.serve --model serving_server --port 9393
测试部署的服务
准备label_list.txt
文件
# 进入到导出模型文件夹
cd inference_model/yolov3_mobilenet_v1_roadsign/
# 将数据集对应的label_list.txt文件拷贝到当前文件夹下
cp ../../dataset/roadsign_voc/label_list.txt .
设置测试文件test_client.py
中的prototxt
文件路径为serving_client/serving_client_conf.prototxt
。
设置fetch
为fetch=["multiclass_nms_0.tmp_0"])
测试
# 进入目录
cd inference_model/yolov3_mobilenet_v1_roadsign/
# 测试代码 test_client.py 会自动创建output文件夹,并在output下生成`bbox.json`和`road554.png`两个文件
python ../../deploy/serving/test_client.py ../../demo/road554.png