“การเรียนรู้เชิงลึก”, “การเรียนรู้ของเครื่อง”, “Python”

การจำแนกภาพโดยใช้การเรียนรู้เชิงลึกและ PyTorch: กรณีศึกษาพร้อมข้อมูลภาพดอกไม้

การจำแนกภาพดอกไม้โดยใช้ Convolutional Deep Neural Network พร้อมไลบรารี PyTorch

การจัดประเภทข้อมูลรูปภาพเป็นหนึ่งในการใช้งานเทคนิค Deep Learning ที่ได้รับความนิยมอย่างมาก ในบทความนี้ เราจะหารือเกี่ยวกับการระบุภาพดอกไม้โดยใช้โครงข่ายประสาทเทียมแบบ deep convolutional

สำหรับสิ่งนี้ เราจะใช้ไลบรารี PyTorch, TorchVision และ PIL ของ Python

การสำรวจข้อมูล

ชุดข้อมูลที่จำเป็นสำหรับปัญหานี้สามารถพบได้ที่ "Kaggle" มันมีโครงสร้างโฟลเดอร์และรูปภาพดอกไม้อยู่ข้างใน ดอกไม้มี 5 ชนิด โครงสร้างโฟลเดอร์มีลักษณะดังนี้

ตอนนี้เราจะเห็นตัวอย่างภาพดอกไม้จากโฟลเดอร์ 'rose'

show_image("../data/flowers/rose/537207677_f96a0507bb.jpg")

การประมวลผลข้อมูลล่วงหน้า

PyTorch คาดหวังข้อมูลในรูปแบบของ 'เทนเซอร์' เสมอ 'เทนเซอร์' เหล่านี้ทำงานระหว่างโหนดของโครงข่ายประสาทเทียมและมีข้อมูลต้นฉบับและข้อมูลก่อนหรือหลังการประมวลผล โดยพื้นฐานแล้ว กล่าวโดยย่อว่า 'เทนเซอร์' นั้นคล้ายคลึงกับอาร์เรย์ 'ตัวเลข'

สำหรับข้อมูลรูปภาพ เราต้องอ่านรูปภาพเป็นเทนเซอร์และใช้ขั้นตอนก่อนการประมวลผลหลายๆ ขั้นตอนก่อนที่จะทำการจำแนกประเภทใดๆ

เราสามารถพิจารณารูปภาพเป็นเทนเซอร์สามมิติได้ แต่ละภาพสามารถมีค่าสีของพิกเซลได้ 3 ประเภท ได้แก่ แดง เขียว และน้ำเงิน ตามลำดับ เราเรียกสิ่งนี้ว่าการเข้ารหัสสี RGB อีกสองมิติคือค่าพิกเซลตามความยาวและความกว้าง

โดยทั่วไป ขั้นตอนก่อนการประมวลผลทั่วไปสองขั้นตอนจำเป็นสำหรับข้อมูลภาพตามที่ระบุด้านล่าง:

  1. ปรับขนาดเป็นเทมเพลต:ปรับขนาดรูปภาพให้เป็นรูปทรงสี่เหลี่ยม ในกรณีของเรา เราจะปรับขนาดภาพแต่ละภาพเป็นภาพขนาด 64x64
  2. การทำให้เป็นมาตรฐาน:การทำให้เป็นมาตรฐานทางสถิติโดยใช้กลไก (x — ค่าเฉลี่ย)/sd ของแต่ละค่าพิกเซล ช่วยปรับปรุงการแสดงภาพ ปรับปรุงคุณสมบัติ และขยายคอนทราสต์ในภาพ

เมื่อใช้ PyTorch เราจะทำชุดการประมวลผลล่วงหน้านี้

นอกจากนี้เรายังสามารถกำหนดฟังก์ชันเพื่อแสดงชุดของภาพที่แปลงแล้วได้

ตอนนี้เราสามารถเห็นภาพที่แปลงแล้วของชุดแรกได้

show_transformed_image(make_grid(image))

เรายังสามารถมีคลาสเพื่อทำดัชนีพจนานุกรมข้อมูลได้

ซึ่งจะช่วยในการระบุชั้นเรียน

การสร้างแบบจำลอง

หากต้องการสร้างโมเดลแมชชีนเลิร์นนิงสำหรับข้อมูลรูปภาพ การป้อนค่าพิกเซลเพียงอย่างเดียวนั้นไม่เพียงพอ มีคุณสมบัติที่ซ่อนอยู่มากมายในภาพที่จะไม่ถูกค้นพบ สำหรับสิ่งนี้ เราควรใช้การผสมผสานระหว่าง Convolution & Max-Polling Layer เพื่อแยกคุณสมบัติที่สำคัญ

ชั้น Convolution

ในทางคณิตศาสตร์ การดำเนินการบิดระหว่างสองฟังก์ชัน f & g ถูกกำหนดเป็น

ในทางปฏิบัติ ถ้าเราถือว่า f เป็นอิมเมจเทนเซอร์ g ควรเป็นเทนเซอร์อีกตัวหนึ่งที่สามารถทำงานเป็น "เคอร์เนลการบิด" ได้

เป็นการสรุปแบบพิกเซลของค่าคูณของเทนเซอร์สองตัว

แผนภาพด้านล่างแสดงผลของการบิดบนเทนเซอร์อิมเมจตัวอย่าง

เคอร์เนล Convolution ขนาด 3x3 เคลื่อนที่ไปรอบ ๆ เทนเซอร์รูปภาพเป็นหน้าต่างที่เริ่มต้นจากตำแหน่ง (0,0) และผลลัพธ์ตัวอย่างที่ (0,0) ของเทนเซอร์เอาท์พุตมีลักษณะดังนี้การคำนวณด้านล่าง

เอาท์พุต (0,0) = อิมเมจเทนเซอร์ (0,0) x เคอร์เนล (0,0) + เทนเซอร์รูปภาพ (0,1) x เคอร์เนล (0,1) + เทนเซอร์รูปภาพ (0,2) x เคอร์เนล (0,2 ) + เทนเซอร์รูปภาพ (1,0) x เคอร์เนล (1,0) + เทนเซอร์รูปภาพ (1,1) x เคอร์เนล (1,1) + เทนเซอร์รูปภาพ (1,2) x เคอร์เนล (1,2) + เทนเซอร์รูปภาพ ( 2,0) x เคอร์เนล (2,0) + เทนเซอร์รูปภาพ (2,1) x เคอร์เนล (2,1) + เทนเซอร์รูปภาพ (2,2) x เคอร์เนล (2,2) = 1 x 1 + 1 x 0 + 1 x 1 + 0 x 0 + 1 x 1 + 1 x 0 + 0 x 1 + 0 x 0 + 1 x 1 = 4

เคอร์เนลเลื่อนตำแหน่ง 1 ตำแหน่งเพื่อคำนวณค่าของตำแหน่งอื่นๆ ของเอาท์พุตเทนเซอร์ 'การเปลี่ยนแปลง' นี้เรียกว่า 'ก้าวย่าง'

จำเป็นต้องมีเลเยอร์ Convolution เพื่อปรับปรุงและแยกคุณสมบัติที่สำคัญและซ่อนเร้นของภาพ ในกรณีของเรา อาจเกิดขึ้นได้ว่า "ดอกไม้" อยู่ที่ตำแหน่งกึ่งกลางของภาพ ดังนั้นการใช้การบิดงอจะช่วยดึงคุณสมบัติหลักของดอกไม้โดยไม่สนใจวัตถุและสีพื้นหลังอื่นๆ

เนื่องจากแต่ละภาพเป็นไปตามโค้ดสี RGB เราจะใช้การดำเนินการแบบบิดสำหรับแต่ละสี และด้วยเหตุนี้เราจึงได้เอาท์พุตเทนเซอร์สามตัว ผลลัพธ์สุดท้ายจะเป็นผลรวมเทนเซอร์ของทั้งสาม 'รหัสสี' แต่ละรายการเหล่านี้เรียกว่า 'ช่องทาง' ในคำศัพท์เฉพาะของ PyTorch API

ตามหลักคณิตศาสตร์แล้ว หากใช้ฟิลเตอร์ขนาด kxk กับภาพที่มีขนาด WxH มันจะสร้างภาพเอาท์พุต/เทนเซอร์ขนาด (W-k+1)x(H-k+1)

ในกรณีของเรา การบิดตัวถูกสร้างขึ้นเช่นนี้

self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=3,stride=1, padding=1)

"out_channels" ระบุจำนวนตัวกรองที่จะใช้ ที่นี่เราได้ใช้ฟิลเตอร์ 12 ตัว และสิ่งเหล่านี้จะสร้างเทนเซอร์รูปภาพระดับกลาง 12 ตัวขนาด 62x62 รูปภาพแต่ละภาพเหล่านี้มีคุณสมบัติพิเศษอย่างหนึ่งของรูปภาพต้นฉบับ

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ 'ตัวกรอง Convolution' ผู้อ่านสามารถไปที่ลิงค์ด้านล่าง



ชั้น ReLU

'ReLU' เป็นฟังก์ชันการเปิดใช้งานที่จับความไม่เป็นเชิงเส้นในเอาต์พุตของฟังก์ชันอื่น ในทางคณิตศาสตร์มันถูกกำหนดให้เป็น

ดังนั้นจึงส่งกลับค่าบวกเสมอ เราสามารถพูดได้ว่ามันคือ 'ตัวกรองเชิงบวก' เราจะใช้เลเยอร์ 'ReLU' หลังจากการบิด

ในกรณีของเรา 'ReLU' จะถูกสร้างขึ้นดังนี้

self.relu1 = nn.ReLU()

แม็กซ์รวมชั้น

โดยทั่วไป 'Max Pooling Layer' จะอยู่หลัง 'ReLU' 'พูลสูงสุด' ขนาด 2 คือหน้าต่าง 2x2 ซึ่งลัดเลาะเทนเซอร์เอาต์พุตของการดำเนินการ 'ReLU' และเลือกค่าพิกเซลสูงสุดภายในหน้าต่าง การดำเนินการนี้สามารถอธิบายได้ด้วยแผนภาพด้านล่าง

วัตถุประสงค์ของเลเยอร์ 'Max Pool' คือการเลือกเฉพาะคุณสมบัติที่มีผลกระทบสูงและมีมูลค่าสูง ช่วยลดมิติของคุณสมบัติต่างๆ

ในกรณีของเรา 'Max Pool' จะถูกสร้างขึ้นดังนี้

self.maxpool1 = nn.MaxPool2d(kernel_size=2)

จะลดขนาดของภาพลง 50% (32 = 64/2)

เลเยอร์ฟังก์ชันเชิงเส้น

ตามชื่อที่แสดงถึง มันเป็นฟังก์ชันเชิงเส้นที่รับเอาต์พุตของ 'Max Pool' เป็นอาร์เรย์แบบแบนและสร้างเอาต์พุตเป็นดัชนีคลาส ค่าเอาต์พุตจาก 'ฟังก์ชันเชิงเส้น' สำหรับดัชนีคลาสที่คาดการณ์ไว้จะเป็นค่าสูงสุด

ในกรณีของเรา 'ฟังก์ชันเชิงเส้น' จะถูกสร้างขึ้นดังนี้

self.lf = nn.Linear(in_features=32 * 32 * 24, out_features=num_classes)

สถาปัตยกรรมโดยรวมของโมเดล

เราจะใช้เลเยอร์ที่แตกต่างกันตามแผนภาพด้านล่าง

เรามีเลเยอร์ 'convolution' และ 'ReLU' สองชุด 'มุมมอง' จะทำให้เทนเซอร์เอาท์พุตแบนราบจากเลเยอร์ 'ReLU' สุดท้าย เรามีอิมเมจเทนเซอร์ขนาด 64x64 เป็นอินพุตซึ่งจะลดลงเหลือ 32x32 เนื่องจากการใช้ 'MaxPool2D' ของเคอร์เนลขนาด 2x2 (32 = 64/2)

ขั้นแรก เราจะแบ่งชุดข้อมูลออกเป็นการฝึกและการทดสอบตามอัตราส่วน 80:20

จากนั้น เราจะเขียนคลาสที่กำหนดเองเพื่อซ้อนเลเยอร์เหล่านี้โดยขยาย 'โมดูล' ที่กำหนดโดยไลบรารี PyTorch

'__init__' กำหนดแต่ละเลเยอร์และพารามิเตอร์ของมัน ในขณะที่ฟังก์ชัน 'ส่งต่อ' ทำการเรียกจริงและการซ้อนเลเยอร์ ผลลัพธ์จากเลเยอร์สุดท้ายจะถูกส่งกลับจากฟังก์ชัน 'ส่งต่อ'

การฝึกอบรมแบบจำลอง

เราจำเป็นต้องมีฟังก์ชัน Optimizer & Loss สำหรับการฝึกโมเดล เราจะใช้ 'Adam Optimizer' & 'Cross-Entropy Loss' สำหรับสิ่งนี้

from torch.optim import Adam
cnn_model = FlowerClassifierCNNModel()
optimizer = Adam(cnn_model.parameters())
loss_fn = nn.CrossEntropyLoss()

ด้วย PyTorch เราจำเป็นต้องตั้งค่าโมเดลในโหมดการฝึก จากนั้นรันการฝึกโดยวนซ้ำชุดข้อมูลการฝึก คำนวณการสูญเสียและขั้นตอนที่เพิ่มขึ้นของเครื่องมือเพิ่มประสิทธิภาพ

เราสามารถเขียนฟังก์ชันสำหรับสิ่งนี้ได้

การเรียกใช้ฟังก์ชัน 'loss.backward' จะกลับไปที่เลเยอร์และคำนวณการสูญเสียที่เกิดขึ้นระหว่างกระบวนการ

เราจะใช้ 'ยุค' 200 เพื่อฝึกโมเดล

train_and_build(200)

การทดสอบโมเดลและความแม่นยำ

เราควรตั้งค่าโมเดลเป็นโหมด 'ประเมิน' เพื่อทดสอบความแม่นยำบนชุดข้อมูลการทดสอบ

ฟังก์ชัน 'torch.max' ส่งกลับค่าสูงสุดจากเทนเซอร์เอาท์พุตของ 'ฟังก์ชันเชิงเส้น' ค่าสูงสุดอนุมานป้ายกำกับคลาสที่คาดการณ์ไว้

ฟังก์ชัน 'torch.sum' จะรวมค่า '1' ที่มีอยู่ในเทนเซอร์ซึ่งเป็นเอาต์พุตของการดำเนินการ 'AND' ระหว่างเทนเซอร์ 'ที่คาดการณ์ไว้' และ 'เอาต์พุตการทดสอบจริง' ดังนั้นผลรวมนี้จึงทำให้ไม่มีภาพที่ทำนายได้ถูกต้อง

และที่นี่เราได้รับความแม่นยำ

test_accuracy

คิดเป็นเกือบ 70.52% เรามีความแม่นยำที่ดีด้วยแบบจำลองง่ายๆ รุ่นนี้สามารถจูนเพิ่มเติมได้

การใช้แบบจำลองในการทำนายด้วยภาพตัวอย่าง

ตอนนี้เราจะดูวิธีใช้โมเดลนี้กับรูปภาพตัวอย่างจากชุดข้อมูลของเรา

show_image("../data/flowers/dandelion/13920113_f03e867ea7_m.jpg")

นี่คือภาพของ 'ดอกแดนดิไลอัน'

ตอนนี้เราจะอ่านรูปภาพโดยใช้ PIL image API และป้อนลงในไปป์ไลน์การแปลงของเราสำหรับการประมวลผลล่วงหน้าที่จำเป็น และใช้แบบจำลองสำหรับการทำนายในภายหลัง

class_index

ดังนั้น จากพจนานุกรมชั้นเรียนไปจนถึงพจนานุกรมดัชนีดังที่กล่าวข้างต้น เราสามารถยืนยันได้ว่าเป็น 'Dandelion' ดังนั้นโมเดลลักษณนามรูปภาพของเราจึงทำงานได้ดี !!

บทสรุป

เราเรียนรู้วิธีจัดหมวดหมู่รูปภาพโดยใช้ไลบรารี PyTorch ในกระบวนการนี้ เราได้ครอบคลุมถึงการประมวลผลภาพล่วงหน้า การสร้างเลเยอร์ Convolution และการทดสอบโมเดลสำหรับภาพที่นำเข้า

ความแม่นยำของแบบจำลองสามารถปรับปรุงเพิ่มเติมได้โดยการปรับแต่ง 'ไฮเปอร์พารามิเตอร์' เช่น การทดลองด้วยพารามิเตอร์ 'Adam Optimizer' การเพิ่มเลเยอร์การบิดพิเศษ การปรับแต่งด้วยขนาดเคอร์เนลและขนาดหน้าต่างพูลสูงสุด ฯลฯ ผู้อ่านบทความนี้สามารถลองใช้เทคนิคเหล่านี้ได้ด้วยตนเอง .

สมุดบันทึก Jupyter สำหรับสิ่งนี้สามารถพบได้จากลิงค์ด้านล่าง



ล่าสุดฉันเขียนหนังสือเกี่ยวกับ ML (https://twitter.com/bpbonline/status/1256146448346988546)