Transfer Learning com Camadas Congeladas no YOLOv5
📚 Este guia explica como congelar camadas do YOLOv5 🚀 ao implementar transfer learning. Transfer learning é uma técnica poderosa de machine learning (ML) que te permite treinar novamente um modelo em novos dados rapidamente, sem precisar retreinar toda a rede do zero. Ao congelar os pesos das camadas iniciais e atualizar apenas os parâmetros das camadas finais, 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çares
Primeiro, clona o repositório YOLOv5 e instala as dependências necessárias listadas no requirements.txt. Certifica-te de que tens um ambiente Python>=3.8.0 com PyTorch>=1.8 instalado. Modelos pré-treinados e datasets necessários serão descarregados automaticamente a partir do mais recente release 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 bias) 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 essas camadas durante a backpropagation, poupando computação e memória.
Aqui tens 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 YOLOv5 consiste tipicamente num backbone (camadas 0-9 em configurações padrão como YOLOv5s/m/l/x) responsável pela feature extraction, e uma head (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 ordem dos módulos se precisares de confirmar quais índices correspondem a um determinado bloco.
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 enquanto reténs 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 alvo 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 grande maioria das características aprendidas intactas. Requer o mínimo de recursos computacionais para fine-tuning.
Comparação de Desempenho
Para ilustrar os efeitos do congelamento de camadas, treinamos o YOLOv5m no Pascal VOC dataset durante 50 epochs, começando pelos weights oficiais pré-treinados no COCO (yolov5m.pt). Comparamos três cenários: treinar todas as camadas (--freeze 0), congelar o backbone (--freeze 10), e congelar tudo exceto as camadas de deteção final (--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 hyp.finetune.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 menor.
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 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 GPU Alocada (%)
Utilização da GPU (%)
Quando usar o Congelamento de Camadas
O congelamento de camadas durante o transfer learning é particularmente vantajoso em várias situações:
- Recursos Computacionais Limitados: Se tiveres restrições de memória GPU ou poder de processamento.
- Datasets Pequenos: Quando o teu dataset alvo é significativamente menor 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 entrada de glossário 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 com GPU Gratuita:
- Google Cloud: Guia de Início Rápido GCP
- Amazon: Guia de Início Rápido AWS
- Azure: Guia de Início Rápido AzureML
- Docker: Guia de Início Rápido Docker
Status do Projeto
Este emblema 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 uma operação consistente e fiável em macOS, Windows e Ubuntu, sendo executados automaticamente a cada 24 horas e em cada novo commit de código.