YOLO-NAS

Deci.AIのアーキテクチャ探索から生まれたバックボーンとネックを持ち、量子化を考慮したRepVGGブロックで構築された畳み込み検出器です。重みはDeci.AIのもので、非商用利用だけが許可されており、LibreYOLOはその重みを一切公開していません。

タスク
detection, pose, oriented boxes
サイズ
s, m, l at 640 px
インストール
pip install libreyolo
サポートティア
コア、v1.1.0以降。学習可能なコア検出器:機能は同じリリースサイクルでフラッグシップに続いて実装されます。
アップストリーム
Deci.AIのYOLO-NAS、Deci.AI proprietary, non-commercial。論文、ソース
ライセンス
コード:Apache-2.0、重み:Deci.AI proprietary, non-commercial。商用利用

インストール

YOLO-NASには基本パッケージ以外の追加パッケージは不要です。

bash
pip install libreyolo

推論

ディスク上に存在しないチェックポイント名は、これらの重みを一切ホストしていないLibreYOLO組織ではなく、Deciの公開CDNから取得されます。転送を開始する前に、ライブラリはプロセスごとに1回Deciのライセンス条件を表示します。ダウンロードしたファイルを開く前に、SHA-256が固定値と照合されます。条件で許可される内容についてはライセンスを参照してください。

Python
from libreyolo import LibreYOLO, SAMPLE_IMAGE # ディスク上にない名前は Deci の CDN から取得# ダウンロード前に 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オブジェクトはすべてのファミリーに共通するため、別の検出器への切り替えは1行の変更で済みます。confは信頼度のしきい値、iouはNMSのしきい値を設定します。ソース、ストリーミング、結果の処理については推論を参照してください。

回転ボックスタスクはresult.obbを返します。公開済みのOBBグラフは1024ピクセルのキャンバスと、記録された18クラスのラベル集合を使います。

バリアント

検出と姿勢推定は異なるヘッドの下で同じアーキテクチャを使い、同じ引数を受け取ります。下の表にあるサイズは検出用です。姿勢推定はその各サイズと、さらに小さい1サイズで公開されています。姿勢推定ヘッドはCOCOのキーポイント集合を予測します。

チェックポイント入力(px)mAP 50-95パラメータ(M)
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のチェックポイントを一切使用しません。その手順が上の3番目のスニペットです。

データセット、データ拡張、マルチGPU、ロガーについては学習を参照してください。

物体検出のデフォルトはamp=Trueとamp_dtype="float16"で、回転ボックスの学習ではamp=Falseを維持します。OBBヘッドは学習、推論、検証に対応し、反転とHSVのデータ拡張を使い、metrics/mAP50-95(OBB)でチェックポイントを選択します。load_detect_weights_for_obb()で検出重みから初期化できます。

検証

val()は、学習に使用した形式の任意のデータセットで測定した適合率、再現率、mAP 50、mAP 50-95を含むmetrics/キーの辞書を返します。

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をインストールせず、単独のランタイムでグラフを実行することもサポートされますが、その場合は前処理と後処理を自分で実装する必要があります。各形式では異なる追加パッケージをインストールし、それぞれ固有の引数をいくつか受け取ります。どちらも該当する形式のページに記載されています。

エクスポートは、同じ重みを別のコンテナに収めたもう1つのコピーです。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 は Pillow の BILINEAR フィルタ(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 は固定小数点で計算し、画像の形状から軸の順序を選ぶため、浮動小数点の重みでは一部のピクセルで 1 レベル異なることがあります。これは私たちの検証の結果を変えません。

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 は Pillow の BILINEAR フィルタ(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 は固定小数点で計算し、画像の形状から軸の順序を選ぶため、浮動小数点の重みでは一部のピクセルで 1 レベル異なることがあります。これは私たちの検証の結果を変えません。

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)が、Deciの公開CDN上の対応するオブジェクトにマッピングされます。

ライブラリがSHA-256を固定しているチェックポイントだけをこの方法で取得できます。それ以外は、検証されていない第三者のpickleを開かずに失敗し、手動でダウンロードしてパスとして渡す必要があります。すでにディスク上にあるファイルはパスから読み込まれ、ダウンロードもチェックサムゲートもありません。ローダーが認識する元の名前のDeci .pthもこれに含まれます。

ライセンス

ダウンロードする特定の重みについて、Hugging Faceリポジトリのライセンスを確認してください。LibreYOLO orgの各チェックポイントにはライセンスが付与されており、同じファミリー内でも常に同一とは限りません。そのリポジトリが正式な情報源です。以下の概要は、このページを最後に検証した時点で適用されていた内容を示します。

これは関連するライセンスの説明であり、法的助言ではありません。商用上重要な場合は、自分でライセンスを読み、専門家の助言を受けてください。

原著作物
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組織に一切ありません。すべての自動ダウンロードは代わりにDeciの公開CDNへ接続し、開始前にプロセスごとに1回Deciの条件を表示します。また、ファイルを開く前に固定されたSHA-256と照合します。

ランダムに初期化されたモデルからの学習が代替手段です。アーキテクチャはアップストリームでApache-2.0、ここではMITなので、この方法で独自データを使って学習したモデルはDeciのチェックポイントに由来しません。

引用

YOLO-NASは論文なしで公開されました。下の項目は、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で検証済みです。このページのサポート表、チェックポイント、ベンチマーク値は手作業で記述したものではなく、リリース済みライブラリと公開済みの重みから生成されています。