Guia de configuração YAML do modelo#
O ficheiro de configuração YAML do modelo serve como projeto arquitetónico das redes neurais da Ultralytics. Define como as camadas se ligam, que parâmetros cada módulo utiliza e como toda a rede é dimensionada para diferentes tamanhos de modelo.
Estrutura da configuração#
Os ficheiros YAML do modelo estão organizados em três secções principais que, em conjunto, definem a arquitetura.
Secção de parâmetros#
A secção parameters especifica as características globais do modelo e o seu comportamento de dimensionamento:
# 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 onlyncdefine o número de classes que o modelo prevê.scalesdefine fatores de dimensionamento composto que ajustam a profundidade, a largura e o número máximo de canais do modelo para gerar variantes de diferentes tamanhos (de nano a extra-large).kpt_shapeaplica-se a modelos de pose. Pode ser[N, 2]para(x, y)pontos-chave ou[N, 3]para(x, y, visibility).
O parâmetro scales permite gerar vários tamanhos de modelo a partir de um único YAML base. Por exemplo, quando carregas yolo26n.yaml, a Ultralytics lê o yolo26.yaml base e aplica os fatores de dimensionamento n (depth=0.50, width=0.25) para criar a variante nano.
Se o teu conjunto de dados especificar um nc ou kpt_shape diferente, a Ultralytics substituirá automaticamente a configuração do modelo em tempo de execução para corresponder ao YAML do conjunto de dados.
Arquitetura do backbone e da head#
A arquitetura do modelo é composta pelas secções do backbone (extração de características) e da head (específica da tarefa):
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 layerOs índices das camadas continuam ao longo do backbone e da head, e os mapas de características concatenados têm de ter dimensões espaciais correspondentes.
Formato de especificação das camadas#
Todas as camadas seguem o mesmo padrão: [from, repeats, module, args]
| Componente | Finalidade | Exemplos |
|---|---|---|
| from | Ligações de entrada | -1 (anterior), 6 (camada 6), [4, 6, 8] (várias entradas) |
| repeats | Número de repetições | 1 (única), 3 (repetir 3 vezes) |
| module | Tipo de módulo | Conv, C2f, TorchVision, Detect |
| args | Argumentos do módulo | [64, 3, 2] (canais, kernel, stride) |
Padrões de ligação#
O campo from cria padrões flexíveis de fluxo de dados em toda a rede:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layerAs camadas são indexadas a partir de 0. Os índices negativos referenciam camadas anteriores (-1 = camada anterior), enquanto os índices positivos referenciam camadas específicas pela sua posição.
Repetição de módulos#
O parâmetro repeats cria secções mais profundas na rede:
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layerO número efetivo de repetições é multiplicado pelo fator de dimensionamento da profundidade definido na configuração do tamanho do modelo.
Módulos disponíveis#
Os módulos estão organizados por funcionalidade e definidos no diretório de módulos da Ultralytics. As tabelas seguintes mostram módulos frequentemente utilizados, organizados por categoria; há muitos outros disponíveis no código-fonte:
Operações básicas#
| Módulo | Finalidade | Fonte | Argumentos |
|---|---|---|---|
Conv | Convolução + BatchNorm + ativação | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample | Aumento da resolução espacial | PyTorch | [size, scale_factor, mode] |
nn.Identity | Operação de passagem direta | PyTorch | [] |
Blocos compostos#
| Módulo | Finalidade | Fonte | Argumentos |
|---|---|---|---|
C2f | Gargalo CSP com 2 convoluções | block.py | [out_ch, shortcut, groups, expansion] |
SPPF | Spatial Pyramid Pooling (rápido) | block.py | [out_ch, kernel_size] |
Concat | Concatenação ao longo dos canais | conv.py | [dimension] |
Módulos especializados#
| Módulo | Finalidade | Fonte | Argumentos |
|---|---|---|---|
TorchVision | Carregar qualquer modelo torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index | Extrair um tensor específico de uma lista | conv.py | [out_ch, index] |
Detect | Head de deteção YOLO | head.py | [nc] |
Isto representa um subconjunto dos módulos disponíveis. Para consultar a lista completa de módulos e respetivos parâmetros, explora o diretório de módulos.
Funcionalidades avançadas#
Integração com TorchVision#
O módulo TorchVision permite integrar facilmente qualquer modelo TorchVision como backbone:
from ultralytics import YOLO
# Modelo com backbone ConvNeXt
model = YOLO("convnext_backbone.yaml")
results = model.train(data="imagenet10", epochs=100)Define o último parâmetro como True para obter mapas de características intermédios para deteção multiescala.
Módulo Index para seleção de características#
Ao utilizar modelos que produzem vários mapas de características, o módulo Index seleciona saídas específicas:
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 detectionSistema de resolução de módulos#
Compreender como a Ultralytics localiza e importa módulos é essencial para a personalização:
Processo de pesquisa de módulos#
A Ultralytics utiliza um sistema de três níveis em parse_model:
# Lógica de resolução principal
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]
) # obter módulo- Módulos PyTorch: nomes que começam por
'nn.'→ espaço de nomestorch.nn - Operações TorchVision: nomes que começam por
'torchvision.ops.'→ espaço de nomestorchvision.ops - Módulos Ultralytics: todos os outros nomes → espaço de nomes global através de importações
Cadeia de importação de módulos#
Os módulos padrão ficam disponíveis através das importações em tasks.py:
from ultralytics.nn.modules import ( # noqa: F401
SPPF,
C2f,
Conv,
Detect,
# ... muitos outros módulos
Index,
TorchVision,
)Integração de módulos personalizados#
Modificação do código-fonte#
Modificar o código-fonte é a forma mais versátil de integrar os teus módulos personalizados, mas pode ser complicado. Para definir e utilizar um módulo personalizado, segue estes passos:
-
Instala a Ultralytics em modo de desenvolvimento utilizando o método de clonagem do Git indicado no guia de início rápido.
-
Define o teu módulo em
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) -
Expõe o teu módulo ao nível do pacote em
ultralytics/nn/modules/__init__.py:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock -
Adiciona-o às importações em
ultralytics/nn/tasks.py:from ultralytics.nn.modules import CustomBlock # noqa -
Adiciona o módulo a
base_modulesemparse_model(). Os módulos deste conjunto recebem automaticamente canais de entrada e saída:base_modules = frozenset( { # Módulos existentes... CustomBlock, } ) -
Utiliza o módulo no YAML do teu modelo:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]] -
Verifica os FLOPs para confirmar que a passagem direta funciona:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # deve imprimir um valor de FLOPs diferente de zero se estiver a funcionar
Exemplos de configuração#
Modelo básico de detecção#
# 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]] # 7Modelo com 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 detectionModelo de classificação#
# 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 já executa o pooling médio adaptativo internamente.
Práticas recomendadas#
Dicas de projeto de arquitetura#
Comece pelo simples: comece com arquiteturas comprovadas antes de personalizá-las. Use configurações YOLO existentes como modelos e faça alterações incrementais, em vez de criar tudo do zero.
Teste de forma incremental: valide cada alteração passo a passo. Adicione um módulo personalizado por vez e verifique se funciona antes de prosseguir para a próxima alteração.
Monitore os canais: garanta que as dimensões dos canais correspondam entre as camadas conectadas. Os canais de saída (c2) de uma camada devem corresponder aos canais de entrada (c1) da próxima camada na sequência.
Use conexões de atalho: aproveite a reutilização de características com padrões [[-1, N], 1, Concat, [1]]. Essas conexões ajudam no fluxo do gradiente e permitem que o modelo combine características de diferentes escalas.
Escolha a escala adequada: escolha as escalas do modelo com base nas suas restrições computacionais. Use nano (n) em dispositivos de borda, small (s) para um desempenho equilibrado e escalas maiores (m, l, x) para obter a máxima precisão.
Considerações de desempenho#
Profundidade vs. largura: redes profundas capturam características hierárquicas complexas por meio de várias camadas de transformação, enquanto redes largas processam mais informações em paralelo em cada camada. Equilibre esses aspectos com base na complexidade da sua tarefa.
Conexões de atalho: melhoram o fluxo do gradiente durante o treinamento e permitem a reutilização de características em toda a rede. Elas são especialmente importantes em arquiteturas mais profundas para evitar o desaparecimento do gradiente.
Blocos bottleneck: reduzem o custo computacional e mantêm a expressividade do modelo. Módulos como C2f usam menos parâmetros que convoluções padrão, preservando a capacidade de aprender características.
Características em múltiplas escalas: são essenciais para detectar objetos de diferentes tamanhos na mesma imagem. Use padrões de rede piramidal de características (FPN) com várias cabeças de detecção em diferentes escalas.
Solução de problemas#
Problemas comuns#
| Problema | Causa | Solução |
|---|---|---|
KeyError: 'ModuleName' | Módulo não importado | Adicione às importações de tasks.py |
| Incompatibilidade na dimensão dos canais | Especificação incorreta de args | Verifique a compatibilidade dos canais de entrada e saída |
AttributeError: 'int' object has no attribute | Tipo de argumento incorreto | Consulte a documentação do módulo para verificar os tipos de argumento corretos |
| Falha ao construir o modelo | Referência inválida a from | Verifique se as camadas referenciadas existem |
Dicas de depuração#
Ao desenvolver arquiteturas personalizadas, a depuração sistemática ajuda a identificar problemas desde o início:
Use uma cabeça de identidade para testar
Substitua cabeças complexas por nn.Identity para isolar problemas no backbone:
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debuggingIsso permite inspecionar diretamente as saídas do backbone:
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 dimensionsInspeção da arquitetura do modelo
Verificar a contagem de FLOPs e imprimir cada camada também pode ajudar a depurar problemas na configuração do modelo personalizado. A contagem de FLOPs deve ser diferente de zero para que o modelo seja válido. Se for zero, provavelmente há um problema na passagem direta. Executar uma passagem direta simples deve revelar o erro exato.
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}")Validação passo a passo
- Comece com o mínimo: teste primeiro a arquitetura mais simples possível
- Adicione gradualmente: aumente a complexidade camada por camada
- Verifique as dimensões: confirme a compatibilidade dos canais e dos tamanhos espaciais
- Valide o escalonamento: teste com diferentes escalas de modelo (
n,s,m)
Perguntas frequentes#
Defina o parâmetro
ncno início do arquivo YAML para corresponder ao número de classes do seu conjunto de dados.nc: 5 # 5 classesSim. Você pode usar qualquer módulo compatível, incluindo backbones TorchVision, ou definir seu próprio módulo personalizado e importá-lo conforme descrito em Integração de módulos personalizados.
Use a seção
scalesno YAML para definir fatores de escala para profundidade, largura e canais máximos. O modelo aplicará esses fatores automaticamente quando você carregar o arquivo YAML base com a escala adicionada ao nome do arquivo (por exemplo,yolo26n.yaml).Esse formato especifica como cada camada é construída:
from: origem ou origens da entradarepeats: número de vezes que o módulo será repetidomodule: tipo de camadaargs: argumentos do módulo
Verifique se os canais de saída de uma camada correspondem aos canais de entrada esperados pela próxima. Use
print(model.model.model)para inspecionar a arquitetura do seu modelo.Consulte o código-fonte no diretório
ultralytics/nn/modulespara ver todos os módulos disponíveis e seus argumentos.Defina seu módulo no código-fonte, importe-o conforme mostrado em Modificação do código-fonte e faça referência a ele pelo nome no arquivo YAML.
Sim, você pode usar
model.load("path/to/weights")para carregar pesos de um checkpoint pré-treinado. No entanto, somente os pesos das camadas correspondentes serão carregados com sucesso.Use
model.info()para verificar se a contagem de FLOPs é diferente de zero. Um modelo válido deve apresentar uma contagem de FLOPs diferente de zero. Se for zero, siga as sugestões em Dicas de depuração para encontrar o problema.