Ir para o conteúdo

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_shapeUltralytics 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 previstos
  • convnext_tiny: Arquitetura do modelo (modelos disponíveis)
  • DEFAULT: Utilizar pesos pré-treinados
  • True: Remover a cabeça de classificação
  • 2: Truncar as 2 últimas camadas
  • False: 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]
  1. Módulos PyTorch: Nomes começados por 'nn.'torch.nn espaço de nome
  2. Operações da TorchVision: Nomes começados por 'ops.'torchvision.ops espaço de nome
  3. 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:

  1. 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)
    
  2. 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
    
  3. Adicionar às importações em ultralytics/nn/tasks.py:

    from ultralytics.nn.modules import CustomBlock  # noqa
    
  4. Tratar argumentos especiais (se necessário) no interior parse_model() em ultralytics/nn/tasks.py:

    elif m is CustomBlock:
        c1, c2 = ch[f], args[0]  # input channels, output channels
        args = [c1, c2, *args[1:]]
    
  5. Utilize o módulo no seu modelo YAML:

    # custom_model.yaml
    nc: 1
    backbone:
        - [-1, 1, CustomBlock, [64]]
    head:
        - [-1, 1, Classify, [nc]]
    
  6. 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

  1. Comece pelo mínimo: Testar primeiro com a arquitetura mais simples possível
  2. Adicionar gradualmente: Construir a complexidade camada por camada
  3. Verificar as dimensões: Verificar a compatibilidade do tamanho do canal e do espaço
  4. 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 entrada
  • repeats: número de vezes a repetir o módulo
  • module: o tipo de camada
  • args: 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.



📅 Criado há 0 dias ✏️ Atualizado há 0 dias