Руководство по конфигурации YAML моделей#
Файл конфигурации YAML модели служит архитектурным планом для нейронных сетей Ultralytics. Он определяет, как соединяются слои, какие параметры использует каждый модуль и как вся сеть масштабируется для моделей разного размера.
Структура конфигурации#
Файлы 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 onlyncзадает количество классов, которые предсказывает модель.scalesопределяет коэффициенты составного масштабирования, которые изменяют глубину, ширину и максимальное число каналов модели для создания вариантов разного размера (от nano до extra-large).kpt_shapeприменяется к моделям pose. Это может быть[N, 2]для(x, y)точек ключевых точек или[N, 3]для(x, y, visibility).
Параметр scales позволяет генерировать модели разного размера из одного базового YAML-файла. Например, когда ты загружаешь yolo26n.yaml, Ultralytics читает базовый yolo26.yaml и применяет коэффициенты масштабирования n (depth=0.50, width=0.25) для сборки варианта nano.
Если в твоем наборе данных указано другое значение nc или kpt_shape, Ultralytics автоматически переопределит конфигурацию модели во время выполнения в соответствии с YAML-файлом датасета.
Архитектура бэкенда и головы#
Архитектура модели состоит из разделов 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Индексы слоев продолжаются по всему бэкбону и голове, а конкатенированные карты признаков должны иметь совпадающие пространственные размерности.
Формат спецификации слоев#
Каждый слой следует единому шаблону: [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 | Операция пропуска (Pass-through) | PyTorch | [] |
Составные блоки#
| Модуль | Цель | Источник | Аргументы |
|---|---|---|---|
C2f | CSP bottleneck с 2 свертками | block.py | [out_ch, shortcut, groups, expansion] |
SPPF | Пространственное пирамидальное объединение (быстрое) | block.py | [out_ch, kernel_size] |
Concat | Конкатенация по каналам | conv.py | [dimension] |
Специализированные модули#
| Модуль | Цель | Источник | Аргументы |
|---|---|---|---|
TorchVision | Загрузка любой модели torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | Извлечение конкретного тензора из списка | conv.py | [out_ch, index] |
Detect | Голова детекции YOLO | head.py | [nc] |
Здесь представлена лишь часть доступных модулей. Полный список модулей и их параметров можно найти в каталоге модулей.
Расширенные возможности#
Интеграция с TorchVision#
Модуль TorchVision обеспечивает бесшовную интеграцию любой модели TorchVision в качестве бэкбона:
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- Модули PyTorch: Имена, начинающиеся с
'nn.'→ пространство именtorch.nn - Операции TorchVision: Имена, начинающиеся с
'torchvision.ops.'→ пространство именtorchvision.ops - Модули Ultralytics: все остальные имена → глобальное пространство имен через импорт
Цепочка импорта модулей#
Стандартные модули становятся доступными через импорт в tasks.py:
from ultralytics.nn.modules import ( # noqa: F401
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)Интеграция пользовательских модулей#
Модификация исходного кода#
Модификация исходного кода — самый универсальный способ интеграции твоих пользовательских модулей, но это может быть непросто. Чтобы определить и использовать собственный модуль, выполни следующие шаги:
-
Установи Ultralytics в режиме разработчика, используя метод клонирования через Git из руководства по быстрому старту.
-
Определи свой модуль в
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) -
Экспортируй свой модуль на уровне пакета в
ultralytics/nn/modules/__init__.py:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock -
Добавь в импорты в
ultralytics/nn/tasks.py:from ultralytics.nn.modules import CustomBlock # noqa -
Добавь модуль в
base_modulesвнутриparse_model(). Модули в этом наборе автоматически получают входные и выходные каналы:base_modules = frozenset( { # Existing modules... CustomBlock, } ) -
Используй модуль в своем YAML-файле модели:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]] -
Проверь 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]]
head:
- [-1, 1, Classify, [nc]]Classify уже выполняет адаптивный пулинг среднего внутри себя.
Лучшие практики#
Советы по проектированию архитектуры#
Начни с простого: сначала используй проверенные архитектуры, прежде чем вносить изменения. Возьми существующие конфигурации YOLO в качестве шаблонов и изменяй их постепенно, а не строй с нуля.
Тестируй итеративно: проверяй каждое изменение шаг за шагом. Добавляй по одному пользовательскому модулю за раз и убедись, что он работает, прежде чем переходить к следующему изменению.
Следи за каналами: Убедись, что размерности каналов совпадают между соединенными слоями. Выходные каналы (c2) одного слоя должны совпадать с входными каналами (c1) следующего слоя в последовательности.
Используй пропускные соединения (skip connections): Задействуй повторное использование признаков с помощью шаблонов [[-1, N], 1, Concat, [1]]. Эти соединения помогают градиентному потоку и позволяют модели объединять признаки из разных масштабов.
Масштабируй правильно: Выбирай масштабы модели исходя из вычислительных ограничений. Используй nano (n) для периферийных устройств (edge), small (s) для сбалансированной производительности и большие масштабы (m, l, x) для максимальной точности.
Вопросы производительности#
Глубина против ширины: глубокие сети захватывают сложные иерархические признаки через множество слоев трансформации, в то время как широкие сети обрабатывают больше информации параллельно на каждом слое. Балансируй эти параметры в зависимости от сложности твоей задачи.
Пропускные соединения (skip connections): улучшают протекание градиентов во время обучения и обеспечивают повторное использование признаков по всей сети. Они особенно важны в глубоких архитектурах для предотвращения исчезновения градиентов.
Блоки «бутылочного горлышка» (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", 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}")Пошаговая проверка
- Начни с минимума: сначала протестируй с простейшей архитектурой
- Добавляй итеративно: наращивай сложность слой за слоем
- Проверь размерности: убедись в совместимости каналов и пространственных размеров
- Проверяй масштабирование: Тестируй с разными масштабами модели (
n,s,m)
FAQ#
Установи параметр
ncв начале твоего YAML-файла так, чтобы он соответствовал количеству классов в твоем датасете.nc: 5 # 5 classesДа. Ты можешь использовать любой поддерживаемый модуль, включая бэкбоны TorchVision, или определить собственный пользовательский модуль и импортировать его, как описано в разделе Интеграция пользовательских модулей.
Используй раздел
scalesв своем YAML для определения коэффициентов масштабирования глубины, ширины и максимального числа каналов. Модель применит их автоматически, когда ты загрузишь базовый YAML-файл с добавленным к имени файла масштабом (например,yolo26n.yaml).Этот формат определяет, как строится каждый слой:
from: входной источник (-ы)repeats: количество повторений модуляmodule: тип слояargs: аргументы для модуля
Убедись, что выходные каналы одного слоя соответствуют ожидаемым входным каналам следующего. Используй
print(model.model.model)для инспекции архитектуры твоей модели.Проверь исходный код в каталоге
ultralytics/nn/modules, чтобы узнать все доступные модули и их аргументы.Определи свой модуль в исходном коде, импортируй его, как показано в разделе Модификация исходного кода, и ссылайся на него по имени в своем YAML-файле.
Да, ты можешь использовать
model.load("path/to/weights")для загрузки весов из предобученной контрольной точки. Однако успешно загрузятся только веса для совпадающих слоев.Используй
model.info(), чтобы проверить, не равен ли нулю счетчик FLOP. Корректная модель должна показывать ненулевое число FLOP. Если оно равно нулю, следуй советам из раздела Советы по отладке, чтобы найти проблему.