[Yolo Series] #2 – Cách train Yolo để detect các object đặc thù

Xin chào các bạn, chúng ta lại cùng tìm hiểu tiếp về Yolo với cách train YOLO nhé. Trong bài trước, mình đã hướng dẫn các bác sử dụng Yolo để phát hiện các đối tượng trong ảnh tại đây: http://sharenow.online/2019/08/05/yolo-series-1-su-dung-yolo-de-nhan-dang-doi-tuong-trong-anh/

Tuy nhiên có một vấn đề như này, model mặc định của Yolo chỉ được train trên 80 đối tượng như: hoa, lá, xe máy, oto, xe bus…. nên nếu bạn muốn phát hiện các đối tượng đặc thù như: súng ống, đạn dược… thì sẽ không thể làm được.

Hôm nay mình sẽ chỉ các bạn từng bước để có thể train model nhận dạng các đối tượng đặc thù theo nhu cầu riêng. Ví dụ hôm nay mình sẽ chọn nhận dạng SÚNG NGẮN nhé. Quên mất, máy mình là máy MacOS nên mình sẽ guide dựa trên đó, trên window hơi khác tý, các bạn cần thì comment mình sẽ guide thêm.

Chúng ta cần làm những gì?

Để train được cho Yolo nhận diện các đối tượng đặc thù theo yêu cầu, cúng ta sẽ cần làm các bước lớn sau.

  1. Tải source code Darknet – Yolo về máy tính, chỉnh tham số và tiến hành biên dịch (make) source code đó ra file thực thi tùy theo hệ điều hành (window thì là exe, macos với linux thì file bash thì phải, tóm lại là file chạy được)
  2. Chuẩn bị dữ liệu train: Hình ảnh của đối tượng bạn định train. Ví dụ như bài này là súng ngắn.
  3. Gán nhãn cho dữ liệu: Cụ thể là với từng ảnh trong dữ liệu, chúng ta sẽ gán nhãn cho máy biết đâu là đối tượng cần nhận dạng bằng cách vẽ một hình chữ nhật xung quanh đối tượng đó. Cái này có tool nhé.
  4. Tạo các file cần thiết để phục vụ quá trình train, chỉnh sửa tham số train trong file cấu hình Yolo.
  5. Chạy lệnh train và ngồi uống cafe đợi.
  6. Tận hưởng thành quả bằng cách detect thử một ảnh sample.

Bước 1. Tải source Darknet về máy

Đầu tiên các bạn tạo thư mục MiAI_Yolo_2 trên máy tính tại đâu nào tùy bạn nhé. Chúng ta sẽ chuyển vào và làm việc trong thư mục này.

Trên Command Prompt hoặc Terminal hãy chuyển vào thư mục MiAI_Yolo_2 bằnh lệnh cd MiAI_Yolo_2, sau đó gõ lệnh:

git clone https://github.com/pjreddie/darknet

Sau khi đợi vài phút, trong thư mục MiAI_Yolo_2 sẽ có thêm thư mục darknet với 1 mớ folder bên trong, như vậy là tải thành công rồi. Bây giờ chúng ta sẽ chuyển sang bước biên dịch (make). Ở bước này, đầu tiên bạn mở file Makefile trong thư mục darknet và lưu ý 2 dòng sau:

# dòng GPU bên dưới để là 1 nếu máy bạn có GPU, ngược lại để 0
GPU=0
# dòng OPENCV để 1 nếu bạn muốn dùng thư viện OpenCV
OPENCV=0

Mình thì hay để OpenCV=1 để mở nhiều kiểu file ảnh hơn (nếu bị lỗi thì các bạn cứ để OPENCV=0 cũng okie vì mấy khi mở các file ảnh khù khoằm đâu) .

Update: Bạn Bùi Lộc có góp thêm idea là nếu để opencv=1 bị lỗi thì gõ lệnh:

SUDO APT-GET INSTALL LIBOPENCV-DEV

Xong, bây giờ bạn lưu lại file Makefile và gõ tiếp lệnh:

make

Sau đó ngồi đợi cho máy chạy xong, nếu không có báo lỗi gì là thành công, chuyển sang bước sau.

Chú ý: Nếu gõ make bị lỗi thì làm như sau: (cách nhanh gọn nhé, chi tiết có nhiều cách nhưng ko mì ăn liền được)

  • Trên window thì cài :Visual Studio 2017 (chẳng hạn)
  • Trên macos thì cài: XCode bản mới nhất

Bước 2. Chuẩn bị dữ liệu train

Dữ liệu train thì các bạn collect trên internet hoặc từ bất cứ nguồn nào bạn có sẵn. Càng nhiều càng tốt và ảnh nên tính bằng đơn vị nghìn cho model ngon lành hơn nhé. Ví dụ về súng ngắn, các bạn có thể tìm bài mình chia sẻ về ảnh súng tại đây nhé: http://sharenow.online/2019/08/06/computer-vision-chia-se-du-lieu-anh-sung-va-dao-de-train-model/

Sau khi có dữ liệu, bạn hãy vào thư mục darknet/data và tạo folder images. Copy tât cả các ảnh bạn dùng để train vào thư mục images.

Tiếp đó quay ra xóa toàn bộ file trong thư mục darknet/data/labels (nếu có file, nếu không có thư mục labels thì tạo ra nhé) và chuyển sang bước 3.

Bước 3. Gán nhãn cho dữ liệu

Để gán nhãn cho dữ liệu, chúng ta sẽ sử dụng một công cụ có sẵn là LabelImg tại đây https://github.com/tzutalin/labelImg.

Các bạn hãy mở Terminal hay Command Promt, chuyển vào thư mục darknet (nếu đang ở thư mục khác) và chạy lệnh:

git clone https://github.com/tzutalin/labelImg

Lại ngồi đợi tý nhé, món này tải hơi lâu. Sau khi chạy xong thì sẽ có một thư mục labelImg được tạo ra trong thư mục darknet, ta chuyển vào trong đó bằng lệnh cd lblImg.

Bây giờ bạn mở link https://github.com/tzutalin/labelImg và kéo xuống phần Installation để xem cách cài đặt các thư viện với từng OS cho chi tiết nhé. Nhưng tóm lại , đại khái là chạy 2 lệnh:

# lệnh cài đặt thư viện pyqt5 (GUI) và lxml
pip install pyqt5 lxml
# lệnh chạy biên dịch mã nguồn thư viện
make qt5py3

Sau khi chạy xong thì mở ứng dụng labelImg bằng lệnh:

python labelImg.py

Một giao diện sẽ hiển thị lên như sau:

cách train YOLO

Trong đó:

  • Bạn chọn Open Dir và trỏ vào thư mục images đã tạo ở trên để load các ảnh.
  • Bạn chọn Change Save Dir và trỏ vào thư mục labels ở trên, để lưu file gán nhãn.
  • Chú ý chọn để cho format là Yolo chứ ko phải là Pascal VOC nhé.

Rồi bây giờ bạn cứ duyệt qua từng file ảnh, chọn Creat Rectbox để vẽ hình chữ nhật quanh vật thể và gắn nhãn cho nó là gun. Vì chúng ta đang train súng nên để vậy, còn bạn train món khác thì thay bằng tên khác. Nhớ nhấn Command +S (hoặc Ctrl +S nếu là window) để lưu lại thao tác gán nhãn với từng file ảnh nhé! Chú ý đây là với cách train YOLO này, nhiều model YOLO biến thể khác sẽ có cách khác.

Bước 4. Chuẩn bị các file cần thiết phục vụ quá trình train dữ liệu

Trong bước này, với cách train YOLO của mình, chúng ta sẽ cần làm việc với 06 file như sau:

  • yolo.data
  • yolo.names
  • train.txt
  • val.txt
  • yolov3.cfg
  • darknet53.conv.74

Chúng ta sẽ đi cụ thể vào từng file như sau:

Đầu tiên là file yolo.names là tên các đối tượng bạn sẽ định nhận dạng. Ví dụ: hoa, súng, oto, xe máy….mỗi tên một dòng. Trong lần này mình chỉ train duy nhất 1 đối tượng là SÚNG NGẮN nên file này mình chỉ để một dòng là GUN. Bạn phải tự tạo ra file này và lưu trong thư mục /darknet/

Tiếp theo là tạo ra 2 file train.txt và val.txt. File train sẽ chứa danh sách các file ảnh sẽ sử dụng để train và tương tự file val.txt sẽ chứa danh sách các file ảnh đẻ thực hiện validation cho model. Thông thường chia ngẫu nhiên theo tỷ lệ 80/20 nghĩa là 80% dữ liệu dành cho train và 20% dữ liệu dành cho val. Tất nhiên tùy các bạn nhé. File train.txt và val.txt sẽ để mỗi ảnh một dòng. Ví dụ:

data/images/sung01.png
data/images/sung_gold.png
data/images/sung_black.png
data/images/sung_2233.png
....

Hai file train và val này cũng lưu trong thư mục /darknet/ luôn.

Giờ ta tiếp tục với file yolo.data, file này sẽ gồm 5 dòng (các phần comment tiếng Việt các bạn phải bỏ đi khi tạo file nhé, mình viết vào để các bạn hiểu thôi):

classses = 1 # Số lượng class, ở đây chỉ có 1 đối tượng lên classes=1
train = train.txt # trỏ đến file train của ta thôi
valid = val.txt # trỏ đến file val của ta
names = yolo.names # trỏ đến file names làm bên trên
backup = backup # là đường dẫn sẽ lưu các file weights trong quá trình train

Done, save lại file này vào thư mục /darknet/ và đi đến file tiếp theo. Mở file yolov3.cfg (trong thư mục /darknet/cfg/) và sửa các dòng như sau:

  • Dòng 7, nếu máy bạn nhiều RAM/GPU VRAM thì để nguyên, còn không thì sửa số 8 thành 16 nhé.
  • Dòng 603, sửa lại thành filters=18 (số 18 tính bằng các lấy số (class + 5)*3 nhé. Ví dụ sau bạn train có 2 class thì sẽ là (2+5)*3 = 21.
  • Dòng 610, sửa lại thành classses=1 (hoặc bằng số nào đó khác nếu bạn train nhiều hơn 1 class)
  • Dòng 689 và 776, sửa giống dòng 603
  • Dòng 696 và 783, sửa giống dòng 610

Ok save file yolov3.cfg lại. Đi tiếp đến file cuối cùng nào. File darket53.conv.74, file này thì các bạn tải tại đây https://pjreddie.com/media/files/darknet53.conv.74 và để vào thư mục darknet/

Done. Sang bước 5 nhé.

Bước 5. Tiến hành train model

Chuyển ra thư mục darknet. Nếu bạn dùng MacOS hay Linux thì chạy lệnh sau để biến file darknet thành file executable nhé:

chmod +x darknet

Tiếp tục mở file cfg/yolov3.cfg và tới dòng 20 sửa max_batches=900000 (to hơn cũng được) để cho hệ thống chạy nhé, nếu không train sẽ không chạy.

Update:Chú ý thêm 1 cái nữa là mặc định thì darknet sẽ save weight theo thuật toán như sau (với cách train YOLO này nhé):

  • Dưới 1000 vòng lặp, save weights mỗi 100 vòng.
  • Trên 1000 vòng lặp, save weights mỗi 10,000 vòng.

Mình thấy thế hơi lâu vì mình thì chỉ train tầm 5,000-6,000 là cùng. Vì vậy các bạn mở file /darknet/examples/detector.c, tìm đến dòng 138 và sửa lại theo ý thích. Ví dụ

if(i%2000==0 || (i < 1000 && i%100 == 0)){

Sửa như trên có nghĩa là nếu dưới 1000 vòng lặp thì save weight mỗi 100 vòng còn lại thì save weights mỗi 2000 vòng lặp nhé. Sau khi sửa xong bạn phải thực hiện biên dịch, make lại như đã làm ở bước 1 nhé.

Rồi, cuối cùng chạy lệnh để train nào:

./darknet detector train yolo.data cfg/yolov3.cfg darknet53.conv.74

Nếu mọi thứ thành công, bạn sẽ nhìn thấy màn hình dạng như sau. Còn nếu có lỗi thì các bạn đọc để sửa, vướng đâu thì comment nhé.

Nguồn: https://user-images.githubusercontent.com/

Bước 6. Kiểm thử quá trình train bằng cách detect thử 1 ảnh

Trong quá trình train YOLO, bạn để ý 2 tham số loss và avg loss, nếu thấy nó bão hòa và không thay đổi nhiều nữa thì có thể stop lại quá trình train.

Sau khi train xong bạn sẽ thấy các file weight lưu ở folder backup nhé. Ví dụ: yolov3_900.weights, yolov3.backup… bạn dùng file nào mới nhất ấy. Ví dụ mình dùng yolov3.backup đi.

Các bạn kiếm thử một ảnh sample nào đó tương đồng một chút với dữ liệu train nói trên nhé (khác quá là ko nhận ra được đâu, vì nó được dạy như nào thì biết thế mà 😀 ). Ví dụ kiếm 1 file tên là sung_test.png đi, ta sẽ sử dụng file YOLO.py đã tải về ở Bài 1 (http://ainoodle.tech/2019/08/05/yolo-series-1-su-dung-yolo-de-nhan-dang-doi-tuong-trong-anh/) để kiểm thử bằng cách chạy lệnh:

python YOLO.py -i sung_test.jpg -cl yolo.names -w backup/yolov3.backup -c cfg/yolov3.cfg

Nếu mọi thứ okie thì bạn sẽ nhận được ảnh có vật thể được nhận dạng kiểu như này :

cách train YOLO

Như vậy các bạn đã biết cách train YOLO và bước đầu tự làm chủ được Yolov3 rồi đó.Nếu có lỗi gì, vướng gì về cách train YOLO thì các bạn comment, mình sẽ giải đáp nhé. Chúc các bạn thành công.

mm
Nguyễn Chiến Thắng

Một người đam mê những điều mới mẻ và công nghệ hiện đại. Uớc mơ cháy bỏng dùng AI, ML để làm cho cuộc sống tốt đẹp hơn! Liên hệ: thangnch@gmail.com hoặc facebook.com/thangnch

Related Post

27 Replies to “[Yolo Series] #2 – Cách train Yolo để detect các object đặc thù”

  1. ‘.’ is not recognized as an internal or external command,
    operable program or batch file.

    em bị lỗi này là ntn ạ

  2. Em chạy make bị lỗi
    Lỗi là
    process_begin: CreateProcess(NULL, chmod +x *.sh, …) failed.
    make (e=2): The system cannot find the file specified.
    make: *** [Makefile:161: setchmod] Error 2
    Lỗi này xử lý thế nào ạ?

  3. Cái ảnh trong data súng bác đánh label và bounding box hết chưa? Nếu có sẵn thì cho mình xịn với.

      1. nó báo lỗi ‘make’ is not recognized as an internal or external command,
        operable program or batch file. trong khi e cài visual studio 2019 rồi a

        1. Chào bạn, mình cũng bị lỗi tương tự vậy, bạn đã fix được chưa ? Hướng dẫn mình với ạ

  4. Resizing
    448
    terminate called after throwing an instance of ‘std::out_of_range’
    what(): basic_string::substr: __pos (which is 140) > this->size() (which is 0)
    Aborted (core dumped)
    ———————————————————–
    Khi bắt đầu quá trình trên em bị lỗi này và chưa biết fix thế nào!
    Anh có biết nguyên nhân do ddaaau không ạ?

  5. Em fix được rồi ạ.
    Em đang train hơn 100 imgs dùng cho nhận diện silense plate.
    model chạy hơn 1 tiếng rồi mà chưa có dấu hiệu dừng lại!!! Em đang dùng CPU.

Leave a Reply

Your email address will not be published. Required fields are marked *