วิธีการ Detect Object ด้วย YOLOv5 และ Customize Object บน Windows 10
รหัสโครงการ 22p21n0185 | บ้านปังปุริเย่
ในบทความนี้ก็ต่อจากบทความที่แล้ว
วิธีติดตั้ง YOLOv5 บน Windows 10
และก็จะขอต่อจากบทความที่แล้วหน่อยนะครับ สำหรับคนที่มีปัญหาระหว่างลง pycocotools เช่นติดตั้ง Build Tools ไปแล้ว แต่ยัง Build Wheel ไม่ผ่าน!
ณ ตอนนี้มี Package ที่ชื่อว่า pycocotools-windows ซึ่ง Build สำหรับ Windows 10 มาพร้อมแล้ว สามารถ Copy คำสั่งได้จากด้านล่างเลยครับ 😁
pip install pycocotools-windows
เอาละครับ ถ้าติดตั้งได้แล้ว เรามาได้วิธีการใช้มันกันดีกว่า 🤔
เมื่อเราโหลด Repository ของ YOLOv5 มาแล้ว เรามาดู File กับ Folder ก่อนดีกว่า ว่าแต่ละ File ทำอะไรและแต่ละโฟลเดอร์เก็บอะไร 🤔
.
├── Dockerfile
├── LICENSE
├── READMEt.md
├── data
│ ├── argoverse_hd.yaml
│ ├── coco.yaml
│ ├── coco128.yaml
│ ├── hyp.finetune.yaml
│ ├── hyp.scratch.yaml
│ ├── images
│ ├── scripts
│ └── voc.yaml
├── detect.py
├── hubconf.py
├── models
│ ├── __init__.py
│ ├── __pycache__
│ ├── common.py
│ ├── experimental.py
│ ├── export.py
│ ├── hub
│ ├── yolo.py
│ ├── yolov5l.yaml
│ ├── yolov5m.yaml
│ ├── yolov5s.yaml
│ └── yolov5x.yaml
├── requirements.txt
├── runs
│ └── detect
├── test.py
├── train.py
├── tutorial.ipynb
├── utils
│ ├── __init__.py
│ ├── __pycache__
│ ├── activations.py
│ ├── autoanchor.py
│ ├── aws
│ ├── datasets.py
│ ├── general.py
│ ├── google_app_engine
│ ├── google_utils.py
│ ├── loss.py
│ ├── metrics.py
│ ├── plots.py
│ ├── torch_utils.py
│ └── wandb_logging
└── weights
└── download_weights.sh14 directories, 35 files
- Dockerfile, LICENSE และ README.md — ก็ตามชื่อครับ 😐
- data — โฟลเดอร์ที่จะเก็บ Dataset ในรูปแบบของ YOLO Format 🤨
- detect.py — ไฟล์ที่เอาไว้ Run Detection 😀
- hubconf.py — สำหรับ Access ใช้โมเดล YOLOv5 ผ่าน TorchHub 😮
- models — โฟลเดอร์ที่เก็บ Config ของแต่ละโมเดล ซึ่งแต่ละโมเดลจะแยกออกเป็นหลายอัน ซึ่งผมจะระบุภายหลังครับ
- requirements.txt — “เพียงแค่ pip install -r requirements.txt ก็ใช้ได้แล้ว แค่มันใช้กับ Windows 10 ไม่ได้อะ” 5555
- runs — โฟลเดอร์นี้จะเก็บผลลัพท์การ Run จากไฟล์ detect.py และ train.py ทั้งหมดซึ่งเป็นโฟลเดอร์ Default ที่ตั้งเอาไว้
- test.py — ไว้สำหรับ Test โมเดลที่เรา Custom เอง
- train.py — ใช่ครับทุกคนคิดถูก มันก็คือที่เทรนโมเดลนั่นแหละ 😏
- tutorials.py — Tutorials แหละครับตามชื่อเลย ซึ่งเขาได้เพิ่มเติม Tools ต่างๆ เช่น Monitor, TensorRT Deployment เป็นต้น
- utils — อย่าไปยุ่งครับ เดี๋ยวมันพัง 555
- weights — จะมี Scripts ที่เอาไว้สำหรับโหลด Weights ที่เขาเทรนมาให้เรียบร้อยแล้ว
โอเค … มาเริ่ม Detect กันแบบง่ายๆ ดีกว่า
python detect.py --help
เมื่อเราเรียก help มาเขาก็แสดง Parameters ที่ต้องการแล้ว ตัวอย่างง่ายๆ นะครับ
python detect.py --source 0 # Webcam
file.jpg # Image
file.mp4 # Video
path\ # Directory
path\*.jpg # glob
rtsp://[URI] # RTSP Stream
rtmp://[URI] # RTMP Stream
http://[URL] # HTTP Stream
detect.py — นั้นรองรับการ Input ได้หลายรูปแบบ
- Webcam — ใช้เลขในการระบุว่าเป็นกล้องตัวไหน
- Image — Path ที่มีนามสกุลไฟล์เป็น .png, .jpg
- Video — พอๆ กับ Image ครับแค่เปลี่ยนนามสกุลไฟล์เป็น .mp4, .avi, etc…
- Directory — ใช้ Path ที่ลงท้ายด้วย \ (Backslash)
- glob — สามารถใช้เครื่องหมาย * ในการระบุไฟล์ที่ต้องการจาก Directory นั้นๆ ได้เหมือนกับ Linux CLI ที่เคยใช้ๆ กัน
- RTSP, RTMP, HTTP Streaming— แม้แต่ Protocol ต่างๆ ก็รองรับ สามารถยัด URI เข้าไปได้เลย
และยังมี Parameters อื่นๆ ที่ detect.py ทีด้วย 😮เช่น
- source — Input ที่อธิบายไปในด้านบนอะครับ 😁
- weights — Model ที่ใช้ในการ Detect เป็น .pt 🤨
- device — Device ที่จะใช้ในการประมวลผลเช่น CUDA หรือ CPU 🙃
- view-img — แสดงผลรูปภาพออกมาด้วย 😎
- save-txt — บันทึกรายละเอียดลงเป็น .txt 😃
- save-conf — ใช้คู่กับ save-txt ซึ่งจะบันทึก Confidence ลงไปด้วย
- classes — คัดกรอง Class ที่จะ detect ออกมา
- conf หรือ conf-thres — วัตถุนั้นจะถูก detect เมื่อมี confidence มากกว่าที่กำหนด
ประมาณนี้นะครับสำหรับ detect.py เรามาพูดถึงเรื่องโมเดลของ YOLOv5 ที่ถูก Pre-trained มาแล้ว 😁
https://github.com/ultralytics/yolov5#pretrained-checkpoints
แต่ละโมเดลมีความแม่นยำต่างกันไป 😶… ยกตัวอย่างโมเดล YOLOv5x มีความแม่นยำมากที่สุด แต่ก็ต้องแลกมาด้วยเวลาในการประมวณผล และไฟล์ใหญ่กว่าชาวบ้านเขา 😮
และสามารถเอา Pre-trained Model ของเขามาเทรนกับ Dataset ของเราได้ ส่วนเรื่องของเวลาในการเทรนก็ขึ้นอยู่กับ ขนาดของโมเดล, ขนาดของ Data และ เครื่องของเรา 😎
เชื่อว่าหลายๆ คนกำลังรอสิ่งนี้นั่นก็คือ … Customize Dataset คร้าบบบ!!! 😍
พูดง่ายๆ ก็คือ Detect Object ด้วย Data ของเรานั่นแหละ 🤔
YOLOv5 ใช้ data เป็น YOLO Format นะครับ ซึ่งเราต้องทำ Annotations หลังจากนั้นก็ Export ออกมาเป็น YOLO Format 🙂
ซึ่งมันเองก็มี Tools ในการทำ Annotations อยู่หลายอันนะครับ
- CVAT — เป็น Tools ของ OpenVINO สำหรับการทำ Annotations ซึ่งเขาเปิดเป็นเว็บให้สามารถใช้ได้ฟรีแต่ก็จะมีการ Limit บางอย่างเพื่อไม่ให้เซิร์ฟเวอร์ล่ม วิธีการปลด Limit ผมแนะนำให้ Run บนเครื่องตัวเอง ซึ่งมันมี Repository ของตัวเองอยู่ สามารถโหลดมาแล้วอ่าน Installation ได้เลยครับ
- labelImg — ต่างกับ CVAT เรื่อง UI แต่ว่ามันถูกเขียนขึ้นโดย Python และไม่มีเว็บให้ลองใช้ แต่ว่ามันฟรีครับ ใช้ง่ายมากก ลงบนเครื่องของเราได้เลย ไม่ยากครับแค่ Copy Paste เหมือนที่ทุกคนทำกันทุกวันเดี๋ยวก็ได้แล้ว
ในบทความนี้ขอใช้ Dataset ของ Dogs vs. Cats จาก Kaggle นะครับ 😎
แต่ในบทความนี้ผมจะขอยก CVAT เป็นหลักนะครับ
CVAT สามารถโหลดลงเครื่องแล้ว Run ผ่าน Docker หรือใช้บนเว็บก็ได้นะครับ แต่ผมแนะนำให้โหลดลงเครื่องเพราะว่าเราสามารถกำหนด Limit ของมันได้ 👍
กดปุ่ม Create New Task 😁
ใส่ชื่อของ Task
เพิ่ม Label ที่ต้องการ 🤔
กดปุ่ม Continue เพื่อสร้าง Class ไปเรื่อยๆ
หลังจากใส่ Class ครบแล้ว ก็กดปุ่ม Done ได้เลย~~
เลือกไฟล์ที่ต้องการที่จะ Annotate (สามารถเลือกได้หลายภาพ) 👇
ใน Advanced configuration สามารถเลือก Segment size เพื่อที่จะแยก Jobs ออกมาหลายๆ อัน (ไม่จำเป็น) ✋
หลังจากที่อัพโหลดรูปภาพแล้วก็กด Submit ได้เลย 😊
หลังจากที่สร้างเสร็จจะมี Notifications ขึ้นมาอยู่ทางด้านขวาบน 🤔
เมื่อกดเข้าไปแล้ว ก็จะมีหน้าแต่เป็นแบบนี้ 😮
ถ้าหากว่าไม่ได้กำหนด Segment size จะไม่มีการแยก Jobs ให้
แต่ว่ามันไม่จำเป็น
เพราะฉะนั้น … ต่อดีกว่า 😑
เมื่อเรากดเข้าไปใน Jobs นะครับ มันจะมีหน้าตาแบบนี้
วิธีการ Annotate นะครับ ในแถบด้านซ้าย จะมีไอคอนนี้ให้เรา *คลิก* 😁
เมื่อคลิกแล้วมันจะขึ้น Pop-up เล็กๆ และเราก็สามารถเลือก Class ในการ Annotate ได้นะครับ หลังจากนั้นเราก็ลากกรอบของเราให้อยู่ใน ROI ได้เลยย 👇
แล้วก็ทำให้ครบเลย ทุกรูปนะครับ 😎
เมื่อ Annotate เสร็จแล้วอย่าลืมปิด Jobs ด้วยนะครับ MENU > Finish the job
ใครที่ทำ Segment Size ก็ต้องปิด Jobs ทุกอันด้วยนะครับ 😅
หลังจากที่ปิด Jobs เสร็จแล้ว เราจะ Export Annotations ที่เราเพิ่งทำไป
Actions > Export as a dataset > YOLO 1.1
หลังจากที่เรา Export ออกมาแล้วจะได้ไฟล์ .zip มานะครับ พอดาวน์โหลด 100% แล้วก็ปิด CVAT ไปได้เลยครับ 😁
หลังจากนั้นก็แตกไฟล์นะครับ โดย YOLOv5 จะรับแค่ train และ validation
สร้าง Directory ชื่อว่า dataset มาในโฟลเดอร์ yolov5 แล้วเราก็จะจัด data หน้าตาแบบนี้ครับ
.dataset
├── images
│ ├── train
│ │ └── [set of training images]
│ └── val
│ └── [set of validation images]
└── labels
├── train
│ └── [set of training annotations]
└── val
└── [set of validation annotations]
A: จัดเสร็จแล้วว เทรนโมเดลได้ยังอะ
B: ใจเย็นๆ ยังไม่หมด
สร้างไฟล์ dataset.yaml ในโฟลดเดอร์ data มา … แล้ว Copy Paste เปลี่ยนชื่อ Class และจำนวนClassด้วยนะครับบ!!
train: ./dataset/images/train/
val: ./dataset/images/val/
ถ้าหากว่าไม่มี Validation Set ก็ใช้เป็น directory เดียวกันได้เลยครับ
nc: 2
จำนวน Class
names: ['cat', 'dog']
ชื่อ Class เรียงตามการสร้าง Class ใน CVAT
# ./data/dataset.yaml
train: ./dataset/images/train/
val: ./dataset/images/val/nc: 2names: ['cat', 'dog']
เทรนโมเดล
B: ไปดาวน์โหลด Model มา
A: ดาวน์โหลดที่ไหนอะ
B: ข้างบนๆ 👆 ตรง Pre-trained Model 😁👍
ผมเลือกเป็นโมเดล YOLOv5s … เนื่องจากขนาดของไฟล์ค่อนข้างเล็ก สามารถนำไป Run บนเครื่องที่สเป็กต่ำๆ ได้
*จริงๆ Wi-Fi ของผมมันไม่อำนวย*
แถเก่งไปละ.. เข้าเรื่องดีกว่า
ไม่อธิบายครับ ยาวเกิน 😂
python train.py --img 640 --batch 2 --epochs 5 --data ".\data\dataset.yaml" --weights ".\weights\yolov5s.pt"
img — ขนาดรูปที่จะเป็น Output ของ Model 😮
batch — ขนาด Input ที่จะฟีดเข้าไปใน Model … ปรับให้มันสมดุลนะครับ สำหรับเครื่องผม VRAM น้อยมากๆ ถ้าปรับมากไปหรือน้อยบางทีโปรแกรมอาจจะงอแงนะครับเช่น BrokenPipe หรือ CUDA OOM 😎
epochs — ตามชื่อนั่นแหละ เทรนกี่รอบ
data — Path หาเข้า dataset.yaml
weights — Path ไปหา Weights ที่เมื่อกี้ไล่ให้ไปโหลดครับ
รอ ยาวๆ~~ 😪
ผมขอข้ามเวลาด้วยการลด Epoch จาก 100 เหลือลง 10 ละกัน ข้้างบนนี่ภาพแต่ง
เมื่อเทรนเสร็จแล้ว Model จะถูกบันทึกไปที่ runs/train/exp
runs
├── detect
└── train
└── exp
├── F1_curve.png
├── PR_curve.png
├── P_curve.png
├── R_curve.png
├── confusion_matrix.png
├── events.out.tfevents.1616481672.DESKTOP-E3G9LEN.6228.0
├── hyp.yaml
├── labels.jpg
├── labels_correlogram.jpg
├── opt.yaml
├── results.png
├── results.txt
├── test_batch0_labels.jpg
├── test_batch0_pred.jpg
├── test_batch1_labels.jpg
├── test_batch1_pred.jpg
├── test_batch2_labels.jpg
├── test_batch2_pred.jpg
├── train_batch0.jpg
├── train_batch1.jpg
├── train_batch2.jpg
└── weights
├── best.pt
└── last.pt
แต่ว่าเจ้า exp มันมาเป็นโฟลเดอร์เลย Model ของเราอยู่หนายยยย!! 😣
มันอยู่ใน exp/weights มีอยู่ 2 อันคือ best.pt กับ last.pt
best.pt — คือโมเดลที่ดีที่สุด
last.pt — คือ Epochs ล่าสุดที่เทรนล่าสุด
A: แล้วเอาโมเดลที่เราเทรนมาใช้ยังไงอะ
B: อ่านต่อสิครับ ถ้าอยากรู้ (มาเขียนตอนใกล้จบอีกด้วย 555)
เหมือนเดิมเลยครับ กันการใช้ detect.py เพียงแค่เติม — weights
python detect.py --source 0
--weights ".\runs\train\exp\weights\best.pt"
เพียงเท่านี้ก็เสร็จสมบูรณ์แล้วคร้าบบบ!! 😁
ขอบคุณมากๆ ครับ 😀
ภวัต แสงเดือน ( นน \ Non )