Объяснение архитектуры 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 свёртками, более быстрый») меняет то, какие признаки доходят до свёртки слияния:
cv1 = Conv(c1, 2 * c, 1), затемchunk(2)разделяет выходные данные на два тензора с числом каналовc.- Блоки
nBottleneck(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 используют 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 Conv→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), применяет softmax по бинам reg_max и принимает ожидаемый индекс бина — где каждый индекс бина взвешен по его вероятности softmax, а затем просуммирован — в качестве предсказанной координаты. Это реализовано как фиксированная свёртка 1x1, весами которой являются индексы бинов arange(reg_max), так что взвешенная сумма представляет собой единое скалярное произведение.
YOLO26: NMS-free, DFL-free#
YOLO26 задает два параметра YAML, которые голова читает напрямую:
end2end: True—Detectвыполняет глубокое копирование своих ветвей в голову «один к одному» (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 |
|---|---|---|---|---|---|
| YOLOv3 | Darknet-53 (Bottleneck) | нет в базовой конфигурации | нет | Исходный: на основе якорей (anchor-based); вариант u: бескориантный (anchor-free) | нет / да (u) |
| YOLOv5 | C3 (CSP) | SPPF | нет | Исходный: на основе якорей (anchor-based); вариант u: бескориантный (anchor-free) | нет / да (u) |
| YOLOv8 | C2f | SPPF | нет | Anchor-free, decoupled | да (reg_max=16) |
| YOLO11 | C3k2 | SPPF | C2PSA | Anchor-free, decoupled | да (reg_max=16) |
| YOLO26 | C3k2 | SPPF + шорткат | C2PSA | Бескориантная, без NMS (end2end) | удалена (reg_max=1) |
Сведения по конкретным моделям, таблицы производительности и примеры использования см. на отдельных страницах для YOLOv3, YOLOv5, YOLOv8, YOLO11 и YOLO26.
Изучите архитектуру самостоятельно#
Метод model.info() выводит сводку по слоям, параметрам и FLOPs, а разобранный список модулей доступен в model.model.model.
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, опубликованным на каждой странице модели:
| Модель | Слои | Параметры | GFLOPs | reg_max | end2end | Слой DFL |
|---|---|---|---|---|---|---|
| YOLOv8n | 72 | 3,151,904 | 8.7 | 16 | False | DFL |
| YOLO11n | 100 | 2,616,248 | 6.5 | 16 | False | DFL |
| YOLO26n | 122 | 2,408,932 | 5.4 | 1 | True | Identity |
YOLO26n сообщает об reg_max=1, end2end=True и слое DFL Identity — это архитектурная подпись ее головы, свободной от NMS и DFL.
Значения параметров и 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с регрессией DFLreg_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 модели.