コンテンツにスキップ

Ultralytics におけるエンドツーエンド検出の理解

はじめに

以前のモデル例: YOLOv8YOLO11からYOLO26へアップグレードする場合、最も大きな変更点の一つとしてNon-Maximum Suppression(NMS)が削除されたことが挙げられます。YOLO 数千もの重複する予測結果を生成するため、最終的な検出結果に絞り込むにはNMS が必要でした。これにより遅延が生じ、エクスポートグラフが複雑化し、ハードウェアプラットフォームによって動作が不安定になる可能性がありました。

YOLO26は異なるアプローチを採用しています。このモデルでは、外部でのフィルタリングを必要とせず、モデルから直接最終的な検出結果を出力します。これは「エンドツーエンドの物体検出」として知られており、すべてのYOLO26モデルでデフォルトで有効になっています。その結果、デプロイメントのパイプラインが簡素化され、レイテンシが低減され、CPU上での推論速度が最大43%向上します

このガイドでは、変更点、コードの更新が必要かどうか、どのエクスポート形式がエンドツーエンド推論に対応しているか、そして従来のYOLO からスムーズに移行する方法について解説します。

このアーキテクチャ変更の背景にある動機を深く掘り下げるには、YOLO26がNMSを削除する理由に関するUltralyticsのブログ投稿を参照してください。

概要

  • Ultralytics またはCLI をお使いですか? 変更は必要ありません。モデル名を次のように置き換えるだけです。 yolo26n.pt.
  • カスタム推論コード(ONNX 、TensorRT)を使用していますか? 後処理を更新してください — 検出結果の出力が変更されました (N, 300, 6)xyxy フォーマットのため、NMS 。その他のタスクでは、追加データ(マスク係数、キーポイント、または角度)が追加されます。
  • エクスポート? ほとんどのフォーマットは、ネイティブでエンドツーエンド出力をサポートしています。ただし、一部のフォーマット(NCNN、RKNN、PaddlePaddle、ExecuTorch、IMX、EdgeTPU)では、オペレータの制約がサポートされていないため(例: torch.topk)。

エンドツーエンド検出の仕組み

YOLO26は、学習時にデュアル ヘッドアーキテクチャを採用しています。両方のヘッドは同じバックボーンとネックを共有していますが、出力の生成方法は異なります:

目的検出出力後処理
1対1 (デフォルト)エンドツーエンド推論(N, 300, 6)信頼度しきい値のみ
一対多従来のYOLO(N, nc + 4, 8400)NMSが必要です

上記の形状は検出用です。その他のタスクでは、検出ごとに追加データを付加して、1対1の出力を拡張します:

タスクエンドツーエンド出力追加データ
検出(N, 300, 6)
セグメンテーション(N, 300, 6 + nm) + プロト (N, nm, H, W)nm マスク係数(デフォルトは32)
ポーズ(N, 300, 57)17 キーポイント × 3 (x, y, 可視性)
OBB(N, 300, 7)回転角度

トレーニング中、両方のヘッドが同時に実行されます。ワンツーメニーヘッドはより豊かな学習シグナルを提供し、ワンツーワンヘッドはクリーンで重複しない予測を生成することを学習します。During 推論 および エクスポート、のみ マンツーマン指導 デフォルトで有効になっており、1画像あたり最大300件の検出結果を以下の形式で出力します [x1, y1, x2, y2, confidence, class_id].

電話をかける際 model.fuse()、より高速な推論のためにConv + BatchNorm層を折りたたみ、エンドツーエンドモデルでは、one-to-manyヘッドも削除し、モデルサイズとFLOPsを削減します。デュアルヘッドアーキテクチャの詳細については、を参照してください。 YOLO26のモデルページ.

コードを変更する必要がありますか?

Ultralytics Python またはCLIの使用

変更は不要です。 標準のUltralytics Python APIまたはCLIを使用する場合、予測検証エクスポートのすべてがエンドツーエンドモデルをそのまま自動的に処理します。

Ultralytics ではコードの変更は不要です

from ultralytics import YOLO

# Load a YOLO26 model
model = YOLO("yolo26n.pt")

# Predict — no NMS step, no code changes
results = model.predict("image.jpg")
yolo predict model=yolo26n.pt source=image.jpg

カスタム推論コードの使用

はい、出力形式が異なります。もしYOLOv8またはYOLO11用にカスタムのポストプロセッシングロジックを記述していた場合(例えば、ONNX RuntimeTensorRTで推論を実行する際)、新しい出力形状に対応するために更新する必要があります。

YOLOv8 YOLO11YOLO26(エンドツーエンド)
検出出力(N, nc + 4, 8400)(N, 300, 6)
ボックス形式xywh (中心x、中心y、幅、高さ)xyxy (左上x、左上y、右下x、右下y)
レイアウトアンカーごとのボックス座標 + クラススコア[x1, y1, x2, y2, conf, class_id]
NMSはいいいえ
後処理NMS 信頼度フィルター信頼度フィルターのみ

segmentationpose、およびobbタスクの場合、YOLO26は各detectionにタスク固有のデータを追加します。上記の出力形状テーブルを参照してください。

どこ Nバッチサイズ および nc はクラスの数です(例:80は COCO)。

エンドツーエンドのモデルを使用すると、後処理がはるかに簡単になります。たとえば、ONNX を使用する場合:

import onnxruntime as ort

# Load and run the exported end-to-end model
session = ort.InferenceSession("yolo26n.onnx")
output = session.run(None, {session.get_inputs()[0].name: input_tensor})

# End-to-end output: (batch, 300, 6) → [x1, y1, x2, y2, confidence, class_id]
detections = output[0][0]  # first image in batch
detections = detections[detections[:, 4] > conf_threshold]  # confidence filter — that's it!

「1対多」ヘッドへの切り替え

YOLO が必要な場合(例えば、NMSの後処理コードを再利用する場合など)、以下の設定を行うことで、いつでも1対多のヘッドに切り替えることができます。 end2end=False:

従来のNMSの出力に「1対多」のヘッダーを使用する

from ultralytics import YOLO

model = YOLO("yolo26n.pt")

# Prediction with NMS (traditional behavior)
results = model.predict("image.jpg", end2end=False)

# Validation with NMS
metrics = model.val(data="coco.yaml", end2end=False)

# Export without end-to-end
model.export(format="onnx", end2end=False)
yolo predict model=yolo26n.pt source=image.jpg end2end=False
yolo val model=yolo26n.pt data=coco.yaml end2end=False
yolo export model=yolo26n.pt format=onnx end2end=False

エクスポート形式の互換性

ほとんどのエクスポート形式は、デフォルトでエンドツーエンド推論に対応しています。これには以下が含まれます。 ONNXTensorRTCoreMLOpenVINOTFLiteTF.js、およびMNN

以下の形式はエンドツーエンドに対応しておらず、自動的に1対多のヘッドにフォールバックします: NCNNRKNNPaddlePaddleExecuTorchIMX、およびEdgeTPU

エンドツーエンドがサポートされていない場合、どうなるのでしょうか

これらの形式のいずれかにエクスポートすると、Ultralytics 「1対多」のヘッドに切り替わり、警告を記録します。手動での操作は不要です。つまり、これらの形式 NMS YOLOv8YOLO11と同様に、推論パイプラインにNMSが必要になるということです。

TensorRT INT8

TensorRT エンドツーエンドに対応していますが、それは 自動無効化 でエクスポートする際 int8=True TensorRT .3.0 以前のバージョンで

精度と速度のトレードオフ

エンドツーエンドの検出は、精度への影響を最小限に抑えつつ、展開において大きなメリットを提供します。

メトリックエンドツーエンド(デフォルト)1対多 +NMSend2end=False)
CPU推論速度最大43%高速化ベースライン
mAP約0.5mAPYOLO1YOLO11と同等か、それ以上の性能
後処理信頼度フィルターのみNMS 全体
展開の複雑性ミニマルNMS が必要

ほとんどの実際のアプリケーションにおいて、約0.5の mAP 速度と簡素化の利点を考慮すると、その差はごくわずかです。最高の精度が最優先事項である場合は、いつでもone-to-manyヘッドを使用してフォールバックできます。 end2end=False.

すべてのモデルサイズ(n、s、m、l、x)にわたる詳細なベンチマークについては、YOLO26の性能指標をご覧ください。

YOLOv8 YOLO11からの移行

既存のプロジェクトをYOLO26にアップグレードする場合、スムーズに移行するための簡単なチェックリストを以下に示します:

  • Ultralytics /CLI : 変更は必要ありません。モデル名を次のように更新するだけです。 yolo26n.pt (または yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • カスタム後処理コード: 新しい出力形式に対応するための更新 — (N, 300, 6) detect用、さらにタスク固有のデータ セグメンテーション, ポーズ、および OBB。また、ボックス形式の変更点に注意してください。 xywh 宛先 xyxy
  • エクスポートパイプライン: ターゲットフォーマットについては、上記のフォーマット互換性セクションを確認してください
  • TensorRT + INT8: エンドツーエンドのサポートには、TensorRTのバージョンが10.3.0より大きいことを確認してください
  • FP16形式でのエクスポート: すべての出力をFP16で出力する必要がある場合は、以下のコマンドでエクスポートしてください end2end=False — 参照 なぜoutput0がFP32のままなのか
  • iOS CoreML: エンドツーエンドは完全にサポートされています。Xcodeプレビューのサポートが必要な場合は、 end2end=False with nms=True
  • エッジデバイス (NCNN, RKNN): これらの形式は自動的に多対一にフォールバックするため、デバイス上のパイプラインにNMSを含めてください。

よくある質問

end2end=TrueとNMS=Trueを一緒に使用できますか?

いいえ。これらのオプションは互いに排他的です。もし nms=True エンドツーエンドモデルにおいて エクスポート、自動的に強制されます nms=False ただし、注意点があります。エンドツーエンドのヘッドは内部ですでに重複フィルタリングを処理しているため、外部のNMS 不要NMS 。

しかしながら、 end2end=False と組み合わせて nms=True これは有効な設定です。従来のNMS エクスポートNMS 組み込んでいます。これは、 CoreML Xcodeのプレビュー機能でdetectionモデルを直接使用できるため、エクスポートが役立ちます。

エンドツーエンドモデルにおいて、max_detパラメータは何を制御するのでしょうか?

The max_det パラメータ(デフォルト:300)は、1対1ヘッドが1枚の画像につき出力できる検出結果の最大数を設定します。これは推論時またはエクスポート時に調整できます:

model.predict("image.jpg", max_det=100)  # fewer detections, slightly faster
model.export(format="onnx", max_det=500)  # more detections for dense scenes

なお、デフォルトのYOLO26チェックポイントは、以下の設定で学習されています max_det=300. この値を増やすことは可能ですが、1対1ヘッドはトレーニング中に最大300個のクリーンなdetectを生成するように最適化されています。そのため、その制限を超えるdetectは品質が低下する可能性があります。1画像あたり300個を超えるdetectが必要な場合は、より高い値で再トレーニングすることを検討してください。 max_det 値。

ONNX (1, 300, 6) ですが、これで合っていますか?

はい、それが検出における想定されるエンドツーエンドの出力形式です: バッチサイズ 1つにつき、最大300件の検出、それぞれに6つの値 [x1, y1, x2, y2, confidence, class_id]。信頼度しきい値でフィルタリングするだけで完了です — NMSは不要です。

その他のタスクでは、出力シェイプが異なります。

タスク出力形状説明
検出(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
セグメンテーション(1, 300, 38) + (1, 32, 160, 160)6つのボックス値 + 32個のマスク係数、さらにプロトタイプマスクtensor
ポーズ(1, 300, 57)6つのボックス値 + 17個のキーポイント × 3 (x、y、可視性)
OBB(1, 300, 7)6つのボックス値 + 1つの回転角度

エクスポートしたモデルがエンドツーエンドかどうかを確認するにはどうすればよいですか?

Python を使用するか、ONNX 直接確認することで、確認できます:

モデルがエンドツーエンドであるか確認する

from ultralytics import YOLO

model = YOLO("yolo26n.onnx")
model.predict(verbose=False)  # run predict to setup predictor first
print(model.predictor.model.end2end)  # True if end-to-end is enabled
import onnxruntime as ort

session = ort.InferenceSession("yolo26n.onnx")
metadata = session.get_modelmeta().custom_metadata_map
print(metadata.get("end2end"))  # 'True' if end-to-end is enabled

あるいは、出力形状を確認してください — エンドツーエンドのdetectモデルの出力 (1, 300, 6)、一方、従来のモデルは出力します。 (1, nc + 4, 8400)。その他のタスク形状については、 出力形状に関するよくある質問.

セグメンテーション、ポーズ推定、およびOBBタスクにおいて、エンドツーエンドの処理はサポートされていますか?

はい。YOLO26のすべてのタスクバリエーション―― 検出, セグメンテーション, 姿勢推定、および 指向物体検出 (obb) — デフォルトでエンドツーエンドの推論をサポートします。 end2end=False すべてのタスクでフォールバックも利用可能です。

各タスクは、タスク固有のデータで基本的なdetect出力を拡張します。

タスクモデルエンドツーエンド出力
検出yolo26n.pt(N, 300, 6)
セグメンテーションyolo26n-seg.pt(N, 300, 38) + プロト (N, 32, 160, 160)
ポーズyolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)


📅 13日前に作成✏️ 11日前に更新
glenn-jocherraimbekovm

コメント