YOLO-NAS
Detektor konwolucyjny, którego backbone i moduł neck powstały w wyniku wyszukiwania architektury przez Deci.AI, zbudowany z bloków RepVGG świadomych kwantyzacji. Jego wagi należą do Deci.AI i są licencjonowane wyłącznie do użytku niekomercyjnego. LibreYOLO nie publikuje żadnej z nich.
- Zadania
- detection, pose, oriented boxes
- Rozmiary
- s, m, l at 640 px
- Instalacja
pip install libreyolo- Poziom obsługi
- Główny, od wersji v1.1.0. Główne trenowalne detektory: otrzymują funkcje po modelach flagowych w tej samej fali wydań.
- Projekt źródłowy
- YOLO-NAS, autorzy: Deci.AI, licencja: Deci.AI proprietary, non-commercial. Publikacja, kod źródłowy
- Licencje
- Kod: Apache-2.0, wagi: Deci.AI proprietary, non-commercial. Użycie komercyjne
Instalacja
YOLO-NAS nie wymaga niczego poza pakietem podstawowym.
pip install libreyoloPredykcja
Punkt kontrolny, którego nazwy nie ma jeszcze na dysku, jest pobierany z publicznego CDN Deci, a nie z organizacji LibreYOLO, która nie udostępnia żadnych z tych wag. Przed rozpoczęciem transferu biblioteka raz na proces wyświetla warunki licencji Deci, a przed otwarciem pobranego pliku jego SHA-256 jest porównywane z przypiętą wartością. Dozwolone zastosowania opisano w sekcji licencjonowanie.
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Nazwa, której nie ma jeszcze na dysku, jest pobierana z CDN Deci. Przed# pobraniem wyświetlane są warunki licencji Deci; pobranie pliku je akceptuje.model = LibreYOLO("LibreYOLONASs.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes: print(box.cls, box.conf, box.xyxy)libreyolo predict model=LibreYOLONASs.pt save=True \ source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpgfrom libreyolo import LibreYOLO, SAMPLE_IMAGE # Przyrostek -pose wybiera głowicę pozy i jej własny zestaw wag.model = LibreYOLO("LibreYOLONASs-pose.pt")result = model(SAMPLE_IMAGE) print(result.keypoints.xy)Zwracany obiekt Results jest taki sam dla każdej rodziny, więc zamiana na
inny detektor wymaga zmiany jednego wiersza. Parametr conf ustawia próg
pewności, a iou próg NMS. Informacje o źródłach, strumieniowaniu i obsłudze
wyników znajdziesz w sekcji predykcja.
Zadanie obróconych ramek zwraca result.obb. Opublikowany graf OBB używa obszaru 1024 pikseli i zapisanego zestawu etykiet 18 klas.
Warianty
Detekcja i estymacja pozy korzystają z tej samej architektury z różnymi głowicami i przyjmują te same argumenty. Rozmiary w poniższej tabeli dotyczą detekcji. Estymacja pozy jest dostępna w tych rozmiarach oraz w jednym mniejszym. Głowica pozy przewiduje zestaw punktów kluczowych COCO.
| Checkpoint modelu | Wejście (px) | mAP 50-95 | Parametry (mln) |
|---|---|---|---|
| LibreYOLONASl | 640 | 56.3 | 66.98 |
| LibreYOLONASm | 640 | 55.4 | 51.18 |
| LibreYOLONASs | 640 | 51.8 | 19.05 |
COCO val2017, 500 images. Wyniki zmierzono za pomocą zestawu benchmarkowego LibreYOLO i opublikowano w Vision Analysis, gdzie porównywane są opóźnienia na różnych urządzeniach i w różnych środowiskach uruchomieniowych oraz znajdują się pełne zapisy przebiegów.
Trenowanie
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")model.train(data="my-dataset.yaml", epochs=100, imgsz=640, batch=16)libreyolo train model=LibreYOLONASs.pt data=my-dataset.yaml \ epochs=100 imgsz=640 batch=16from libreyolo import LibreYOLONAS # Nie są używane punkty kontrolne Deci: model zaczyna od losowych wag,# więc wynik trenowania pochodzi wyłącznie z własnych danych.model = LibreYOLONAS(None, size="s")model.train(data="my-dataset.yaml", imgsz=640, batch=16)Gdy epochs, lr0 i amp nie zostaną podane, są ustalane osobno dla każdego
zadania, więc przebieg estymacji pozy rozpoczyna się z innymi wartościami
domyślnymi niż przebieg detekcji. Domyślnym optymalizatorem jest AdamW. Liczba
klas pochodzi z pliku YAML zbioru danych, a głowica jest przebudowywana przed
pierwszą epoką. W głowicy pozy liczba punktów kluczowych jest obsługiwana tak samo,
więc punkt kontrolny pozy COCO można dostroić do szkieletu o innej liczbie punktów.
Dostrajanie zaczyna się od wag Deci, których dotyczy licencja Deci. Trenowanie losowo zainicjalizowanego modelu nie korzysta z żadnego punktu kontrolnego Deci, jak pokazuje trzeci fragment powyżej.
Informacje o zbiorach danych, augmentacji, wielu GPU i loggerach znajdziesz w sekcji trenowanie.
Detekcja domyślnie używa amp=True z amp_dtype="float16"; trenowanie obróconych ramek zachowuje amp=False. Głowica OBB obsługuje trenowanie, predykcję i walidację, stosuje augmentację odbiciami i HSV oraz wybiera checkpointy według metrics/mAP50-95(OBB). load_detect_weights_for_obb() inicjalizuje ją wagami detekcji.
Walidacja
Metoda val() zwraca słownik kluczy metrics/ obejmujących precyzję, czułość,
mAP 50 i mAP 50-95, mierzone na dowolnym zbiorze danych w formacie użytym do trenowania.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])libreyolo val model=LibreYOLONASs.pt data=my-dataset.yaml# Dołączony plik yaml COCO zawiera osadzony skrypt pobierania, dlatego wymaga# jawnego zezwolenia, chyba że zbiór danych jest już dostępny lokalnie.libreyolo val model=LibreYOLONASl.pt data=coco.yaml imgsz=640 \ allow_download_scripts=TrueEksport
| Zadanie | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: obsługiwane | Detection to TorchScript: obsługiwane | Detection to ExecuTorch: obsługiwane | Detection to TensorRT: obsługiwane | Detection to OpenVINO: obsługiwane | Detection to Paddle: obsługiwane | Detection to MNN: obsługiwane | Detection to RKNN: obsługiwane | Detection to ncnn: obsługiwane | Detection to TFLite: obsługiwane | Detection to CoreML: brak obsługi | Detection to Core AI: obsługiwane |
| Pose | Pose to ONNX: obsługiwane | Pose to TorchScript: obsługiwane | Pose to ExecuTorch: obsługiwane | Pose to TensorRT: obsługiwane | Pose to OpenVINO: obsługiwane | Pose to Paddle: obsługiwane | Pose to MNN: brak obsługi | Pose to RKNN: brak obsługi | Pose to ncnn: obsługiwane | Pose to TFLite: brak obsługi | Pose to CoreML: brak obsługi | Pose to Core AI: brak obsługi |
| Oriented boxes | Oriented boxes to ONNX: obsługiwane | Oriented boxes to TorchScript: obsługiwane | Oriented boxes to ExecuTorch: obsługiwane | Oriented boxes to TensorRT: obsługiwane | Oriented boxes to OpenVINO: obsługiwane | Oriented boxes to Paddle: brak obsługi | Oriented boxes to MNN: brak obsługi | Oriented boxes to RKNN: brak obsługi | Oriented boxes to ncnn: obsługiwane | Oriented boxes to TFLite: brak obsługi | Oriented boxes to CoreML: brak obsługi | Oriented boxes to Core AI: brak obsługi |
Wyeksportowany artefakt jest ponownie ładowany przez LibreYOLO() na podstawie
rozszerzenia pliku, więc plik .onnx lub .engine zachowuje się jak punkt
kontrolny i zwraca ten sam obiekt Results. Obsługiwane jest także uruchamianie
grafu w samym środowisku uruchomieniowym bez zainstalowanego LibreYOLO, ale
wówczas samodzielnie trzeba zaimplementować przetwarzanie wstępne i końcowe.
Każdy format instaluje inny dodatek i przyjmuje kilka własnych argumentów.
Obie informacje znajdują się na stronie danego formatu.
Eksport jest kolejną kopią tych samych wag w innym kontenerze. Eksportowanie punktu kontrolnego Deci nie zmienia ani pochodzenia wag, ani obejmującej je licencji.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")model.export(format="onnx", imgsz=640)libreyolo export model=LibreYOLONASs.pt format=onnx imgsz=640from libreyolo import LibreYOLO, SAMPLE_IMAGE # Fabryka wybiera ścieżkę na podstawie rozszerzenia pliku, dlatego# artefakt ładuje się jak punkt kontrolny i zwraca ten sam obiekt Results.model = LibreYOLO("LibreYOLONASs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)Wejścia i wyjścia ONNX
LibreYOLONAS detect
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Kolor | RGB |
| Skalowanie | piksel / 255 |
| Normalizacja | brak |
| Zmiana rozmiaru | custom, Pillow bilinear |
Jak odtworzyć dwuliniowe skalowanie Pillow
LibreYOLO skaluje filtrem BILINEAR z Pillow (Image.resize). To nie jest OpenCV INTER_LINEAR ani INTER_AREA: przy zmniejszaniu Pillow poszerza filtr o współczynnik zmniejszenia, a skalowania OpenCV zmieniają detekcje i przesuwają ramki o kilka pikseli. Aby odtworzyć to bez Pillow, przeskaluj jedną oś, zaokrąglij do 8 bitów, potem przeskaluj drugą oś i zaokrąglij ponownie. Dla każdej osi niech s = in_size / out_size oraz f = max(s, 1). Piksel wyjściowy i ma środek c = (i + 0.5) * s i czyta piksele źródłowe j od int(c - f + 0.5) do int(c + f + 0.5) - 1, przycięte do obrazu, każdy z wagą max(0, 1 - |j + 0.5 - c| / f), podzieloną przez sumę wag. Pillow liczy w arytmetyce stałoprzecinkowej i wybiera kolejność osi na podstawie kształtu obrazu, więc wagi zmiennoprzecinkowe mogą się od niego różnić o jeden poziom na kilku pikselach. To nie zmienia wyników w naszych sprawdzeniach.
Square input only. Export rejects a non-square imgsz, and height equals width, 640 by default.
The image is not scaled to fill the canvas. The longest side goes to R = min(636, height, width), so 636 at 640 x 640.
Scale by r = min(R / h, R / w) and resize to (round(w * r), round(h * r)). The rounding is Python round, so an exact .5 goes to the even neighbor.
Paste the resized image onto a canvas filled with 114 at left = (width - new_w) // 2 and top = (height - new_h) // 2.
On the test image, cv2.resize with INTER_LINEAR loses two of the eight detections, and INTER_AREA moves boxes by up to 1.4 px.
Divide by 255 after the resize. There is no mean or std normalization.
Detection, eksport domyślny
| Wyjście | Kształt | Znaczenie |
|---|---|---|
pred_logits | [batch, anchors, 4] | Boxes, despite the name. x1, y1, x2, y2 in input-canvas pixels. anchors is the cell count over strides 8, 16 and 32, 8400 at 640 x 640. |
pred_boxes | [batch, anchors, nc] | Class scores, despite the name. Sigmoid already applied. 80 classes for the COCO checkpoints. |
Przetwarzanie końcowe
- The output names are swapped relative to their content. Read boxes from pred_logits and scores from pred_boxes, or tell them apart by the last dimension (4 for boxes).
- Take the best class per anchor: score = max over classes, class = argmax. One anchor yields at most one detection.
- Keep anchors whose score is strictly above the confidence threshold (0.25 by default).
- Keep the 1000 highest scoring candidates.
- Map boxes back to the original image: subtract left from x and top from y, divide by r, clip to the image. Drop boxes left with zero width or height.
- Run NMS per class with IoU 0.45 and keep at most 300 detections.
- nms=True is not available for this family: export raises NotImplementedError.
LibreYOLONAS pose
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Kolor | BGR |
| Skalowanie | piksel / 255 |
| Normalizacja | brak |
| Zmiana rozmiaru | custom, Pillow bilinear |
Jak odtworzyć dwuliniowe skalowanie Pillow
LibreYOLO skaluje filtrem BILINEAR z Pillow (Image.resize). To nie jest OpenCV INTER_LINEAR ani INTER_AREA: przy zmniejszaniu Pillow poszerza filtr o współczynnik zmniejszenia, a skalowania OpenCV zmieniają detekcje i przesuwają ramki o kilka pikseli. Aby odtworzyć to bez Pillow, przeskaluj jedną oś, zaokrąglij do 8 bitów, potem przeskaluj drugą oś i zaokrąglij ponownie. Dla każdej osi niech s = in_size / out_size oraz f = max(s, 1). Piksel wyjściowy i ma środek c = (i + 0.5) * s i czyta piksele źródłowe j od int(c - f + 0.5) do int(c + f + 0.5) - 1, przycięte do obrazu, każdy z wagą max(0, 1 - |j + 0.5 - c| / f), podzieloną przez sumę wag. Pillow liczy w arytmetyce stałoprzecinkowej i wybiera kolejność osi na podstawie kształtu obrazu, więc wagi zmiennoprzecinkowe mogą się od niego różnić o jeden poziom na kilku pikselach. To nie zmienia wyników w naszych sprawdzeniach.
Square input only. Export rejects a non-square imgsz, and height equals width, 640 by default.
Channels are BGR, unlike detection. Pad value and position also differ from detection.
The longest side goes to R = min(640, height, width), so it fills the canvas.
Scale by r = min(R / h, R / w) and resize to (round(w * r), round(h * r)). The rounding is Python round, so an exact .5 goes to the even neighbor.
Paste the resized image in the top-left corner of a canvas filled with 127. All padding is on the bottom and the right.
On the test image, cv2.resize with INTER_LINEAR or INTER_AREA moves boxes by up to 5 px and keypoints by more than 10 px.
Divide by 255 after the resize. There is no mean or std normalization.
Pose, eksport domyślny
| Wyjście | Kształt | Znaczenie |
|---|---|---|
boxes | [batch, anchors, 4] | Person boxes as x1, y1, x2, y2 in input-canvas pixels. anchors is the cell count over strides 8, 16 and 32, 8400 at 640 x 640. |
scores | [batch, anchors, nc] | Class scores, sigmoid already applied. nc is 1 (person) for the COCO pose checkpoints. |
keypoints_xy | [batch, anchors, num_keypoints, 2] | Keypoint x, y in input-canvas pixels. num_keypoints is 17 (COCO order) for the COCO pose checkpoints. |
keypoints_conf | [batch, anchors, num_keypoints] | Per-keypoint visibility score, sigmoid already applied. |
Przetwarzanie końcowe
- Take the best class per anchor: score = max over classes, class = argmax. With one class this is just the person score.
- Keep anchors whose score is at or above the confidence threshold (0.25 by default). This is >=, not > as in detection.
- Keep the 1000 highest scoring candidates.
- Map boxes and keypoints back to the original image: divide x and y by r. The image sits in the top-left corner, so there is no pad offset to subtract.
- Clip boxes to the image and drop boxes left with zero width or height. Keypoints are not clipped and can fall outside the image.
- Run NMS per class with IoU 0.45 and keep at most 300 detections. Keep each survivor's keypoints as (x, y, keypoints_conf).
- nms=True is not available for this family: export raises NotImplementedError.
LibreYOLONAS obb
| Tensor | images float32 [batch, 3, height, width] |
|---|---|
| Kolor | BGR |
| Skalowanie | piksel / 255 |
| Normalizacja | brak |
| Zmiana rozmiaru | custom, bilinear |
Square input only. Export rejects a non-square imgsz, and height equals width, 1024 by default.
Channels are BGR, unlike detection. The resize filter and the pad position also differ from detection.
The longest side goes to R = min(1024, height, width), so it fills the canvas.
Scale by r = min(R / h, R / w) and resize to (round(w * r), round(h * r)). The rounding is Python round, so an exact .5 goes to the even neighbor.
The resize is cv2.resize with INTER_LINEAR, not Pillow as in detection and pose. It is skipped when the image already has that size. On the test image, Pillow's filter here changes the detection count.
Paste the resized image in the top-left corner of a canvas filled with 114. All padding is on the bottom and the right.
Divide by 255 after the resize. There is no mean or std normalization.
Oriented boxes, eksport domyślny
| Wyjście | Kształt | Znaczenie |
|---|---|---|
boxes | [batch, anchors, 5] | Rotated boxes as cx, cy, w, h, angle. cx, cy, w and h are in input-canvas pixels. The angle is in radians. The graph computes it as (sigmoid(logit) - 0.25) x pi, so it lies between -pi/4 and 3pi/4 and is not wrapped yet. The w side points along (cos angle, sin angle) in image coordinates, y down. anchors is the cell count over strides 8, 16 and 32, 21504 at 1024 x 1024. |
scores | [batch, anchors, nc] | Class scores, sigmoid already applied. 18 classes (DOTA 2.0) for the published checkpoints. |
Przetwarzanie końcowe
- Take the best class per anchor: score = max over classes, class = argmax. One anchor yields at most one detection.
- Keep anchors whose score is at or above the confidence threshold (0.25 by default). This is >=, not > as in detection.
- Keep the 1000 highest scoring candidates.
- Map boxes back to the original image: divide cx, cy, w and h by r. The image sits in the top-left corner, so there is no pad offset, and the angle does not change.
- Clip cx to 0 to the image width and cy to 0 to the image height. w and h are not clipped. Drop boxes with w or h at or below 0.
- Put the long side first: if h > w, swap w and h and add pi/2 to the angle. Then wrap the angle to [-pi/2, pi/2) with angle = ((angle + pi/2) mod pi) - pi/2.
- Run greedy NMS per class on exact rotated-box IoU (polygon intersection area over union, for example cv2.rotatedRectangleIntersection) with IoU 0.45, and keep at most 300 detections. LibreYOLO does not use upstream's matrix soft-NMS.
- LibreYOLO also reports an axis-aligned box per detection. With ex = abs(cos angle) * w / 2 + abs(sin angle) * h / 2 and ey = abs(sin angle) * w / 2 + abs(cos angle) * h / 2, it is cx - ex, cy - ey, cx + ex, cy + ey, clipped to the image.
- nms=True is not available for this family: export raises NotImplementedError.
Aby sprawdzić własną implementację, uruchom ten sam plik w LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") zwraca wyniki wzorcowe. Zweryfikowano w LibreYOLO 1.7.0.
Punkty kontrolne
Nie ma żadnych do wyświetlenia. Licencja Deci zabrania redystrybucji, dlatego
organizacja LibreYOLO nie publikuje żadnych wag YOLO-NAS, a pobieranie jest
kierowane gdzie indziej. Nazwa w postaci LibreYOLONAS<size>.pt,
LibreYOLONAS<size>-pose.pt dla estymacji pozy albo
LibreYOLONAS<size>-obb.pt (s, m, l) dla obróconych ramek jest mapowana na
odpowiedni obiekt w publicznym CDN Deci.
W ten sposób można pobierać tylko punkty kontrolne, których SHA-256 jest
przypięte w bibliotece. Każdy inny przypadek jest bezpiecznie odrzucany zamiast
otwierania niezweryfikowanego pliku pickle innej firmy. Taki plik trzeba pobrać
ręcznie i przekazać jako ścieżkę. Plik znajdujący się już na dysku jest ładowany
ze swojej ścieżki, bez pobierania i kontroli sumy. Dotyczy to również pliku .pth
Deci pod oryginalną nazwą, który jest rozpoznawany przez moduł ładujący.
Licencjonowanie
Sprawdź licencję w repozytorium konkretnych pobieranych wag na Hugging Face. Każdy checkpoint w organizacji LibreYOLO ma licencję, która nie zawsze jest taka sama w całej rodzinie. To repozytorium jest źródłem rozstrzygającym, a poniższe podsumowanie opisuje stan z chwili ostatniej weryfikacji tej strony.
To opis obowiązujących licencji, a nie porada prawna. Jeśli odpowiedź ma znaczenie komercyjne, przeczytaj licencje i zasięgnij własnej porady prawnej.
- Oryginalna praca
- YOLO-NAS, Deci.AI
- Licencja projektu źródłowego
- Deci.AI proprietary, non-commercial
- Kod źródłowy projektu
- github.com/Deci-AI/super-gradients
- Kod LibreYOLO
- MIT
- Wagi
- Deci.AI proprietary, non-commercial, rozpowszechniane przez autorów. LibreYOLO ich nie hostuje ani nie udostępnia kopii.
- Interpretacja
- Two licenses apply here and they are not the same. The SuperGradients source this port follows is Apache-2.0 and LibreYOLO's own implementation is MIT, so nothing restricts the architecture or the training code. Deci's published checkpoints are a different matter: the YOLO-NAS license grants a revocable, non-transferable right to use them and nothing more. It forbids redistribution and sublicensing, forbids offering them as a managed or remote service, restricts modification and reverse engineering, and rules out commercial use, including any model running in a production environment, unless you hold a separate agreement with Deci. LibreYOLO therefore does not mirror them, and prints those terms once before the download starts. Weights trained from a randomly initialized model on your own data derive from no Deci checkpoint.
LibreYOLO nie udostępnia ani nie tworzy kopii lustrzanych tych wag. W organizacji LibreYOLO w Hugging Face nie ma niczego dla tej rodziny. Każde automatyczne pobieranie jest zamiast tego kierowane do publicznego CDN Deci, przed rozpoczęciem raz na proces wyświetla warunki Deci, a przed otwarciem pliku sprawdza go względem przypiętej sumy SHA-256.
Alternatywą jest trenowanie losowo zainicjalizowanego modelu. Architektura ma licencję Apache-2.0 w projekcie źródłowym i MIT tutaj, więc model wytrenowany w ten sposób na własnych danych nie pochodzi z żadnego punktu kontrolnego Deci.
Cytowanie
YOLO-NAS został opublikowany bez artykułu naukowego. Poniższa pozycja jest tą, o której cytowanie proszą jego autorzy, i dotyczy SuperGradients, biblioteki, w której model został wydany.
@misc{supergradients,
doi = {10.5281/ZENODO.7789328},
url = {https://zenodo.org/record/7789328},
author = {Aharon, Shay and {Louis-Dupont} and {Ofri Masad} and Yurkova, Kate and {Lotem Fridman} and {Lkdci} and Khvedchenya, Eugene and Rubin, Ran and Bagrov, Natan and Tymchenko, Borys and Keren, Tomer and Zhilko, Alexander and {Eran-Deci}},
title = {Super-Gradients},
publisher = {GitHub},
journal = {GitHub repository},
year = {2021},
}Skopiowano z bloku cytowania autorów w github.com/Deci-AI/super-gradients#citing.