7.13. Triệt tiêu non-max

Một mạng phát hiện thường tạo ra nhiều hộp giới hạn ứng viên chồng lên nhau xung quanh cùng một đối tượng trong thực tế: mỗi anchor gần đối tượng sẽ kích hoạt với điểm số tương tự nhau, và bộ xử lý hậu kỳ nhận thấy tất cả chúng. Triệt tiêu non-max (NMS) là bước biến cụm đó thành một hộp duy nhất.

Thuật toán rất ngắn gọn: sắp xếp các hộp ứng viên theo điểm số, lấy hộp có điểm cao nhất, triệt tiêu mọi hộp khác chồng lên nó vượt quá ngưỡng đã chọn, sau đó lấy hộp cao nhất tiếp theo từ những gì còn lại, và lặp lại. Thước đo độ chồng lấp là intersection-over-union (IoU) -- diện tích chung của hai hộp chia cho diện tích kết hợp của chúng, một giá trị từ 0 (không chồng lấp) đến 1 (hai hộp giống hệt nhau). Tham số constructor nms_threshold trên mỗi bộ xử lý hậu kỳ đi kèm là ngưỡng cắt, trên đó các hộp được coi là bản sao của một hộp đã được giữ lại.

Left, three overlapping bounding boxes around a single subject, labelled with scores 0.92, 0.83, and 0.71. An arrow points to the right, where one surviving box remains with the score 0.92. The two lower-scoring boxes are suppressed by the higher-scoring one because their intersection-over-union with it exceeds the threshold.

NMS thu gọn một cụm các phát hiện chồng lấp thành hộp có điểm cao nhất.

7.13.1. Soft-NMS

Lớp ml.utils.NMS đi kèm triển khai Soft-NMS, một cải tiến làm giảm điểm số của hộp chồng lấp theo một lượng phụ thuộc vào mức độ chồng lấp, thay vì loại bỏ hộp đó hoàn toàn. Nếu điểm số đã giảm xuống dưới ngưỡng thì hộp bị loại bỏ; nếu không nó tồn tại với điểm số thấp hơn và cạnh tranh trong vòng tiếp theo.

Tham số nms_sigma kiểm soát mức độ giảm điểm số mạnh đến đâu. Với nms_sigma nhỏ (mặc định đi kèm là 0.1) độ giảm rất dốc: một hộp chồng lấp nhiều sẽ bị giảm điểm số xuống gần bằng không và Soft-NMS trở thành NMS cổ điển. Với nms_sigma lớn hơn, độ giảm nhẹ nhàng hơn và các hộp chồng lấp của các đối tượng khác nhau tồn tại thường xuyên hơn, điều này quan trọng khi các đối tượng thực tế cùng lớp thực sự chồng lấp nhau (một đám đông khuôn mặt, một cụm bàn tay).

Đặt nms_sigma thành <= 0 vô hiệu hóa hoàn toàn quá trình giảm điểm số: các hộp chồng lấp đi qua với điểm số gốc của chúng, và chỉ có ngưỡng điểm số mới lọc chúng.

7.13.2. Xây dựng trực tiếp

Mỗi bộ xử lý hậu kỳ đi kèm đều tạo một NMS mới cho mỗi lần suy luận, thêm từng ứng viên vào đó, và gọi get_bounding_boxes() ở cuối. Một bộ xử lý hậu kỳ tùy chỉnh tuân theo cùng một mẫu:

from ml.utils import NMS

iw = model.input_shape[0][2]
ih = model.input_shape[0][1]

nms = NMS(iw, ih, inputs[0].roi)
for box, score, class_idx in candidates:
    nms.add_bounding_box(box.xmin, box.ymin,
                         box.xmax, box.ymax,
                         score, class_idx)
result = nms.get_bounding_boxes(threshold=nms_threshold,
                                sigma=nms_sigma)

Constructor nhận chiều rộng và chiều cao đầu vào của mạng theo điểm ảnh và vùng quan tâm (ROI) của ảnh gốc mà mô hình đã chạy trên đó; add_bounding_box() nhận tọa độ hộp trong không gian điểm ảnh đầu vào mạng đó, và get_bounding_boxes() ánh xạ lại các hộp sống sót về tọa độ ảnh bằng cách sử dụng ROI. Quá trình ánh xạ lại tự động tính đến sự co giãn chuẩn hóa -- cùng ROI mà bộ dự đoán đã thấy được dùng để chiếu các hộp trở lại -- vì vậy các hộp được trả về đã sẵn sàng để vẽ lên khung hình chụp.

Giá trị trả về có dạng danh sách các danh sách theo lớp, được lập chỉ mục bởi label_index được truyền vào add_bounding_box. Các danh sách lớp rỗng được giữ nguyên để chỉ mục khớp với chỉ mục lớp của mô hình; enumerate(result) duyệt qua các lớp cùng với các phát hiện của chúng.