![Tìm hiểu mô hình YOLO cho phát hiện vật - Từ YOLOv1 đến YOLOv3](/_next/image?url=%2Fposts-data%2F2020-10-11-tim-hieu-mo-hinh-yolo-cho-phat-hien-vat-tu-v1-den-v5%2Fthumbnail.png&w=1080&q=75)
Tìm hiểu mô hình YOLO cho phát hiện vật - Từ YOLOv1 đến YOLOv3
11/10/202016phút đọcObject Detection
YOLO - You Only Look Once là một trong những mô hình phát hiện vật tốt nhất ở thời điểm hiện tại. Dù đều được gọi là YOLO, các phiên bản của mô hình này đều có những cải tiến rất đáng kể sau mỗi phiên bản. Sau 3 phiên bản của tác giả chính Joseph Redmon là YOLOv1 đến v3.
Lưu ý: Bài viết này chỉ mang tính chất tổng hợp vấn đề, để hiểu sâu hơn về lý thuyết và cách triển khai mô hình, các bạn nên đọc paper của mỗi mạng, kết hợp tham khảo các mã nguồn cài đặt tương ứng.
I. YOLOv1
Đầu vào của bài toán phát hiện vật là một bức ảnh. Chúng ta không chỉ phải phân loại được object trên bức ảnh mà còn phải định vị được vị trí của đối tượng đó. Các phương pháp trước YOLOv1 thường sử dụng 2 bước: bước (1) thường sử dụng sliding window để lấy các vùng khác nhau của bức ảnh, hoặc sử dụng một thuật toán lựa chọn các vùng ứng viên (có thể chứa vật), tiếp theo đó, bước (2) sẽ phân loại các vị trí này xem vật đó thuộc lớp nào. Các cách tiếp cận này có nhược điểm là yêu cầu một lượng tính toán lớn, và bị phân nhỏ thành nhiều bước, khó có thể tối ưu về mặt tốc độ. Kiến trúc YOLOv1 coi bài toán phát hiện vật như một bài toán regression. Từ input là ảnh đầu vào, qua một mạng gồm các lớp convolution, pooling và fully connected là có thể ra được output. Kiến trúc này có thể được tối ưu để chạy trên GPU với một lần forward pass, và vì thế đạt được tốc độ rất cao.
![Cách YOLOv1 dự đoán - Hình ảnh từ [1]](/_next/image?url=%2Fposts-data%2F2020-10-11-tim-hieu-mo-hinh-yolo-cho-phat-hien-vat-tu-v1-den-v5%2Fyolo-v1-predictions.png&w=2048&q=75)
Ý tưởng
Ý tưởng chính của YOLOv1 là chia ảnh thành một lưới các ô (grid cell) với kích thước SxS (mặc định là 7x7). Với mỗi grid cell, mô hình sẽ đưa ra dự đoán cho B bounding box. Ứng với mỗi box trong B bounding box này sẽ là 5 tham số x, y, w, h, confidence, lần lượt là tọa độ tâm (x, y), chiều rộng, chiều cao và độ tự tin của dự đoán. Với grid cell trong lưới SxS kia, mô hình cũng dự đoán xác suất rơi vào mỗi class.
Độ tự tin của dự đoán ứng với mỗi bounding box được định nghĩa là , trong đó là xác suất có vật trong cell và là intersection over union của vùng dự đoán và ground truth.
Xác suất rơi vào mỗi class cho một grid cell được ký hiệu . Các giá trị xác suất cho C class sẽ tạo ra C output cho mỗi grid cell. Lưu ý là B bounding box của cùng một grid cell sẽ chia sẻ chung một tập các dự đoán về class của vật, đồng nghĩa với việc tất cả các bounding box trong cùng một grid cell sẽ chỉ có chung một class.
Vậy tổng số output của mô hình sẽ là . Hình dưới đây là kiến trúc của YOLOv1. Mạng backbone của YOLOv1 lấy ý tưởng từ kiến trúc GoogleNet.
![Kiến trúc của YOLOv1 - Hình ảnh từ lilianweng.github.io](/_next/image?url=%2Fposts-data%2F2020-10-11-tim-hieu-mo-hinh-yolo-cho-phat-hien-vat-tu-v1-den-v5%2Fyolo-v1-architecture.png&w=3840&q=75)
Về hàm loss và việc huấn luyện mô hình YOLOv1, các bạn có thể tìm hiểu thêm trong paper YOLOv1, mục [1] trong phần Tham khảo cuối bài viết.
Nhược điểm của YOLOv1
YOLOv1 áp đặt các ràng buộc về không gian trên những bounding box, mỗi grid cell chỉ có thể predict rất ít bounding box (B) và duy nhất một class. Các ràng buộc này hạn chế khả năng nhận biết số object nằm gần nhau, cũng như đối với các object có kích thước nhỏ.
Ngoài ra, trong quá trình training, loss function không có sự đánh giá riêng biệt giữa error của bounding box kích thước nhỏ so với error của bounding box kích thước lớn. Việc coi chúng như cùng loại và tổng hợp lại làm ảnh hưởng đến độ chính xác toàn cục của mạng. Error nhỏ trên box lớn nhìn chung ít tác hại, nhưng error nhỏ với box rất nhỏ sẽ đặc biệt ảnh hưởng đến giá trị IOU.
II. YOLOv2 & YOLO 9000
YOLOv2 đặt tên là YOLO9000 đã được Joseph Redmon và Ali Farhadi công bố vào cuối năm 2016 và có mặt trong 2017 CVPR. Cải tiến chính của phiên bản này tốt hơn, nhanh hơn, tiên tiến hơn để bắt kịp faster R-CNN (phương pháp sử dụng Region Proposal Network), xử lý được những vấn đề gặp phải của YOLOv1.
1. Thêm Batch Normalization
Kĩ thuật Batch Normalization được đưa vào sau tất cả các lớp convolution của YOLOv2. Kĩ thuật này không những giảm được thời gian huấn luyện, mà còn có tác dụng tăng tính phổ quát (generalize) cho mạng. Ở YOLOv2, Batch Normalization giúp tăng mAP lên khoảng 2%. Mạng cũng không cần sử dụng thêm Dropout để tăng tính phổ quát.
2. High resolution classifier
YOLO được huấn luyện với 2 pha. Pha đầu sẽ huấn luyện một mạng classifier với ảnh đầu vào kích thước nhỏ (224x224) và pha sau sẽ loại bỏ lớp fully connected và sử dụng mạng classifier này như phần khung xương (backbone) để huấn luyện mạng detection. Lưu ý rằng ảnh đầu vào kích thước nhỏ cũng thường được sử dụng để huấn luyện các mạng classifier, mà sau đó sẽ được sử dụng như pretrained model cho phần backbone của các mạng detection khác. Ở pha sau YOLO trước hết finetune mạng backbone dưới ảnh đầu vào kích thước lớn hơn là 448x448, để mạng "quen" dần với kích thước ảnh đầu vào lớn, sau đó mới sử dụng kết quả này để huấn luyện cho quá trình detection. Điều này giúp tăng mAP của YOLOv2 lên khoảng 4%.
3. Sử dụng kiến trúc anchorbox để đưa ra dự đoán
Trong YOLOv2, tác giả loại bỏ lớp fully connected ở giữa mạng và sử dụng kiến trúc anchorbox để predict các bounding box. Việc dự đoán các offset so với anchorbox sẽ dễ dàng hơn nhiều so với dự đoán toạ độ bounding box. Thay đổi này làm giảm mAP đi một chút nhưng làm recall tăng lên.
4. K-mean clustering cho lựa chọn anchor
Thay vì phải chọn anchorbox bằng tay, YOLOv2 sử dụng thuật toán k-means để đưa ra các lựa chọn anchorbox tốt nhất cho mạng. Việc này tạo ra mean IoU tốt hơn.
5. Direct location prediction
YOLOv1 không có các hạn chế trong việc dự đoán vị trí của bounding box. Khi các trọng số được khởi tạo ngẫu nhiên, bounding box có thể được dự đoán ở bất kỳ đâu trong ảnh. Điều này khiến mô hình không ổn định trong giai đoạn đầu của quá trình huấn luyện. Vị trí của bounding box có thể ở rất xa so với vị trí của grid cell.
YOLOv2 sử dụng hàm sigmoid ( ) để hạn chế giá trị trong khoảng 0 đến 1, từ đó có thể hạn chế các dự đoán bounding box ở xung quanh grid cell, từ đó giúp mô hình ổn định hơn trong quá trình huấn luyện.
Cho anchorbox có kích thước nằm tại grid cell với vị trí top left là , mô hình sẽ dự đoán các offset và scale , , , và bounding box . Độ tự tin (confidence của dự đoán là ).
![Dự đoán bounding box trong YOLOv2 - nguồn [2]](/_next/image?url=%2Fposts-data%2F2020-10-11-tim-hieu-mo-hinh-yolo-cho-phat-hien-vat-tu-v1-den-v5%2Fyolo-v2-direct-location-prediction.png&w=3840&q=75)
Dự đoán bounding box trong YOLOv2 - nguồn [2]
YOLOv2 đã có thêm 5% mAP khi áp dụng phương pháp này.
6. Add fine-grained features
YOLOv2 sử dụng feature map 13x13 để đưa ra các dự đoán, lớn hơn 7x7 của YOLOv1.
Faster R-CNN và SSD đưa ra dự đoán ở nhiều tầng khác nhau trong mạng để tận dụng các feature map ở các kích thước khác nhau. YOLOv2 cũng kết hợp các feature ở các tầng khác nhau lại để đưa ra dự đoán, cụ thể kiến trúc nguyên bản của YOLOv2 kết hợp feature map 26x26 lấy từ đoạn gần cuối với feature map 13x13 ở cuối để đưa ra các dự đoán. Cụ thể là các feature map này sẽ được ghép vào nhau (concatenate) để tạo thành một khối sử dụng cho dự đoán.
![Kiến trúc YOLOv2 - hình ảnh từ [7]](/_next/image?url=%2Fposts-data%2F2020-10-11-tim-hieu-mo-hinh-yolo-cho-phat-hien-vat-tu-v1-den-v5%2Fyolo-v2-architecture.png&w=1920&q=75)
Vậy làm thế nào để concatenate được 2 feature map kích thước và để trở thành một feature map ?
Thông thường việc concatenate 2 feature map chỉ thực hiện được khi chúng có cùng chiều rộng và chiều dài. Tuy nhiên trong YOLOv2 tác giả sử dụng lớp Reorg, tuy nhiên lại không mô tả kỹ về kĩ thuật này trong paper. Thực ra Reorg chỉ là kĩ thuật tổ chức lại bộ nhớ để biến feature map 26x26 thành 13x13 với chiều sâu lớn hơn để có thể thực hiện phép concatenate với feature map 13x13 ở cuối.
Trong trường hợp tổng quát của phép Reorg, ta sẽ biến feature map kích thước thành kích thước , tức là số lượng tham số trong feature map vẫn được giữ nguyên. Khi ta muốn giảm kích thước dài, rộng đi mỗi cạnh 2 lần thì số channel phải được tăng lên 4 lần. Việc biến đổi này hoàn toàn không giống phép resize trong xử lý ảnh. Để dễ hình dung, bạn có thể xem hình vẽ dưới đây:
![Kĩ thuật Reorg trong YOLOv2](/_next/image?url=%2Fposts-data%2F2020-10-11-tim-hieu-mo-hinh-yolo-cho-phat-hien-vat-tu-v1-den-v5%2Fyolo-v2-reorg.png&w=1920&q=75)
Đây là một lát cắt (channel) của feature map kích thước 4x4. Để đưa về kích thước 2x2, tức là giảm chiều rộng đi 2 lần và chiều dài đi 2 lần, ta tách channel của feature map 4x4 thành 4 ma trận như hình trên, ứng với 4 channel chiều sâu của feature map 2x2 mới. Vị trí các giá trị trong mỗi channel của feature map 2x2 mới sẽ lấy thưa thớt trên feature map 4x4 ban đầu với stride = 2 theo 2 trục dài và rộng.
Tôi tìm thấy một bài viết khá chi tiết, bao gồm cả code về kỹ thuật Reorg, các bạn có thể tham khảo tại blog của Lei Mao. Bằng kĩ thuật "Add fine-grained features", performance của mạng YOLOv2 được tăng thêm 1%.
7. Multi-Scale Training
Sau khi thêm kĩ thuật anchorbox cho YOLOv2, tác giả đã thay đổi input của mạng thành 416x416 thay vì 448x448. Tuy vậy, YOLOv2 được thiết kể chỉ gồm các lớp convolution và pooling nên có thể thích ứng với nhiều kích thước ảnh đầu vào khác nhau. Tác giả đã huấn luyện mạng trên nhiều kích thước ảnh khác nhau để tăng khả năng thích ứng của YOLOv2 với đa dạng kích thước ảnh.
8. Light-weight backbone
Điểm cải tiến của YOLOv2 còn phải kể đến backbone mới có tên Darknet-19. Mạng này bao gồm 19 lớp convolution và 5 lớp maxpooling tạo ra tốc độ nhanh hơn phiên bản YOLO trước.
YOLO9000
YOLO9000 đưa ra cách kết hợp các dataset khác với ImageNet để có thể phát hiện nhiều class hơn. Tác giả tạo một directed graph gọi là WordTree như hình dưới. Để có thể merge được các label từ tập ImageNet (1000 class) với COCO/PASCAL (100 class), tác giả dựa vào WordNet để xây dựng quan hệ giữa các class, từ đó có thể huấn luyện mạng nhận dạng các class có quan hệ với nhau.
![WordTree - YOLO9000 - hình ảnh từ [2]](/_next/image?url=%2Fposts-data%2F2020-10-11-tim-hieu-mo-hinh-yolo-cho-phat-hien-vat-tu-v1-den-v5%2Fyolo-9k-word-tree.png&w=3840&q=75)
Ví dụ để dự đoán xác suất rơi vào một class, ta nhân các xác suất từ nhánh gốc của đồ thị và dừng lại khi xác suất vào các class nhánh nhỏ hơn một ngưỡng nào đó.
Pr("persian cat" | contain a "physical object")
= Pr("persian cat" | "cat")
Pr("cat" | "animal")
Pr("animal" | "physical object")
Pr(contain a "physical object") # confidence score.
III. YOLOv3
YOLOv3 có kiến trúc khá giống YOLOv2. Tác giả đã thêm các cải tiến mới trong các nghiên cứu gần đây vào YOLOv2 để tạo ra YOLOv3. Các cải tiến đó bao gồm:
- Logistic regression cho confidence score: YOLOv3 predict độ tự tin của bounding box (có chứa vật hay không) sử dụng logistic regression
- Thay softmax bằng các logistic classifier rời rạc: YOLOv3 sử dụng các logistic classifier thay vì softmax cho việc classify đối tượng. Việc này cho hiệu quả tốt hơn nếu các label không "mutually exclusive", tức là có thể có đối tượng cùng thuộc 2 hay nhiều class khác nhau. Ví dụ với bài toán cần phát hiện 2 đối tượng là "chó" và "chó Phú Quốc". Rõ ràng nếu đối tượng là "chó Phú Quốc" thì nó cũng thuộc class "chó", và việc sử dụng softmax là không phù hợp trong trường hợp này.
- Backbone mới - Darknet-53: Backbone được thiết kế lại với việc thêm các residual blocks (kiến trúc sử dụng trong ResNet).
- Multi-scale prediction: YOLOv3 sử dụng kiến trúc Feature Pyramid Networks (FPN) để đưa ra các dự đoán từ nhiều scale khác nhau của feature map. Việc này giúp YOLOv3 tận dụng các feature map với độ thô - tinh khác nhau cho việc dự đoán.
- Skip-layer concatenation: YOLOv3 cũng thêm các liên kết giữa các lớp dự đoán. Mô hình upsample các lớp dự đoán ở các tầng sau và sau đó concatenate với các lớp dự đoán ở các tầng trước đó. Phương pháp này giúp tăng độ chính xác khi predict các object nhỏ.
Chú ý: Về Multi-scale prediction và Skip-layer concatenation các bạn có thể xem kiến trúc YOLOv3 ở hình dưới để dễ hình dung hơn.
![Kiến trúc YOLOv3 - Hình ảnh từ [5]](/_next/image?url=%2Fposts-data%2F2020-10-11-tim-hieu-mo-hinh-yolo-cho-phat-hien-vat-tu-v1-den-v5%2Fyolo-v3-darknet-53.png&w=3840&q=75)
VI. Tương lai của YOLO
YOLO đã trở nên rất nổi tiếng cho bài toán phát hiện vật thể thời gian thực. Tuy nhiên kể từ phiên bản YOLOv3, tác giả đầu tiên của YOLO là Joseph Redmon đã không còn nghiên cứu và cải thiện kiến trúc này nữa. Anh còn tuyên bố đã ngừng nghiên cứu về thị giác máy tính do các lo ngại công nghệ được sử dụng sai mục đích (sử dụng cho quân sự, các lo ngại về quyền riêng tư). Tuy thế, trên quan điểm của tôi, công nghệ luôn có 2 mặt, tốt và xấu. Chúng ta vẫn sẽ nhận được các "bản nâng cấp" YOLO từ các tác giả khác, như YOLOv4, YOLOv5 vừa mới ra mắt gần đây.
Tham khảo
- [1] You Only Look Once: Unified, Real-Time Object Detection.
- [2] YOLO9000: Better, Faster, Stronger.
- [3] YOLOv3: An Incremental Improvement.
- [4] YOLOv4: Optimal Speed and Accuracy of Object Detection.
- [5] Optimized YOLOv3 Algorithm and Its Application in Traffic Flow Detections
- [6] YOLO v2 Reorg Layer Explained.
- [7] Determination of Vehicle Trajectory through Optimization of Vehicle Bounding Boxes Using a Convolutional Neural Network
- [8] https://lilianweng.github.io/lil-log/2018/12/27/object-detection-part-4.html