Ultralytics YOLO27:

Руководство по конфигурации YAML модели#

Файл конфигурации YAML модели служит архитектурной схемой для нейронных сетей Ultralytics. В нём определяется, как соединяются слои, какие параметры использует каждый модуль и как вся сеть масштабируется для моделей разных размеров.

Model YAML configuration workflow.

Структура конфигурации#

Файлы YAML моделей организованы в три основных раздела, которые совместно определяют архитектуру.

Раздел параметров#

В разделе параметров указываются глобальные характеристики модели и параметры её масштабирования:

# Parameters
nc: 80 # number of classes
scales: # compound scaling constants [depth, width, max_channels]
    n: [0.50, 0.25, 1024] # nano: shallow layers, narrow channels
    s: [0.50, 0.50, 1024] # small: shallow depth, standard width
    m: [0.50, 1.00, 512] # medium: moderate depth, full width
    l: [1.00, 1.00, 512] # large: full depth and width
    x: [1.00, 1.50, 512] # extra-large: maximum performance
kpt_shape: [17, 3] # pose models only
  • nc задаёт количество классов, которые предсказывает модель.
  • scales задают составные коэффициенты масштабирования, которые регулируют глубину и ширину модели, а также максимальное количество каналов для создания вариантов разных размеров — от nano до extra-large.
  • kpt_shape применяется к моделям позы. Он может быть равен [N, 2] для (x, y) ключевых точек или [N, 3] для (x, y, visibility).
Сокращение дублирования с помощью `scales`

Параметр scales позволяет создавать модели разных размеров на основе одного базового YAML-файла. Например, при загрузке yolo26n.yaml Ultralytics считывает базовый файл yolo26.yaml и применяет коэффициенты масштабирования n (depth=0.50, width=0.25) для создания варианта nano.

`nc` и `kpt_shape` зависят от набора данных

Если в твоём наборе данных указаны другие nc или kpt_shape, Ultralytics автоматически переопределит конфигурацию модели во время выполнения в соответствии с YAML-файлом набора данных.

Архитектура backbone и head#

Архитектура модели состоит из разделов backbone (извлечение признаков) и head (для конкретной задачи):

nc: 80

backbone:
    # [from, repeats, module, args]
    - [-1, 1, Conv, [64, 3, 2]] # 0: Initial convolution
    - [-1, 1, Conv, [128, 3, 2]] # 1: Downsample
    - [-1, 3, C2f, [128, True]] # 2: Feature processing

head:
    - [-1, 1, nn.Upsample, [None, 2, nearest]] # 3: Upsample
    - [[-1, 0], 1, Concat, [1]] # 4: Spatially compatible skip connection
    - [-1, 3, C2f, [256]] # 5: Process features
    - [[5], 1, Detect, [nc]] # 6: Detection layer

Индексы слоёв продолжаются от backbone к head, а объединяемые карты признаков должны иметь одинаковые пространственные размеры.

Формат спецификации слоя#

Каждый слой соответствует единому шаблону: [from, repeats, module, args]

КомпонентНазначениеПримеры
fromВходные соединения-1 (предыдущий), 6 (слой 6), [4, 6, 8] (несколько входов)
repeatsКоличество повторений1 (однократно), 3 (повторить 3 раза)
moduleТип модуляConv, C2f, TorchVision, Detect
argsАргументы модуля[64, 3, 2] (каналы, ядро, шаг)

Шаблоны соединений#

Поле from создаёт гибкие шаблоны передачи данных во всей твоей сети:

- [-1, 1, Conv, [64, 3, 2]]    # Takes input from previous layer
Индексация слоёв

Индексация слоёв начинается с 0. Отрицательные индексы ссылаются на предыдущие слои (-1 = предыдущий слой), а положительные индексы — на определённые слои по их позиции.

Повторение модулей#

Параметр repeats создаёт более глубокие секции сети:

- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layer

Фактическое количество повторений умножается на коэффициент масштабирования глубины из конфигурации размера твоей модели.

Доступные модули#

Модули организованы по функциональности и определены в каталоге модулей Ultralytics. В следующих таблицах приведены часто используемые модули по категориям; многие другие доступны в исходном коде:

Базовые операции#

МодульНазначениеИсточникАргументы
ConvСвёртка + BatchNorm + активацияconv.py[out_ch, kernel, stride, pad, groups]
nn.UpsampleПространственное увеличение разрешенияPyTorch[size, scale_factor, mode]
nn.IdentityОперация сквозной передачиPyTorch[]

Составные блоки#

МодульНазначениеИсточникАргументы
C2fБутылочное горлышко CSP с двумя свёрткамиblock.py[out_ch, shortcut, groups, expansion]
SPPFПространственное пирамидальное объединение (быстрое)block.py[out_ch, kernel_size]
ConcatКонкатенация по каналамconv.py[dimension]

Специализированные модули#

МодульНазначениеИсточникАргументы
TorchVisionЗагрузка любой модели torchvisionblock.py[out_ch, model_name, weights, unwrap, truncate, split]
IndexИзвлечение определённого тензора из спискаconv.py[out_ch, index]
DetectHead детектирования YOLOhead.py[nc]
Полный список модулей

Здесь представлен лишь набор доступных модулей. Полный список модулей и их параметров можно найти в каталоге модулей.

Расширенные возможности#

Интеграция с TorchVision#

Модуль TorchVision обеспечивает удобную интеграцию любой модели TorchVision в качестве backbone:

from ultralytics import YOLO

# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="imagenet10", epochs=100)
Признаки разных масштабов

Задай последний параметр равным True, чтобы получить промежуточные карты признаков для детектирования в нескольких масштабах.

Модуль Index для выбора признаков#

При использовании моделей, выдающих несколько карт признаков, модуль Index выбирает определённые выходные данные:

nc: 80

backbone:
    - [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]] # Multi-output
head:
    - [0, 1, Index, [192, 4]] # Select 4th feature map (192 channels)
    - [0, 1, Index, [384, 6]] # Select 6th feature map (384 channels)
    - [0, 1, Index, [768, 8]] # Select 8th feature map (768 channels)
    - [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detection

Система разрешения модулей#

Понимание того, как Ultralytics находит и импортирует модули, крайне важно для кастомизации:

Процесс поиска модулей#

Ultralytics использует трёхуровневую систему в parse_model:

# Core resolution logic
m = (
    getattr(torch.nn, m[3:])
    if m.startswith("nn.")
    else getattr(__import__("torchvision").ops, m[16:])
    if m.startswith("torchvision.ops.")
    else globals()[m]
)  # get module
  1. Модули PyTorch: имена, начинающиеся с 'nn.' → пространство имён torch.nn
  2. Операции TorchVision: имена, начинающиеся с 'torchvision.ops.' → пространство имён torchvision.ops
  3. Модули Ultralytics: все остальные имена → глобальное пространство имён через импорты

Цепочка импорта модулей#

Стандартные модули становятся доступными через импорты в tasks.py:

from ultralytics.nn.modules import (  # noqa: F401
    SPPF,
    C2f,
    Conv,
    Detect,
    # ... many more modules
    Index,
    TorchVision,
)

Интеграция пользовательских модулей#

Изменение исходного кода#

Изменение исходного кода — наиболее универсальный способ интеграции пользовательских модулей, но он может быть непростым. Чтобы определить и использовать пользовательский модуль, выполни следующие шаги:

  1. Установи Ultralytics в режиме разработки, клонировав Git-репозиторий по инструкции из руководства по быстрому старту.

  2. Определи свой модуль в ultralytics/nn/modules/block.py:

    class CustomBlock(nn.Module):
        """Custom block with Conv-BatchNorm-ReLU sequence."""
    
        def __init__(self, c1, c2):
            """Initialize CustomBlock with input and output channels."""
            super().__init__()
            self.layers = nn.Sequential(nn.Conv2d(c1, c2, 3, 1, 1), nn.BatchNorm2d(c2), nn.ReLU())
    
        def forward(self, x):
            """Forward pass through the block."""
            return self.layers(x)
  3. Сделай свой модуль доступным на уровне пакета в ultralytics/nn/modules/__init__.py:

    from .block import CustomBlock  # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock
  4. Добавь его в импорты в ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
  5. Добавь модуль в base_modules внутри parse_model(). Модули в этом наборе автоматически получают входное и выходное количество каналов:

    base_modules = frozenset(
        {
            # Existing modules...
            CustomBlock,
        }
    )
  6. Используй модуль в YAML-файле модели:

    # custom_model.yaml
    nc: 1
    backbone:
        - [-1, 1, CustomBlock, [64]]
    head:
        - [-1, 1, Classify, [nc]]
  7. Проверь FLOPs, чтобы убедиться в корректной работе прямого прохода:

    from ultralytics import YOLO
    
    model = YOLO("custom_model.yaml", task="classify")
    model.info()  # should print non-zero FLOPs if working

Примеры конфигураций#

Базовая модель детектирования#

# Simple YOLO detection model
nc: 80
scales:
    n: [0.33, 0.25, 1024]

backbone:
    - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
    - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
    - [-1, 3, C2f, [128, True]] # 2
    - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
    - [-1, 6, C2f, [256, True]] # 4
    - [-1, 1, SPPF, [256, 5]] # 5

head:
    - [-1, 1, Conv, [256, 3, 1]] # 6
    - [[6], 1, Detect, [nc]] # 7

Модель с backbone TorchVision#

# ConvNeXt backbone with YOLO head
nc: 80

backbone:
    - [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]]

head:
    - [0, 1, Index, [192, 4]] # P3 features
    - [0, 1, Index, [384, 6]] # P4 features
    - [0, 1, Index, [768, 8]] # P5 features
    - [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detection

Модель классификации#

# Simple classification model
nc: 1000

backbone:
    - [-1, 1, Conv, [64, 7, 2, 3]]
    - [-1, 1, nn.MaxPool2d, [3, 2, 1]]
    - [-1, 4, C2f, [64, True]]
    - [-1, 1, Conv, [128, 3, 2]]
    - [-1, 8, C2f, [128, True]]

head:
    - [-1, 1, Classify, [nc]]

Classify уже выполняет адаптивное усредняющее объединение внутри себя.

Рекомендации#

Советы по проектированию архитектуры#

Начинай с простого: начни с проверенных архитектур, прежде чем переходить к настройке. Используй существующие конфигурации YOLO как шаблоны и вноси изменения постепенно, вместо того чтобы создавать всё с нуля.

Тестируй постепенно: проверяй каждое изменение шаг за шагом. Добавляй по одному пользовательскому модулю и убеждайся, что он работает, прежде чем переходить к следующему изменению.

Следи за каналами: убедись, что размерности каналов совпадают между соединёнными слоями. Выходные каналы (c2) одного слоя должны соответствовать входным каналам (c1) следующего слоя в последовательности.

Используй пропускающие соединения: задействуй повторное использование признаков с помощью шаблонов [[-1, N], 1, Concat, [1]]. Эти соединения улучшают прохождение градиента и позволяют модели объединять признаки с разных масштабов.

Правильно выбирай масштаб: выбирай масштаб модели с учётом доступных вычислительных ресурсов. Используй nano (n) для периферийных устройств, small (s) для сбалансированной производительности, а крупные масштабы (m, l, x) — для максимальной точности.

Особенности производительности#

Глубина и ширина: глубокие сети извлекают сложные иерархические признаки через несколько слоёв преобразования, а широкие сети обрабатывают больше информации параллельно на каждом слое. Выбирай баланс с учётом сложности задачи.

Пропускающие соединения: улучшают прохождение градиента во время обучения и обеспечивают повторное использование признаков во всей сети. Они особенно важны в глубоких архитектурах, поскольку помогают предотвращать исчезновение градиентов.

Блоки-узкие места: снижают вычислительные затраты, сохраняя выразительность модели. Такие модули, как C2f, используют меньше параметров, чем стандартные свёртки, сохраняя способность извлекать признаки.

Многоуровневые признаки: необходимы для обнаружения объектов разных размеров на одном изображении. Используй шаблоны пирамидальной сети признаков (FPN) с несколькими головами обнаружения на разных масштабах.

Устранение неполадок#

Распространённые проблемы#

ПроблемаПричинаРешение
KeyError: 'ModuleName'Модуль не импортированДобавь модуль в импорты tasks.py
Несовпадение размерностей каналовНеверное задание argsПроверь совместимость входных и выходных каналов
AttributeError: 'int' object has no attributeНеверный тип аргументаПроверь документацию модуля, чтобы узнать правильные типы аргументов
Не удалось собрать модельНедопустимая ссылка fromУбедись, что указанные слои существуют

Советы по отладке#

При разработке пользовательских архитектур систематическая отладка помогает выявлять проблемы на раннем этапе:

Используй Identity Head для тестирования

Замени сложные головы на nn.Identity, чтобы изолировать проблемы бэкбона:

nc: 1
backbone:
    - [-1, 1, CustomBlock, [64]]
head:
    - [-1, 1, nn.Identity, []] # Pass-through for debugging

Это позволяет напрямую проверить выходы бэкбона:

import torch

from ultralytics import YOLO

model = YOLO("debug_model.yaml", task="detect")
output = model.model(torch.randn(1, 3, 640, 640))
print(f"Output shape: {output.shape}")  # Should match expected dimensions

Проверка архитектуры модели

Проверка количества FLOPs и вывод каждого слоя также могут помочь отладить проблемы в конфигурации пользовательской модели. Для корректной модели количество FLOPs должно быть ненулевым. Если оно равно нулю, вероятно, проблема связана с прямым проходом. Запуск простого прямого прохода должен показать точную возникшую ошибку.

from ultralytics import YOLO

# Build model with verbose output to see layer details
model = YOLO("debug_model.yaml", task="detect", verbose=True)

# Check model FLOPs. Failed forward pass causes 0 FLOPs.
model.info()

# Inspect individual layers
for i, layer in enumerate(model.model.model):
    print(f"Layer {i}: {layer}")

Проверка шаг за шагом

  1. Начни с минимума: сначала протестируй максимально простую архитектуру
  2. Добавляй постепенно: наращивай сложность слой за слоем
  3. Проверяй размерности: проверь совместимость каналов и пространственных размеров
  4. Проверяй масштабирование: протестируй разные масштабы модели (n, s, m)

Часто задаваемые вопросы#

  • Установи параметр nc в верхней части YAML-файла в соответствии с количеством классов в датасете.

    nc: 5 # 5 classes
  • Да. Можно использовать любой поддерживаемый модуль, включая бэкбоны TorchVision, либо определить собственный пользовательский модуль и импортировать его, как описано в разделе Интеграция пользовательского модуля.

  • Используй scales section в YAML-файле, чтобы задать коэффициенты масштабирования глубины, ширины и максимального количества каналов. Модель автоматически применит их при загрузке базового YAML-файла с масштабом, добавленным к имени файла (например, yolo26n.yaml).

  • Этот формат определяет способ построения каждого слоя:

    • from: источник входных данных
    • repeats: количество повторений модуля
    • module: тип слоя
    • args: аргументы модуля
  • Проверь, что выходные каналы одного слоя соответствуют ожидаемым входным каналам следующего. Используй print(model.model.model), чтобы проверить архитектуру модели.

  • Проверь исходный код в каталоге ultralytics/nn/modules, где перечислены все доступные модули и их аргументы.

  • Определи модуль в исходном коде, импортируй его, как показано в разделе Изменение исходного кода, и укажи его имя в YAML-файле.

  • Да, можно использовать model.load("path/to/weights") для загрузки весов из предварительно обученной контрольной точки. Однако успешно загрузятся только веса слоёв, которые совпадают.

  • Используй model.info(), чтобы проверить, что количество FLOPs ненулевое. У корректной модели количество FLOPs должно быть ненулевым. Если оно равно нулю, воспользуйся рекомендациями из раздела Советы по отладке, чтобы найти проблему.

Комментарии