Como fazer o ajuste fino de YOLO num conjunto de dados personalizado#
O ajuste fino adapta um modelo pré-treinado para reconhecer novas classes, partindo de pesos aprendidos em vez de uma inicialização aleatória. Em vez de treinar do zero durante centenas de épocas, o ajuste fino aproveita as características pré-treinadas do COCO e converge nos dados personalizados numa fração do tempo.
Este guia aborda o ajuste fino de YOLO26 em conjuntos de dados personalizados, desde a utilização básica até técnicas avançadas, como o congelamento de camadas e o treino em duas fases.
Ajuste fino vs. treino do zero#
Um modelo pré-treinado já aprendeu características visuais gerais — deteção de contornos, reconhecimento de texturas e compreensão de formas — a partir de milhões de imagens. A aprendizagem por transferência através do ajuste fino reutiliza esse conhecimento e ensina ao modelo apenas o aspeto das novas classes, razão pela qual converge mais rapidamente e requer menos dados. O treino do zero descarta tudo isso e obriga o modelo a aprender tudo a partir de padrões ao nível dos píxeis, exigindo significativamente mais recursos. Consulta o Guia de configuração YAML do modelo para saberes em que diferem os ficheiros .yaml que contêm apenas a arquitetura dos checkpoints.
| Fine-tuning | Treino do zero | |
|---|---|---|
| Pesos iniciais | Pré-treinado no COCO (80 classes) | Inicialização aleatória |
| Comando | YOLO("yolo26n.pt") | YOLO("yolo26n.yaml") |
| Convergência | Mais rápida — o backbone já está treinado | Mais lenta — todas as camadas aprendem do zero |
| Requisitos de dados | Menores — as características pré-treinadas compensam a menor quantidade de dados | Maiores — o modelo tem de aprender todas as características apenas a partir do conjunto de dados |
| Quando utilizar | Classes personalizadas com imagens naturais | Domínios fundamentalmente diferentes do COCO (médico, satélite, radar) |
Quando um ficheiro .pt é carregado com YOLO("yolo26n.pt"), os pesos pré-treinados são armazenados no modelo. Chamar .train(data="custom.yaml") depois disso transfere automaticamente todos os pesos compatíveis para a nova arquitetura do modelo, reinicializa as camadas que não correspondem (como a cabeça de deteção quando o número de classes é diferente) e inicia o treino. Não é necessário carregar pesos manualmente, manipular camadas nem escrever código personalizado de aprendizagem por transferência.
Como funciona a transferência de pesos pré-treinados#
Quando um modelo pré-treinado é ajustado num conjunto de dados com um número de classes diferente (por exemplo, das 80 classes do COCO para 5 classes personalizadas), a Ultralytics realiza uma transferência de pesos com análise das formas:
- Transferência completa do backbone e do neck — estas camadas extraem características visuais gerais e as suas formas são independentes do número de classes.
- A cabeça de deteção é parcialmente reinicializada — as camadas de saída da classificação (
cv3,one2one_cv3) têm formas associadas ao número de classes (80 vs. 5). As linhas compatíveis cujos nomes de classe coincidem são remapeadas antes de as linhas não correspondentes serem inicializadas. As camadas de regressão de caixas (cv2,one2one_cv2) na cabeça têm formas fixas, independentemente do número de classes, pelo que são transferidas normalmente. - A grande maioria dos pesos é transferida quando o número de classes muda. Por exemplo, ao ajustar o YOLO26n do COCO (80 classes) num conjunto de dados com 5 classes, são transferidos 606 dos 708 tensores de pesos, além de quaisquer linhas de classificação compatíveis correspondentes por nome.
Para conjuntos de dados com o mesmo número de classes que o modelo pré-treinado (por exemplo, ao ajustar pesos pré-treinados no COCO noutro conjunto de dados com 80 classes), 100% dos pesos são transferidos, incluindo a cabeça de deteção.
Transferir classes com aliases de nomes#
A Ultralytics transfere linhas correspondentes da cabeça de classificação pelo nome da classe entre conjuntos de dados, ignorando maiúsculas e minúsculas e os espaços em branco circundantes. Quando classes equivalentes utilizam nomes diferentes, muda o nome das classes do checkpoint de origem em memória antes do carregamento. Isto preserva os pesos de classificação pré-treinados para conceitos partilhados que, de outro modo, seriam tratados como não correspondentes e inicializados aleatoriamente.
Este exemplo de Objects365 v2 para COCO muda o nome das classes de origem no checkpoint carregado, que train() passa depois como pesos pré-treinados:
from ultralytics import YOLO
# Source Objects365 v2 name (lowercased) -> target COCO name
ALIASES = {
"wild bird": "bird",
"handbag/satchel": "handbag",
"luggage": "suitcase",
"bowl/basin": "bowl",
"orange/tangerine": "orange",
"monitor/tv": "tv",
"stuffed toy": "teddy bear",
"hair dryer": "hair drier",
}
model = YOLO("path/to/yolo26s-objects365.pt")
# Objects365 class names are Title-Cased, so match on the lowercased name
model.model.names = {i: ALIASES.get(name.lower(), name) for i, name in model.model.names.items()}
model.train(data="coco.yaml", epochs=100, imgsz=640)A definição cls_remap ativa esta transferência baseada no nome por predefinição. O treino apresenta Remapped N/M cls head rows from pretrained weights by class name quando as linhas compatíveis são copiadas; define cls_remap=False para a desativar.
Exemplo básico de ajuste fino#
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # load pretrained model
model.train(data="custom.yaml", epochs=50, imgsz=640)Escolher o tamanho do modelo#
Os modelos maiores têm mais capacidade, mas também mais parâmetros para atualizar, o que pode aumentar o risco de sobreajuste quando os dados de treino são limitados. Começar com um modelo mais pequeno (YOLO26n ou YOLO26s) e aumentar o tamanho apenas se as métricas de validação estabilizarem é uma abordagem prática. O tamanho ideal do modelo depende da complexidade da tarefa, do número de classes, da diversidade do conjunto de dados e do hardware disponível para a implementação. Consulta a página completa do modelo YOLO26 para veres os tamanhos disponíveis e os benchmarks de desempenho.
Seleção do otimizador e da taxa de aprendizagem#
A definição optimizer=auto predefinida seleciona o otimizador e a taxa de aprendizagem com base no número total de iterações de treino:
- 10 000 iterações ou menos (conjuntos de dados pequenos ou poucas épocas): AdamW com uma taxa de aprendizagem baixa, calculada automaticamente
- Mais de 10 000 iterações (conjuntos de dados grandes): MuSGD (um otimizador híbrido Muon+SGD) com lr=0.01
Para a maioria das tarefas de ajuste fino, a definição predefinida funciona bem sem qualquer afinação manual. Considera definir explicitamente o otimizador quando:
- O treino é instável (a perda apresenta picos ou diverge): experimenta
optimizer=AdamW, lr0=0.001para obter uma convergência mais estável - Ajuste fino de um modelo grande num conjunto de dados pequeno: um otimizador explícito com uma taxa de aprendizagem mais baixa, como
optimizer=AdamW, lr0=0.001, pode ajudar a preservar as características pré-treinadas
Quando optimizer=auto, os valores lr0 e momentum são ignorados. Para controlar manualmente a taxa de aprendizagem, define explicitamente o otimizador: optimizer=SGD, lr0=0.005.
Congelar camadas#
O congelamento impede que camadas específicas sejam atualizadas durante o treino. Isto acelera o treino e reduz o sobreajuste quando o conjunto de dados é pequeno em relação à capacidade do modelo.
O parâmetro freeze aceita um número inteiro ou uma lista. Um número inteiro freeze=10 congela as primeiras 10 camadas (índices 0-9), que abrangem a maior parte do backbone do YOLO26. O backbone estende-se pelas camadas 0-10, pelo que freeze=10 deixa o bloco C2PSA final (camada 10) treinável; usa freeze=11 para congelar todo o backbone. Uma lista pode conter índices de camadas, como freeze=[0, 3, 5], para um congelamento parcial do backbone, ou cadeias de texto com nomes de módulos, como freeze=["23.cv2", "23.one2one_cv2"], para um controlo detalhado sobre ramos específicos dentro de uma camada (neste caso, ambos os ramos de regressão de caixas da cabeça de deteção).
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=50, freeze=10)A profundidade de congelamento adequada depende da semelhança entre o domínio-alvo e os dados pré-treinados, bem como da quantidade de dados de treino disponível:
| Cenário | Recomendação | Justificação |
|---|---|---|
| Conjunto de dados grande, domínio semelhante | freeze=None (predefinição) | Dados suficientes para adaptar todas as camadas sem sobreajuste |
| Conjunto de dados pequeno, domínio semelhante | freeze=10 | Preserva as características do backbone e reduz os parâmetros treináveis |
| Conjunto de dados muito pequeno | freeze=23 | Apenas a cabeça de deteção é treinada, minimizando o risco de sobreajuste |
| Domínio muito diferente do COCO | freeze=None | As características do backbone podem não ser transferidas eficazmente e precisam de ser novamente treinadas |
A profundidade de congelamento também pode ser tratada como um hiperparâmetro — experimentar alguns valores (0, 5, 10) e comparar o mAP de validação é uma forma prática de encontrar a melhor definição para um conjunto de dados específico.
Principais hiperparâmetros para o ajuste fino#
O ajuste fino requer geralmente menos ajustes de hiperparâmetros do que o treino do zero. Os parâmetros mais importantes são:
epochs: o ajuste fino converge mais rapidamente do que o treino do zero. Começa com um valor moderado e usapatiencepara interromper o treino antecipadamente quando as métricas de validação estabilizarem.patience: o valor predefinido de 100 foi concebido para execuções de treino longas. Reduzi-lo para 10-20 evita desperdiçar tempo em execuções que já convergiram.warmup_epochs: o warmup conduz gradualmente a taxa de aprendizagem até ao valor programado durante as primeiras épocas, pelo que é menos provável que os primeiros batches perturbem as características pré-treinadas. Mantém-no diferente de zero durante o ajuste fino, mas não é necessário utilizar a predefinição completa de 3 épocas: a pesquisa evolutiva por trás do ajuste fino oficial do YOLO26 no COCO — uma continuação de várias épocas a partir de pesos do Objects365 — estabeleceu cerca de uma época para cada tamanho de modelo.
Para veres a lista completa de parâmetros de treino, consulta a referência da configuração de treino. Para comportamentos que os parâmetros não permitem expor — taxas de aprendizagem por camada, recorte de gradientes ou métricas de validação personalizadas — cria uma subclasse do treinador.
Ajuste fino em duas fases#
O ajuste fino em duas fases divide o treino em duas etapas. A primeira congela o backbone e treina apenas o neck e a cabeça, permitindo que as camadas de deteção se adaptem às novas classes sem perturbar as características pré-treinadas. A segunda descongela todas as camadas e treina o modelo completo com uma taxa de aprendizagem mais baixa, para aperfeiçoar o backbone para o domínio-alvo.
Esta abordagem é particularmente útil quando o domínio-alvo difere significativamente do COCO (imagens médicas, imagens aéreas, microscopia), quando o backbone pode precisar de adaptação, mas treinar tudo de uma vez causa instabilidade. Para descongelamento automático através de uma abordagem baseada em callback, consulta Congelar e descongelar o backbone.
from ultralytics import YOLO
# Stage 1: freeze backbone, train head and neck
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=20, freeze=10, name="stage1", exist_ok=True)
# Stage 2: unfreeze all, fine-tune with lower lr
model = YOLO("runs/detect/stage1/weights/best.pt")
model.train(data="custom.yaml", epochs=30, optimizer="AdamW", lr0=0.001, name="stage2", exist_ok=True)Problemas comuns#
O modelo não produz previsões#
-
Dados de treino insuficientes: treinar com muito poucas amostras é a causa mais comum — o modelo não consegue aprender nem generalizar a partir de dados insuficientes. Garante exemplos diversificados suficientes por classe antes de investigarem outras causas.
-
Verifica os caminhos do conjunto de dados: caminhos de imagem inválidos geram um erro do conjunto de dados. Ficheiros de etiquetas individuais em falta ou vazios são tratados como imagens de fundo e comunicados durante a análise; uma divisão de treino sem etiquetas gera um erro. Valida o conjunto de dados antes do treino:
yolo detect val model=yolo26n.pt data=custom.yaml -
Baixa o limiar de confiança: se existirem previsões, mas estas forem filtradas, experimenta
conf=0.1durante a inferência. -
Verifica o número de classes: garante que
ncemdata.yamlcorresponde ao número real de classes nos ficheiros de etiquetas.
O mAP de validação estabiliza cedo#
- Adiciona mais dados: o ajuste fino beneficia significativamente de dados de treino adicionais, especialmente de exemplos diversificados com diferentes ângulos, condições de iluminação e fundos.
- Verifica o equilíbrio entre classes: as classes sub-representadas terão um AP baixo. Adiciona mais exemplos ou ajusta
cls_pwno conjunto de validação. - Reduz a aumentação: em conjuntos de dados muito pequenos, uma aumentação intensa pode prejudicar mais do que ajudar. Experimenta
mosaic=0.5oumosaic=0.0. - Aumenta a resolução: em conjuntos de dados com objetos pequenos, experimenta
imgsz=1280para preservar os detalhes.
O desempenho nas classes originais degrada-se após o ajuste fino#
Isto é conhecido como esquecimento catastrófico — o modelo perde conhecimentos aprendidos anteriormente quando é ajustado exclusivamente com dados novos. O esquecimento é, em grande parte, inevitável sem incluir imagens do conjunto de dados original juntamente com os dados novos. Para o atenuar:
- Combina os conjuntos de dados: inclui exemplos das classes originais juntamente com as novas classes durante o ajuste fino. Esta é a única forma fiável de evitar o esquecimento.
- Congela o backbone e o neck: congelar o backbone e o neck para que apenas a cabeça de deteção seja treinada ajuda em execuções de ajuste fino curtas com uma taxa de aprendizagem muito baixa.
- Treina durante menos épocas: quanto mais tempo o modelo treinar exclusivamente com dados novos, maior será o esquecimento.
Perguntas frequentes#
Não existe um mínimo fixo — os resultados dependem da complexidade da tarefa, do número de classes e da semelhança entre o domínio e o COCO. Imagens mais diversificadas (com diferentes condições de iluminação, ângulos e fundos) são mais importantes do que a quantidade absoluta. Começa com o que tens e aumenta a quantidade se as métricas de validação forem insuficientes.
Carrega um ficheiro
.ptpré-treinado e chama.train()com o caminho para umdata.yamlpersonalizado. A Ultralytics trata automaticamente da transferência de pesos, da reinicialização da cabeça de deteção e da seleção do otimizador. Consulta a secção Ajuste fino básico para veres o exemplo de código completo.As causas mais comuns são caminhos de imagem inválidos, ficheiros de etiquetas em falta ou vazios, uma discrepância entre
ncno YAML e os ficheiros de etiquetas reais, ou um limiar de confiança demasiado elevado. Consulta Problemas comuns para obteres uma lista completa de verificação para a resolução de problemas.Depende do tamanho do conjunto de dados e da semelhança entre os domínios. Em conjuntos de dados pequenos com um domínio semelhante ao COCO, congelar o backbone (
freeze=10) evita o sobreajuste. Em domínios muito diferentes do COCO, deixar todas as camadas descongeladas (freeze=None) permite que o backbone se adapte. Consulta Congelar camadas para obteres recomendações detalhadas.Inclui exemplos das classes originais nos dados de treino juntamente com as novas classes. Se isso não for possível, congelar mais camadas (
freeze=10ou superior) e utilizar uma taxa de aprendizagem mais baixa ajuda a preservar o conhecimento pré-treinado. Consulta O desempenho nas classes originais degrada-se para obteres mais informações.