คัมภีร์ YOLO LPR Object Detection (สอน Custom Model , ใช้ dataset ของตัวเองมาเทรน ชิวๆ part1 เตรียม data)

Pattanan Tingpattana
4 min readNov 26, 2019

--

มาถึงก็ขอเกริ่นก่อนนิดนึง บทความนี้เขียนขึ้นมาสำหรับมือใหม่ที่ต้องการจะ custom model เป็นของตัวเองในการใช้ YOLO Object Detection เด้อ ใครที่เทพแล้วก็ข้ามไปซะ เพราะที่จะทำต่อไปนี้คือ basic ? ชิวๆ ย้ำว่าชิวเด้อ (เดี๋ยวจะอธิบายแบบระเอียดเท่าที่จะทำได้นะ — เลต สะ โก๋วว)

ทำความเข้าใจ?

A . อี YOLO ที่เขาพูดๆกันมันไว้ใช้ทำอะไรกันเหรอ?

ตอบ หลักๆมันมีประโยชน์ไว้ใช้จำแนกประเภทสิ่งของ (classification) หรือ Object Detection นั่นแแหละ คือมันจะสนใจแต่ object ที่เราต้องการ

เนี่ย จำแนกประเภทสิ่งของแบบ จ๊าบ ว้าว ดูมีความเป็น ai

คือที่จะพาทำวันนี้ก็คือ จะพา Train data ที่เป็นชนิดรูปภาพมา Train ให้มันสามารถแยกประเภทวัตถุได้โดยที่เป็น dataset ของเรา

โดย dataset ครั้งนี้ผมจะใช้ dataset ที่เป็นรูปรถยนต์ หรือยานพาหนะที่เป็นพวก 4 ล้อ

ความต้องการ

ตอนนี้ เราต้องการให้โปรแกรม มันแยกประเภทได้ว่า รูปที่เรา input เข้ามามันมีรถอยู่ในรูปหรือไม่ ถ้ามี ให้มันหาตำแหน่งของป้ายทะเบียน แล้วก็ให้มันตีกรอบ หรือ crop วัตถุที่เป็นป้ายทะเบียนรถ หรือยานพาหนะไป save เพื่อเอาไปใช้อย่างอื่นต่อไป…

ตัวอย่างเด้อ

นี่ภาพ Input
ปิ้ง++ และนี่ Output

…เริ่มเลยดีกว่า… เอ้า ปาย ปาย ปาย ปาย ปาย ปาย 555

  1. เริ่มจากเตรียม dataset ที่เรามี ไหนดูซิ..
แว้ป…โฟลเดอร์นี้มีประมาณ 1500 image (คือยิ่งเยอะยิ่งดีแหละ)

2. เราต้องสร้าง label image ซึ่งในที่นี้จะใช้เป็น .txt

label image มันคืออะไร? ทำไมต้องมี? ทำไมต้องใช้ ?

อธิบายแปป

การทำ label imageเนี่ย มันคือการกำหนดตำแหน่งของ object ที่เราต้องการเว้ย ซึ่งใน ไฟล์ .txt จะเก็บตำแหน่งที่เรากำหนดไว้ตามนี้

นี่คือตำแหน่งของ object ที่เราต้องการ ที่มันอยู่ในภาพ

|category number| |bounding box left X| |bounding box top Y| |bounding box right X| |bounding box bottom Y|

ค่าแรก category number มันคือ class ของ object เริ่มต้นจาก 0 ถ้าเรามี 5 object ในภาพเช่น คน หมา แมว… ก็ 0,1,2 ไปเรื่อยๆ ในที่นี้เรามี class เดียวก็ 0 วนๆไปครับ

ค่าที่สอง bounding box left X คือ ตำแหน่งเริ่มต้นแกน X ของ object

ค่าที่สาม bounding box top X คือ ตำแหน่งเริ่มต้นแกน X ของ object ที่อยู่ขวาล่าง

ค่าที่สี่ bounding box top Y คือ ตำแหน่งเริ่มต้นแกน Y ของ object ที่อยู่ขวาล่าง

พอเราได้ไอ้ตำแหน่ง 2 จุดนี้ เราจะได้ค่า กว้าง x ยาว มาเอง (ขี้เกียจพิมแล้วไปหาเองเด้อ 55)

วิธีการทำ label image นะ

https://github.com/tzutalin/labelImg วาร์ปไปตามนี้เลย อันนี้เหมือนเป็น tool ที่เอาไว้ทำ label โดยล้วนๆ แตกไฟล์เสร็จรันทำตาม เอ้อ ต้องลง PyQt5 ด้วยเด้อ เพราะมันต้องเรียกใช้หน้า interface หรือ gui ที่เป็น PyQt

พอ labelเสร็จ ตามรูปก็จะได้ชื่อไฟล์ตามรูปที่ label ไว้

3. จะเห็นว่าตอนนี้เรามีไฟล์อยู่ 2 ชนิดแล้ว คือ .jpg กับ .txt

จะได้ label ที่บอกตำแหน่งป้ายทะเบียน กับ image แบบนี้

4. YOLO step

ไป clone project มาซะ https://github.com/AlexeyAB/darknet พูดง่ายๆก็ไป download นั่นแหละ โหลดมาเพื่อจะใช้เป็นตัวช่วยในการ Learn

แตกไฟล์เสร็จก็จะได้หน้าตาแบบนี้

เสร็จทีนี้สร้าง path ตามนี้ เพราะผมเอาไว้ในนี้

D:\GOD_YOLOV3_1\darknet-master\build\darknet\x64\data\obj

ซึ่งในโฟลเดอร์ obj เนี่ยผมจะเก็บไฟล์ภาพ และ .txt ที่เรา label ไว้

คือง่ายๆ เอามันมารวมกันไว้ในนี้แหละ

5. เตรียมไฟล์ config

สร้างไฟล์ obj.names และ obj.data เก็บไว้ในโฟลเดอร์ data นะ

  • 5.1 ) สร้างไฟล์ obj.names ทำหน้าที่คอบบอกชื่อ class
ตัวอย่างมี class เดียวจึงมีแค่ชื่อเดียว
  • 5.2 ) สร้างไฟล์ obj.data
obj.data

classes = 1 หมายความว่า เรามีคลาสเดียว นั่นคือคลาสป้ายทะเบียนนั่นเอง

train = จะบอก path ที่เชื่อมไปตอน train ข้อมูลของเรา

valid = จะบอก path ที่เชื่อมไปตอน test ข้อมูลของเรา

names = คอยบอกชื่อ object ไม่มีอะไร

backup = ตอนที่เรา train เสร็จ มันจะเก็บไฟล์ weights ไว้ใน path นี้ (ที่เราต้องการก็คือไอ้ไฟล์ weights นี่แหละ)

  • 5.3 ) ต่อมาเราต้องมีไฟล์ train.txt และ test.txt เพื่อบอกที่อยู่ของ image data และ image label

import os

path=’data/obj/’

imgList=os.listdir(‘images’)

print(imgList)

textFile=open(‘train.txt’,’w’)

for img in imgList:

imgPath=path+ img +’\n’

textFile.write(imgPath)

ข้างบนคือ code generate path train และ test

test.txt
train.txt

ใน valid file เราควรแบ่งจากข้อมูลทั้งหมดสัก 10%-15% ที่เหลือให้เป็นข้อมูล train

จะได้ train 90% , test 10%

เมื่อได้ไฟล์มา ให้เอาไปไว้ในโฟลเดอร์ data แบบนี้
  • 5.4 )ปรับตัว config เริ่มจาก coppy file yolo.2.0.cfg

จาก D:\GOD_YOLOV3_1\darknet-master\build\darknet\x64\cfg

ไปไว้ที่

D:\GOD_YOLOV3_1\darknet-master\build\darknet\x64

เปลี่ยนชื่อใหม่เป็น yolo.2.0-obj.cfg เอาไปเปิดใน IDLE หรือ Notepad ก็ได้

เปิดมาหน้าตาจะประมาณนี้ มันคือชั้น layer หรือโครงสร้าง Neural Network

แก้บรรทัดที่2

batch = 1 เป็น batch = 64

แก้บรรทัดที่3

subdivisions=1 เป็น subdivisions=8

แล้วเลื่อนลงมาล่างสุด บรรทัดที่ 224 เปลี่ยน filters =425 เป็น filters =30 ( ได้จาก จำนวนคลาส +5 ทั้งหมดคูณด้วย 5 ได้ 30)

เปลี่ยน classes=80 ให้เป็น 1 เพราะมันคือจำนวน class ที่เอาเอาเข้าไป train

เสร็จแล้ว Save!

โหลด darknet19_448.conv.23

จาก http://pjreddie.com/media/files/darknet19_448.conv.23

เอาไปไว้ที่ D:\GOD_YOLOV3_1\darknet-master\build\darknet\x64

  • 5.4 ) ขั้นตอนนี้สุดท้ายของการเตรียมไฟล์ละ ค่อนข้างยุ่งยากวุ่นวายเพราะต้อง install ยับๆ 5555

ที่ต้องติดตั้ง ::

  • CUDA 10.0, cuDNN 7.4 and OpenCV 3.x (opencv เวอร์ชั่นต้องไม่เกิน 3.4 มั้ง)

เริ่ม!

โหลดและติดตั้ง cuDNN v7.4.1 for CUDA 10.0 : https://developer.nvidia.com/rdp/cudnn-archive ติดตั้งเสร็จแล้วก็ Add Path

แล้วก็ Add path

ต้องใช้ Visual Studio ด้วยนะ ถ้าไม่มีก็ไปโหลด https://visualstudio.microsoft.com/downloads/ ปี 2019 ปีอื่นก็ใช้ได้แหละ

::

เปิด path นี้มา D:\GOD_YOLOV3_1\darknet-master\build\darknet หน้าตาเป็นแบบนี้

จะเห็นไฟล์ darknet.sln , darknet_no_gpu.sln

darknet_no_gpu.sln : ถ้าต้องการเทรนแบบไม่ใช้ gup ให้เลือกตัวนี้

darknet.sln : ถ้าต้องการเทรนแบบใช้ gup ให้เลือกตัวนี้

เลือกสันอันที่ต้องการ แล้วคลิกขวา open with Visual Studio

เซ็ตค่าตามรูป

เซ็ตค่าเสร็จแล้วก็ทำการ Build darknet_no_gpu.sln ใน Visual Studio

เสร็จแล้วจะได้ไฟล์ darknet_no_gpu.exe อยู่ใน \build\darknet

coppy darknet_no_gpu.exe ไปวางไว้ใน \build\darknet\x64

เสร็จแล้วขั้นตอนการเตรียมไฟล์ที่ต้องใช้

part นี้ มันยาวไปแล้วอะ เดี๋ยวจะมาต่อ part หน้าเด้อ ถ้าต่อ part นี้มันจะปนกันมั่วซั่ว ตั้วเหลง มันจะ งง 555

… Part ต่อไปจะเริ่ม Train แล้วนะ พักชมโฆษณาน่าสนใจสักครู่เดี๋ยวมาต่อ

รอหน่อย อร่อยแน่

--

--