基於飛槳PaddleClas實現軋鋼帶表面缺陷分類,top1準確率可達100%

飛槳PaddlePaddle發表於2020-08-13
基於飛槳PaddleClas實現軋鋼帶表面缺陷分類,top1準確率可達100%

【飛槳開發者說】路星奎,瀋陽化工大學資訊工程學院研究生在讀,計算機視覺技術愛好者,研究方向為影像分類、目標檢測、影像分割等

基於飛槳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實現軋鋼帶表面缺陷分類,top1準確率可達100%
本專案基於PaddleClas,在AI Studio實現任務搭建,選擇ResNet50_vd作為訓練模型,經過除錯在測試集上的top1準確率達到了100%。本專案的實現過程可分為如下幾個關鍵步驟:
  1. 環境搭建與資料處理
  2. 模型選擇與引數配置
  3. 模型訓練
  4. 模型評估
  5. 模型推理
基於飛槳PaddleClas實現軋鋼帶表面缺陷分類,top1準確率可達100%


環境搭建與資料處理

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

基於飛槳PaddleClas實現軋鋼帶表面缺陷分類,top1準確率可達100%
需要注意的是:
資料存放的位置與生成的資料列表檔案中的圖片路徑需要一致,這也是初學者時常犯錯的地方。資料列表檔案中路徑與標籤之間的分割符號,行與行之間的換行符號。



模型選擇引數配置

資料預處理之後,需要選擇並訓練網路。本專案選擇的網路是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設定需要評估的模型路徑較為方便。
基於飛槳PaddleClas實現軋鋼帶表面缺陷分類,top1準確率可達100%

需要注意的是:
載入模型時,需要指定模型的字首,如模型引數所在的資料夾為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,與正確的標籤一致,預測正確。
基於飛槳PaddleClas實現軋鋼帶表面缺陷分類,top1準確率可達100%
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。

相關文章