Configuração do modelo YAML
O arquivo de configuração YAML do modelo serve como o projeto arquitetônico das redes neurais Ultralytics . Ele define como as camadas se conectam, quais parâmetros cada módulo usa e como a rede inteira é dimensionada em diferentes tamanhos de modelo.
Estrutura de configuração
Os ficheiros YAML do modelo estão organizados em três secções principais que funcionam em conjunto para definir a arquitetura.
Secção Parâmetros
A secção de parâmetros especifica as caraterísticas globais do modelo e o comportamento de escala:
# 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
define o número de classes que o modelo prevê.scales
definem factores de escala compostos que ajustam a profundidade, largura e canais máximos do modelo para produzir diferentes variantes de tamanho (nano a extra-grande).kpt_shape
aplica-se a modelos de pose. Pode ser[N, 2]
para(x, y)
pontos-chave ou[N, 3]
para(x, y, visibility)
.
Reduzir a redundância com scales
O scales
permite gerar vários tamanhos de modelo a partir de uma única base YAML. Por exemplo, quando você carrega o yolo11n.yaml
, Ultralytics lê a base yolo11.yaml
e aplica o n
factores de escala (depth=0.50
, width=0.25
) para construir a variante nano.
nc
e kpt_shape
são dependentes do conjunto de dados
Se o seu conjunto de dados especificar uma nc
ou kpt_shape
Ultralytics substituirá automaticamente a configuração do modelo em tempo de execução para corresponder ao conjunto de dados YAML.
Arquitetura do backbone e da cabeça
A arquitetura do modelo consiste em secções de base (extração de caraterísticas) e de cabeça (específica da tarefa):
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
Formato da especificação da camada
Todas as camadas seguem o mesmo padrão: [from, repeats, module, args]
Componente | Propósito | Exemplos |
---|---|---|
de | Ligações de entrada | -1 (anterior), 6 (camada 6), [4, 6, 8] (entradas múltiplas) |
repete | Número de repetições | 1 (individual), 3 (repetir 3 vezes) |
módulo | Tipo de módulo | Conv , C2f , TorchVision , Detect |
argumentos | Argumentos do módulo | [64, 3, 2] (canais, kernel, stride) |
Padrões de ligação
O from
cria padrões flexíveis de fluxo de dados em toda a sua rede:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layer
- [[-1, 6], 1, Concat, [1]] # Combines current layer with layer 6
- [[4, 6, 8], 1, Detect, [nc]] # Detection head using 3 feature scales
Indexação de camadas
As camadas são indexadas a partir de 0. Os índices negativos referem-se a camadas anteriores (-1
= camada anterior), enquanto os índices positivos referem camadas específicas pela sua posição.
Repetição de módulos
O 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 layer
A contagem real de repetições é multiplicada pelo fator de escala de profundidade da configuração do tamanho do modelo.
Módulos disponíveis
Os módulos são organizados por funcionalidade e definidos no diretório de módulosUltralytics . 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 | Propósito | Fonte | Argumentos |
---|---|---|---|
Conv |
Convolução + BatchNorm + Ativação | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample |
Amostragem espacial elevada | PyTorch | [size, scale_factor, mode] |
nn.Identity |
Operação de passagem | PyTorch | [] |
Blocos compostos
Módulo | Propósito | Fonte | Argumentos |
---|---|---|---|
C2f |
Gargalo do CSP com 2 convoluções | block.py | [out_ch, shortcut, expansion] |
SPPF |
Agrupamento de pirâmides espaciais (rápido) | block.py | [out_ch, kernel_size] |
Concat |
Concatenação por canal | conv.py | [dimension] |
Módulos especializados
Módulo | Propósito | Fonte | Argumentos |
---|---|---|---|
TorchVision |
Carregar qualquer modelo torchvision | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index |
Extrair um tensor específico da lista | block.py | [out_ch, index] |
Detect |
Cabeça de deteção YOLO | head.py | [nc, anchors, ch] |
Lista completa de módulos
Isto representa um subconjunto dos módulos disponíveis. Para obter a lista completa de módulos e respectivos parâmetros, explore o diretório de módulos.
Funcionalidades avançadas
Integração 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="coco8.yaml", epochs=100)
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, False]]
head:
- [-1, 1, Classify, [nc]]
Repartição dos parâmetros:
768
: Canais de saída previstosconvnext_tiny
: Arquitetura do modelo (modelos disponíveis)DEFAULT
: Utilizar pesos pré-treinadosTrue
: Remover a cabeça de classificação2
: Truncar as 2 últimas camadasFalse
: Devolver um tensor único (não uma lista)
Caraterísticas multi-escala
Definir o último parâmetro para True
para obter mapas de caraterísticas intermédios para a deteção multi-escala.
Módulo de índice para seleção de caraterísticas
Ao utilizar modelos que produzem vários mapas de caraterísticas, o módulo Index seleciona resultados específicos:
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
Sistema de resolução de módulos
Compreender como Ultralytics localiza e importa módulos é crucial para a personalização:
Processo de pesquisa de módulos
Ultralytics utiliza um sistema de três níveis em 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]
- Módulos PyTorch: Nomes começados por
'nn.'
→torch.nn
espaço de nome - Operações da TorchVision: Nomes começados por
'ops.'
→torchvision.ops
espaço de nome - MódulosUltralytics : Todos os outros nomes → espaço de nomes global através de importações
Cadeia de importação de módulos
Os módulos standard ficam disponíveis através de importações em tasks.py
:
from ultralytics.nn.modules import ( # noqa: F401, E501
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)
Integração de módulos personalizados
Modificação do código fonte
A modificação do código fonte é a forma mais versátil de integrar os seus módulos personalizados, mas pode ser complicada. Para definir e utilizar um módulo personalizado, siga estes passos:
-
Definir o seu módulo em
ultralytics/nn/modules/block.py
:class CustomBlock(nn.Module): def __init__(self, c1, c2): super().__init__() self.layers = nn.Sequential(nn.Conv2d(c1, c2, 3, 1, 1), nn.BatchNorm2d(c2), nn.ReLU()) def forward(self, x): return self.layers(x)
-
Exponha o seu 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
-
Adicionar às importações em
ultralytics/nn/tasks.py
:from ultralytics.nn.modules import CustomBlock # noqa
-
Tratar argumentos especiais (se necessário) no interior
parse_model()
emultralytics/nn/tasks.py
:elif m is CustomBlock: c1, c2 = ch[f], args[0] # input channels, output channels args = [c1, c2, *args[1:]]
-
Utilize o módulo no seu modelo YAML:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]]
-
Verificar os FLOPs para garantir que o passe para a frente 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]] # 7
Modelo TorchVision Backbone
# 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
Modelo 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]]
- [-1, 1, nn.AdaptiveAvgPool2d, [1]]
head:
- [-1, 1, Classify, [nc]]
Melhores práticas
Dicas de design de arquitetura
Comece com simplicidade: Comece com arquitecturas comprovadas antes de as personalizar. Utilize as configurações YOLO existentes como modelos e modifique-as gradualmente em vez de as construir de raiz.
Teste de forma incremental: 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 alteração seguinte.
Monitorizar canais: Assegurar a correspondência das dimensões dos canais entre as camadas ligadas. Os canais de saída (c2
) de uma camada deve corresponder aos canais de entrada (c1
) da camada seguinte da sequência.
Utilizar ligações de salto: Aproveitar a reutilização de funcionalidades com [[-1, N], 1, Concat, [1]]
padrões. Estas ligações ajudam o fluxo de gradiente e permitem que o modelo combine caraterísticas de diferentes escalas.
Dimensionar adequadamente: Escolha as escalas do modelo com base nas suas limitações computacionais. Utilizar nano (n
) para dispositivos periféricos, pequenos (s
) para um desempenho equilibrado, e escalas maiores (m
, l
, x
) para uma precisão máxima.
Considerações sobre o desempenho
Profundidade vs Largura: As redes profundas captam caraterísticas hierárquicas complexas através de várias camadas de transformação, enquanto as redes largas processam mais informações em paralelo em cada camada. Equilibre-os com base na complexidade da tarefa.
Ignorar conexões: Melhoram o fluxo de gradiente durante o treinamento e permitem a reutilização de recursos em toda a rede. São particularmente importantes em arquitecturas mais profundas para evitar o desaparecimento de gradientes.
Blocos de estrangulamento: Reduzir o custo computacional, mantendo a expressividade do modelo. Módulos como C2f
utilizam menos parâmetros do que as convoluções normais, preservando simultaneamente a capacidade de aprendizagem de caraterísticas.
Caraterísticas multi-escala: Essencial para a deteção de objectos de diferentes tamanhos na mesma imagem. Utilize padrões de Rede de Pirâmide de Caraterísticas (FPN) com várias cabeças de deteção a diferentes escalas.
Resolução de problemas
Problemas Comuns
Problema | Causa | Solução |
---|---|---|
KeyError: 'ModuleName' |
Módulo não importado | Adicionar a tasks.py importações |
Inadequação da dimensão do canal | Incorreto args especificação |
Verificar a compatibilidade dos canais de entrada/saída |
AttributeError: 'int' object has no attribute |
Tipo de argumento incorreto | Verificar a documentação do módulo para os tipos de argumentos corretos |
O modelo não constrói | Inválido from referência |
Assegurar a existência de camadas referenciadas |
Dicas de depuração
Ao desenvolver arquitecturas personalizadas, a depuração sistemática ajuda a identificar problemas numa fase inicial:
Utilizar o Identity Head para testar
Substituir cabeças complexas por nn.Identity
para isolar os problemas da espinha dorsal:
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debugging
Isto permite a inspeção direta das saídas da espinha dorsal:
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
Inspeção da arquitetura do modelo
Verificar a contagem de FLOPs e imprimir cada camada também pode ajudar a depurar problemas com sua configuração de modelo personalizado. A contagem de FLOPs deve ser diferente de zero para um modelo válido. Se for zero, é provável que haja um problema com a passagem para frente. A execução de uma simples passagem para a frente deve mostrar o erro exato que está sendo encontrado.
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}")
Validação passo a passo
- Comece pelo mínimo: Testar primeiro com a arquitetura mais simples possível
- Adicionar gradualmente: Construir a complexidade camada por camada
- Verificar as dimensões: Verificar a compatibilidade do tamanho do canal e do espaço
- Validar o escalonamento: Teste com diferentes escalas de modelos (
n
,s
,m
)
FAQ
Como é que altero o número de classes no meu modelo?
Definir o nc
no topo do seu ficheiro YAML para corresponder ao número de classes do seu conjunto de dados.
nc: 5 # 5 classes
Posso utilizar um backbone personalizado no meu modelo YAML?
Sim. Pode utilizar qualquer módulo suportado, incluindo os backbones TorchVision, ou definir o seu próprio módulo personalizado e importá-lo conforme descrito em Integração de módulos personalizados.
Como é que dimensiono o meu modelo para diferentes tamanhos (nano, pequeno, médio, etc.)?
Use o comando scales
seção no seu YAML para definir factores de escala para profundidade, largura e canais máximos. O modelo aplicá-los-á automaticamente quando carregar o ficheiro YAML de base com a escala anexada ao nome do ficheiro (por exemplo, yolo11n.yaml
).
O que é que o [from, repeats, module, args]
formato significa?
Este formato especifica a forma como cada camada é construída:
from
: fonte(s) de entradarepeats
: número de vezes a repetir o módulomodule
: o tipo de camadaargs
: argumentos para o módulo
Como é que resolvo os erros de incompatibilidade de canais?
Verifique se os canais de saída de uma camada correspondem aos canais de entrada esperados da camada seguinte. Utilizar print(model.model.model)
para inspecionar a arquitetura do seu modelo.
Onde posso encontrar uma lista dos módulos disponíveis e dos seus argumentos?
Verificar o código fonte no ultralytics/nn/modules
diretório para todos os módulos disponíveis e os seus argumentos.
Como é que adiciono um módulo personalizado à minha configuração YAML?
Defina seu módulo no código-fonte, importe-o como mostrado em Modificação do código-fonte e faça referência a ele pelo nome em seu arquivo YAML.
Posso utilizar pesos pré-treinados com um YAML personalizado?
Sim, pode utilizar model.load("path/to/weights")
para carregar pesos de um ponto de controlo pré-treinado. No entanto, apenas os pesos das camadas que correspondem seriam carregados com êxito.
Como posso validar a configuração do meu modelo?
Use model.info()
para verificar se a contagem de FLOPs é diferente de zero. Um modelo válido deve mostrar uma contagem de FLOPs diferente de zero. Se for zero, siga as sugestões em Dicas de depuração para encontrar o problema.