转自AI Studio,原文链接:
路面病害检测-从数据清洗到模型部署的全流程方案 - 飞桨AI Studio
1. 项目说明
无论是水泥还是沥青路面,在通车使用一段时间之后,都会陆续出现各种损坏、变形及其它缺陷,这些我们统称为路面病害。如下图1所示。

图1路面病害示例
根据美国科氏公司的研究表明:一条质量合格的道路,在使用寿命75%的时间内性能下降40%,这一阶段称之为预防性养护阶段;如不能及时养护,在随后12%的使用寿命时间内,性能再次下降40%,从而造成养护成本大幅度的增加。本项目基于RDD2020路面病害数据集和一个辅助数据集完成路面病害检测的全流程任务。
方案难点:
- 数据集质量不佳: 数据集质量不佳,存在未标注、标注不规范、标注不统一等情况,需要进行数据清洗;
- 较高的模型泛化能力: 由于使用车载手机拍摄,受光照光线等影响,对模型泛化能力的要求较高;
- 实时性: 路面病害检测场景下,需要在移动端部署,对实时性能要求较高。
2. 安装说明
环境要求
- PaddlePaddle >= 2.2
- Python >= 3.7
- PaddleDetection >=2.4
- PaddleSlim >=1.0
- PaddleLite >=2.1
安装的相关问题参考PaddleDetection安装文档, PaddleSlim仓库,PaddleLite仓库
2.1 安装PaddleDetection
In [42]
## clone repository
!git clone https://gitee.com/PaddlePaddle/PaddleDetection.git
In [2]
## install dependencies
%cd PaddleDetection
!pip install -r requirements.txt
!python setup.py install
In [4]
## 测试是否安装成功
!python ppdet/modeling/tests/test_architectures.py
In [ ]
%cd
/home/aistudio
2.2 安装PaddleSlim
In [39]
!pip install paddleslim -i https://pypi.tuna.tsinghua.edu.cn/simple
In [38]
## 或者克隆后安装
!git clone https://github.com/PaddlePaddle/PaddleSlim.git
%cd PaddleSlim
!python setup.py install
2.3 安装PaddleLite
In [11]
!pip install paddlelite
3. 数据准备
本项目使用的主要数据集为 RDD2020 比赛数据集,是 RDD2020的路面病害检测比赛数据集。包括26336张手机拍摄的路面图片。保含多个类别的路面病害,但是本项目只关注其中的4种病害,分别是:Longitudinal Cracks(D00), Transverse Cracks(D10), Alligator Cracks(D20), 和 Potholes(D40)。本项目中,仅仅使用该数据集的训练集,共21041张图片。经过数据清洗,去除未标注的图片、不含有以上四个类别的图片后的有效图片共14568张。对该数据集进行1:9的划分后,训练集共12949张,验证集共1619张。数据集示例图片如下图2所示:

图2 RDD2020比赛数据集图片示例
图片来源:RDD2020 比赛数据集
为了增加模型的泛化能力,本项目另外使用了一个稍小一点的路面病害数据集,称为路面病害产品数据集,来自【全球开放数据创新应用大赛】的道路路面病害智能分析赛道。该数据集共包括6000张图片,共8个类别Crack, Manhole, Net, Pothole, Patch-Crack, Patch-Net, Patch-Pothole, other。经过数据清洗,去除不含有关注的四个类别的图片后,该数据集共有2854张图片,全部加入到RDD2020的路面病害检测训练集中。该数据集示例图片如下图3所示:

图3 路面病害产品数据集图片示例
经过数据预处理,最后训练集共有15803张图片,验证集共有1619张图片。
3.1 预处理RDD2020比赛数据集
In [ ]
%cd
/home/aistudio
In [ ]
## 解压缩训练集
!tar xzf data/data138375/train.tar.gz -C work/
In [ ]
## 数据清洗
!python code/clean_data.py
finished creating 14568 xmls!
In [ ]
# 数据预处理,包括训练集和验证集的划分等
!python code/preprocess.py
Finished preprocessing the data including train val split, creating 12949 train images and 1619 eval images!
In [ ]
%cd PaddleDetection/
/home/aistudio/PaddleDetection
In [ ]
##将训练数据集转为coco格式
!python tools/x2coco.py \
--dataset_type voc \
--voc_anno_dir /home/aistudio/voc_annos/ \
--voc_anno_list /home/aistudio/train.txt \
--voc_label_list /home/aistudio/label_list.txt \
--voc_out_name /home/aistudio/train.json
Start converting ! 100%|██████████████████████████████████| 12949/12949 [00:00<00:00, 16718.23it/s]
In [ ]
##将验证数据集转为coco格式
!python tools/x2coco.py \
--dataset_type voc \
--voc_anno_dir /home/aistudio/voc_annos/ \
--voc_anno_list /home/aistudio/val.txt \
--voc_label_list /home/aistudio/label_list.txt \
--voc_out_name /home/aistudio/val.json
Start converting ! 100%|█████████████████████████████████████| 1619/1619 [00:00<00:00, 5399.41it/s]
3.2 预处理路面病害产品数据集
In [ ]
%cd
/home/aistudio
In [36]
## 解压缩
!unzip data/data140177/train.zip -d new_dataset/
由于该数据集与RDD2020的路面病害检测数据集的类别不统一,经过仔细观察,去除该数据集中的Manhole、Net、Patch-Net和Other。Pothole保持不变,Patch-Crack改为Alligator Cracks,Patch-Pothole改为Pothole,Crack根据形状分为Longitudinal Cracks和Transverse Cracks。
为了避免数据的id重复,将该产品数据集加入到RDD2020的路面病害检测数据集时给已有数据的id加30000。
In [ ]
## 预处理产品数据集
!python code/process_new_data.py
before adding 12949 after adding 15803 finished adding 2854 images and processing new dataset!
4.模型选择
当前主流的目标检测算法主要分为两类:服务端算法和端侧算法:
- 服务端算法,其优势在于模型精度较高,但实时性较差。最具代表性的就是RCNN类算法。如图4所示:

图4 服务端检测算法模型
- 端侧算法,其优势在于实时性较好,同时要求模型大小尽可能的小,但精度通常没有服务端算法高。PicoDet算法就是一种典型的端侧算法。如图5所示:

图5 边缘端检测算法模型
为了能够解决端侧部署的实用要求,在经过初步的模型训练筛选后,本项目采用PP-PicoDet算法。
5. 模型训练
对picodet系列的不同模型进行训练比较,这里以picodet_s_416模型为例,模型的配置文件为:picodet_s_416_coco_lcnet.yml
。
In [ ]
%cd PaddleDetection
/home/aistudio/PaddleDetection
5.1 训练
训练时将PaddleDetection中提供的配置文件的学习率改为原来的1/4,可以适当减小原来的epoch数量。
In [29]
# GPU单卡训练
!python tools/train.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml --eval
5.2 验证
用通过训练时评估保存的最好模型进行模型验证。由于训练模型需要较长时间,本项目提供了训练好的模型供验证、测试和部署。以下提供两种不同使用方法:自己训练的模型和本项目提供的训练好的模型。
In [28]
## 使用自己训练的模型
!python tools/eval.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml -o weights=output/picodet_s_416_coco_lcnet/best_model.pdparams
In [28]
## 使用本项目训练好的模型
!python tools/eval.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml -o weights=/home/aistudio/models/picodet_s_416/best_model.pdparams
5.3 模型预测
对一张图片进行预测。
In [25]
## 修改标签使推理图片更加可读
!python /home/aistudio/code/make_labels_readable.py
In [27]
## 使用自己训练的模型
!python tools/infer.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml \
--infer_img=/home/aistudio/Czech_001496.jpg \
--output_dir=/home/aistudio/infer_output_s_416/ \
--draw_threshold=0.5 \
-o weights=output/picodet_s_416_coco_lcnet/best_model \
--use_vdl=True
In [23]
## 使用本项目训练好的模型
!python tools/infer.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml \
--infer_img=/home/aistudio/Czech_001496.jpg \
--output_dir=/home/aistudio/infer_output_s_416/ \
--draw_threshold=0.5 \
-o weights=/home/aistudio/models/picodet_s_416/best_model \
--use_vdl=True
预测结果如下图6所示:

图6 picodet_s_416模型预测结果
6. 模型部署
由于本项目要在手机端进行模型部署,这里选择PaddleLite进行模型部署。PaddleLite支持各个边缘平台,详细信息可以参考PaddleLite文档
6.1 模型导出
首先需要将训练好的模型导出成静态推理模型。
In [31]
## 使用自己训练的模型
!python tools/export_model.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml -o weights=output/picodet_s_416_coco_lcnet/best_model.pdparams \
--output_dir inference_models
In [9]
## 使用本项目训练好的模型
!python tools/export_model.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml -o weights=/home/aistudio/models/picodet_s_416/best_model.pdparams \
--output_dir inference_models
6.2 将inference模型转化为PaddleLite优化模型
然后使用PaddleLite工具将静态推理模型转化为可以部署的PaddleLite模型,转化时可以选择将要部署的平台架构。
In [23]
## 创建需要的文件夹
import os
if not os.path.exists("optimized_inference_models/picodet_s_416_coco_lcnet"):
os.makedirs("optimized_inference_models/picodet_s_416_coco_lcnet")
In [33]
!paddle_lite_opt --valid_targets=arm --model_file=inference_models/picodet_s_416_coco_lcnet/model.pdmodel --param_file=inference_models/picodet_s_416_coco_lcnet/model.pdiparams --optimize_out=optimized_inference_models/picodet_s_416_coco_lcnet/model
In [17]
## 转化为fp16精度的模型
!paddle_lite_opt --valid_targets=arm --model_file=inference_models/picodet_s_416_coco_lcnet/model.pdmodel --param_file=inference_models/picodet_s_416_coco_lcnet/model.pdiparams --optimize_out=optimized_inference_models/picodet_s_416_coco_lcnet/model_fp16 --enable_fp16=true
6.3 真机部署
这里参考PaddleLite的官方部署demo将模型部署在Iphone手机上. 需要注意的是在修改部署代码时要修改label文件、添加训练好的模型,修改ViewController.mm
文件中的资源配置信息,并且要根据模型的输入要求修改输入的尺寸参数。本项目训练好的picodet_s_416可部署模型在models
文件夹内。 运行效果如下图7所示。
图7 picodet_s_416模型iphone真机部署效果图
7. 模型优化
以上模型的真机预测性能如下图8所示。

图8 picodet_s_416模型真机部署性能
可以看出,实时性比较好,基本为25fps。下面尝试在不改变模型的情况下对模型进行量化并比较性能。
7.1 模型量化
这里使用PaddleSlim对模型进行量化压缩,量化分为在线量化和离线量化两种。为了保持模型性能,这里采用在线量化的方法。
In [35]
## 在线量化训练
!python tools/train.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml --slim_config /home/aistudio/code/picodet_s_416_quant_config.yml --eval
In [ ]
## 量化后验证(使用自己训练的模型)
!python tools/eval.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml --slim_config /home/aistudio/code/picodet_s_416_quant_config.yml -o weights=output/picodet_s_416_quant_config/best_model.pdparams
In [ ]
## 量化后验证(使用本项目训练好的模型)
!python tools/eval.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml --slim_config /home/aistudio/code/picodet_s_416_quant_config.yml -o weights=/home/aistudio/models/picodet_s_416/best_model_quant.pdparams
In [ ]
## 量化后预测(使用自己训练的模型)
!python tools/infer.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml --slim_config /home/aistudio/code/picodet_s_416_quant_config.yml -o weights=output/picodet_s_416_quant_config/best_model.pdparams \
--infer_img=/home/aistudio/Czech_001496.jpg \
--output_dir=/home/aistudio/infer_output_afterquant_s416/ \
--draw_threshold=0.5 \
In [21]
## 量化后预测(使用本项目训练好的模型)
!python tools/infer.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml --slim_config /home/aistudio/code/picodet_s_416_quant_config.yml -o weights=/home/aistudio/models/picodet_s_416/best_model_quant.pdparams \
--infer_img=/home/aistudio/Czech_001496.jpg \
--output_dir=/home/aistudio/infer_output_afterquant_s416/ \
--draw_threshold=0.5 \
在观察到模型性能基本没有问题的情况下,重复之前的模型部署过程。
In [ ]
## 导出静态推理模型(使用自己训练的模型)
!python tools/export_model.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml --slim_config /home/aistudio/code/picodet_s_416_quant_config.yml -o weights=output/picodet_s_416_quant_config/best_model.pdparams \
--output_dir inference_models/picodet_s_416_quant_config
In [ ]
## 导出静态推理模型(使用本项目训练好的模型)
!python tools/export_model.py -c /home/aistudio/code/picodet_s_416_coco_lcnet.yml --slim_config /home/aistudio/code/picodet_s_416_quant_config.yml -o weights=/home/aistudio/models/picodet_s_416/best_model_quant.pdparams \
--output_dir inference_models/picodet_s_416_quant_config
In [ ]
## 导出真机部署模型
!paddle_lite_opt --valid_targets=arm --model_file=inference_models/picodet_s_416_quant_config/picodet_s_416_quant_config/model.pdmodel --param_file=inference_models/picodet_s_416_quant_config/picodet_s_416_quant_config/model.pdiparams --optimize_out=optimized_inference_models/picodet_s_416_quant_config/model
In [ ]
## 导出fp16精度的真机部署模型
!paddle_lite_opt --valid_targets=arm --model_file=inference_models/picodet_s_416_quant_config/picodet_s_416_quant_config/model.pdmodel --param_file=inference_models/picodet_s_416_quant_config/picodet_s_416_quant_config/model.pdiparams --optimize_out=optimized_inference_models/picodet_s_416_quant_config_fp16/model --enable_fp16=true
7.2 模型量化后效果
通过量化压缩,模型大小由原来的5.2M变为了2M。真机部署时发现,模型预测速度比量化前变快了一些,如下图9和图10所示。

图9 picodet_s_416模型量化前真机部署性能

图10 picodet_s_416模型量化后真机部署性能
但是量化后在常规的阈值0.5的情况下不能检测出目标,将阈值降低为0.4时目标就可以检测出来了。
7.3 使用fp16精度推理的效果比较
通过使用fp16精度模型,模型预测速度有较大提高,如下图11和图12所示。

图11 picodet_s_416模型fp32真机部署性能

图12 picodet_s_416模型fp16真机部署性能
8. 总结
本案例中,对各种模型进行了尝试。实验结果如下:
模型 | MAP | 推理速度-iphone11 | 推理速度-iphone11(fp16) | 模型大小 |
---|---|---|---|---|
picodet_l_640 | 0.551 | 316ms(3.16fps) | 170ms(5.88fps) | 23.6M |
picodet_l_640量化后 | 0.523 | 277ms(3.61fps) | 273ms(3.66fps) | 6.9M |
picodet_l_320 | 0.446 | 82ms(12.19fps) | 43ms(23.26fps) | 23.6M |
picodet_l_320量化后 | 0.421 | 71ms(14.08fps) | 71ms(14.08fps) | 6.9M |
picodet_s_416 | 0.476 | 37ms(27.03fps) | 21ms(47.62fps) | 5.2M |
picodet_s_416量化后 | 0.436 | 32ms(31.25fps) | 35ms(28.57fps) | 2M |
picodet_s_320 | 0.417 | 22ms(45.45fps) | 13ms(76.92fps) | 5.2M |
picodet_xs_416 | 0.409 | 26ms(38.46fps) | 18ms(55.55fps) | 3.3M |
可以看到,对于不同的模型,模型大小和输入图片大小直接影响模型精度和速度,对于小模型来说量化压缩的性价比不高。模型部署的性能要多次实验后才能选择确定。 使用fp16精度推理后,非压缩模型的速度明显变快,在iphone11上基本可以达到原来的1倍半到2倍之间,性能可观。
模型进一步优化思路:
- 数据集的质量和数量会直接影响模型的精度,后续可以对数据集进行逐张梳理来提高数据集质量,同时可以引入更多的外部数据集来提高模型的泛化能力。
- Batch size大小以及学习率的选择也会对模型的训练性能有影响,后续可以通过调参来提高模型性能。
- 不同的边缘平台对推理的性能和速度都有影响,后续可以根据需要在不同的边缘平台上进行实验选择。
更多资源
-
更多深度学习知识、产业案例、面试宝典等,请参考:awesome-DeepLearning
-
更多PaddleDetection使用教程,请参考:PaddleDetection
-
飞桨框架相关资料,请参考:飞桨深度学习平台