Poda de modelos e esparsidade no YOLOv5
📚 Este guia explica como aplicar poda a modelos YOLOv5 🚀 para criar redes mais eficientes enquanto mantém o desempenho.
O que é poda de modelos?
Poda de modelos é uma técnica usada para reduzir o tamanho e a complexidade de redes neurais através da remoção de parâmetros menos importantes (pesos e conexões). Este processo cria um modelo mais eficiente com vários benefícios:
- Tamanho de 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 em um modelo mais leve com precisão similar.
Antes de começares
Clone o repositório e instale os requirements.txt em um ambiente Python>=3.8.0, incluindo PyTorch>=1.8. Modelos e datasets são baixados automaticamente a partir da última release do YOLOv5.
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # installTestar o desempenho da linha de 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 o teu próprio ponto de verificação (checkpoint) do treino de um conjunto de dados personalizado ./weights/best.pt. Para detalhes sobre todos os modelos disponíveis, vê a tabela no README.
python val.py --weights yolov5x.pt --data coco.yaml --img 640 --halfSaí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/exp-2/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/expAplicar poda ao YOLOv5x (30% de esparsidade)
Podemos aplicar poda ao modelo usando o comando torch_utils.prune() definido em utils/torch_utils.py. Para testar um modelo podado, atualizamos o val.py para podar o YOLOv5x com 0,3 de esparsidade (30% dos pesos definidos como zero):
Resultado 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/exp-3/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/exp-3Análise dos resultados
A partir dos resultados, podemos observar:
- 30% de esparsidade alcançada: 30% dos parâmetros de peso do modelo nas camadas
nn.Conv2destão agora em 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 impacto menor no desempenho, tornando-a uma técnica de otimização eficaz para implementação em ambientes com recursos limitados.
Ajuste fino (fine-tuning) de modelos podados
Para obter melhores resultados, os modelos podados devem passar por ajuste fino após a poda para recuperar a precisão. Isto pode ser feito através de:
- Aplicação da poda com um nível de esparsidade desejado
- Treino do modelo podado por algumas épocas com uma taxa de aprendizagem menor
- Avaliação do modelo podado ajustado em relação à linha de base
Este processo ajuda os parâmetros restantes a adaptar-se para compensar as conexões removidas, recuperando frequentemente a maior parte ou a totalidade da precisão original.
Ambientes Suportados
A Ultralytics fornece uma gama de ambientes prontos a usar, cada um pré-instalado com dependências essenciais como CUDA, CUDNN, Python e PyTorch, para dar início aos teus projetos.
- 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 selo indica que todos os testes de Integração Contínua (CI) do GitHub Actions do YOLOv5 estão passando com sucesso. Esses testes de CI verificam rigorosamente a funcionalidade e o desempenho do YOLOv5 em vários aspectos fundamentais: 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.