基于PP-PicoDet的钢铁缺陷检测


1.背景介绍

近年来,AI视觉检测在安防、工业制造等产业智能化升级进程中发挥着举足轻重的作用。
自动检查和缺陷检测系统使用 AI 来检查零部件的故障和缺陷。通过这种方法,制造厂能够自动检测成品表面的缺陷,该方法广泛应用于金属、半导体晶圆和隐形眼镜等制造领域。
本项目为满足实际工业部署和实时性需求选择PP-PicoDet模型,降低了检测硬件的配置需求,实现了从图像中识别出钢铁表面的缺陷位置,并给出锚点框的坐标,同时对不同的缺陷进行分类的功能。

2.数据集介绍

本数据集来自NEU表面缺陷检测数据集,收集了6种典型的热轧带钢表面缺陷,即氧化铁皮压入(RS)、斑块(Pa)、开裂(Cr)、点蚀(PS)、夹杂(In)和划痕(Sc)。

3. 技术方案


3.1PP-PicoDet模型特点:

方案选择PP-PicoDet轻量化模型,主要看中PP-PicoDet体积小、速度快、精度较高的优势,非常适合本项目的部署环境和性能要求。同时,飞桨提供的预训练模型也可以最大程度上提升模型的收敛速度和精度。

3.2 PP-PicoDet模型结构介绍

paddleDetection 已更新至2.4 版本,picodet增强版 将 backbone 从 ESnet 换成了 LCNet,将 neck 中的 CSP module 换成了 LCNet module。CSP-PAN

4. 安装说明

环境要求:

# 克隆PaddleDetection仓库
# 只有第一次运行空项目时需要执行
!git clone https://github.com/PaddlePaddle/PaddleDetection.git
#配置目标检测路径 (进入到PaddleDetection工作目录)#没加~第二次运行找不到
%cd ~/PaddleDetection/
#安装Python依赖库。Python依赖库在requirements.txt中给出。(本地)
!pip install -r requirements.txt -i https://mirror.baidu.com/pypi/simple
!pip install paddledet>=2.2.2 -i https://mirror.baidu.com/pypi/simple
# 编译安装paddledet
# 每次启动项目后都需要先执行
!python setup.py install
#!python ppdet/modeling/tests/test_architectures.py  
#不加#运行测试后单卡训练运行会报错,去掉该段程序也会报错(该段代码需带#运行)

5. 数据处理


5.1数据准备

# unzip 解压文件-d创建解压后文件存放目录,并rm移除多余的目录  断网再次运行需删除PaddleDetection/dataset/steel这个文件夹
! unzip /home/aistudio/data/data105746/train.zip -d /home/aistudio/PaddleDetection/dataset/steel
!rm -r /home/aistudio/data/steel/__MACOSX
! unzip /home/aistudio/data/data105747/test.zip -d /home/aistudio/PaddleDetection/dataset/steel
!rm -r /home/aistudio/data/steel/__MACOSX
# 安装paddlex 用于拆分数据集
# 升级pip
!pip install --upgrade pip -i https://mirror.baidu.com/pypi/simple
!pip install "paddlex>2.0.0" -i https://mirror.baidu.com/pypi/simple 
#/home/aistudio/data/steel/train/文件夹下的ANNOTATIONS和IMAGES---移动变为Annotations和JPEGImages文件夹
!mv /home/aistudio/PaddleDetection/dataset/steel/train/ANNOTATIONS  /home/aistudio/PaddleDetection/dataset/steel/train/Annotations
!mv /home/aistudio/PaddleDetection/dataset/steel/train/IMAGES  /home/aistudio/PaddleDetection/dataset/steel/train/JPEGImages

5.2 拆分数据集

#使用paddleX拆分数据集(可参考5.3处链接)
!paddlex --split_dataset --format VOC --dataset_dir /home/aistudio/PaddleDetection/dataset/steel/train --val_value 0.2 --test_value 0.1

0.7的训练集,0.2的验证集,0.1的测试集,Train数量为:980、Eval 数量为:280,测试的数量为:140

2022-12-11 13:22:30 [INFO]	Dataset split starts...
2022-12-11 13:22:30 [INFO]	Dataset split done.
2022-12-11 13:22:30 [INFO]	Train samples: 980
2022-12-11 13:22:30 [INFO]	Eval samples: 280
2022-12-11 13:22:30 [INFO]	Test samples: 140
2022-12-11 13:22:30 [INFO]	Split files saved in /home/aistudio/PaddleDetection/dataset/steel/train
# 临时环境安装
!pip install pycocotools -i https://mirror.baidu.com/pypi/simple
!pip install lap -i https://mirror.baidu.com/pypi/simple

5.3 数据格式转换

数据格式转换,数据拆分
下面是Paddle提供的两个处理数据的命令说明文档。
PadlleX:

https://github.com/PaddlePaddle/PaddleX/tree/develop/docs/data

PaddleDetection: https://github.com/PaddlePaddle/PaddleDetection/blob/release%2F2.3/docs/tutorials/PrepareDataSet.md

%cd /home/aistudio/PaddleDetection/
#转换train
!python tools/x2coco.py \
        --dataset_type voc \
        --voc_anno_dir /home/aistudio/PaddleDetection/dataset/steel/train/ \
--voc_anno_list /home/aistudio/PaddleDetection/dataset/steel/train/train_list.txt \
--voc_label_list /home/aistudio/PaddleDetection/dataset/steel/train/labels.txt \
--voc_out_name /home/aistudio/PaddleDetection/dataset/steel/train/voc_train.json
#/home/aistudio/PaddleDetection/dataset/steel/train

#转换eval
!python tools/x2coco.py \
        --dataset_type voc \
        --voc_anno_dir /home/aistudio/PaddleDetection/dataset/steel/train/ \
--voc_anno_list /home/aistudio/PaddleDetection/dataset/steel/train/val_list.txt \
--voc_label_list /home/aistudio/PaddleDetection/dataset/steel/train/labels.txt \
--voc_out_name /home/aistudio/PaddleDetection/dataset/steel/train/voc_val.json

#转换test
!python tools/x2coco.py \
        --dataset_type voc \
        --voc_anno_dir /home/aistudio/PaddleDetection/dataset/steel/train/ \
--voc_anno_list /home/aistudio/PaddleDetection/dataset/steel/train/test_list.txt \
--voc_label_list /home/aistudio/PaddleDetection/dataset/steel/train/labels.txt \
--voc_out_name /home/aistudio/PaddleDetection/dataset/steel/train/voc_test.json

!rm -r /home/aistudio/PaddleDetection/dataset/steel/train/Annotations/*
!mv /home/aistudio/PaddleDetection/dataset/steel/train/*.json /home/aistudio/PaddleDetection/dataset/steel/train/Annotations/

6. 模型训练

通常一个项目模型完整的落地流程可以总结为如下6个步骤,其中需要根据评估和预测的结果,对模型进行反复的优化和再训练:

也可以参考 PaddleDetecion 提供的 快速上手指南。另外,在实际项目的推进过程中,可以根据实际情况决定是否采用模型压缩的相关手段。

6.1 PicoDet 的配置文件

PicoDet-s-416 的配置文件,由 1 个入口配置文件,和5个相关联的子配置文件组成。
入口配置文件位于:

PaddleDetection/configs/picodet/picodet_s_416_coco_lcnet.yml

相关的 5 个子配置文件为:

  '../datasets/coco_detection.yml',
  '../runtime.yml',
  '_base_/picodet_v2.yml',
  '_base_/optimizer_300e.yml',
  '_base_/picodet_416_reader.yml',

接下来我们从子配置文件开始,依次说明每个配置文件的用途和需要修改的部分。

6.1.1 数据集配置文件 coco_detection.yml

入口配置文件位于:PaddleDetection/configs/datasets/coco_detection.yml

设置数据集的配置信息。根据本案例的情况,请按照如下内容进行修改 num_classes、image_dir、anno_path、dataset_dir

metric: COCO
num_classes: 6  #数据集有6个分类 

TrainDataset:
  !COCODataSet
    image_dir: JPEGImages
    anno_path: Annotations/voc_train.json
    dataset_dir: dataset/steel/train
    data_fields: ['image', 'gt_bbox', 'gt_class', 'is_crowd']

EvalDataset:
  !COCODataSet
    image_dir: JPEGImages
    anno_path: Annotations/voc_val.json
    dataset_dir: dataset/steel/train

TestDataset:
  !ImageFolder
    image_dir: JPEGImages
    anno_path: Annotations/voc_test.json  # Also support txt (like VOC's label_list.txt)
    dataset_dir: dataset/steel/train  # If set, anno_path will be 'dataset_dir/anno_path'

因本案例是检测钢铁表面缺陷的,因此num_classes有6个分类。

6.1.2 修改入口配置文件 picodet_s_416_coco_lcnet.yml

这是控制模型训练的主配置文件位于:PaddleDetection/configs/picodet/picodet_s_416_coco_lcnet.yml,其中设置的参数会覆盖掉子配置文件中的相关参数。这也是为什么我们6.1.3子配置文件中基本保留了默认配置而不做修改,原因就在于,在主配置文件内集中修改参数,可以更方便的修改训练参数,避免要修改的参数过于分散。为缩短实验时间epoch: 30 和snapshot_epoch: 1

按如下内容修改主配置文件的内容:

_BASE_: [
  '../datasets/coco_detection.yml',
  '../runtime.yml',
  '_base_/picodet_v2.yml',
  '_base_/optimizer_300e.yml',
  '_base_/picodet_416_reader.yml',
]

pretrain_weights: https://paddledet.bj.bcebos.com/models/picodet_s_416_coco_lcnet.pdparams
weights: output/picodet_s_416_coco_lcnet/model_final
find_unused_parameters: True
use_ema: true
use_gpu: true
epoch: 30
snapshot_epoch: 1

LCNet:
  scale: 0.75
  feature_maps: [3, 4, 5]

LCPAN:
  out_channels: 96

PicoHeadV2:
  conv_feat:
    name: PicoFeat
    feat_in: 96
    feat_out: 96
    num_convs: 2
    num_fpn_stride: 4
    norm_type: bn
    share_cls_reg: True
    use_se: True
  feat_in_chan: 96

TrainReader:
  batch_size: 8

LearningRate:
  base_lr: 0.06
  schedulers:
  - !CosineDecay
    max_epochs: 300
  - !LinearWarmup
    start_factor: 0.1
    steps: 300

其中:

  • Batch Size指模型在训练过程中,前向计算一次(即为一个step)所用到的样本数量
  • 如若使用多卡训练, batch_size会均分到各张卡上(因此需要让batch size整除卡数)
  • Batch Size跟机器的显存/内存高度相关,batch_size越高,所消耗的显存/内存就越高
  • step与epoch的关系:1个epoch由多个step组成,例如训练样本有800张图像,train_batch_size为8, 那么每个epoch都要完整用这800张图片训一次模型,而每个epoch总共包含800//8即100个step

6.1.3 默认不修改的yml

运行时配置文件 runtime.yml 用于设置运行时的参数,主要包括:

use_gpu:  是否使用GPU训练
use_xpu:  是否使用XPU训练
log_iter:  显示训练信息的间隔
save_dir:  模型保存路径
snapshot_epoch: 保存模型的间隔
# Exporting the model: 与导出模型相关的设置

这里我们暂且保留默认值,不做修改即可。

模型网络参数 picodet_v2.yml

用于设置模型的网络参数,也包括预训练集的加载,这里为了可以快速开始实际训练,我们也暂时保留默认的参数,不做修改。

训练优化参数 optimizer_300e.yml

主要说明了学习率和优化器的配置。其中比较重要的参数是训练轮数 epoch 和 学习率 base_lr。同样,我们暂时不在这里修改,稍后再设置。

6.2 开始训练

# GPU 单卡训练
%cd ~/PaddleDetection
!export CUDA_VISIBLE_DEVICES=0   # windows和Mac下不需要执行该命令
!python tools/train.py -c configs/picodet/picodet_s_416_coco_lcnet.yml --use_vdl=true --vdl_log_dir=vdl_dir/scalar --eval
Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.281
Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.602
Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.213
Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.134
Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.234
Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.390
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=  1 ] = 0.212
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 10 ] = 0.442
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.508
Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.231
Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.438
Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.609
[12/11 13:39:43] ppdet.engine INFO: Total sample number: 280, averge FPS: 20.09930010448373
[12/11 13:39:43] ppdet.engine INFO: Best test bbox ap is 0.281.
[12/11 13:39:43] ppdet.utils.checkpoint INFO: Save checkpoint: output/picodet_s_416_coco_lcnet

7. 模型评估

# GPU单卡评估
!python tools/eval.py -c configs/picodet/picodet_s_416_coco_lcnet.yml  -o weights=output/picodet_s_416_coco_lcnet/model_final.pdparams   
Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.281
Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.602
Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.213
Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.134
Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.234
Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.390
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=  1 ] = 0.212
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 10 ] = 0.442
Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.508
Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.231
Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.438
Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.609
[12/11 13:40:43] ppdet.engine INFO: Total sample number: 280, averge FPS: 48.80814227976918

我们来看一下 PaddleDetection 模型评估结果中的指标各自代表什么意思。

8. 模型预测

模型预测也很简单,一行代码搞定,其中最常用的参数有:

--output_dir:  保存检测结果的文件夹,默认保存在output文件夹。
--draw_threshold:  可视化时分数的阈值,默认大于0.5的box会显示出来。
--save_txt:  将图片的预测结果保存到文本文件中,与预测结果图片在同一文件夹下。
#模型预测
!python tools/infer.py -c configs/picodet/picodet_s_416_coco_lcnet.yml --infer_img=dataset/steel/test/IMAGES/1693.jpg -o weight=output/picodet_s_416_coco_lcnet/model_final.pdparams 

9. 模型导出

在模型训练过程中保存的模型文件是包含前向预测和反向传播的过程,在实际的工业部署则不需要反向传播,因此需要将模型进行导成部署需要的模型格式。
导出后的模型会保存在:

output_inference/picodet_s_416_coco_lcnet/

包含如下文件:

infer_cfg.yml
model.pdiparams
model.pdiparams.info
model.pdmodel

导出后的文件,将用于后续的模型部署。

# 导出模型
!python tools/export_model.py -c configs/picodet/picodet_s_416_coco_lcnet.yml -o weight=output/picodet_s_416_coco_lcnet/model_final.pdparams
[12/13 18:17:47] ppdet.utils.checkpoint INFO: Finish loading model weights: output/picodet_s_416_coco_lcnet/model_final.pdparams
loading annotations into memory...
Done (t=0.00s)
creating index...
index created!
[12/13 18:17:47] ppdet.engine INFO: Export inference config file to output_inference/picodet_s_416_coco_lcnet/infer_cfg.yml
[12/13 18:17:53] ppdet.engine INFO: Export model and saved in output_inference/picodet_s_416_coco_lcnet

_lcnet

!python deploy/python/infer.py --model_dir=output_inference/picodet_s_416_coco_lcnet\
        --image_file=/home/aistudio/PaddleDetection/dataset/steel/test/IMAGES/1403.jpg\
        --device=GPU
import cv2
import matplotlib.pyplot as plt
import numpy as np

image = cv2.imread('output/1693.jpg')
plt.figure()
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()

在这里插入图片描述

10 数据模型可视化

可视化—设置logdir–选择PaddleDetection/vdl_dir文件夹—启动VisualDL服务

11 项目总结

本次项目的实践,从选题、确定数据集、选择模型、训练、评估、预测到导出模型,实现模型的可视化,是一次难得的全流程项目体验,感谢飞桨,提供的平台和算力,感谢高睿大佬(TowerNet)对此次任务的耐心指导。

参考文献:

  • https://aistudio.baidu.com/aistudio/projectdetail/4031589?contributionType=1
  • https://aistudio.baidu.com/aistudio/projectdetail/3344390?contributionType=1
  • https://aistudio.baidu.com/aistudio/projectdetail/3151246?channelType=0&channel=0
  • https://aistudio.baidu.com/aistudio/projectdetail/3846170?channelType=0&channel=0
  • https://aistudio.baidu.com/aistudio/projectdetail/4670836?channelType=0&channel=0
  • https://aistudio.baidu.com/aistudio/projectdetail/1885319?channelType=0&channel=0
  • https://www.guyuehome.com/37172
FLAG支持脚本用途默认值备注
-cALL指定配置文件None必选,例如-c configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.yml
-oALL设置或更改配置文件里的参数内容None相较于-c设置的配置文件有更高优先级,例如:-o use_gpu=False
–evaltrain是否边训练边测试False如需指定,直接--eval即可
-r/–resume_checkpointtrain恢复训练加载的权重路径None例如:-r output/faster_rcnn_r50_1x_coco/10000
–slim_configALL模型压缩策略配置文件None例如--slim_config configs/slim/prune/yolov3_prune_l1_norm.yml
–use_vdltrain/infer是否使用VisualDL记录数据,进而在VisualDL面板中显示FalseVisualDL需Python>=3.5
–vdl_log_dirtrain/infer指定 VisualDL 记录数据的存储路径train:vdl_log_dir/scalar infer: vdl_log_dir/imageVisualDL需Python>=3.5
–output_evaleval评估阶段保存json路径None例如 --output_eval=eval_output, 默认为当前路径
–json_evaleval是否通过已存在的bbox.json或者mask.json进行评估False如需指定,直接--json_eval即可, json文件路径在--output_eval中设置
–classwiseeval是否评估单类AP和绘制单类PR曲线False如需指定,直接--classwise即可
–output_dirinfer/export_model预测后结果或导出模型保存路径./output例如--output_dir=output
–draw_thresholdinfer可视化时分数阈值0.5例如--draw_threshold=0.7
–infer_dirinfer用于预测的图片文件夹路径None--infer_img--infer_dir必须至少设置一个
–infer_imginfer用于预测的图片路径None--infer_img--infer_dir必须至少设置一个,infer_img具有更高优先级
–save_txtinfer是否在文件夹下将图片的预测结果保存到文本文件中False可选

请点击此处查看本环境基本用法.

Please click here for more detailed instructions.

此文章为搬运
原项目链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐