Poda e Esparsidade de Modelos em YOLOv5
📚 Este guia explica como aplicar pruning (poda) aos modelos YOLOv5 🚀 para criar redes mais eficientes, mantendo o desempenho.
O que é Poda de Modelo (Model Pruning)?
A poda de modelos é uma técnica usada para reduzir o tamanho e a complexidade das redes neurais, removendo parâmetros menos importantes (pesos e conexões). Este processo cria um modelo mais eficiente com vários benefícios:
- Tamanho do modelo reduzido para facilitar a implementação em dispositivos com recursos limitados
- Velocidades de inferência mais rápidas com impacto mínimo na precisão
- Menor uso de memória e consumo de energia
- Eficiência geral aprimorada para aplicações em tempo real
A poda funciona identificando e removendo parâmetros que contribuem minimamente para o desempenho do modelo, resultando num modelo mais leve com precisão semelhante.
Antes de Começar
Clone o repositório e instale os requirements.txt num ambiente Python>=3.8.0, incluindo PyTorch>=1.8. Os modelos e os conjuntos de dados são descarregados automaticamente a partir da última versão do YOLOv5.
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install
Testar o Desempenho Base
Antes de realizar a poda, estabeleça um desempenho de referência para comparar. Este comando testa o YOLOv5x no COCO val2017 com tamanho de imagem de 640 pixels. yolov5x.pt
é o maior e mais preciso modelo disponível. Outras opções são yolov5s.pt
, yolov5m.pt
e yolov5l.pt
, ou seu próprio checkpoint do treinamento de um conjunto de dados personalizado ./weights/best.pt
. Para obter detalhes sobre todos os modelos disponíveis, consulte o README tabela.
python val.py --weights yolov5x.pt --data coco.yaml --img 640 --half
Saída:
val: data=/content/yolov5/data/coco.yaml, weights=['yolov5x.pt'], batch_size=32, imgsz=640, conf_thres=0.001, iou_thres=0.65, task=val, device=, workers=8, single_cls=False, augment=False, verbose=False, save_txt=False, save_conf=False, save_json=True, project=runs/val, name=exp, exist_ok=False, half=True, dnn=False
YOLOv5 🚀 v6.0-224-g4c40933 torch 1.10.0+cu111 CUDA:0 (Tesla V100-SXM2-16GB, 16160MiB)
Fusing layers...
Model Summary: 444 layers, 86705005 parameters, 0 gradients
val: Scanning '/content/datasets/coco/val2017.cache' images and labels... 4952 found, 48 missing, 0 empty, 0 corrupt: 100% 5000/5000 [00:00<?, ?it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 157/157 [01:12<00:00, 2.16it/s]
all 5000 36335 0.732 0.628 0.683 0.496
Speed: 0.1ms pre-process, 5.2ms inference, 1.7ms NMS per image at shape (32, 3, 640, 640) # <--- base speed
Evaluating pycocotools mAP... saving runs/val/exp2/yolov5x_predictions.json...
...
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.507 # <--- base mAP
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.689
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.552
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.345
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.559
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.652
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.381
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.630
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.682
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.526
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.731
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.829
Results saved to runs/val/exp
Aplicar Poda ao YOLOv5x (30% de Esparsidade)
Podemos aplicar pruning ao modelo usando o torch_utils.prune()
comando. Para testar um modelo podado, atualizamos val.py
para podar o YOLOv5x para 0,3 de esparsidade (30% dos pesos definidos como zero):
Saída com 30% de poda:
val: data=/content/yolov5/data/coco.yaml, weights=['yolov5x.pt'], batch_size=32, imgsz=640, conf_thres=0.001, iou_thres=0.65, task=val, device=, workers=8, single_cls=False, augment=False, verbose=False, save_txt=False, save_conf=False, save_json=True, project=runs/val, name=exp, exist_ok=False, half=True, dnn=False
YOLOv5 🚀 v6.0-224-g4c40933 torch 1.10.0+cu111 CUDA:0 (Tesla V100-SXM2-16GB, 16160MiB)
Fusing layers...
Model Summary: 444 layers, 86705005 parameters, 0 gradients
Pruning model... 0.3 global sparsity
val: Scanning '/content/datasets/coco/val2017.cache' images and labels... 4952 found, 48 missing, 0 empty, 0 corrupt: 100% 5000/5000 [00:00<?, ?it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 157/157 [01:11<00:00, 2.19it/s]
all 5000 36335 0.724 0.614 0.671 0.478
Speed: 0.1ms pre-process, 5.2ms inference, 1.7ms NMS per image at shape (32, 3, 640, 640) # <--- prune speed
Evaluating pycocotools mAP... saving runs/val/exp3/yolov5x_predictions.json...
...
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.489 # <--- prune mAP
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.677
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.537
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.334
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.542
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.635
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.370
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.612
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.664
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.496
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.722
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.803
Results saved to runs/val/exp3
Análise de Resultados
A partir dos resultados, podemos observar:
- 30% de esparsidade alcançada: 30% dos parâmetros de peso do modelo em
nn.Conv2d
as camadas agora são zero - Tempo de inferência permanece inalterado: Apesar da poda, a velocidade de processamento é essencialmente a mesma
- Impacto mínimo no desempenho: o mAP caiu ligeiramente de 0,507 para 0,489 (apenas 3,6% de redução)
- Redução do tamanho do modelo: O modelo podado requer menos memória para armazenamento
Isto demonstra que a poda pode reduzir significativamente a complexidade do modelo com apenas um pequeno impacto no desempenho, tornando-a uma técnica de otimização eficaz para implantação em ambientes com recursos limitados.
Ajuste Fino de Modelos Podados
Para melhores resultados, os modelos podados devem ser ajustados após a poda para recuperar a precisão. Isso pode ser feito por:
- Aplicando a poda com um nível de esparsidade desejado
- Treinar o modelo podado por algumas épocas com uma taxa de aprendizagem mais baixa
- Avaliando o modelo podado e ajustado em relação à linha de base
Este processo ajuda os parâmetros restantes a se adaptarem para compensar as conexões removidas, muitas vezes recuperando a maior parte ou toda a precisão original.
Ambientes suportados
A Ultralytics oferece uma variedade de ambientes prontos para uso, cada um pré-instalado com dependências essenciais como CUDA, CUDNN, Python e PyTorch, para dar o pontapé inicial em seus projetos.
- Notebooks GPU Gratuitos:
- Google Cloud: Guia de Início Rápido do GCP
- Amazon: Guia de Início Rápido AWS
- Azure: Guia de Início Rápido AzureML
- Docker: Guia de Início Rápido do Docker
Estado do Projeto
Este selo indica que todos os testes de Integração Contínua (CI) das Ações do GitHub YOLOv5 estão sendo aprovados com sucesso. Esses testes de CI verificam rigorosamente a funcionalidade e o desempenho do YOLOv5 em vários aspectos principais: treinamento, validação, inferência, exportação e benchmarks. Eles garantem uma operação consistente e confiável no macOS, Windows e Ubuntu, com testes realizados a cada 24 horas e a cada novo commit.