基于飞桨PaddleClas实现轧钢带表面缺陷分类,top1准确率可达100%


【飞桨开发者说】路星奎,沈阳化工大学信息工程学院研究生在读,计算机视觉技术爱好者,研究方向为图像分类、目标检测、图像分割等


2019年7月的飞桨活动中,第一次接触飞桨开源深度学习框架,这也是我学习的第一个深度学习框架,一年的时间里见证了飞桨以简为先,由简至精。2020年4月,飞桨正式开源PaddleClas,包含23个系列的分类网络以及117个预训练模型和性能评估,从数据增广、骨干网络设计、损失定义、优化器设计、知识蒸馏、特征迁移学习等不同的角度对图像分类问题进行深入探索。

在本篇文章中,我尝试使用PaddleClas进行热轧钢带表面缺陷的分类任务,经过调试最终在测试集上的准确率达到了100%。

PaddleClas GitHub:
https://github.com/PaddlePaddle/PaddleClas

项目简介

在热轧带钢的生产过程中受制造工艺、生产条件和原材料质量等相关问题的制约,生产出的工业产品往往存在缺陷。热轧带钢表面缺陷种类较多,其中常见的典型表面缺陷有六种,即:轧制氧化皮(RS),斑块(Pa),开裂(Cr),点蚀表面(PS),内含物(In)和划痕(Sc)。这些缺陷会在带钢后续产品的使用过程中造成隐患,导致制造产品质量下降,因此准确、快速地判断缺陷的类型是非常有必要的。

本项目使用的NEU 表面缺陷数据集包括 1,800 个原始分辨率为 200×200的灰度图像,其中六种不同类型的典型表面缺陷各含300 个样本数据。在模型训练与评估阶段,按照4:1比例将全部样本数据划分为训练集(1440个)与测试集(360个)。
下图展示了六种典型表面缺陷的样本图像,NEU 表面缺陷数据集在图像分类任务上面临如下挑战:
  • 类内缺陷在外观上存在较大差异,类间缺陷相似,类内缺陷在外观上存在很大相似。例如,划痕(最后一列)可能是水平划痕,垂直划痕和倾斜划痕等。
  • 同样,类间缺陷也具有类似情况,例如,氧化皮,裂纹和表面凹痕。
  • 另外,由于照明和材料变化的影响,类内缺陷图像的灰度是变化的。
本项目基于PaddleClas,在AI Studio实现任务搭建,选择ResNet50_vd作为训练模型,经过调试在测试集上的top1准确率达到了100%。本项目的实现过程可分为如下几个关键步骤:
  1. 环境搭建与数据处理
  2. 模型选择与参数配置
  3. 模型训练
  4. 模型评估
  5. 模型推理


环境搭建与数据处理

01  环境搭建


环境要求:
Python3
CUDA >= 9.0
cuDNN >= 5.0
nccl >= 2.1.2
PaddlePaddle v1.7或更高版本

安装过程:
安装PaddleClas套件。
git clone https://github.com/PaddlePaddle/PaddleClas.git

安装Python依赖库。
cd PaddleClas pip install --upgrade -r requirements.txt

在命令行环境下环境变量。
export PYTHONPATH=./:$PYTHONPATH

在Notebook中使用os.environ设置环境变量。
cd PaddleClas import os os.environ['PYTHONPATH']="/home/aistudio/PaddleClas"

02  数据处理

解压数据集并将数据集移动至指定位置,通过代码生成训练集文件夹、测试集文件夹、标签文件以及相应的路径txt文件,主要代码如下:
image_path_pre = os.path.join(all_file_dir, class_dir)   img = Image.open(os.path.join(image_path_pre, file))   if random.uniform(0, 1) <= train_ratio:       shutil.copyfile(os.path.join(image_path_pre, file), os.path.join(train_image _dir, file))       train_file.write("{0} {1}\n".format(os.path.join("trainImageSet", file), label_id))   else:       shutil.copyfile(os.path.join(image_path_pre, file), os.path.join(eval_image_dir, file))       eval_file.write("{0} {1}\n".format(os.path.join("evalImageSet", file), label_id))   train.txt内的部分数据格式如下所示: trainImageSet/Cr_227.bmp 0 trainImageSet/Cr_87.bmp 0 trainImageSet/Cr_194.bmp 0 trainImageSet/Cr_93.bmp 0

需要注意的是:
数据存放的位置与生成的数据列表文件中的图片路径需要一致,这也是初学者时常犯错的地方。数据列表文件中路径与标签之间的分割符号,行与行之间的换行符号。



模型选择参数配置

数据预处理之后,需要选择并训练网络。本项目选择的网络是ResNet50_vd,关于ResNet网络结构的代码分析,可单击链接:
https://aistudio.baidu.com/aistudio/projectdetail/438756

在PaddleClas/configs/ResNet/ResNet50_vd.yaml中的修改必要参数
  • classes_num:6  分类数
  • total_images:1431  总图片数
  • save_interval:10  每隔多少个epoch保存模型
  • validate:True  是否在训练时评估
  • valid_interval:10    每隔多少个epoch进行模型评估
  • epochs:50  训练总epoch数 
  • image_shape: [3, 224, 224]  图片大小  
TRAIN: 
  • batch_size: 64  批大小
  • num_workers: 4  数据读取器worker数量
  • file_list: "./dataset/NEU-CLS/train.txt"  train文件列表
  • data_dir: "./dataset/NEU-CLS"  train文件路径  
关于学习率的设置
大部分的神经网络选择的初始学习率为0.1,batch_size是256,根据实际的模型大小和显存情况,可以将学习率设置为0.1×k,batch_size设置为256×k。
更多的训练技巧和参数设置可以关注PaddleClas技术文档,其对相关参数进行了详细的解释说明:
https://paddleclas.readthedocs.io/zh_CN/latest/models/Tricks.html

模型训练

使用已经准备好的脚本下载预训练模型,指令如下:
python ../download_model.py ResNet50_vd_pretrained mv ../ResNet50_vd_pretrained ./
执行训练指令,使用已经配置好的neu.yaml文件。

PaddleClas通过launch方式启动多卡多进程训练,通过设置FLAGS_selected_gpus指定GPU运行卡号,指令如下:
python -m paddle.distributed.launch --selected_gpus="0" tools/train.py \           -c ../ neu.yaml  \   #配置文件路径 -o pretrained_model=./ResNet50_vd_pretrained  #预训练模型存放路径
本次项目中设置的是阶段性模型评估,同时保存评估结果最好的模型,参数在下述目录:
PaddleClas/output/ResNet50_vd/best_model。
best_model文件夹下包含ppcls.pdmodel、ppcls.pdopt、ppcls.pdparams三个文件用来进行后续的评估推理使用。

模型评估

首先需要修改评估所需的配置文件,有两种方式:
  • configs/eval.yaml,直接修改
  • -o,设置需要评估的模型路径
建议在configs/eval.yaml中修改必要的参数,使用-o设置需要评估的模型路径较为方便。

需要注意的是:
加载模型时,需要指定模型的前缀,如模型参数所在的文件夹为output/ResNet50_vd/ best_model,模型参数的名称为output/ResNet50_vd/best_model/ppcls.pdparams,则pretrained_model参数需要指定为output/ResNet50_vd/best_model/ppcls,PaddleClas会自动补齐.pdparams的后缀。

使用已经配置好的eval.yaml文件,评估命令如下:

python -m paddle.distributed.launch --selected_gpus="0" tools/eval.py \       -c .. /eval.yaml \   #配置文件路径     -o pretrained_model=output/ResNet50_vd/best_model/ppcls  #评估模型路径

作为示例模型迭代训练50次,其中效果最好的评估结果为:
eval loss_avg:  0.6195 top1_avg: 0.9313 top5_avg: 1.0000 elapse_sum: 1.253ss

模型推理

PaddlePaddle模型的保存方式分为如下两种:
  • persistable模型(fluid.save_persistabels保存的模型):一般作为模型的 checkpoint,可以加载后重新训练。persistable 模型保存的是零散的权重文件,每个文件代表模型中的一个 Variable,这些零散的文件不包含结构信息,需要结合模型的结构一起使用。
  • inference 模型(fluid.io.save_inference_model保存的模型):一般是模型训练完成后保存的固化模型,用于预测部署。
与 persistable 模型相比,inference 模型会额外保存模型的结构信息,用于配合权重文件构成完整的模型。

根据模型的保存方式以及选择引擎的不同,PaddlePaddle衍生出三种预测推理方式:
  • 预测引擎 + inference 模型
  • 训练引擎 + persistable 模型
  • 训练引擎 + inference 模型
本文选择使用“预测引擎 + inference模型”的方式完成模型推理,执行步骤如下:

Ⅰ 选择训练好的模型并转化为inference 模型

python tools/export_model.py \  
    --model='ResNet50_vd' \   #模型名称
    --pretrained_model=output/ResNet50_vd/best_model/ppcls \  #需要转换的模型路径
    --output_path=./inference  #输出的预测模型保存路径

保存在Inference目录下的预测模型包含 model、params 两个文件。

Ⅱ 通过预测引擎和inference模型进行推理

python tools/infer/predict.py --use_gpu=1  \  #是否使用 GPU 预测
    -m inference/model \  #模型文件路径
    -p inference/params \  #权重文件路径
    -i "dataset/NEU-CLS/Rs/RS_5.bmp" \   #待预测的图片文件路径

下图是一张轧制氧化皮(RS,标签为3)缺陷类型的测试数据,经过模型推理之后输出的预测标签为3,与正确的标签一致,预测正确。
class: 3
score: 0.8317301869392395

心得体会

本项目使用了飞桨开源深度学习框架以及PaddleClas套件,在AI Studio上完成了数据处理、模型训练、模型评估推理等工作。PaddleClas套件让图像分类技术变得更为简单便捷,降低了开发者的上手难度。

在此强烈安利AI Studio。AI Studio是基于百度深度学习平台飞桨的人工智能学习与实训社区,提供在线编程环境、免费GPU算力、海量开源算法和开放数据,帮助开发者快速创建和部署模型,对于像笔者一样没有硬件条件的学习者是一个很大的助力。

整个项目包括数据集与相关代码已公开在AI Studio上,欢迎小伙伴们Fork。
https://aistudio.baidu.com/aistudio/projectdetail/685319

如在使用过程中有问题,可加入飞桨官方QQ群进行交流:1108045677。
飞桨PaddlePaddle
飞桨PaddlePaddle

飞桨(PaddlePaddle)是中国首个自主研发、功能完备、开源开放的产业级深度学习平台。

https://www.paddlepaddle.org
专栏二维码
工程数据分析百度飞桨
暂无评论
暂无评论~