Guia de configuração do YAML do modelo#
O ficheiro de configuração YAML do modelo serve como projeto arquitetónico das redes neuronais 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 e o comportamento de dimensionamento do modelo:
# 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 compostos que ajustam a profundidade, a largura e o número máximo de canais do modelo para produzir 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, ao carregar 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 da especificação das camadas#
Todas as camadas seguem o padrão consistente: [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 tua 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 de rede mais profundas:
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layerO número real de repetições é multiplicado pelo fator de dimensionamento da profundidade da configuração do tamanho do teu 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 os módulos mais utilizados por categoria, estando muitos outros disponíveis no código-fonte:
Operações básicas#
| Módulo | Finalidade | Origem | Argumentos |
|---|---|---|---|
Conv | Convolução + BatchNorm + Ativação | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample | Upsampling espacial | PyTorch | [size, scale_factor, mode] |
nn.Identity | Operação de passagem direta | PyTorch | [] |
Blocos compostos#
| Módulo | Finalidade | Origem | Argumentos |
|---|---|---|---|
C2f | Bottleneck 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 por canal | conv.py | [dimension] |
Módulos especializados#
| Módulo | Finalidade | Origem | 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 os respetivos parâmetros, explora o diretório de módulos.
Funcionalidades avançadas#
Integração com TorchVision#
O módulo TorchVision permite a integração perfeita de qualquer modelo TorchVision como backbone:
from ultralytics import YOLO
# Model with ConvNeXt backbone
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 é fundamental para a personalização:
Processo de pesquisa de módulos#
A Ultralytics utiliza um sistema de três níveis em 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- Módulos PyTorch: nomes que começam por
'nn.'→ namespacetorch.nn - Operações TorchVision: nomes que começam por
'torchvision.ops.'→ namespacetorchvision.ops - Módulos da Ultralytics: todos os outros nomes → namespace 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,
# ... many more modules
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 complexo. 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 do 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_modulesdentro deparse_model(). Os módulos deste conjunto recebem automaticamente os canais de entrada e saída:base_modules = frozenset( { # Existing modules... 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 garantir que a passagem forward funciona:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
Configurações de exemplo#
Modelo básico de deteçã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 internamente o average pooling adaptativo.
Boas práticas#
Dicas de design da arquitetura#
Comece de forma simples: Comece com arquiteturas comprovadas antes de personalizar. Use configurações YOLO existentes como modelos e faça modificações incrementais em vez de criar tudo do zero.
Teste incrementalmente: Valide cada modificação passo a passo. Adicione um módulo personalizado de cada vez e verifique se funciona antes de avançar 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 camada seguinte 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 dos gradientes e permitem que o modelo combine características de diferentes escalas.
Escale adequadamente: Escolha as escalas do modelo com base nas suas limitações computacionais. Use nano (n) para 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: As redes profundas capturam características hierárquicas complexas por meio de várias camadas de transformação, enquanto as redes largas processam mais informações em paralelo em cada camada. Equilibre esses fatores com base na complexidade da sua tarefa.
Conexões de atalho: Melhoram o fluxo dos gradientes durante o treinamento e permitem a reutilização de características em toda a rede. São particularmente importantes em arquiteturas mais profundas para evitar o desaparecimento dos gradientes.
Blocos de gargalo: Reduzem o custo computacional mantendo a capacidade expressiva do modelo. Módulos como C2f usam menos parâmetros do que as convoluções padrão, preservando a capacidade de aprendizagem de características.
Características multiescala: São essenciais para detetar objetos de diferentes tamanhos na mesma imagem. Use padrões de rede de pirâmide de características (FPN) com várias cabeças de deteção em diferentes escalas.
Resolução de problemas#
Problemas comuns#
| Problema | Causa | Solução |
|---|---|---|
KeyError: 'ModuleName' | Módulo não importado | Adicione às importações de tasks.py |
| Incompatibilidade nas dimensões 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 argumentos corretos |
| Falha ao criar o modelo | Referência inválida a from | Garanta que as camadas referenciadas existam |
Dicas de depuração#
Ao desenvolver arquiteturas personalizadas, uma depuração sistemática ajuda a identificar problemas antecipadamente:
Use uma cabeça de identidade para testes
Substitua as cabeças complexas por nn.Identity para isolar os problemas do 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 seu modelo personalizado. A contagem de FLOPs deve ser diferente de zero para um modelo válido. Se for zero, é provável que exista um problema na passagem direta. Executar uma passagem direta simples deve mostrar o erro exato que está a ocorrer.
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 pelo mínimo: Teste primeiro a arquitetura mais simples possível
- Adicione incrementalmente: Aumente a complexidade camada a camada
- Verifique as dimensões: Confirme a compatibilidade dos canais e do tamanho espacial
- Valide o escalonamento: Teste com diferentes escalas de modelo (
n,s,m)
Perguntas frequentes#
Defina o parâmetro
ncno início do seu ficheiro YAML para corresponder ao número de classes do seu conjunto de dados.nc: 5 # 5 classesSim. Pode usar qualquer módulo compatível, incluindo backbones TorchVision, ou definir o seu próprio módulo personalizado e importá-lo conforme descrito em Integração de módulos personalizados.
Use a secção
scalesno seu YAML para definir fatores de escala para a profundidade, a largura e o número máximo de canais. O modelo aplicará automaticamente esses fatores quando carregar o ficheiro YAML base com a escala adicionada ao nome do ficheiro (por exemplo,yolo26n.yaml).Este formato especifica como cada camada é construída:
from: origem da entradarepeats: número de vezes que o módulo deve 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 da camada seguinte. 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 os respetivos argumentos.Defina o 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 seu ficheiro YAML.
Sim, pode usar
model.load("path/to/weights")para carregar pesos de um checkpoint pré-treinado. No entanto, apenas 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.