YOLOアーキテクチャの解説:YOLOv3からYOLO26まで#
すべてのUltralytics YOLOモデルは、特徴を抽出するバックボーン、スケール間で特徴を融合するネック、ボックスとクラスを予測するヘッドの3つのステージで構成されています。このガイドでは、各ステージを構成するモジュールと、YOLOv3からYOLO26までの変化を説明し、各コンポーネントをultralytics/cfg/models/配下の設定ファイル内の定義、およびultralytics/nn/modules/内のモジュールクラスに対応付けます。
各モデルはYAMLファイルで宣言的に定義され、レイヤーを順に並べたリストで表されます。各レイヤーは[from, repeats, module, args]形式に従います。つまり、入力元となるレイヤー、モジュールの繰り返し回数、レイヤークラス(Conv、C3k2、SPPF、Detect、…)、およびコンストラクター引数を指定します。モデルYAML設定ガイドでは、この形式に加えて、repeatsとargsがバリアントの深さ倍率と幅倍率に応じてどのようにスケーリングされるか、モジュール解決システムの全容を説明しています。このガイドでは、モジュールそのものと、バージョンごとの変化に焦点を当てます。
3つのステージ#
すべてのUltralytics YOLOモデルでは、画像がそれぞれ異なる役割を持つ3つの連続したステージを通過します。
| ステージ | 役割 | 出力 |
|---|---|---|
| バックボーン | 入力画像から複数の解像度で特徴を抽出します | ストライド8、16、32(P3、P4、P5)の特徴マップ |
| ネック | 小さい物体と大きい物体の両方がコンテキスト情報を得られるよう、スケール間で特徴を融合します | マルチスケールで融合された特徴マップ |
| ヘッド | 融合された特徴からバウンディングボックスとクラススコアを予測します | アンカーポイントごとの検出結果 |
基本単位はConvブロック(conv.pyで定義)です。2D畳み込み、バッチ正規化、SiLU活性化を順に適用します。以下のより大きなモジュールはすべて、Convブロックを組み合わせて構成されています。
アーキテクチャ図#
各バージョンはバックボーン → ネック → ヘッドという同じ骨格を維持し、特定のステージを変更しています。以下のタブにはバージョンごとの構造が表示されます。バックボーンとネックのステージはultralytics/cfg/models/の設定に従っています。一方、YOLOv3とYOLOv5のヘッドは、パッケージの設定で実際に採用されているアンカーフリーのuバリアントのヘッドではなく、元のアンカーベース形式で描画されています。タブを順に確認すると、各世代で追加された要素がわかります。要約すると、YOLOv3はFPNのみを使用するアンカーベースの検出器です。YOLOv5ではボトムアップのPAN経路とSPPFが追加されます。YOLOv8ではC2fブロックに切り替わり、アンカーフリーのDFLヘッドが採用されます。YOLO11ではC2PSAアテンションとC3k2ブロックが追加されます。YOLO26ではSPPF残差が追加され、DFLが削除され、オプションでNMSフリーのヘッドが追加されます。
YOLOv3とYOLOv5の図には、元のアンカーベースのヘッドを示しています。ultralyticsパッケージでは、アンカーフリーのYOLOv3uおよびYOLOv5u設定を提供しています。これらは、Darknet-53およびC3バックボーンに、YOLOv8のDetectヘッドを組み合わせたもので、検出ヘッドで説明しています。
バックボーンブロック:Bottleneck → C3 → C2f → C3k2#
バックボーンでは、ストライド2のConvダウンサンプリングレイヤーの間に、繰り返し使用するCSP(Cross-Stage Partial)ブロックを積み重ねます。この繰り返しブロックは、バージョン間で最も大きく変化した部分です。以下のブロックはすべてblock.pyにあります。c1/c2は入力/出力チャネル、c = 0.5 * c2は隠れ層の幅です。
Bottleneck(YOLOv3)#
基本単位はBottleneckです。2つのConvレイヤー(デフォルトのカーネルは(3, 3))で構成され、shortcut=Trueとc1 == c2の場合は残差加算が任意で行われます。YOLOv3のDarknet-53バックボーンでは、CSP分割を行わずにこれらを直接積み重ね、3つのスケール(ストライド8、16、32)で検出します。
C3(YOLOv5)#
YOLOv5のC3では、入力を2つの1x1畳み込みに分割します。cv1はn個のBottleneckブロック(カーネルは(1, 1)、続いて(3, 3))に順に渡され、cv2はそれらを迂回します。2つの経路を連結し、3つ目の1x1 Convで融合します。
def forward(self, x):
# C3:ボトルネック経路m(cv1(x))をバイパスcv2(x)と連結し、その後cv3で融合します
return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))最後のボトルネック出力だけが融合畳み込みに渡されるため、cv3が受け取る特徴マップは2つです。
C2f(YOLOv8)#
YOLOv8のC2f(「2つの畳み込みを備えたCSP Bottleneck、高速化」)では、融合畳み込みに渡される特徴が変更されています。
cv1 = Conv(c1, 2 * c, 1)の後、chunk(2)で出力をcチャネルのテンソル2つに分割します。n個のBottleneck(c, c)ブロック(カーネルは(3, 3)、(3, 3))を順に実行し、各ブロックには直前のブロックの出力を入力します。- すべての
n + 2中間テンソルを連結し、cv2 = Conv((2 + n) * c, c2, 1)で融合します。
C3では2つの特徴マップを融合畳み込みに渡すのに対し、C2fではn + 2個を渡します。すべての中間ボトルネック出力を再利用します。
C3k2(YOLO11およびYOLO26)#
YOLO11とYOLO26では、C2fのサブクラスであり、繰り返し単位を入れ替えたC3k2を使用します。コンストラクターのフラグに応じて、n個のブロックはそれぞれ次のいずれかになります。
- 通常の
Bottleneck(デフォルト、c3k=False)、 C3kブロック(c3k=True)。カーネルサイズを設定できるC3バリアントです。またはBottleneck+PSABlockのペア(attn=True)。
2つ目のYAML引数は、スケールがm、l、xのいずれでもない限り、c3kを設定します。これらのスケールではTrueに固定されるため、1つのyolo11.yamlですべての5つのバリアントに対応できます。そのため、[-1, 2, C3k2, [512, False]]はnおよびsでBottleneck内部構造を構築し、m、l、xではC3k内部構造を構築します。512はスケーリング前のチャネル数で、バリアントの幅倍率によってnでは128、xでは768になります。CSPモジュールでは、repeatsフィールド(ここでは2)は、バリアントの深さ倍率でスケーリングされる前の値であり、個別のモジュールを積み重ねる回数ではなく、ブロック内部の繰り返し回数になります。
空間プーリング:SPP → SPPF#
バックボーンの終端では、空間ピラミッドプーリングブロックによって受容野を広げます。YOLOv5では、元の複数カーネルを用いるSPPをSPPF(Spatial Pyramid Pooling - Fast)に置き換えました。これは単一のMaxPool2d(kernel_size=5, stride=1, padding=2)をn = 3回連続して適用し、入力と3つのプーリング出力を連結して、1x1 Convで融合します。連鎖した5x5プーリングが大きなカーネルの受容野をカバーするため、数学的にはSPP(k=(5, 9, 13))と等価でありながら、計算コストが低くなります。
YOLO26ではショートカットフラグ(SPPF, [1024, 5, 3, True])を渡します。最も深い層のc1 == c2 == 1024であるため、SPPFが残差接続(return y + x)を追加します。
空間アテンション:C2PSA(YOLO11以降)#
YOLO11では、SPPFの後にC2PSAが追加されました。これはCSPブロックで、アクティブな経路はn個のPSABlock(Position-Sensitive Attention)モジュールを積み重ねています。cv1 = Conv(c1, 2 * c, 1)が特徴を分割し、片方をPSABlockスタックに通した後、cv2 = Conv(2 * c, c1, 1)が連結結果を融合します。各PSABlockでは、マルチヘッドアテンションの後に2層のフィードフォワードネットワーク(Conv(c, 2 * c, 1) → Conv(2 * c, c, 1))を適用します。いずれも残差接続を備えています。YOLO26でも、同じC3k2 + C2PSAバックボーンを使用しています。
ネック:FPN + PAN#
ネックでは、トップダウンのFeature Pyramid Network(FPN)と、それに続くボトムアップのPath Aggregation Network(PAN)によって、バックボーンのP3/P4/P5特徴マップを融合します。YAMLのヘッドセクションでは、FPNはnn.Upsample + Concat(意味情報を高解像度側へ伝達)、PANはストライド2のConv + Concat(位置情報を上位側へ戻す)です。
# YOLO11 head (FPN top-down, then PAN bottom-up)
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 6], 1, Concat, [1]] # cat backbone P4
- [-1, 2, C3k2, [512, False]] # 13
# ... second upsample + concat to P3 ...
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 13], 1, Concat, [1]] # cat head P4 (PAN)
- [-1, 2, C3k2, [512, False]] # 19ネックでは、同じ世代のバックボーンブロックを再利用します。YOLOv5ではC3、YOLOv8ではC2f、YOLO11とYOLO26ではC3k2を使うため、各結合点ではバックボーンと同じモジュールが実行されます。融合された3つの出力がヘッドに渡されます。例外はYOLOv3です。YOLOv3のネックはトップダウンFPNのみで構成され、YAMLのヘッドにストライド2のダウンサンプリングはありません。YOLOv5で導入されたボトムアップPAN経路もありません。
検出ヘッド:アンカーベース → アンカーフリー → NMSフリー#
ヘッドは、融合された3つの特徴マップを検出タスクの予測に変換します。設計はバージョンごとに変化し、アンカーベースからアンカーフリー、さらにNMSフリーへと進化しました。
アンカーフリーで分離されたDetect#
元のYOLOv3とYOLOv5では、アンカーベースで結合されたヘッドを使用していました。事前定義されたアンカーボックスと、ボックスとクラスの予測を共有するブランチで構成されています。独立したultralytics/yolov3およびultralytics/yolov5リポジトリでは、このアンカーベースの設計を維持しています。一方、メインのultralyticsパッケージでは、アンカーフリーのYOLOv3uおよびYOLOv5uバリアントを提供しています。これらはDarknet-53およびC3バックボーンに、YOLOv8のアンカーフリーDetectヘッドを組み合わせています。また、ここで説明するyolov3.yamlとyolov5.yamlの設定は、過去の設計ではなく、これらのuバリアントを対象としています。
Detectヘッド(head.py)はアンカーフリーで、予測を分離しています。ピラミッドの各レベルで2つの並列ブランチを実行し、アンカーボックスではなくグリッドポイントに対して直接予測します。
- ボックスブランチ(
cv2):Conv(x, c2, 3)→Conv(c2, c2, 3)→Conv2d(c2, 4 * reg_max, 1)。 - クラスブランチ(
cv3): YOLO11とYOLO26では、深さ方向分離可能なブロック2つ(DWConv+1x1 Conv)の後にConv2d(c3, nc, 1)を適用します。YOLOv8では従来のバリアントを使用し、3x3 Convレイヤー2つの後にConv2d(c3, nc, 1)を適用します。
そのため、各アンカーポイントはno = nc + 4 * reg_max個の出力を生成します。事前定義されたアンカーをなくすことで、調整が必要なハイパーパラメーターからアンカーボックスのサイズとアスペクト比を除外できます。
Distribution Focal Loss(DFL)#
YOLOv8とYOLO11では、4つのボックス座標それぞれを単一のスカラーではなく、reg_max = 16個のビン上の分布として回帰します(Generalized Focal Lossの積分形式)。DFLモジュールは、4 * reg_max個のボックスチャネルを(4, reg_max)に整形し、reg_max個のビンに対してsoftmaxを適用した後、期待ビンインデックスを取得します。これは、各ビンインデックスに対応するsoftmax確率を重みとして掛け合わせ、その合計を予測座標とするものです。これは、重みがビンインデックスarange(reg_max)である固定の1x1畳み込みで実装されるため、重み付き和は単一の内積になります。
YOLO26:NMSフリー、DFLフリー#
YOLO26では、ヘッドが直接読み取る2つのYAMLパラメーターを設定します。
end2end: True—Detectはブランチをディープコピーして、ワンツーワンヘッド(one2one_cv2/one2one_cv3)を作成します。このヘッドは、オブジェクトごとに1つの予測を学習します。このYAML設定では、学習用のヘッドを2つ作成します。実行時にはnms=Falseがワンツーワンヘッドを選択し、Non-Maximum Suppression(NMS)の後処理を削除します。推論とエクスポートの詳細については、エンドツーエンド検出ガイドをご覧ください。reg_max: 1— ビンが1つの場合、self.dflはnn.Identity()とno = nc + 4になります。ヘッドは座標を直接回帰し、エクスポートされたONNXグラフにはDFL演算が含まれません。
5つのモデルサイズ(n/s/m/l/x)全体で、YOLO26はCOCOで40.9~57.5 mAPを達成し、T4でのTensorRTレイテンシは1.7~11.8 msです。YOLO26の論文で報告されています。
バージョンごとの概要#
| バージョン | バックボーンブロック | 空間プーリング | アテンション | 検出ヘッド | DFL |
|---|---|---|---|---|---|
| YOLOv3 | Darknet-53(Bottleneck) | 基本設定ではなし | なし | 元の設計:アンカーベース、uバリアント:アンカーフリー | なし / あり(u) |
| YOLOv5 | C3(CSP) | SPPF | なし | 元の設計:アンカーベース、uバリアント:アンカーフリー | なし / あり(u) |
| YOLOv8 | C2f | SPPF | なし | アンカーフリー、分離型 | あり(reg_max=16) |
| YOLO11 | C3k2 | SPPF | C2PSA | アンカーフリー、分離型 | あり(reg_max=16) |
| YOLO26 | C3k2 | SPPF + ショートカット | C2PSA | アンカーフリー、2つのヘッド。NMSフリーは任意 | 削除済み(reg_max=1) |
モデルごとの詳細、パフォーマンステーブル、使用例については、YOLOv3、YOLOv5、YOLOv8、YOLO11、YOLO26の各ページをご覧ください。
アーキテクチャを自分で確認する#
model.info()メソッドは、レイヤー、パラメーター、FLOPsの概要を出力し、解析済みのモジュールリストはmodel.model.modelで確認できます。
from ultralytics import YOLO
# 事前トレーニング済みモデルを読み込む
model = YOLO("yolo11n.pt")
# 公開されている仕様とカウントを一致させるため、ConvレイヤーとBatchNormレイヤーを融合します
model.fuse()
# レイヤー、パラメーター、勾配、GFLOPsの概要を出力します
model.info()
# 検出ヘッド(ネットワーク内の最後のモジュール)を確認します
head = model.model.model[-1]
print(type(head).__name__, "| reg_max:", head.reg_max, "| DFL layer:", type(head.dfl).__name__)3世代にわたってスニペットを実行すると、変化を数値で確認できます。これらはultralyticsパッケージから得られた実際の融合モデル出力で、各モデルページに掲載されているパラメーター数とFLOPs数に一致しています。
| モデル | レイヤー | パラメーター数 | GFLOPs | reg_max | DFLレイヤー |
|---|---|---|---|---|---|
| YOLOv8n | 72 | 3,151,904 | 8.7 | 16 | DFL |
| YOLO11n | 100 | 2,616,248 | 6.5 | 16 | DFL |
| YOLO26n | 120 | 2,408,932 | 5.5 | 1 | Identity |
YOLO26nではreg_max=1とDFLレイヤーIdentityが報告されています。予測と検証では、デフォルトでNMSを使うワンツーメニーモードを使用します。NMSフリー推論を行うには、nms=Falseを設定します。両方のヘッドが学習されます。
パラメーター数とFLOPsの値は、各Convとそのバッチ正規化レイヤーを統合した融合済みモデル(model.fuse())について報告しています。これは公開済みの仕様と一致します。チェックポイントを新しく読み込んだ直後は、融合前のためカウントがわずかに高くなります。
結論#
バージョンを追うごとに、YOLOアーキテクチャは一度に1つのステージを変更してきました。バックボーンはDarknet-53から、CSPベースのC3、C2f、C3k2ブロックとC2PSAアテンションへと移行しました。ネックはFPN + PAN構造を維持しながら、SPPがSPPFに置き換わりました。ヘッドはアンカーベースからアンカーフリーへと移行し、その後、YOLO26ではDFLを使わない設計となり、オプションでNMSフリーのエンドツーエンドヘッドが追加されました。
カスタムアーキテクチャを定義する方法については、モデルYAML設定ガイドをご覧いただくか、モデルページでモデルを比較してください。ご質問はGitHubまたはDiscordでお問い合わせください。
よくある質問#
YOLOモデルは、ストライド8、16、32で画像から特徴を抽出するバックボーン、FPNとPANを使って複数のスケール間で特徴を融合するネック、バウンディングボックスとクラススコアを予測するヘッドで構成されます。YOLOv3からYOLO26まで、すべてのUltralytics YOLOモデルがこの3ステージ設計に従っています。
C2f(YOLOv8)はCSPブロックで、融合コンボリューションの前に、各内部Bottleneck(n + 2特徴マップ)の出力をすべて連結します。これに対し、旧型のC3では2つだけを渡します。C3k2(YOLO11およびYOLO26)はC2fのサブクラスであり、c3kフラグが設定されている場合、各BottleneckをC3kブロック(カーネルサイズを設定可能なC3のバリアント)に置き換えられます。どちらもblock.pyで定義されています。YOLO11では、YOLOv8に対して構造上の変更が3つあります。バックボーンとネックの
C2fブロックをC3k2に置き換え、SPPFの後にC2PSA自己アテンションブロックを挿入し、ヘッドの分類ブランチをより軽量な深さ方向分離コンボリューションに切り替えています。どちらも、reg_max=16DFL回帰を備えた同じアンカーフリーの分離型Detectヘッドを維持しています。そのため、検出インターフェースを再設計するのではなく、パラメーター数とFLOPsを減らしながら精度を向上させています。最新のUltralytics YOLOモデルはアンカーフリーです。YOLOv8、YOLO11、YOLO26は、ボックス回帰と分類のブランチを分離したアンカーフリーの分離型
Detectヘッドを使用します。元のYOLOv3とYOLOv5はアンカーベースでしたが、UltralyticsではYOLOv8と同じアンカーフリーヘッドを設定したYOLOv3uおよびYOLOv5uバリアントとして提供しています。はい。YOLO26には、
nms=Falseを使ったNMSフリー推論に対応するone-to-oneヘッドが含まれています。デフォルトのone-to-many推論経路ではNMSを使用し、トレーニング中は両方のヘッドに教師信号を与えます。詳しくはエンドツーエンド検出ガイドをご覧ください。DFLは各ボックス座標を
reg_max個のビン(YOLOv8とYOLO11ではデフォルトで16)にわたるソフトマックス分布として回帰し、単一のスカラーを予測する代わりに期待値を座標として使用します。YOLO26ではreg_max=1が設定されるため、DFLレイヤーは恒等演算となり、ヘッドが座標を直接回帰します。その結果、エクスポートされたONNXまたはTensorRTグラフにDFL演算は含まれません。モデルをPythonで読み込み、
model.info()を呼び出すと、レイヤー、パラメーター、GFLOPsの概要を確認できます。解析済みのレイヤーはmodel.model.modelにあります。たとえば、model.model.model[-1]はDetectヘッドであり、reg_maxやdflなどの属性を参照できます。アーキテクチャ全体は、モデルのYAML設定ファイルで定義されています。