Bắt đầu từ mục tiêu kinh doanh
Chuyển mục tiêu kinh doanh thành một tác vụ thị giác máy tính, các lớp được xác định rõ và bài kiểm tra nghiệm thu có thể chạy dưới dạng code, trước khi thu thập dù chỉ một hình ảnh.

Một nhóm kho hàng chụp ảnh mọi thứ trong một tháng, rồi mới biết trưởng bộ phận an toàn chỉ quan tâm đến người ở gần xe nâng đang di chuyển và một nửa số nhãn phải làm lại. Một trang mục tiêu được thống nhất trước khi chụp bức ảnh đầu tiên sẽ ngăn tình trạng đó. Việc này chỉ mất một buổi chiều và quyết định mọi lựa chọn tiếp theo trong khóa học: cần thu thập gì, cần gán nhãn gì và khi nào model đủ tốt để đưa vào vận hành.
Thực hành
Mục tiêu trên một trang#

Năm hàng trả lời các câu hỏi làm cơ sở cho mọi bước tiếp theo. Hướng dẫn xác định mục tiêu dự án trình bày các nội dung tương tự chi tiết hơn. Dưới đây là ví dụ đã điền về kho hàng mà khóa học này sẽ tiếp tục sử dụng:
| Hàng | Câu hỏi được trả lời | Ví dụ về kho hàng |
|---|---|---|
| Mục tiêu kinh doanh | Điều gì sẽ thay đổi đối với doanh nghiệp và vào thời điểm nào? | Giảm 30% số sự cố suýt va chạm ở cửa xuất nhập hàng trong vòng sáu tháng. |
| Tác vụ thị giác máy tính | Model tạo ra đầu ra gì? | Phát hiện vật thể: hộp bao quanh xe nâng và người. |
| Các lớp | Chính xác thì đối tượng nào được gán nhãn? | forklift, person, pallet; mọi thứ khác là nền. |
| Bài kiểm tra nghiệm thu | Con số nào có nghĩa là "đưa vào vận hành"? | Recall trên person ≥ 0.95 với precision ≥ 0.85 trên 500 frame từ các camera không được dùng trong huấn luyện. |
| Ngoài phạm vi | Phiên bản v1 sẽ không cam kết xử lý điều gì? | Khu vực xuất nhập hàng tối đen, người bị kệ hàng che khuất hoàn toàn và xe nâng tay pallet. |
Đặt trang này ở nơi cả nhóm đều có thể thấy. Nếu sau này bên liên quan phản đối một hàng nào đó, hãy sửa trang trước rồi mới sửa dataset.
Chọn tác vụ đơn giản nhất có thể giải đáp câu hỏi#

Tác vụ quyết định người gán nhãn cần vẽ gì, và điều đó quyết định phần lớn ngân sách gán nhãn. Đi theo cây quyết định này và dừng ở tác vụ đầu tiên có thể trả lời câu hỏi kinh doanh:
Ultralytics YOLO hỗ trợ bảy tác vụ. Khi lập kế hoạch dataset, điều quan trọng là chi phí gán nhãn của từng tác vụ; Nền tảng Thị giác Máy tính so sánh chi tiết các tác vụ này trong bài học về tác vụ thị giác máy tính.
| Tác vụ | Sản phẩm người gán nhãn tạo ra | Công sức gán nhãn | Chọn tác vụ này khi |
|---|---|---|---|
| Phân loại | Một nhãn cho mỗi hình ảnh | Thấp nhất | Chỉ cần một câu trả lời cho mỗi hình ảnh |
| Phát hiện | Lớp + hộp trục song song cho mỗi vật thể | Thấp | Bạn cần đếm hoặc xác định vị trí vật thể |
| OBB | Lớp + hộp xoay cho mỗi vật thể | Trung bình | Vật thể dài, mảnh hoặc được nhìn từ trên cao |
| Pose | Lớp + các keypoint được đặt tên cho mỗi vật thể | Cao | Vị trí khớp hoặc bộ phận có ý nghĩa |
| Phân đoạn đối tượng | Class + polygon cho mỗi đối tượng | Cao | Đường viền của mỗi đối tượng có ý nghĩa |
| Phân đoạn ngữ nghĩa | Một class cho mỗi pixel | Cao nhất | Bạn cần các vùng, không phải các đối tượng có thể đếm được |
| Ước tính độ sâu | Không vẽ gì: một bản đồ độ sâu cho mỗi ảnh, thường lấy từ cảm biến độ sâu | Phụ thuộc vào phần cứng ghi hình | Bạn cần khoảng cách tại mọi pixel |

Hãy xem bảng chuối như một bảng giá: phát hiện đã cho biết sự hiện diện, vị trí và số lượng; chỉ hai bảng phân đoạn mới bổ sung kích thước và hình dạng, với chi phí gán nhãn cao hơn nhiều. Nếu doanh nghiệp chỉ cần biết “có bao nhiêu quả chuối”, thì phát hiện là lựa chọn phù hợp, còn polygon chỉ làm lãng phí ngân sách.
Các nhóm thường chọn segmentation vì có vẻ chính xác hơn, rồi hết ngân sách gán nhãn trước khi dataset bao phủ ca đêm, trời mưa hoặc địa điểm thứ hai. Đa giác tốn kém hơn hộp nhiều lần cho mỗi đối tượng. Chỉ chọn segmentation khi một hàng trong mục tiêu đòi hỏi chính đường viền, chẳng hạn để đo diện tích hoặc tạo mask cắt ảnh.
Viết định nghĩa class mà người gán nhãn có thể áp dụng#
Một class chỉ hữu ích khi hai người gán nhãn phân loại cùng một đối tượng theo cùng một cách. Hãy viết định nghĩa mỗi class thành một câu, nêu rõ một đối tượng trông tương tự nhưng không thuộc class đó:
forklift: xe nâng chạy bằng động cơ, bao gồm càng nâng và cột nâng. Không bao gồm xe nâng pallet thủ công.person: bất kỳ người nào, kể cả người chỉ nhìn thấy một phần, đang ngồi hoặc ở trong cabin xe. Không bao gồm hình phản chiếu và áp phích.pallet: pallet vận chuyển bằng gỗ hoặc nhựa, có hoặc không có hàng. Không bao gồm các thùng hàng xếp chồng không có đế pallet.
Sau đó, hãy chủ động chọn mức độ chi tiết. Class khái quát (“phương tiện”) tốn ít chi phí hơn và hội tụ nhanh hơn; class chi tiết (“sedan”, “bán tải”) hữu ích hơn cho các bước tiếp theo nhưng khó duy trì tính nhất quán hơn. Hãy bắt đầu từ nhu cầu của doanh nghiệp. Sau này có thể gộp nhãn chi tiết thành nhãn khái quát chỉ bằng một dòng code, nhưng không thể tách nhãn khái quát nếu không gán nhãn lại.
"Bất cứ thứ gì trông nguy hiểm" hoặc "vật cản lối đi" không phải là một lớp. Những mô tả này yêu cầu mỗi người gán nhãn tự đưa ra đánh giá, và model được huấn luyện bằng các đánh giá không nhất quán sẽ học theo sự thiếu nhất quán đó. Hãy viết lại lớp mơ hồ cho đến khi người gán nhãn mới có thể áp dụng chỉ dựa trên định nghĩa, hoặc chuyển lớp đó thành quy tắc áp dụng sau detection (ví dụ: "mọi pallet nằm bên trong đa giác lối đi").
Chuyển metric thành bài kiểm tra nghiệm thu có thể chạy được#
Chọn metric phù hợp với chi phí của một sai sót:
- Bỏ sót gây tốn kém (an toàn, lỗi sản phẩm): đặt ngưỡng nghiệm thu theo recall của class đó.
- Cảnh báo sai gây tốn kém (tự động loại bỏ linh kiện, cảnh báo nhân viên): đặt ngưỡng nghiệm thu theo precision.
- Mọi class đều quan trọng như nhau (đếm, kiểm kê): đặt ngưỡng nghiệm thu theo AP từng class để không class nào có thể ẩn sau giá trị trung bình.
Hướng dẫn về các metric hiệu suất YOLO giải thích từng metric. Sau đó, hãy viết bài kiểm tra thành code để câu hỏi “đã đủ tốt chưa?” không còn là đề tài tranh luận. Script này chạy ngay hôm nay với model pretrained trên tập demo COCO8, rồi có thể chạy với checkpoint và tập holdout của riêng bạn:
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # later: your fine-tuned runs/detect/train/weights/best.pt
metrics = model.val(data="coco8.yaml", classes=[0], verbose=False) # 0 = person; later: your holdout YAML
precision, recall = metrics.box.mp, metrics.box.mr
print(f"person: precision={precision:.2f} recall={recall:.2f}")
print("PASS" if recall >= 0.95 and precision >= 0.85 else "FAIL: below the acceptance test") all 4 10 0.939 0.8 0.848 0.387
person: precision=0.94 recall=0.80
FAIL: below the acceptance testÝ nghĩa của từng dòng:
classes=[0]chỉ chấm điểmperson, vì vậy các class khác không thể làm tăng kết quả. Hãy dùng ID class an toàn của riêng bạn.- Dòng kết quả của validator cho biết có 4 ảnh với 10 người được gán nhãn.
mpvàmrlà precision và recall tại ngưỡng confidence giúp cân bằng hai chỉ số này tốt nhất (F1 tối đa). - Model COCO pretrained phát hiện được 8 trong số 10 người, nên recall là 0.80: khá chính xác nhưng chưa đủ an toàn. Kết quả FAIL cho thấy bài kiểm tra đang làm đúng nhiệm vụ. Trong khóa học này, FAIL đồng nghĩa với việc quay lại xử lý dữ liệu, không phải điều chỉnh hyperparameter.
Một tập test được lấy từ cùng camera và ngày quay như tập huấn luyện sẽ đo khả năng ghi nhớ, chứ không phải mức độ sẵn sàng. Hãy nêu rõ tập holdout trong mục tiêu ("camera không dùng trong huấn luyện", "hai tuần video gần nhất") và xây dựng tập đó theo Chia dataset đúng cách.
Ghi rõ những gì v1 sẽ không làm#
Không model nào hoàn hảo, vì vậy hãy xác định trước những trường hợp bỏ sót có thể chấp nhận: các điều kiện bạn không cam kết xử lý (sương mù dày, bóng tối hoàn toàn), những đối tượng trông tương tự mà bạn chấp nhận model nhầm lẫn, và các class hiếm được để lại cho v2. Hàng này giúp tránh việc đánh giá một model đạt mục tiêu theo một chuẩn 100% chưa từng được viết ra, đồng thời cho nhóm thu thập dữ liệu biết hiện chưa cần dành công sức cho những trường hợp nào.
Hiển thị lời giải
Ví dụ mục tiêu đã hoàn thiện cho một dự án khác: chuỗi cửa hàng tạp hóa phát hiện các vị trí kệ trống:
| Hàng | Câu trả lời |
|---|---|
| Mục tiêu kinh doanh | Giảm 25% số phút hết hàng của 200 sản phẩm bán chạy nhất trong vòng một quý. |
| Tác vụ thị giác máy tính | Phát hiện. Cửa hàng cần vị trí của từng khoảng trống, không cần đường viền, nên bounding box phù hợp hơn polygon. |
| Các lớp | gap: một vị trí kệ trống rộng ít nhất bằng một sản phẩm; không bao gồm vị trí bị người mua sắm hoặc xe đẩy che khuất. price_tag: nhãn gắn ở mép kệ; không bao gồm nhãn dán khuyến mãi. |
| Bài kiểm tra nghiệm thu | Recall trên gap ≥ 0.90 với precision ≥ 0.80 trên 400 ảnh từ 5 cửa hàng không dùng trong quá trình huấn luyện. |
| Ngoài phạm vi | Cửa tủ đông bị lóa, quầy hàng ở đầu dãy kệ, khu vực rau củ quả. |
Recall được ưu tiên vì bỏ sót một khoảng trống sẽ làm mất doanh thu, còn cảnh báo sai chỉ khiến nhân viên phải đi bộ một đoạn ngắn. acceptance_test.py chỉ thay đổi ở ba chỗ: data="holdout_stores.yaml" (năm cửa hàng chưa thấy), classes=[0] (0 giờ là gap), và các ngưỡng recall >= 0.90 and precision >= 0.80.