Transfer Learning com Camadas Congeladas no YOLOv5#
📚 Este guia explica como congelar camadas do YOLOv5 🚀 ao implementar transfer learning. O transfer learning é uma técnica poderosa de machine learning (ML) que permite retreinar rapidamente um modelo em novos dados sem retreinar toda a rede do zero. Ao congelar os pesos das camadas iniciais e atualizar apenas os parâmetros das camadas posteriores, podes reduzir significativamente os requisitos de recursos computacionais e o tempo de treino. No entanto, esta abordagem pode impactar ligeiramente a precisão final do modelo.
Antes de começar#
Primeiro, clona o repositório do YOLOv5 e instala as dependências necessárias listadas em requirements.txt. Certifica-te de que tens um ambiente Python>=3.8.0 com o PyTorch>=1.8 instalado. Modelos pré-treinados e datasets necessários serão transferidos automaticamente a partir do mais recente lançamento do YOLOv5.
git clone https://github.com/ultralytics/yolov5 # clone repository
cd yolov5
pip install -r requirements.txt # install dependenciesComo Funciona o Congelamento de Camadas#
Quando congelas camadas numa neural network, impedes que os seus parâmetros (pesos e vieses) sejam atualizados durante o processo de treino. No PyTorch, isto é alcançado definindo o atributo requires_grad dos tensores da camada como False. Consequentemente, os gradientes não são calculados para estas camadas durante a backpropagation, poupando computação e memória.
Eis como o YOLOv5 implementa o congelamento de camadas no seu training script:
# Freeze specified layers
freeze = [f"model.{x}." for x in range(freeze)] # Define layers to freeze based on module index
for k, v in model.named_parameters():
v.requires_grad = True # Ensure all parameters are initially trainable
if any(x in k for x in freeze):
print(f"Freezing layer: {k}")
v.requires_grad = False # Disable gradient calculation for frozen layersExplorando a Arquitetura do Modelo#
Compreender a estrutura do modelo YOLOv5 é crucial para decidir quais camadas congelar. Podes inspecionar os nomes de todos os módulos e os seus parâmetros usando o seguinte snippet de Python:
# Assuming 'model' is your loaded YOLOv5 model instance
for name, param in model.named_parameters():
print(name)
"""
Example Output:
model.0.conv.conv.weight
model.0.conv.bn.weight
model.0.conv.bn.bias
model.1.conv.weight
model.1.bn.weight
model.1.bn.bias
model.2.cv1.conv.weight
model.2.cv1.bn.weight
...
"""A arquitetura do YOLOv5 consiste tipicamente num backbone (camadas 0-9 em configurações padrão como YOLOv5s/m/l/x) responsável pela feature extraction, e numa cabeça (as camadas restantes) que realiza a object detection.
# Example YOLOv5 v6.0 backbone structure
backbone:
# [from, number, module, args]
- [-1, 1, Conv, [64, 6, 2, 2]] # Layer 0: Initial convolution (P1/2 stride)
- [-1, 1, Conv, [128, 3, 2]] # Layer 1: Downsampling convolution (P2/4 stride)
- [-1, 3, C3, [128]] # Layer 2: C3 module
- [-1, 1, Conv, [256, 3, 2]] # Layer 3: Downsampling convolution (P3/8 stride)
- [-1, 6, C3, [256]] # Layer 4: C3 module
- [-1, 1, Conv, [512, 3, 2]] # Layer 5: Downsampling convolution (P4/16 stride)
- [-1, 9, C3, [512]] # Layer 6: C3 module
- [-1, 1, Conv, [1024, 3, 2]]# Layer 7: Downsampling convolution (P5/32 stride)
- [-1, 3, C3, [1024]] # Layer 8: C3 module
- [-1, 1, SPPF, [1024, 5]] # Layer 9: Spatial Pyramid Pooling Fast
# Example YOLOv5 v6.0 head structure
head:
- [-1, 1, Conv, [512, 1, 1]] # Layer 10
- [-1, 1, nn.Upsample, [None, 2, "nearest"]] # Layer 11
- [[-1, 6], 1, Concat, [1]] # Layer 12: Concatenate with backbone P4 (from layer 6)
- [-1, 3, C3, [512, False]] # Layer 13: C3 module
# ... subsequent head layers for feature fusion and detectionOpções de Congelamento#
Podes controlar quais camadas são congeladas usando o argumento --freeze no comando de treino. Este argumento especifica o índice do primeiro módulo não congelado; todos os módulos antes deste índice terão os seus pesos congelados. Usa model.model (um nn.Sequential) para inspecionar a ordenação dos módulos se precisares de confirmar quais índices correspondem a um bloco específico.
Congelar Apenas o Backbone#
Para congelar todo o backbone (camadas 0 a 9), o que é comum ao adaptar o modelo a novas classes de objetos, mantendo capacidades gerais de extração de características aprendidas a partir de um grande dataset como o COCO:
python train.py --weights yolov5m.pt --data your_dataset.yaml --freeze 10Esta estratégia é eficaz quando o teu dataset de destino partilha características visuais de baixo nível semelhantes (bordas, texturas) com os dados de treino originais (por exemplo, COCO), mas contém categorias de objetos diferentes.
Congelar Tudo Exceto as Camadas Finais de Deteção#
Para congelar quase toda a rede, deixando apenas as camadas de convolução de saída final (parte do módulo Detect, tipicamente o último módulo, por exemplo, o módulo 24 no YOLOv5s) treináveis:
python train.py --weights yolov5m.pt --data your_dataset.yaml --freeze 24Esta abordagem é útil quando precisas principalmente de ajustar o modelo para um número diferente de classes de saída, mantendo a vasta maioria das características aprendidas intactas. Requer menos recursos computacionais para fine-tuning.
Comparação de Desempenho#
Para ilustrar os efeitos do congelamento de camadas, treinámos o YOLOv5m no Pascal VOC dataset durante 50 epochs, começando a partir dos weights oficiais pré-treinados do COCO (yolov5m.pt). Comparámos três cenários: treinar todas as camadas (--freeze 0), congelar o backbone (--freeze 10) e congelar todas exceto as camadas de deteção finais (--freeze 24).
# Example command for training with backbone frozen
python train.py --batch 48 --weights yolov5m.pt --data voc.yaml --epochs 50 --cache --img 512 --hyp data/hyps/hyp.VOC.yaml --freeze 10Resultados de Precisão#
Os resultados mostram que o congelamento de camadas pode acelerar significativamente o treino, mas pode levar a uma ligeira redução no mAP (mean Average Precision) final. Treinar todas as camadas geralmente produz a melhor precisão, enquanto congelar mais camadas oferece um treino mais rápido à custa de um desempenho potencialmente inferior.
Comparação de mAP50 durante o treino
Comparação de mAP50-95 durante o treino
*Summary table of performance metrics*
Utilização de Recursos#
Congelar mais camadas reduz substancialmente os requisitos de memória da GPU e a utilização geral. Isto torna o transfer learning com camadas congeladas uma opção atraente ao trabalhar com recursos de hardware limitados, permitindo treinar modelos maiores ou usar tamanhos de imagem maiores do que seria possível de outra forma.
Memória da GPU Alocada (%)
Utilização da GPU (%)
Quando Usar Congelamento de Camadas#
O congelamento de camadas durante o transfer learning é particularmente vantajoso em várias situações:
- Recursos Computacionais Limitados: Se tens restrições na memória da GPU ou no poder de processamento.
- Datasets Pequenos: Quando o teu dataset de destino é significativamente menor do que o dataset de pré-treino original, o congelamento ajuda a evitar o overfitting.
- Prototipagem Rápida: Quando precisas de adaptar rapidamente um modelo existente a uma nova tarefa ou domínio para uma avaliação inicial.
- Domínios de Características Semelhantes: Se as características de baixo nível no teu novo dataset forem muito semelhantes às do dataset no qual o modelo foi pré-treinado.
Explora mais sobre as nuances do transfer learning na nossa glossary entry e considera técnicas como hyperparameter tuning para otimizar o desempenho.
Ambientes suportados#
A Ultralytics oferece vários ambientes prontos a usar com dependências essenciais como CUDA, CuDNN, Python e PyTorch pré-instaladas.
- Notebooks de GPU Grátis:
- Google Cloud: Guia de Início Rápido do GCP
- Amazon: Guia de Início Rápido da AWS
- Azure: Guia de Início Rápido do AzureML
- Docker: Guia de Início Rápido do Docker
Status do projeto#
Este selo confirma que todos os testes de Integração Contínua (CI) do YOLOv5 GitHub Actions estão a passar com sucesso. Estes testes de CI avaliam rigorosamente a funcionalidade e o desempenho do YOLOv5 em operações chave: training, validation, inference, export e benchmarks. Garantem um funcionamento consistente e fiável no macOS, Windows e Ubuntu, sendo executados automaticamente a cada 24 horas e em cada novo commit de código.