การจำแนกหมาแมว (Pet) โดยใช้ Transfer Learning บน FastAI

ขั้นตอนการทำ Image Classification  

Ref : AI จำแนกรูปภาพ หมา แมว 37 สายพันธุ์ ใช้ Pet Dataset เทรน Machine Learning สร้างโมเดล Deep Neural Network ด้วย fastai ภาษา Python – Image Classification ep.1


การเทรน Dog vs Cat

Tool : FastAI
  1. โหลดค่าเริ่มต้น
    1. Magic command
    2. Import library
  2. เตรียมข้อมูล
    1. untar_data(URLs.PET) เพื่อแตกไฟล์โหลดจาก url
    2. ดึงลิสท์ของพาธรูปทั้งหมด ด้วย get_image_files
    3. กำหนด batchsize, seed, reg pattern
    4. สร้าง DataBunch โดยใช้ ImageDataBunch
      1. Regular Expression : from_name_re โดยแกะคลาสจากชื่อไฟล์ [Data Pipeline]
      2. Data Transform : ds_tfms=get_transforms() [Data Augmentation]
      3. Image size
      4. Batch size
      5. Normalize : normalize(imagenet_stat)
    5. สำรวจข้อมูลที่ได้
      1. databunch.show_batch()
      2. databunch.classes
      3. databunch.c
  3. สร้างโมเดล
    1. cnn_learner โดย default จะแทนที่ layer สุดท้ายด้วย dense จำนวนคลาส
    2. โมเดลถูกเซฟที่ $home/.torch/models
    3. กำหนด Data bunch, models.resnet34, metrics=accuracy
  4. เทรนโมเดล 
    1. learner.fit_one_cycle(4) คือ การเทรนแบบพิเศษ ที่ใช้ Learning Rate ไม่คงที่ 
    2. 1 epoch คือ ใช้ป้อนข้อมูล หมด Dataset 1 รอบ
  5. ดูผลลัพธ์
    1. learner.recorder.plot_losses() กราฟ Loss 
    2. learner.recorder.plot_lr() กราฟ Learning Rate 
    3. learner.recorder.plot_metrics() กราฟ Accuracy
    4. learner.save() และ learner.load() เซฟและโหลด
    5. สร้าง ClassificationInterpretation.from_learner(learner) มาช่วยตีความผลลัพธ์
    6. interpretation.plot_top_losses() 9 อันดับแรกที่ทายผิด
    7. interpretation.plot_confusion_matrix()
    8. interpretation.most_confused()
  6. เทรนต่อ
    1. learner.unfreeze()
    2. learner.lr_find() 
      • ฟังก์ชันนี้ จะลองเทรนโมเดลดู โดยค่อย ๆ เพิ่ม Learning Rate ไปจนกระทั้ง Loss พุ่ง เพื่อดูว่าโมเดลสามารถรับ Learning Rate ได้มากสุดเท่าไร
    3. learner.recorder.plot() 
      • พล็อตกราฟ Learning Rate มาดู จะเห็นได้ว่า Loss ค่อย ๆ เพิ่มตาม Learning Rate ค่อย ๆ ชันไปจนพุ่งทะลุเพดาน ที่ประมาณ 1e-3 ให้เราเลือก Learning Rate ก่อนที่มันจะชันแล้วลดลง 2-5 เท่า แล้วลองเทรนดู ถ้าผลลัพธ์ไม่น่าพอใจก็ให้ load โมเดลใหม่ แล้วปรับ Learning Rate
    4. learner.fit_one_cycle(3, max_lr=slice(1e-6, 5e-4))
      • max_lr คือ เนื่องจากเรากำลังเทรนหลาย ๆ Layer พร้อม ๆ กัน แล้ว Layer แต่ละ Layer ก็ต้องการ Learning Rate ที่ไม่เท่ากัน เราสามารถกำหนด Learning Rate ให้กับทุก ๆ Layer ได้ด้วยฟังก์ชัน slice ที่จะกระจายให้ทุก Layer ไล่ค่าตั้งแต่ Layer แรก = 1e-6 น้อยสุด ไป Layer สุดท้าย = 5e-4 มากสุด
    5. เสร็จแล้ว

การทำ Data Pipeline 

1) Data Pipeline คือ การจัดเตรียมข้อมูล ให้อยู่ในรูปแบบที่เหมาะสม ป้อนให้โมเดล Machine Learning นำไปใช้ได้ ตั้งแต่ต้นทางไม่ว่าจะเป็น ไฟล์รูปภาพ ไฟล์ข้อความ ไฟล์เสียง ไฟล์วิดีโอ ข้อมูลตาราง Tabular 

2) ขั้นตอนดังนี้
  1. List All Examples / Get Files 
    • ดึงรายการข้อมูลทั้งหมดใน Dataset (ชื่อไฟล์)
    • tfms – พ่วงด้วย Transform ที่จำเป็น
  2. Split to Training Set, Validation Set  
    • แบ่งข้อมูลออกเป็น Training Set, Validation Set
    • by Random %, Folder name, CSV, … – ด้วยวิธีต่าง ๆ เช่น Random %, ตามไฟล์เดอร์, ตามที่ระบุในไฟล์ CSV, …
  3. Label 
    • แปะ Label ให้กับข้อมูล สำหรับงาน Supervised Learning
    • Folder name, File name, CSV, … – จากชื่อโฟลเดอร์, ชื่อไฟล์, ตามที่ระบุใน CSV, etc. โดย Label ของ Validation Set จะขึ้นกับ Training Set
  4. Transform (Optional) 
    • แปลงข้อมูล โดย Transform ของ Validation Set จะขึ้นกับ Training Set
    • per Example/Image – ต่อ 1 ตัวอย่าง เช่น แปลง Channel รูป, Resize รูป, etc.
    • per Training Set – Normalize, Fill N/A wtih Median, Categorize, Tokenize, Numericalize, etc.
  5. To Tensor 
    • แปลงเป็น Tensor เนื่องจาก PyTorch รับ Tensor
  6. DataLoader to Batch  
    • เราไม่สามารถโหลดทั้ง Dataset ได้พร้อมกัน เราจำเป็นต้องใช้ DataLoader สับไพ่ข้อมูล (Shuffle) และแบ่งข้อมูลออกเป็น Batch (Lazy Loading)
  7. Transform per Batch 
    • แปลงข้อมูล ต่อ Batch
  8. DataBunch
    • สร้าง DataBunch ห่อ Training Set, Validation Set
  9. Add Test Set (Optional) 
    • เพิ่มข้อมูล Test Set (ถ้ามี)



from fastai.vision.all import *

path  = untar_data(URLs.PETS)
files = get_image_files(path/"images")
np.random.seed(42)

print("First item = " ,files[0])
print("len images = " ,len(files))


regex_pattern = r'/([^/]+)_\d+.jpg$'
dls = ImageDataLoaders.from_path_re(path, files, regex_pattern, item_tfms=Resize(128))

print("Class = ", dls.vocab)
print("Len Class = ", dls.c)
dls.show_batch()


learn = cnn_learner(dls, resnet18, metrics=[error_rate,accuracy])
learn.fit_one_cycle(4)


learn.save('pets-resnet18-1')
learn.recorder.plot_sched()
learn.recorder.plot_loss()
learn.load('pets-resnet18-1')

interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix(figsize=(15,15))
interp.print_classification_report()
interp.plot_top_losses(9, figsize=(15,15))
interp.most_confused(min_val=5)


learn.unfreeze()
learn.lr_find()
learn.fit_one_cycle(3, lr_max=slice(9e-6, 5e-4))


learn.save('pets-resnet18-2')
learn.load('pets-resnet18-2')
learn.recorder.plot_sched()
learn.recorder.plot_loss()

interp = ClassificationInterpretation.from_learner(learn)
interp.plot_confusion_matrix(figsize=(15,15))
interp.print_classification_report()
interp.plot_top_losses(9, figsize=(15,15))
interp.most_confused(min_val=5)

Previous
Next Post »