[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://miai.vn/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/darknetCode language: PHP (php)

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=0Code language: PHP (php)

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

Gõ thêm đoạn này:

export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib:/usr/local/cudnn/lib
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfigCode language: JavaScript (javascript)

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 Thư viện Mì AI: https://miai.vn/thu-vien-mi-ai nhé!

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/labelImgCode language: PHP (php)

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 qt5py3Code language: PHP (php)

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

python labelImg.pyCode language: CSS (css)

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

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 trainCode language: PHP (php)

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)){Code language: HTML, XML (xml)

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/

Nếu train bị lỗi, các bạn có thể tham khảo post này: https://miai.vn/2019/11/05/tong-hop-phuong-an-khac-phuc-loi-khi-train-yolo/ để tìm cách khắc phục hoặc post lên group nhé Group trao đổi, chia sẻ: https://facebook.com/groups/miaigroup .

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 (https://miai.vn/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 :

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.

Related Post

65 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.

  6. chỗ chạy lệnh làm sao để tắt ảnh đang chạy để chạy ảnh khác vậy anh ?

      1. chỗ chạy lệnh cmd á anh, lúc e test thử bằng lệnh python YOLO.py -i imgTEst/2.jpg -cl yolo.names -w backup/yolov3_900.weights -c cfg/yolov3.cfg nó ra YOLO Execution time: 0.13503623008728027 nó chạy ok nhưng cứ nhấp nháy mãi chỗ đó
        làm sao để chạy ảnh khác ạ,

  7. Cho em hỏi là e không tìm thấy file YOLO.py trong thư mục darknet ạ, hay trong thư mục darknet thay bằng file khác vậy a
    >python YOLO.py -i data/images/armas.jpg -cl yolo.names -w backup/yolov3_2000.weights -c cfg/yolov3.cfg
    python: can’t open file ‘YOLO.py’: [Errno 2] No such file or directory

  8. hi anh Thắng ạ.
    Em đã train được nhưng đến phần kiểm tra thì nó chỉ hiện ra cái hình test với dòng YOLO Execution time: 0.1477370262145996
    Nhưng ko hiện ra hình kèm những box như trong link bài [YOLO Series] #1 ạ.
    Em cảm ơn anh!

  9. Chào ad ạ
    Em muốn train cho sdd thì cách làm có giống không ạ????

  10. Cho em hỏi chút là 2 tham số loss và avg loss mình có thể nhìn thấy ở đâu được ạ?

  11. darknet detector train yolo.data cfg/yolov3.cfg darknet53.conv.74
    cho em hỏi là lúc em chạy lệnh này mà nó ra lỗi: First section must be [net] or [network]: Invalid argument
    darknet: ./src/utils.c:256: error: Assertion `0′ failed.
    là như thế nào ạ 🙁

  12. anh cho em hỏi thêm về tham số max_batch trong MakeFile được không ạ?
    tại em nghe anh nói thì em vẫn ko biết nó để làm gì, có phải để càng cao là số batch nó lấy cho 1 lần train là càng nhiều hay không? và nếu lấy max_batch vượt quá số lượng dataset thì có bị gì ko?

    1. Max_batch là số lượng vòng lặp tối đa mà ta sẽ train. Anh thì toàn để to oành lên sau đó tuỳ vào loss mà stop giữa chừng. Loss ngon thì ta stop thôi. Để nhỏ qua lại phải chạy tiếp khi cần 😀

  13. Em bị lỗi như này khi chạy lênh make ạ
    em đã cài gnu32 và mingw32 rồi ạ

    gcc -Iinclude/ -Isrc/ -DGPU -I/usr/local/cuda/include/ -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DGPU -c ./src/gemm.c -o obj/gemm.o
    In file included from ./src/utils.h:5:0,
    from ./src/gemm.c:2:
    include/darknet.h:6:21: fatal error: pthread.h: No such file or directory
    #include
    ^
    compilation terminated.
    Makefile:89: recipe for target ‘obj/gemm.o’ failed
    make: *** [obj/gemm.o] Error 1

  14. anh Thăng cho em hỏi, làm cách nào để giảm loss trong traiining yolo4 thế ạ? em đã tinh chỉnh data nhiều lần nhưng loss không giảm là bao

  15. a thắng cho e hỏi là e có dataset đèn giao thông xanh, đỏ. E cần 1 bản yolo detect được người, đèn giao thông và stop sign. Liệu e có thể traing thêm thẳng vào bản yolo-tiny đã được đào tạo sẵn k ạ.

      1. không biết là em có thể nhắn tin riêng trên facebook của anh để trao đổi được không ạ

  16. Em chạy make bị lỗi á anh, thế thêm dòng này ở đâu vậy anh ?
    export PATH=/usr/local/cuda/bin:$PATH
    export LD_LIBRARY_PATH=/usr/local/cuda/lib:/usr/local/cudnn/lib
    export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

  17. Em dùng window, ở bước 2 khi nhập lệnh “make qt5py3” em bị lỗi này, anh giúp em với ạ
    make : The term ‘make’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check
    the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At line:1 char:1
    + make qt5py3
    + ~~~~
    + CategoryInfo : ObjectNotFound: (make:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Leave a Reply

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