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

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

Model YAML configuration workflow.

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

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

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

Раздел parameters задает глобальные характеристики модели и принципы масштабирования:

# 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 применяется к моделям распознавания поз (pose). Оно может быть [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:
    # [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]] # 6: Upsample
    - [[-1, 2], 1, Concat, [1]] # 7: Skip connection
    - [-1, 3, C2f, [256]] # 8: Process features
    - [[8], 1, Detect, [nc]] # 9: Detection layer

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

Каждый слой следует стандартному шаблону: [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Пространственное апсемплинг (Upsampling)PyTorch[size, scale_factor, mode]
nn.IdentityОперация пропуска (Pass-through)PyTorch[]

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

МодульЦельИсточникАргументы
C2fCSP bottleneck с 2 сверткамиblock.py[out_ch, shortcut, expansion]
SPPFПространственное пирамидальное пулингование (быстрое)block.py[out_ch, kernel_size]
ConcatКонкатенация по каналамconv.py[dimension]

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

МодульЦельИсточникАргументы
TorchVisionЗагрузка любой модели torchvisionblock.py[out_ch, model_name, weights, unwrap, truncate, split]
IndexИзвлечение конкретного тензора из спискаblock.py[out_ch, index]
DetectГолова детекции YOLOhead.py[nc, anchors, ch]
Полный список модулей

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

Продвинутые функции

Интеграция TorchVision

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

from ultralytics import YOLO

# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="coco8.yaml", epochs=100)
Многомасштабные признаки

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

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

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

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 "nn." in m else getattr(torchvision.ops, m[4:]) if "ops." in m else globals()[m]
  1. PyTorch modules: Имена, начинающиеся с 'nn.' → пространство имен torch.nn
  2. TorchVision operations: Имена, начинающиеся с '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 clone из руководства по началу работы.

  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. Обработай специальные аргументы (если нужно) внутри parse_model() в файле ultralytics/nn/tasks.py:

    # Add this condition in the parse_model() function
    if m is CustomBlock:
        c1, c2 = ch[f], args[0]  # input channels, output channels
        args = [c1, c2, *args[1:]]
  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

Модель с бэкбоном 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]]
    - [-1, 1, nn.AdaptiveAvgPool2d, [1]]

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

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

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

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

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

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

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

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

Соображения по производительности

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

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

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

Мультимасштабные признаки: важны для обнаружения объектов разного размера на одном и том же изображении. Используй паттерны Feature Pyramid Network (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")
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", 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)

Часто задаваемые вопросы (FAQ)

Как мне изменить количество классов в модели?

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

nc: 5 # 5 classes

Могу ли я использовать пользовательский бэкбон в YAML-файле модели?

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

Как мне масштабировать свою модель для разных размеров (nano, small, medium и т.д.)?

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

Что означает формат [from, repeats, module, args]?

Этот формат определяет, как строится каждый слой:

  • from: входной источник(и)
  • repeats: количество повторений модуля
  • module: тип слоя
  • args: аргументы для модуля

Как мне устранить ошибки несоответствия каналов?

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

Где я могу найти список доступных модулей и их аргументов?

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

Как мне добавить пользовательский модуль в конфигурацию YAML?

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

Могу ли я использовать предобученные веса с пользовательским YAML?

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

Как мне валидировать конфигурацию модели?

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

Комментарии