Como ajustar o YOLO a um 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 por centenas de épocas, o ajuste fino aproveita os recursos pré-treinados do COCO e converge com dados personalizados em uma fração do tempo.
Este guia aborda o ajuste fino do YOLO26 em conjuntos de dados personalizados, desde o uso básico até técnicas avançadas, como congelamento de camadas e treinamento em duas etapas.
Ajuste fino vs. treinamento do zero#
Um modelo pré-treinado já aprendeu recursos visuais gerais — detecção de bordas, reconhecimento de texturas e compreensão de formas — a partir de milhões de imagens. O aprendizado por transferência por meio do ajuste fino reutiliza esse conhecimento e ensina ao modelo apenas a aparência das novas classes, por isso ele converge mais rápido e exige menos dados. O treinamento do zero descarta tudo isso e obriga o modelo a aprender tudo a partir de padrões no nível dos pixels, o que exige significativamente mais recursos. Consulte o Guia de configuração YAML do modelo para saber como os arquivos .yaml, que contêm apenas a arquitetura, diferem dos checkpoints.
| Ajuste fino | Treinamento 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 — os recursos pré-treinados compensam a menor quantidade de dados | Maiores — o modelo precisa aprender todos os recursos apenas com o conjunto de dados |
| Quando usar | Classes personalizadas com imagens naturais | Domínios fundamentalmente diferentes do COCO (médico, satélite, radar) |
Quando um arquivo .pt é carregado com YOLO("yolo26n.pt"), os pesos pré-treinados são armazenados no modelo. Depois disso, chamar .train(data="custom.yaml") transfere automaticamente todos os pesos compatíveis para a nova arquitetura do modelo, reinicializa as camadas incompatíveis (como a cabeça de detecção quando o número de classes é diferente) e inicia o treinamento. Não é necessário carregar pesos manualmente, manipular camadas nem escrever código personalizado de aprendizado por transferência.
Como funciona a transferência de pesos pré-treinados#
Quando um modelo pré-treinado é ajustado em um conjunto de dados com um número diferente de classes (por exemplo, as 80 classes do COCO para 5 classes personalizadas), Ultralytics realiza a transferência de pesos considerando as dimensões:
- A transferência do backbone e do neck é completa — essas camadas extraem recursos visuais gerais, e suas dimensões são independentes do número de classes.
- A cabeça de detecção é parcialmente reinicializada — as camadas de saída de classificação (
cv3,one2one_cv3) têm dimensões vinculadas ao número de classes (80 vs. 5). As linhas compatíveis cujos nomes de classe correspondem são remapeadas antes de as linhas sem correspondência serem inicializadas. As camadas de regressão de caixas (cv2,one2one_cv2) da cabeça têm dimensões fixas, independentemente do número de classes, portanto 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) a um conjunto de dados com 5 classes, são transferidos 606 dos 708 tensores de peso, além de quaisquer linhas de classificação compatíveis cujos nomes correspondam.
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 a outro conjunto de dados com 80 classes), 100% dos pesos são transferidos, incluindo a cabeça de detecção.
Transferir classes com aliases de nome#
Ultralytics transfere linhas correspondentes da cabeça de classificação entre conjuntos de dados usando o nome da classe, sem diferenciar maiúsculas de minúsculas e ignorando espaços em branco no início e no fim. Quando classes equivalentes usam nomes diferentes, renomeie em memória as classes do checkpoint de origem antes de carregá-lo. Isso preserva os pesos de classificação pré-treinados para conceitos compartilhados que, de outro modo, seriam considerados sem correspondência e inicializados aleatoriamente.
Este exemplo de Objects365 v2 para COCO renomeia as classes de origem no checkpoint carregado, que train() passa adiante como pesos pré-treinados:
from ultralytics import YOLO
# Nome da classe de origem do Objects365 v2 (em minúsculas) -> nome da classe de destino do COCO
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")
# Os nomes das classes do Objects365 usam iniciais maiúsculas; por isso, a correspondência é feita com o nome em minúsculas
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 configuração cls_remap ativa por padrão essa transferência baseada em nomes. O treinamento exibe Remapped N/M cls head rows from pretrained weights by class name quando linhas compatíveis são copiadas; defina cls_remap=False para desativá-la.
Exemplo básico de ajuste fino#
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # carregar modelo pré-treinado
model.train(data="custom.yaml", epochs=50, imgsz=640)Escolher o tamanho do modelo#
Modelos maiores têm mais capacidade, mas também mais parâmetros para atualizar, o que pode aumentar o risco de sobreajuste quando há poucos dados de treinamento. Começar com um modelo menor (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 implantação. Consulte a página completa do modelo YOLO26 para ver os tamanhos disponíveis e os benchmarks de desempenho.
Seleção do otimizador e da taxa de aprendizado#
A configuração padrão optimizer=auto seleciona o otimizador e a taxa de aprendizado com base no número total de iterações de treinamento:
- 10.000 iterações ou menos (conjuntos de dados pequenos ou poucas épocas): AdamW com uma taxa de aprendizado baixa, calculada automaticamente
- Mais de 10.000 iterações (conjuntos de dados grandes): MuSGD (um otimizador híbrido Muon+SGD) com lr=0.01
Na maioria das tarefas de ajuste fino, a configuração padrão funciona bem sem nenhum ajuste manual. Considere definir o otimizador explicitamente quando:
- O treinamento estiver instável (a perda apresenta picos ou diverge): experimente
optimizer=AdamW, lr0=0.001para obter uma convergência mais estável - Você estiver ajustando um modelo grande com um conjunto de dados pequeno: um otimizador explícito com uma taxa de aprendizado menor, como
optimizer=AdamW, lr0=0.001, pode ajudar a preservar os recursos pré-treinados
Quando optimizer=auto, os valores lr0 e momentum são ignorados. Para controlar manualmente a taxa de aprendizado, defina explicitamente o otimizador: optimizer=SGD, lr0=0.005.
Congelamento de camadas#
O congelamento impede que camadas específicas sejam atualizadas durante o treinamento. Isso acelera o treinamento e reduz o sobreajuste quando o conjunto de dados é pequeno em relação à capacidade do modelo.
O parâmetro freeze aceita um inteiro ou uma lista. O inteiro freeze=10 congela as 10 primeiras camadas (índices 0-9), que abrangem a maior parte do backbone YOLO26. O backbone vai das camadas 0 a 10; portanto, freeze=10 mantém treinável o bloco C2PSA final (camada 10); use freeze=11 para congelar o backbone inteiro. Uma lista pode conter índices de camadas, como freeze=[0, 3, 5], para congelar parcialmente o backbone, ou strings com nomes de módulos, como freeze=["23.cv2", "23.one2one_cv2"], para controlar com precisão ramificações específicas de uma camada (neste caso, ambas as ramificações de regressão de caixas da cabeça de detecçã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 de destino e os dados pré-treinados, além da quantidade de dados de treinamento disponível:
| Cenário | Recomendação | Justificativa |
|---|---|---|
| Conjunto de dados grande, domínio semelhante | freeze=None (padrão) | Dados suficientes para adaptar todas as camadas sem sobreajuste |
| Conjunto de dados pequeno, domínio semelhante | freeze=10 | Preserva os recursos do backbone e reduz o número de parâmetros treináveis |
| Conjunto de dados muito pequeno | freeze=23 | Somente a cabeça de detecção é treinada, minimizando o risco de sobreajuste |
| Domínio muito diferente do COCO | freeze=None | Os recursos do backbone podem não ser bem transferidos e talvez precisem ser treinados novamente |
A profundidade de congelamento também pode ser tratada como um hiperparâmetro: testar alguns valores (0, 5, 10) e comparar o mAP de validação é uma forma prática de encontrar a melhor configuração para um conjunto de dados específico.
Principais hiperparâmetros para o ajuste fino#
Em geral, o ajuste fino exige menos ajustes de hiperparâmetros do que o treinamento do zero. Os parâmetros mais importantes são:
epochs: o ajuste fino converge mais rápido do que o treinamento do zero. Comece com um valor moderado e usepatiencepara interromper o treinamento assim que as métricas de validação estabilizarem.patience: o valor padrão de 100 foi projetado para treinamentos longos. Reduzi-lo para 10-20 evita perder tempo com treinamentos que já convergiram.warmup_epochs: o aquecimento ajusta gradualmente a taxa de aprendizado até o valor programado ao longo das primeiras épocas, reduzindo a probabilidade de os lotes iniciais perturbarem os recursos pré-treinados. Mantenha-o diferente de zero durante o ajuste fino, mas não é necessário usar o valor padrão completo de 3 épocas: a busca evolutiva por trás do ajuste fino oficial do YOLO26 no COCO — uma continuação de várias épocas a partir dos pesos do Objects365 — definiu cerca de uma época para cada tamanho de modelo.
Para ver a lista completa de parâmetros de treinamento, consulte a referência de configuração de treinamento. Para comportamentos não contemplados pelos parâmetros — taxas de aprendizado por camada, recorte de gradiente ou métricas de validação personalizadas — crie uma subclasse do trainer.
Ajuste fino em duas etapas#
O ajuste fino em duas etapas divide o treinamento em duas fases. Na primeira fase, o backbone é congelado e somente o neck e a cabeça são treinados, permitindo que as camadas de detecção se adaptem às novas classes sem perturbar os recursos pré-treinados. Na segunda fase, todas as camadas são descongeladas, e o modelo completo é treinado com uma taxa de aprendizado menor para refinar o backbone para o domínio de destino.
Essa abordagem é especialmente útil quando o domínio de destino difere significativamente do COCO (imagens médicas, imagens aéreas, microscopia), pois talvez seja necessário adaptar o backbone, mas treinar tudo de uma vez causa instabilidade. Para descongelar automaticamente usando uma abordagem baseada em callback, consulte Congelar e descongelar o backbone.
from ultralytics import YOLO
# Etapa 1: congelar o backbone, treinar a cabeça e o neck
model = YOLO("yolo26n.pt")
model.train(data="custom.yaml", epochs=20, freeze=10, name="stage1", exist_ok=True)
# Etapa 2: descongelar tudo e ajustar fino com uma lr menor
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 gera previsões#
-
Dados de treinamento insuficientes: treinar com pouquíssimas amostras é a causa mais comum — o modelo não consegue aprender nem generalizar com tão poucos dados. Antes de investigar outras causas, garanta que haja exemplos diversos suficientes por classe.
-
Verifique os caminhos do conjunto de dados: caminhos de imagem inválidos geram um erro no conjunto de dados. Arquivos de rótulo ausentes ou vazios são tratados como imagens de fundo e informados durante a verificação; se uma divisão de treinamento não tiver rótulos, será gerado um erro. Valide o conjunto de dados antes do treinamento:
yolo detect val model=yolo26n.pt data=custom.yaml -
Reduza o limiar de confiança: se houver previsões, mas elas forem filtradas, experimente
conf=0.1durante a inferência. -
Verifique o número de classes: confirme que
ncemdata.yamlcorresponde ao número real de classes nos arquivos de rótulo.
O mAP de validação estabiliza cedo#
- Adicione mais dados: o ajuste fino se beneficia significativamente de dados de treinamento adicionais, especialmente de exemplos diversos com diferentes ângulos, condições de iluminação e planos de fundo.
- Verifique o equilíbrio entre as classes: classes sub-representadas terão AP baixo. Adicione mais exemplos ou ajuste
cls_pwno conjunto de validação. - Reduza o aumento de dados: em conjuntos de dados muito pequenos, o aumento de dados intenso pode prejudicar mais do que ajudar. Experimente
mosaic=0.5oumosaic=0.0. - Aumente a resolução: para conjuntos de dados com objetos pequenos, experimente
imgsz=1280para preservar os detalhes.
O desempenho nas classes originais piora após o ajuste fino#
Isso é conhecido como esquecimento catastrófico — o modelo perde conhecimentos aprendidos anteriormente quando é ajustado exclusivamente com dados novos. O esquecimento é praticamente inevitável sem incluir imagens do conjunto de dados original junto com os dados novos. Para reduzir esse efeito:
- Mescle os conjuntos de dados: inclua exemplos das classes originais junto com as classes novas durante o ajuste fino. Essa é a única forma confiável de evitar o esquecimento.
- Congele o backbone e o neck: congelar o backbone e o neck para que somente a cabeça de detecção seja treinada ajuda em ajustes finos curtos com uma taxa de aprendizado muito baixa.
- Treine por menos épocas: quanto mais tempo o modelo treinar exclusivamente com dados novos, maior será o esquecimento.
Perguntas frequentes#
Não há um mínimo fixo — os resultados dependem da complexidade da tarefa, do número de classes e da semelhança do domínio com o COCO. Imagens mais diversas (com diferentes condições de iluminação, ângulos e planos de fundo) são mais importantes do que a quantidade total. Comece com o que você tem e aumente a quantidade se as métricas de validação forem insuficientes.
Carregue um arquivo
.ptpré-treinado e chame.train()com o caminho para umdata.yamlpersonalizado. Ultralytics gerencia automaticamente a transferência de pesos, a reinicialização da cabeça de detecção e a seleção do otimizador. Consulte a seção Ajuste fino básico para ver o exemplo completo de código.As causas mais comuns são caminhos de imagem inválidos, arquivos de rótulo ausentes ou vazios, uma incompatibilidade entre
ncno YAML e os arquivos de rótulo reais, ou um limiar de confiança muito alto. Consulte Problemas comuns para ver uma lista completa de verificações para solucionar problemas.Isso depende do tamanho do conjunto de dados e da semelhança entre os domínios. Para conjuntos de dados pequenos com um domínio semelhante ao do COCO, congelar o backbone (
freeze=10) evita o sobreajuste. Para domínios muito diferentes do COCO, deixar todas as camadas descongeladas (freeze=None) permite que o backbone se adapte. Consulte Congelamento de camadas para ver recomendações detalhadas.Inclua exemplos das classes originais nos dados de treinamento junto com as novas classes. Se isso não for possível, congelar mais camadas (
freeze=10ou mais) e usar uma taxa de aprendizado menor ajuda a preservar o conhecimento pré-treinado. Consulte O desempenho piora nas classes originais para saber mais.