YOLOv5におけるモデルのプルーニングとスパース性
📚 このガイドでは、YOLOv5 🚀モデルにプルーニングを適用して、パフォーマンスを維持しながらより効率的なネットワークを作成する方法を説明します。
モデルのプルーニングとは?
モデルのプルーニングは、重要度の低いパラメータ(重みや接続)を削除することで、ニューラルネットワークのサイズと複雑さを削減するための手法です。このプロセスにより、次のような利点を持つより効率的なモデルが作成されます。
- モデルサイズの削減により、リソース制限のあるデバイスへのデプロイが容易になる
- 精度の低下を最小限に抑えつつ、推論速度を高速化できる
- メモリ使用量とエネルギー消費の削減
- リアルタイムアプリケーションにおける全体的な効率の向上
プルーニングは、モデルのパフォーマンスへの寄与が最小限であるパラメータを特定して削除することで機能し、同様の精度を保ちながらより軽量なモデルを実現します。
始める前に
Clone repo and install requirements.txt in a Python>=3.8.0 environment, including PyTorch>=1.8. Models and datasets download automatically from the latest YOLOv5 release.
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # installベースラインパフォーマンスのテスト
プルーニングを行う前に、比較対象となるベースラインのパフォーマンスを確立します。このコマンドでは、画像サイズ640ピクセルでCOCO val2017データセットを使用してYOLOv5xをテストします。yolov5x.ptは利用可能な中で最大かつ最も高精度なモデルです。その他のオプションとして、yolov5s.pt、yolov5m.pt、yolov5l.ptがあるほか、独自のデータセットをトレーニングして得た./weights/best.ptも使用可能です。利用可能な全モデルの詳細については、READMEのテーブルを参照してください。
python val.py --weights yolov5x.pt --data coco.yaml --img 640 --half出力:
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/expYOLOv5xへのプルーニングの適用(スパース性30%)
We can apply pruning to the model using the torch_utils.prune() command defined in utils/torch_utils.py. To test a pruned model, we update val.py to prune YOLOv5x to 0.3 sparsity (30% of weights set to zero):
30%プルーニング後の出力:
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-3結果の分析
結果から以下のことが観察できます。
- 30%のスパース性を達成:
nn.Conv2dレイヤー内のモデルの重みパラメータの30%がゼロになりました - 推論時間は変化なし: プルーニングを行っても、処理速度は基本的に同じです
- パフォーマンスへの影響は最小限: mAPが0.507から0.489へわずかに低下しました(わずか3.6%の減少)
- モデルサイズの縮小: プルーニングされたモデルは、ストレージに必要なメモリが少なくて済みます
これは、プルーニングによってパフォーマンスへの影響を最小限に抑えつつ、モデルの複雑さを大幅に削減できることを示しており、リソース制限のある環境へのデプロイにおいて効果的な最適化手法となります。
プルーニング済みモデルのファインチューニング
最良の結果を得るには、精度を回復させるためにプルーニング後にファインチューニングを行う必要があります。これは以下の手順で行えます。
- 目的のスパース性レベルでプルーニングを適用する
- 低い学習率で数エポック分、プルーニングされたモデルをトレーニングする
- ファインチューニングされたプルーニング済みモデルをベースラインと比較評価する
このプロセスにより、残りのパラメータが削除された接続を補うように適応し、多くの場合、元の精度のほとんどまたはすべてを回復できます。
サポートされている環境
Ultralyticsは、プロジェクトを迅速に開始できるよう、CUDA、CUDNN、Python、PyTorch といった必須の依存関係がプリインストールされた、すぐに使える環境を幅広く提供しています。
- 無料GPUノートブック:
- Google Cloud: GCPクイックスタートガイド
- Amazon: AWSクイックスタートガイド
- Azure: AzureMLクイックスタートガイド
- Docker: Dockerクイックスタートガイド
プロジェクトステータス
このバッジは、すべてのYOLOv5 GitHub Actions継続的インテグレーション(CI)テストが正常に通過していることを示しています。これらのCIテストは、学習、検証、推論、エクスポート、およびベンチマークといったYOLOv5のさまざまな主要な側面について、機能とパフォーマンスを厳密にチェックします。macOS、Windows、Ubuntuにおいて一貫した信頼性の高い動作を保証しており、テストは24時間ごとおよび新しいコミットごとに実施されます。