YOLO Vision 2026:

Объяснение архитектуры YOLO: от YOLOv3 до YOLO26#

Каждая модель Ultralytics YOLO состоит из трёх этапов: бэкбона (backbone), который извлекает признаки, нека (neck), объединяющего их по масштабам, и головы (head), предсказывающей ограничивающие рамки (боксы) и классы. В этом руководстве описаны модули, из которых состоит каждый этап, и то, как они менялись от YOLOv3 до YOLO26, прослеживая каждый компонент до его определения в конфигурационных файлах в ultralytics/cfg/models/ и классов модулей в ultralytics/nn/modules/.

Каждая модель декларативно задается в YAML-файле как упорядоченный список слоев, где каждый слой следует формату [from, repeats, module, args]: какие слой(и) подают на него данные, сколько раз повторяется модуль, класс слоя (Conv, C3k2, SPPF, Detect, …) и аргументы его конструктора. В руководстве по конфигурации моделей в YAML этот формат документирован полностью — включая то, как масштабируются repeats и args в зависимости от множителей глубины и ширины варианта, — наряду с системой разрешения модулей. Это руководство сосредоточено на самих модулях и на том, как они менялись от версии к версии.

Три этапа#

Каждая модель Ultralytics YOLO направляет изображение через три последовательных этапа, каждый из которых выполняет свою задачу:

ЭтапЗадачаВыходные данные
BackboneИзвлечение признаков из входного изображения с несколькими разрешениямиКарты признаков с шагом 8, 16 и 32 (P3, P4, P5)
NeckОбъединение признаков разных масштабов, чтобы как мелкие, так и крупные объекты имели контекстОбъединенные многомасштабные карты признаков
HeadПредсказание ограничивающих рамок и оценок классов по объединенным признакамОбнаружения на точку привязки

Фундаментальной единицей является блок Conv (определенный в conv.py): двумерная свёртка, батч-нормализация и активация SiLU, применяемые последовательно. Каждый более крупный модуль ниже строится путем композиции блоков Conv.

Диаграммы архитектуры#

Каждая версия сохраняет один и тот же скелет бэкбон → нек → голова и изменяет конкретные этапы. Вкладки ниже показывают структуру для каждой версии: этапы бэкбона и нека следуют конфигурациям в ultralytics/cfg/models/, в то время как головы YOLOv3 и YOLOv5 нарисованы в их исходной форме на основе якорей (anchor-based), а не в бескориантной (u-вариант) голове, которую фактически поставляют конфигурации их пакетов. Просмотр вкладок показывает, что добавило каждое поколение. Кратко говоря, эволюция такова: YOLOv3 — это детектор только на базе FPN на основе якорей; YOLOv5 добавляет восходящий путь PAN и SPPF; YOLOv8 переключается на блок C2f с бескориантной DFL-головой; YOLO11 добавляет внимание C2PSA и блок C3k2; а YOLO26 добавляет остаточную связь SPPF и делает голову свободной от NMS и DFL. Цвета узлов соответствуют условным обозначениям диаграмм в документации: зеленый — вход, синий — бэкбон, серый — пространственный пулинг и внимание, оранжевый — нек, фиолетовый — голова и выход.

flowchart TD
    IN[Input 640x640]:::start --> ST[Conv stem<br/>5x stride-2 down to P1-P5]:::proc
    ST --> BB[Darknet-53 backbone<br/>stacked Bottleneck]:::proc
    BB --> FPN[Neck FPN only<br/>top-down Upsample + Concat]:::decide
    FPN --> HD[Detect head<br/>3 scales, anchor-based]:::out
    HD --> O[Predictions + NMS]:::out
    classDef start fill:#4CAF50,color:#fff
    classDef proc fill:#2196F3,color:#fff
    classDef decide fill:#FF9800,color:#fff
    classDef out fill:#9C27B0,color:#fff

На диаграммах YOLOv3 и YOLOv5 показана исходная голова на основе якорей. Пакет ultralytics поставляет бескориантные конфигурации YOLOv3u и YOLOv5u — те же бэкбоны Darknet-53 и C3 с головой Detect из YOLOv8, — описанные в разделе Детектирующая голова.

Блоки Backbone: Bottleneck → C3 → C2f → C3k2#

Бэкбон объединяет в стек повторяющийся CSP-блок (Cross-Stage Partial) между слоями субдискретизации (downsampling) Conv с шагом 2. Именно этот повторяющийся блок претерпел наибольшие изменения в разных версиях. Все блоки ниже находятся в block.py; c1/c2 — это входные/выходные каналы, а c = 0.5 * c2 — скрытая ширина.

Bottleneck (YOLOv3)#

Базовым элементом является Bottleneck: два слоя Conv (ядра по умолчанию (3, 3)) с опциональным добавлением остаточной связи (residual add), когда shortcut=True и c1 == c2. Бэкбон Darknet-53 YOLOv3 объединяет их напрямую в стек, без разделения CSP, и выполняет детектирование на трёх масштабах (шаги 8, 16, 32).

C3 (YOLOv5)#

YOLOv5's C3 разделяет входные данные между двумя свертками 1x1: cv1 передает данные в последовательные блоки Bottleneck n (ядра (1, 1), затем (3, 3)), а cv2 обходит их. Эти два пути объединяются и сливаются третьей сверткой 1x1 Conv:

def forward(self, x):
    # C3: bottleneck path m(cv1(x)) concatenated with bypass cv2(x), then fused by cv3
    return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))

Только выходной результат финального «бутылочного горлышка» (bottleneck) доходит до свёртки слияния, поэтому cv3 видит 2 карты признаков.

C2f (YOLOv8)#

YOLOv8 C2f («CSP Bottleneck с 2 свёртками, более быстрый») меняет то, какие признаки доходят до свёртки слияния:

  1. cv1 = Conv(c1, 2 * c, 1), затем chunk(2) разделяет выходные данные на два тензора с числом каналов c.
  2. Блоки n Bottleneck(c, c) (ядра (3, 3), (3, 3)) выполняются последовательно, и на вход каждого подается вывод предыдущего блока.
  3. Все промежуточные тензоры n + 2 конкатенируются и объединяются с помощью cv2 = Conv((2 + n) * c, c2, 1).

Там, где C3 передает в свою свёртку слияния 2 карты признаков, C2f передает n + 2 — переиспользуется каждый выходной результат промежуточного «бутылочного горлышка».

C3k2 (YOLO11 и YOLO26)#

YOLO11 и YOLO26 используют C3k2, подкласс C2f, который заменяет повторяющийся элемент. Каждый из блоков n становится, в зависимости от флагов конструктора:

  • обычным Bottleneck (по умолчанию, c3k=False),
  • блоком C3k (c3k=True) — вариантом C3 с настраиваемым размером ядра, или
  • парой Bottleneck + PSABlock (attn=True).

Второй аргумент YAML задает c3k; например, [-1, 2, C3k2, [512, True]] строит один модуль C3k2 с 512 выходными каналами, внутренними блоками которого являются C3k (поскольку c3k=True). Для модулей CSP поле repeats — здесь 2, до того как оно будет масштабировано множителем глубины варианта — становится внутренним числом повторений блока вместо стекирования отдельных модулей.

Пространственное объединение: SPP → SPPF#

В конце бэкбона блок пространственного пирамидального пулинга расширяет рецептивное поле. YOLOv5 заменила исходный многоядерный SPP на SPPF (Spatial Pyramid Pooling - Fast): один MaxPool2d(kernel_size=5, stride=1, padding=2), применяемый n = 3 раза последовательно, причем вход и все три объединенных пулингом выхода конкатенируются и объединяются с помощью 1x1 Conv. Это математически эквивалентно SPP(k=(5, 9, 13)), но дешевле, поскольку соединенные в цепочку пулинги 5x5 покрывают рецептивные поля больших ядер.

YOLO26 передает флаг сокращения/остаточной связи (SPPF, [1024, 5, 3, True]); поскольку c1 == c2 == 1024 на самом глубоком слое, SPPF добавляет остаточное соединение (return y + x).

Пространственное внимание: C2PSA (YOLO11+)#

YOLO11 добавила C2PSA после SPPF. Это CSP-блок, активной ветвью которого является стек модулей n PSABlock (Position-Sensitive Attention): cv1 = Conv(c1, 2 * c, 1) разделяет признаки, одна половина проходит через стек PSABlock, а cv2 = Conv(2 * c, c1, 1) объединяет результат конкатенации. Каждый PSABlock применяет многоголовое внимание, за которым следует двухслойная полносвязная сеть (Conv(c, 2 * c, 1)Conv(2 * c, c, 1)), каждая с остаточным соединением. YOLO26 сохраняет тот же бэкбон C3k2 + C2PSA.

Neck: FPN + PAN#

Нек объединяет карты признаков P3/P4/P5 бэкбона с помощью нисходящей сети пирамиды признаков (FPN), за которой следует восходящая сеть агрегации путей (PAN). В секции головы YAML FPN представляет собой nn.Upsample + Concat (переносящие семантическую информацию вниз к более высоким разрешениям), а PAN — это Conv с шагом 2 + 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

Нек переиспользует блок бэкбона своего поколения — C3 в YOLOv5, C2f в YOLOv8, C3k2 в YOLO11 и YOLO26, — поэтому каждая точка слияния запускает тот же модуль, который использует бэкбон. Три объединенных выхода поступают на голову. YOLOv3 является исключением: ее нек представляет собой только нисходящий FPN (ее голова в YAML не имеет субдискретизации с шагом 2), без восходящего пути PAN, который появился в YOLOv5.

Detection Head: Anchor-Based → Anchor-Free → NMS-Free#

Голова преобразует три объединенные карты признаков в предсказания для задачи детектирования. Ее дизайн менялся от версии к версии: от основанного на якорях (anchor-based) к бескориантному (anchor-free) и к бескориантному без NMS (NMS-free).

Бескориантная, разделенная Detect#

Исходные YOLOv3 и YOLOv5 использовали основанную на якорях (anchor-based) сопряженную голову: предопределенные якорные рамки и общую ветвь для предсказаний рамок и классов. Автономные репозитории ultralytics/yolov3 и ultralytics/yolov5 сохраняют этот дизайн на основе якорей. Основной пакет ultralytics вместо этого поставляет бескориантные варианты YOLOv3u и YOLOv5u — те же бэкбоны Darknet-53 и C3 с бескориантной головой Detect из YOLOv8, — а конфигурации yolov3.yaml и yolov5.yaml, документированные здесь, являются именно этими вариантами u, а не историческим дизайном.

Голова Detect (head.py) не использует якоря и является разделенной: для каждого уровня пирамиды она запускает две параллельные ветви и делает предсказания непосредственно по точкам сетки, а не относительно якорных рамок.

  • Ветвь рамок (cv2): Conv(x, c2, 3)Conv(c2, c2, 3)Conv2d(c2, 4 * reg_max, 1).
  • Ветвь классов (cv3): в YOLO11 и YOLO26 — два глубинных сепарабельных блока (DWConv + 1x1 Conv) → Conv2d(c3, nc, 1); YOLOv8 использует устаревший вариант: два слоя 3x3 ConvConv2d(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), применяет softmax по бинам reg_max и принимает ожидаемый индекс бина — где каждый индекс бина взвешен по его вероятности softmax, а затем просуммирован — в качестве предсказанной координаты. Это реализовано как фиксированная свёртка 1x1, весами которой являются индексы бинов arange(reg_max), так что взвешенная сумма представляет собой единое скалярное произведение.

YOLO26: NMS-free, DFL-free#

YOLO26 задает два параметра YAML, которые голова читает напрямую:

  • end2end: TrueDetect выполняет глубокое копирование своих ветвей в голову «один к одному» (one2one_cv2/one2one_cv3), которая выдает одно предсказание на объект, устраняя шаг постобработки подавления немаксимумов (NMS). Подробности об экспорте и миграции см. в руководстве по сквозному детектированию (End-to-End Detection).
  • reg_max: 1 — с одним бином self.dfl превращается в nn.Identity() и no = nc + 4; голова регрессирует координаты напрямую, и в экспортированном графе ONNX не появляется операция DFL.

В пяти своих размерах моделей (n/s/m/l/x) YOLO26 достигает mAP 40.9-57.5 на COCO при задержке T4 TensorRT 1.7-11.8 мс, как сообщается в статье по YOLO26.

Сводка по версиям#

ВерсияБлок BackboneПространственное объединениеВниманиеГолова обнаруженияDFL
YOLOv3Darknet-53 (Bottleneck)нет в базовой конфигурациинетИсходный: на основе якорей (anchor-based); вариант u: бескориантный (anchor-free)нет / да (u)
YOLOv5C3 (CSP)SPPFнетИсходный: на основе якорей (anchor-based); вариант u: бескориантный (anchor-free)нет / да (u)
YOLOv8C2fSPPFнетAnchor-free, decoupledда (reg_max=16)
YOLO11C3k2SPPFC2PSAAnchor-free, decoupledда (reg_max=16)
YOLO26C3k2SPPF + шорткатC2PSAБескориантная, без NMS (end2end)удалена (reg_max=1)

Сведения по конкретным моделям, таблицы производительности и примеры использования см. на отдельных страницах для YOLOv3, YOLOv5, YOLOv8, YOLO11 и YOLO26.

Изучите архитектуру самостоятельно#

Метод model.info() выводит сводку по слоям, параметрам и FLOPs, а разобранный список модулей доступен в model.model.model.

Изучите архитектуру модели YOLO
from ultralytics import YOLO

# Load a pretrained model
model = YOLO("yolo11n.pt")

# Fuse Conv + BatchNorm layers so counts match the published specs
model.fuse()

# Print a summary: layers, parameters, gradients, GFLOPs
model.info()

# Inspect the detection head (the last module in the network)
head = model.model.model[-1]
print(type(head).__name__, "| reg_max:", head.reg_max, "| end2end:", head.end2end)

Запуск этого фрагмента кода на трёх поколениях наглядно демонстрирует изменения в цифрах. Это реальные выходы объединенных (fused) моделей из пакета ultralytics, соответствующие количеству параметров и FLOPs, опубликованным на каждой странице модели:

МодельСлоиПараметрыGFLOPsreg_maxend2endСлой DFL
YOLOv8n723,151,9048.716FalseDFL
YOLO11n1002,616,2486.516FalseDFL
YOLO26n1222,408,9325.41TrueIdentity

YOLO26n сообщает об reg_max=1, end2end=True и слое DFL Identity — это архитектурная подпись ее головы, свободной от NMS и DFL.

Подсчет объединенных (fused) и необъединенных слоев

Значения параметров и FLOPs приводятся для объединенной модели (model.fuse()), которая объединяет каждый слой Conv и его слой батч-нормализации. Это соответствует опубликованным спецификациям; только что загруженный чекпойнт сообщает о немного больших значениях до объединения.

Заключение#

В разных версиях архитектура YOLO менялась по одному этапу за раз: бэкбон перешел от Darknet-53 к блокам C3, C2f и C3k2 на базе CSP с вниманием C2PSA; нек сохранил свою структуру FPN + PAN, в то время как SPP стал SPPF; а голова перешла от основанной на якорях к бескориантной, а затем к сквозному дизайну YOLO26 без NMS и DFL.

Чтобы определить пользовательские архитектуры, см. Руководство по конфигурации моделей в YAML или сравните модели на страницах моделей. Если у вас возникли вопросы, обращайтесь на GitHub или в Discord.

FAQ#

  • Модель YOLO имеет backbone, который извлекает признаки из изображения с шагами 8, 16 и 32, neck, который объединяет эти признаки по масштабам с помощью FPN и PAN, и head, который предсказывает ограничивающие рамки (bounding boxes) и оценки классов. Каждая модель Ultralytics YOLO от YOLOv3 до YOLO26 следует этому трехстадийному дизайну.

  • C2f (YOLOv8) — это CSP-блок, который конкатенирует выходы каждого внутреннего Bottleneck — карт признаков n + 2 — перед своей свёрткой слияния, тогда как более старый C3 передает только 2. C3k2 (YOLO11 и YOLO26) — это подкласс C2f, который может заменять каждый Bottleneck блоком C3k (вариант C3 с настраиваемым размером ядра), когда установлен его флаг c3k. Оба определены в block.py.

  • YOLO11 вносит три структурных изменения в YOLOv8: заменяет блок бэкбона и нека C2f на C3k2, вставляет блок самовнимания C2PSA после SPPF и переключает классификационную ветвь головы на более легкие глубинные сепарабельные свёртки. Обе сохраняют ту же бескориантную разделенную голову Detect с регрессией DFL reg_max=16, поэтому эти изменения снижают количество параметров и FLOPs при одновременном повышении точности, не перепроектируя интерфейс детектирования.

  • Современные модели Ultralytics YOLO являются бескориантными (anchor-free). YOLOv8, YOLO11 и YOLO26 используют бескориантную разделенную голову Detect с раздельными ветвями для регрессии рамок и классификации. Исходные YOLOv3 и YOLOv5 были основаны на якорях, но Ultralytics поставляет их в виде вариантов YOLOv3u и YOLOv5u, конфигурации которых используют ту же бескориантную голову, что и YOLOv8.

  • Да — YOLO26 устанавливает end2end=True, что дает Detect голову «один к одному», которая производит одно предсказание на объект и удаляет шаг постобработки «подавление немаксимумов» (Non-Maximum Suppression), необходимый в более ранних моделях. Подробности см. в руководстве по сквозному детектированию (End-to-End Detection).

  • DFL регрессирует каждую координату рамки как распределение softmax по бинам reg_max (по умолчанию 16 в YOLOv8 и YOLO11) и принимает ожидаемое значение в качестве координаты, а не предсказывает единый скаляр. YOLO26 устанавливает reg_max=1, поэтому слой DFL становится тождественной операцией (identity operation), голова регрессирует координаты напрямую, и в экспортированных графах ONNX или TensorRT не появляется операция DFL.

  • Загрузите модель в Python и вызовите model.info() для получения сводки по слоям, параметрам и GFLOPs. Разобранные слои находятся в model.model.model — например, model.model.model[-1] представляет собой голову Detect, предоставляющую доступ к таким атрибутам, как reg_max и end2end. Полная архитектура определена в файле конфигурации YAML модели.

Участники

Комментарии