Poda de modelos e esparsidade no YOLOv5
Este guia explica como aplicar a poda aos modelos YOLOv5 🚀 para criar redes mais eficientes, mantendo o desempenho.
O que é a poda de modelos?
A poda de modelos é uma técnica utilizada para reduzir o tamanho e a complexidade das redes neuronais, removendo parâmetros menos importantes (pesos e ligações). Esse processo cria um modelo mais eficiente com vários benefícios:
- Tamanho reduzido do modelo para facilitar a implementação em dispositivos com recursos limitados
- Velocidades de inferência mais rápidas com um impacto mínimo na precisão
- Menor utilização de memória e consumo de energia
- Eficiência global melhorada para aplicações em tempo real
A poda funciona através da identificação e remoção de parâmetros que contribuem minimamente para o desempenho do modelo, resultando num modelo mais leve com uma precisão semelhante.
Antes de começar
Clonar repo e instalar requirements.txt em um Python>=3.8.0 incluindo PyTorch>=1.8. Os modelos e conjuntos de dados são descarregados automaticamente a partir daversão mais recentede YOLOv5 .
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install
Testar o desempenho da linha de base
Antes da poda, estabeleça um desempenho de linha de base para comparação. Este comando testa o YOLOv5x no COCO val2017 com tamanho de imagem de 640 pixels. yolov5x.pt
é o maior e mais exato modelo disponível. Outras opções são yolov5s.pt
, yolov5m.pt
e yolov5l.pt
ou o seu próprio ponto de controlo a partir do treino de um conjunto de dados personalizado ./weights/best.pt
. Para mais informações sobre todos os modelos disponíveis, consulte o LEIA-ME tabela.
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_hybrid=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 a poda ao YOLOv5x (30% de dispersão)
Podemos aplicar a poda ao modelo utilizando a função torch_utils.prune()
comando. Para testar um modelo podado, actualizamos val.py
para reduzir a esparsidade do YOLOv5x para 0,3 (30% dos pesos definidos como zero):
30% de produção podada:
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_hybrid=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 são agora zero - O tempo de inferência mantém-se inalterado: Apesar da poda, a velocidade de processamento é essencialmente a mesma
- Impacto mínimo no desempenho: o mAP desceu 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, o que a torna uma técnica de otimização eficaz para implementação em ambientes com recursos limitados.
Afinação de modelos podados
Para obter melhores resultados, os modelos podados devem ser ajustados após a poda para recuperar a exatidão. Isto pode ser feito da seguinte forma:
- Aplicar a poda com um nível de esparsidade pretendido
- Treinar o modelo podado durante algumas épocas com uma taxa de aprendizagem mais baixa
- Avaliação do modelo podado ajustado em relação à linha de base
Este processo ajuda os restantes parâmetros a adaptarem-se para compensar as ligações removidas, recuperando frequentemente a maior parte ou a totalidade da precisão original.
Ambientes suportados
Ultralytics fornece uma gama de ambientes prontos a utilizar, cada um pré-instalado com dependências essenciais, tais como CUDA, CUDNN, Python, e PyTorchpara dar início aos seus projectos.
- Grátis GPU Notebooks:
- Google Nuvem: Guia de início rápido do GCP
- Amazon: Guia de início rápido do AWS
- Azure: Guia de início rápido do AzureML
- Docker: Guia de início rápido do Docker
Estado do projeto
Este emblema indica que todos os testes de Integração Contínua (CI) do YOLOv5 GitHub Actions foram aprovados com êxito. 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.