YOLO-NAS

Згортковий детектор, бекбон і neck якого створено пошуком архітектури Deci.AI та побудовано з блоків RepVGG, пристосованих до квантування. Ваги належать Deci.AI, ліцензовані лише для некомерційного використання, і LibreYOLO не публікує жодних із них.

Задачі
detection, pose, oriented boxes
Розміри
s, m, l at 640 px
Встановлення
pip install libreyolo
Рівень підтримки
Основний, починаючи з v1.1.0. Основні придатні до навчання детектори: функції з'являються після флагманських моделей у тій самій хвилі випуску.
Першоджерело
YOLO-NAS, автори: Deci.AI, ліцензія Deci.AI proprietary, non-commercial. Стаття, джерело
Ліцензії
Код: Apache-2.0, ваги: Deci.AI proprietary, non-commercial. Комерційне використання

Установлення

YOLO-NAS не потребує нічого додаткового до базового пакета.

bash
pip install libreyolo

Передбачення

Якщо контрольної точки із заданою назвою ще немає на диску, вона завантажується з публічного CDN Deci, а не з організації LibreYOLO, де ці ваги не розміщено. Перед початком передавання бібліотека один раз за процес виводить умови ліцензії Deci, а перед відкриттям завантаженого файла перевіряє його SHA-256 за закріпленим значенням. Дозволи за цими умовами описано в розділі ліцензування.

Python
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Назва, якої ще немає на диску, завантажується з CDN Deci. Спочатку# виводяться умови ліцензії Deci; завантаження файла означає їх прийняття.model = LibreYOLO("LibreYOLONASs.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes:    print(box.cls, box.conf, box.xyxy)
CLI
libreyolo predict model=LibreYOLONASs.pt save=True \  source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg
Поза
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Суфікс -pose вибирає голову пози та її власний набір ваг.model = LibreYOLO("LibreYOLONASs-pose.pt")result = model(SAMPLE_IMAGE) print(result.keypoints.xy)

Повернений об'єкт Results однаковий для всіх сімейств, тому для переходу на інший детектор достатньо змінити один рядок. conf задає поріг упевненості, а iou задає поріг NMS. Докладніше про джерела, потокове оброблення та роботу з результатами дивіться в розділі передбачення.

Завдання орієнтованих рамок повертає result.obb. Опублікований граф OBB використовує полотно 1024 пікселі й записаний набір міток із 18 класів.

Варіанти

Виявлення об'єктів та оцінювання пози використовують ту саму архітектуру з різними головами й приймають однакові аргументи. Розміри в таблиці нижче стосуються виявлення; модель пози опубліковано в цих розмірах і ще в одному меншому. Голова пози передбачає набір ключових точок COCO.

Контрольна точкаВхід (пікс.)mAP 50-95Параметри (млн)
LibreYOLONASl64056.366.98
LibreYOLONASm64055.451.18
LibreYOLONASs64051.819.05

COCO val2017, 500 images. Виміряно засобами бенчмарку LibreYOLO й опубліковано на сторінці Vision Analysis, де порівнюють затримку на різному обладнанні та в різних середовищах виконання, а також зберігають повні записи запусків.

Навчання

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")model.train(data="my-dataset.yaml", epochs=100, imgsz=640, batch=16)
CLI
libreyolo train model=LibreYOLONASs.pt data=my-dataset.yaml \  epochs=100 imgsz=640 batch=16
З нуля
from libreyolo import LibreYOLONAS # Контрольна точка Deci не використовується: модель починає з випадкових ваг,# тому результат запуску походить лише з ваших даних.model = LibreYOLONAS(None, size="s")model.train(data="my-dataset.yaml", imgsz=640, batch=16)

Якщо epochs, lr0 та amp не задано, їх значення визначаються окремо для кожного завдання, тому запуск оцінювання пози починається з інших типових значень, ніж запуск виявлення. Типово оптимізатором є AdamW. Кількість класів береться з YAML датасету, а голову перебудовано відповідно до неї перед першою епохою. Для голови пози кількість ключових точок обробляється так само, тому контрольну точку пози COCO можна донавчити на скелеті іншого розміру.

Донавчання починається з ваг Deci, на які поширюється ліцензія Deci. Навчання випадково ініціалізованої моделі взагалі не залучає контрольної точки Deci, як показано в третьому фрагменті вище.

Докладніше про датасети, аугментацію, кілька GPU та засоби журналювання дивіться в розділі навчання.

Виявлення типово використовує amp=True з amp_dtype="float16"; навчання орієнтованих рамок зберігає amp=False. Голова OBB підтримує навчання, передбачення й валідацію, використовує аугментацію віддзеркаленням і HSV та вибирає контрольні точки за metrics/mAP50-95(OBB). load_detect_weights_for_obb() ініціалізує її вагами виявлення.

Валідація

val() повертає словник ключів metrics/, що охоплюють точність, повноту, mAP 50 і mAP 50-95, виміряні на будь-якому датасеті у форматі, на якому проводилося навчання.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])
CLI
libreyolo val model=LibreYOLONASs.pt data=my-dataset.yaml
На COCO
# Вбудований файл COCO yaml містить убудований скрипт завантаження, тому# потрібен явний дозвіл, якщо датасету ще немає локально.libreyolo val model=LibreYOLONASl.pt data=coco.yaml imgsz=640 \  allow_download_scripts=True

Експорт

ЗадачаONNXTorchScriptExecuTorchTensorRTOpenVINOPaddleMNNRKNNncnnTFLiteCoreMLCore AI
DetectionDetection to ONNX: підтримуєтьсяDetection to TorchScript: підтримуєтьсяDetection to ExecuTorch: підтримуєтьсяDetection to TensorRT: підтримуєтьсяDetection to OpenVINO: підтримуєтьсяDetection to Paddle: підтримуєтьсяDetection to MNN: підтримуєтьсяDetection to RKNN: підтримуєтьсяDetection to ncnn: підтримуєтьсяDetection to TFLite: підтримуєтьсяDetection to CoreML: не підтримуєтьсяDetection to Core AI: підтримується
PosePose to ONNX: підтримуєтьсяPose to TorchScript: підтримуєтьсяPose to ExecuTorch: підтримуєтьсяPose to TensorRT: підтримуєтьсяPose to OpenVINO: підтримуєтьсяPose to Paddle: підтримуєтьсяPose to MNN: не підтримуєтьсяPose to RKNN: не підтримуєтьсяPose to ncnn: підтримуєтьсяPose to TFLite: не підтримуєтьсяPose to CoreML: не підтримуєтьсяPose to Core AI: не підтримується
Oriented boxesOriented boxes to ONNX: підтримуєтьсяOriented boxes to TorchScript: підтримуєтьсяOriented boxes to ExecuTorch: підтримуєтьсяOriented boxes to TensorRT: підтримуєтьсяOriented boxes to OpenVINO: підтримуєтьсяOriented boxes to Paddle: не підтримуєтьсяOriented boxes to MNN: не підтримуєтьсяOriented boxes to RKNN: не підтримуєтьсяOriented boxes to ncnn: підтримуєтьсяOriented boxes to TFLite: не підтримуєтьсяOriented boxes to CoreML: не підтримуєтьсяOriented boxes to Core AI: не підтримується

Експортований артефакт завантажується назад через LibreYOLO() за суфіксом файла, тому файл .onnx або .engine поводиться як контрольна точка й повертає той самий об'єкт Results. Також підтримується запуск графа в чистому середовищі виконання без установленої LibreYOLO, але тоді попереднє та подальше оброблення потрібно реалізувати самостійно. Кожен формат установлює окремий додатковий пакет і приймає кілька власних аргументів. Обидва аспекти описано на сторінці цього формату.

Експорт створює ще одну копію тих самих ваг в іншому контейнері. Експорт контрольної точки Deci не змінює ні походження ваг, ні ліцензію, що на них поширюється.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLONASs.pt")model.export(format="onnx", imgsz=640)
CLI
libreyolo export model=LibreYOLONASs.pt format=onnx imgsz=640
Використання експортованого файла
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Фабрика визначає маршрут за суфіксом файла, тому експортований артефакт# завантажується як будь-яка контрольна точка й повертає той самий об'єкт Results.model = LibreYOLO("LibreYOLONASs.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)

Входи та виходи ONNX

LibreYOLONAS detect

Тензорimages float32 [batch, 3, height, width]
КолірRGB
Масштабуванняпіксель / 255
Нормалізаціянемає
Зміна розміруcustom, Pillow bilinear
Як відтворити білінійну зміну розміру Pillow

LibreYOLO змінює розмір фільтром BILINEAR з Pillow (Image.resize). Це не OpenCV INTER_LINEAR і не INTER_AREA: під час зменшення Pillow розширює фільтр на коефіцієнт зменшення, а зміна розміру в OpenCV змінює детекції та зсуває рамки на кілька пікселів. Щоб відтворити його без Pillow, змініть розмір за однією віссю, округліть до 8 біт, потім змініть розмір за іншою віссю й округліть знову. Для кожної осі нехай s = in_size / out_size і f = max(s, 1). Вихідний піксель i має центр c = (i + 0.5) * s і читає вихідні пікселі j від int(c - f + 0.5) до int(c + f + 0.5) - 1, обмежені зображенням, кожен з вагою max(0, 1 - |j + 0.5 - c| / f), поділеною на суму ваг. Pillow рахує у фіксованій крапці й обирає порядок осей за формою зображення, тому ваги з плаваючою крапкою можуть відрізнятися від нього на один рівень на кількох пікселях. Це не змінює результати в наших перевірках.

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, експорт за замовчуванням
ВихідФормаЗначення
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.

Постобробка

  1. 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).
  2. Take the best class per anchor: score = max over classes, class = argmax. One anchor yields at most one detection.
  3. Keep anchors whose score is strictly above the confidence threshold (0.25 by default).
  4. Keep the 1000 highest scoring candidates.
  5. 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.
  6. Run NMS per class with IoU 0.45 and keep at most 300 detections.
  7. nms=True is not available for this family: export raises NotImplementedError.

LibreYOLONAS pose

Тензорimages float32 [batch, 3, height, width]
КолірBGR
Масштабуванняпіксель / 255
Нормалізаціянемає
Зміна розміруcustom, Pillow bilinear
Як відтворити білінійну зміну розміру Pillow

LibreYOLO змінює розмір фільтром BILINEAR з Pillow (Image.resize). Це не OpenCV INTER_LINEAR і не INTER_AREA: під час зменшення Pillow розширює фільтр на коефіцієнт зменшення, а зміна розміру в OpenCV змінює детекції та зсуває рамки на кілька пікселів. Щоб відтворити його без Pillow, змініть розмір за однією віссю, округліть до 8 біт, потім змініть розмір за іншою віссю й округліть знову. Для кожної осі нехай s = in_size / out_size і f = max(s, 1). Вихідний піксель i має центр c = (i + 0.5) * s і читає вихідні пікселі j від int(c - f + 0.5) до int(c + f + 0.5) - 1, обмежені зображенням, кожен з вагою max(0, 1 - |j + 0.5 - c| / f), поділеною на суму ваг. Pillow рахує у фіксованій крапці й обирає порядок осей за формою зображення, тому ваги з плаваючою крапкою можуть відрізнятися від нього на один рівень на кількох пікселях. Це не змінює результати в наших перевірках.

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, експорт за замовчуванням
ВихідФормаЗначення
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.

Постобробка

  1. Take the best class per anchor: score = max over classes, class = argmax. With one class this is just the person score.
  2. Keep anchors whose score is at or above the confidence threshold (0.25 by default). This is >=, not > as in detection.
  3. Keep the 1000 highest scoring candidates.
  4. 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.
  5. Clip boxes to the image and drop boxes left with zero width or height. Keypoints are not clipped and can fall outside the image.
  6. Run NMS per class with IoU 0.45 and keep at most 300 detections. Keep each survivor's keypoints as (x, y, keypoints_conf).
  7. nms=True is not available for this family: export raises NotImplementedError.

LibreYOLONAS obb

Тензорimages float32 [batch, 3, height, width]
КолірBGR
Масштабуванняпіксель / 255
Нормалізаціянемає
Зміна розміру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, експорт за замовчуванням
ВихідФормаЗначення
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.

Постобробка

  1. Take the best class per anchor: score = max over classes, class = argmax. One anchor yields at most one detection.
  2. Keep anchors whose score is at or above the confidence threshold (0.25 by default). This is >=, not > as in detection.
  3. Keep the 1000 highest scoring candidates.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. nms=True is not available for this family: export raises NotImplementedError.

Щоб перевірити власну реалізацію, пропустіть той самий файл через LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") повертає еталонні результати. Перевірено на LibreYOLO 1.7.0.

Контрольні точки

Перелік порожній. Ліцензія Deci забороняє повторне розповсюдження, тому організація LibreYOLO не публікує ваг YOLO-NAS, а завантаження відбувається з іншого джерела: назва у формі LibreYOLONAS<size>.pt, LibreYOLONAS<size>-pose.pt для пози або LibreYOLONAS<size>-obb.pt (s, m, l) для орієнтованих рамок відповідає об'єкту в публічному CDN Deci.

Так можна отримати лише контрольні точки, SHA-256 яких закріплено в бібліотеці. Для всього іншого операцію відхилено без відкриття неперевіреного стороннього pickle. Такий файл потрібно завантажити вручну й передати як шлях. Файл, який уже є на диску, завантажується за своїм шляхом без завантаження з мережі й перевірки контрольної суми. Це також стосується файла Deci .pth під початковою назвою, яку розпізнає завантажувач.

Ліцензування

Перевіряйте ліцензію в репозиторії Hugging Face конкретних ваг, які завантажуєте. Кожна контрольна точка в організації LibreYOLO має ліцензію, і вона не завжди однакова для всього сімейства. Цей репозиторій є авторитетним джерелом, а наведене нижче резюме описує умови на момент останньої перевірки сторінки.

Це опис відповідних ліцензій, а не юридична консультація. Якщо відповідь має комерційне значення, самостійно прочитайте ліцензії та зверніться по юридичну консультацію.

Оригінальна робота
YOLO-NAS, Deci.AI
Ліцензія першоджерела
Deci.AI proprietary, non-commercial
Джерело першоджерела
github.com/Deci-AI/super-gradients
Код LibreYOLO
MIT
Ваги
Deci.AI proprietary, non-commercial, поширюється авторами. LibreYOLO не розміщує й не дублює ці ваги.
Тлумачення
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 не розміщує й не дзеркалює ці ваги: для цього сімейства в організації LibreYOLO на Hugging Face нічого немає. Кожне автоматичне завантаження натомість звертається до публічного CDN Deci, один раз за процес виводить умови Deci перед початком і перевіряється за закріпленим SHA-256 до відкриття файла.

Альтернативою є навчання випадково ініціалізованої моделі. Оригінальна архітектура має ліцензію Apache-2.0, а ця реалізація має ліцензію MIT, тому модель, навчена таким способом на ваших даних, не походить від контрольної точки Deci.

Цитування

YOLO-NAS випущено без статті. Нижче наведено запис, який просять використовувати автори; він стосується SuperGradients, бібліотеки, у складі якої випущено модель.

@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},
}

Скопійовано з блоку цитування авторів на сторінці github.com/Deci-AI/super-gradients#citing.

Перевірено з LibreYOLO v1.6.0. Таблиці підтримки, контрольні точки й результати бенчмарків на цій сторінці згенеровано з випущеної бібліотеки та опублікованих ваг, а не написано вручну.