Phân loại ảnh
Phân loại ảnh gán một phân phối nhãn cho toàn ảnh và không định vị gì bên trong. Key tác vụ là classify.
Định nghĩa
Phân loại ảnh tạo một điểm số trên mỗi lớp đối tượng cho toàn ảnh và hoàn toàn không có tọa độ. Nó trả lời trong ảnh có gì, không bao giờ trả lời ở đâu, đây là điểm phân biệt với phát hiện đối tượng.
classify là key tác vụ chuẩn, còn hậu tố -cls trong tên tệp checkpoint chọn
tác vụ. Hậu tố này là bắt buộc thay vì tùy chọn trên classification family, vì
vậy LibreResNet50.pt không được đọc như classifier, chỉ
LibreResNet50-cls.pt mới được đọc như vậy.
predict() điền result.probs và để boxes rỗng. .data là toàn bộ vector
điểm số, .top1 là index của điểm cao nhất và .top1conf là giá trị của nó,
.top5 là năm index cao nhất theo thứ tự giảm dần và .top5conf là các điểm
tương ứng. Index trỏ vào result.names. Slicing đối tượng Results không bao
giờ cắt probs vì vector thuộc về ảnh, không phải một dòng.
Mô hình
Các bộ phân loại ảnh có thể huấn luyện gồm: ResNet,
ConvNeXt, MobileNetV4,
EfficientNetV2 và
DINOv2. Bốn family đầu chạy trên package cơ sở và cung
cấp trọng số đã công bố. DINOv2 cần pip install "libreyolo[rfdetr]" và không
có checkpoint được LibreYOLO lưu trữ: nó nạp backbone upstream với linear head
được khởi tạo ngẫu nhiên, vì vậy đây là điểm bắt đầu tinh chỉnh thay vì mô hình
dự đoán sẵn sàng.
Năm family khác dự đoán, xác thực và xuất, nhưng train() phát sinh
NotImplementedError: ViT, Swin,
VGG, AlexNet và
DeiT.
CLIP và SigLIP2 phân loại mà không
có tập nhãn cố định. Chúng tính điểm ảnh so với text prompt, vì vậy
set_classes() định nghĩa lớp đối tượng tại thời điểm gọi và hoàn toàn không có
bước huấn luyện cho tập nhãn mới. Cả hai cũng phục vụ tác vụ embed.
ConvNeXt V2 bổ sung phân loại có giám sát với trọng số được huấn luyện sẵn CC-BY-NC-4.0. PE hỗ trợ phân loại zero-shot; V-JEPA 2 huấn luyện các probe phân loại video.
Dự đoán
Trọng số được tải từ Hugging Face trong lần sử dụng đầu tiên và lưu vào cache cục bộ.
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Hậu tố -cls trong tên tệp chọn tác vụ, vì vậy không cần# đối số task.model = LibreYOLO("LibreResNet50-cls.pt")result = model(SAMPLE_IMAGE, save=True) print(result.names[result.probs.top1], float(result.probs.top1conf))print(result.probs.top5)libreyolo predict model=LibreResNet50-cls.pt save=True \ source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpgfrom libreyolo import LibreYOLO, SAMPLE_IMAGE result = LibreYOLO("LibreResNet50-cls.pt")(SAMPLE_IMAGE)probs = result.probs # .data là toàn bộ vector (C,); top5/top5conf là các view đã sắp xếp.print(probs.data.shape)for index, score in zip(probs.top5, probs.top5conf): print(result.names[index], float(score))from libreyolo import LibreYOLO, SAMPLE_IMAGE # CLIP tính điểm ảnh so với text prompt, vì vậy tập nhãn được đặt# tại thời điểm gọi thay vì ghi cố định trong checkpoint.model = LibreYOLO("LibreCLIPb32-cls.pt")model.set_classes(["a person jumping", "an empty street", "a parked car"])result = model(SAMPLE_IMAGE) print(model.names[result.probs.top1], float(result.probs.top1conf))conf, iou và max_det không có tác dụng ở đây: không có candidate để đặt
ngưỡng hoặc suppression, chỉ có một phân phối. Xem dự đoán để
biết về nguồn, stream và cách xử lý kết quả.
Định dạng dataset
Phân loại dùng cây thư mục, không dùng tệp nhãn hoặc YAML. data là thư mục gốc
dataset.
dataset/ train/ tench/000001.jpg parachute/000002.jpg val/ tench/000101.jpg parachute/000102.jpgtrain/ là bắt buộc và định nghĩa mapping từ lớp đối tượng tới index bằng tên
thư mục đã sắp xếp, vì vậy thư mục đầu tiên theo bảng chữ cái trở thành lớp 0.
val/ là bắt buộc để xác thực. Split test/ có thể tồn tại nhưng lệnh huấn
luyện và xác thực mặc định không dùng. Mọi split ngoài train phải chứa cùng
tên thư mục lớp như tập lớp dự kiến, nhờ vậy khi không khớp, thao tác thất bại
rõ ràng thay vì tính điểm như dự đoán sai. Các phần mở rộng ảnh được chấp nhận
là .jpg, .jpeg, .png, .bmp, .webp, .tif và .tiff.
data chấp nhận ba loại: đường dẫn tới thư mục chứa split train/, URL .zip
hoặc một trong các tên dataset đã biết imagenette160 và smoke10, được tải và
cache trong lần sử dụng đầu tiên.
Loader chuẩn là libreyolo.data.classify_dataset.
Huấn luyện
from libreyolo import LibreYOLO # imagenette160 là tên dataset đã biết và được tải trong lần sử dụng đầu tiên.# Truyền thư mục có split train/ cho dữ liệu riêng của bạn.model = LibreYOLO("LibreResNet50-cls.pt")model.train(data="imagenette160", epochs=5)libreyolo train model=LibreResNet50-cls.pt data=imagenette160 epochs=5libreyolo train model=LibreResNet50-cls.pt data=imagenette160 \ epochs=50 device=0,1 batch=-1Không có nc để khai báo: số lượng lớp đối tượng lấy từ tên thư mục dưới
train/, còn linear layer cuối được dựng lại cho khớp trong khi backbone chuyển
nguyên trạng. Xem huấn luyện để biết về dataset, augmentation,
multi-GPU và logger.
ResNet, ConvNeXt, ConvNeXt V2, MobileNetV4, EfficientNetV2 và DINOv2 hỗ trợ trọng số loss cls_pw hoặc class_weights. scale trong phân loại điều khiển diện tích cắt, còn crop_pct điều khiển cắt ảnh khi đánh giá. Xem augmentation.
Bộ lọc resize là một phần của mô hình. Đặt model.interpolation thành "bilinear", "bicubic", "nearest" hoặc "bilinear_no_antialias" trước khi huấn luyện: huấn luyện, val(), predict(), hiệu chỉnh INT8 và xuất đều dùng nó, còn save(), best.pt và last.pt ghi lại nó, nên việc nạp lại giữ nguyên. Mọi tên khác phát sinh ValueError. "bilinear_no_antialias" resize bằng bilinear thuần và không khử răng cưa ở mọi nơi, kể cả RandomResizedCrop, cho các mô hình sẽ chạy sau một phép resize runtime không khử răng cưa. MobileNetV4, ResNet, ConvNeXt, ConvNeXt V2, EfficientNetV2, DeiT, Swin và ViT mặc định dùng bicubic; AlexNet và VGG dùng bilinear.
Xác thực
val() trả về một dictionary gồm các key metrics/, được tính trên split
val/ của thư mục gốc dataset.
from libreyolo import LibreYOLO model = LibreYOLO("LibreResNet50-cls.pt") # Một dict các khóa metrics/, kèm top1, top5 và confusion_matrixmetrics = model.val(data="imagenette160") print(metrics["metrics/accuracy_top1"])print(metrics["metrics/accuracy_top5"])print(metrics.top1, metrics.top5)libreyolo val model=LibreResNet50-cls.pt data=imagenette160metrics/accuracy_top1 là tỷ lệ ảnh có lớp đạt điểm cao nhất đúng với lớp thật,
và là con số chính mà quá trình huấn luyện dùng để chọn epoch tốt nhất.
metrics/accuracy_top5 là tỷ lệ ảnh có lớp thật xuất hiện ở bất kỳ vị trí nào
trong năm lớp đạt điểm cao nhất, số liệu này cung cấp ít thông tin hơn khi
dataset có ít lớp hơn. Dictionary còn có fitness, bản sao của giá trị top-1.
Đánh giá ImageFolder còn trả về macro metrics/precision, metrics/recall và metrics/f1, lấy trung bình trên các lớp đối tượng có trong nhãn đích đánh giá. Lớp không được dự đoán đóng góp precision bằng 0. Fitness mặc định vẫn là độ chính xác top-1. Đánh giá và hiệu chuẩn dùng phép biến đổi đánh giá của mô hình.
Kết quả là một lớp con của dict có ba thuộc tính: top1 và top5 giữ hai giá trị
độ chính xác, còn confusion_matrix đếm mỗi ảnh ở lớp top-1 của nó so với nhãn,
lập chỉ mục matrix[predicted, true]. plots=True ghi nó dưới dạng số đếm vào
confusion_matrix.png và dưới dạng tỉ lệ của mỗi nhãn vào
confusion_matrix_normalized.png. Trên 2,000 lớp đối tượng, ma trận dày đặc và các
biểu đồ của nó không khả dụng, và nonzero(), tp_fp() cùng class_accuracy()
đọc số đếm thay thế; xem Xác thực và metric.
Xuất
from libreyolo import LibreYOLO model = LibreYOLO("LibreResNet50-cls.pt")model.export(format="onnx")libreyolo export model=LibreResNet50-cls.pt format=onnxfrom libreyolo import LibreYOLO, SAMPLE_IMAGE # Factory định tuyến theo hậu tố tệp, vì vậy artifact đã xuất được nạp# như checkpoint và trả về cùng một đối tượng Results.model = LibreYOLO("LibreResNet50-cls.onnx")result = model(SAMPLE_IMAGE) print(result.probs.top1, result.probs.top1conf)Artifact đã xuất được nạp lại qua LibreYOLO() theo hậu tố tệp, vì vậy tệp
.onnx hoặc .engine hoạt động như checkpoint và trả về cùng Results. Phạm
vi định dạng khác nhau theo family; ma trận trên từng trang mô hình được tạo từ
tập đã xác thực thay vì nhập thủ công. Xem xuất và triển khai để
biết các định dạng, thành phần bổ sung và ràng buộc.