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

时间:2022-07-23
本文章向大家介绍基于飞桨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

[Thanks for reading.]

·ResNet网络结构代码分析·

https://aistudio.baidu.com/aistudio/projectdetail/438756

·飞桨官网地址·

https://www.paddlepaddle.org.cn/

·飞桨 PaddleClas 项目地址·

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

Gitee: https://gitee.com/paddlepaddle/PaddleClas

·飞桨开源框架项目地址·

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

Gitee: https://gitee.com/paddlepaddle/Paddle