ํ ์คํธ ์๊ฐ ํ๋(TTA)
๐ This guide explains how to use Test Time Augmentation (TTA) during testing and inference for improved mAP and Recall with YOLOv5 ๐.
์์ํ๊ธฐ ์ ์
๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ๋ณต์ ํ๊ณ ์๊ตฌ์ฌํญ.txt๋ฅผ ์ค์นํฉ๋๋ค. Python>=3.8.0 ํ๊ฒฝ์ ํฌํจํ์ฌ PyTorch>=1.8. ๋ชจ๋ธ ๋ฐ ๋ฐ์ดํฐ ์ธํธ๋ ์ต์ YOLOv5 ๋ฆด๋ฆฌ์ค์์ ์๋์ผ๋ก ๋ค์ด๋ก๋๋ฉ๋๋ค.
git clone https://github.com/ultralytics/yolov5 # clone
cd yolov5
pip install -r requirements.txt # install
์ ์์ ์ผ๋ก ํ ์คํธ
TTA๋ฅผ ์๋ํ๊ธฐ ์ ์ ๋น๊ตํ ๊ธฐ์ค ์ฑ๋ฅ์ ์ค์ ํ๊ณ ์ถ์ต๋๋ค. ์ด ๋ช
๋ น์ ์ด๋ฏธ์ง ํฌ๊ธฐ 640ํฝ์
์ COCO val2017์์ YOLOv5x๋ฅผ ํ
์คํธํฉ๋๋ค. yolov5x.pt
์ ๊ฐ์ฅ ํฌ๊ณ ์ ํํ ๋ชจ๋ธ์
๋๋ค. ๋ค๋ฅธ ์ต์
์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. yolov5s.pt
, yolov5m.pt
๊ทธ๋ฆฌ๊ณ yolov5l.pt
๋๋ ์ฌ์ฉ์ ์ง์ ๋ฐ์ดํฐ ์ธํธ ํ์ต์์ ์ป์ ์์ฒด ์ฒดํฌํฌ์ธํธ ./weights/best.pt
. ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ๋ชจ๋ธ์ ๋ํ ์์ธํ ๋ด์ฉ์ README๋ฅผ ์ฐธ์กฐํ์ธ์. ํ
์ด๋ธ.
์ถ๋ ฅ:
val: data=./data/coco.yaml, weights=['yolov5x.pt'], batch_size=32, imgsz=640, conf_thres=0.001, iou_thres=0.65, task=val, device=, 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
YOLOv5 ๐ v5.0-267-g6a3ee7c torch 1.9.0+cu102 CUDA:0 (Tesla P100-PCIE-16GB, 16280.875MB)
Fusing layers...
Model Summary: 476 layers, 87730285 parameters, 0 gradients
val: Scanning '../datasets/coco/val2017' images and labels...4952 found, 48 missing, 0 empty, 0 corrupted: 100% 5000/5000 [00:01<00:00, 2846.03it/s]
val: New cache created: ../datasets/coco/val2017.cache
Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 157/157 [02:30<00:00, 1.05it/s]
all 5000 36335 0.746 0.626 0.68 0.49
Speed: 0.1ms pre-process, 22.4ms inference, 1.4ms NMS per image at shape (32, 3, 640, 640) # <--- baseline speed
Evaluating pycocotools mAP... saving runs/val/exp/yolov5x_predictions.json...
...
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.504 # <--- baseline mAP
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.688
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.546
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.351
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.551
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.644
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.382
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.628
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.681 # <--- baseline mAR
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.524
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.735
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.826
TTA๋ก ํ ์คํธ
์ถ๊ฐ --augment
๋ฅผ ๊ธฐ์กด val.py
๋ช
๋ น์ ์คํํ์ฌ TTA๋ฅผ ํ์ฑํํ๊ณ ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ์ฝ 30% ๋๋ฆฌ๋ฉด ๋ ๋์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค. TTA๋ฅผ ํ์ฑํํ ์ถ๋ก ์ ์ผ๋ฐ์ ์ผ๋ก ์ด๋ฏธ์ง๋ฅผ ์ข์ฐ๋ก ๋ค์ง์ด 3๊ฐ์ ๋ค๋ฅธ ํด์๋์์ ์ฒ๋ฆฌํ๊ณ ์ถ๋ ฅ์ NMS ์ ์ ๋ณํฉํ๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ ์ถ๋ก ์ ์ฝ 2~3๋ฐฐ์ ์๊ฐ์ด ์์๋ฉ๋๋ค. ์๋ ๊ฐ์์ ์ผ๋ถ๋ ๋จ์ํ ์ด๋ฏธ์ง ํฌ๊ธฐ๊ฐ ๋ ํฌ๊ธฐ ๋๋ฌธ์ด๊ณ (832 ๋ 640), ์ผ๋ถ๋ ์ค์ TTA ์์
๋๋ฌธ์ด๊ธฐ๋ ํฉ๋๋ค.
์ถ๋ ฅ:
val: data=./data/coco.yaml, weights=['yolov5x.pt'], batch_size=32, imgsz=832, conf_thres=0.001, iou_thres=0.6, task=val, device=, single_cls=False, augment=True, verbose=False, save_txt=False, save_hybrid=False, save_conf=False, save_json=True, project=runs/val, name=exp, exist_ok=False, half=True
YOLOv5 ๐ v5.0-267-g6a3ee7c torch 1.9.0+cu102 CUDA:0 (Tesla P100-PCIE-16GB, 16280.875MB)
Fusing layers...
/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py:718: UserWarning: Named tensors and all their associated APIs are an experimental feature and subject to change. Please do not use them for anything important until they are released as stable. (Triggered internally at /pytorch/c10/core/TensorImpl.h:1156.)
return torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode)
Model Summary: 476 layers, 87730285 parameters, 0 gradients
val: Scanning '../datasets/coco/val2017' images and labels...4952 found, 48 missing, 0 empty, 0 corrupted: 100% 5000/5000 [00:01<00:00, 2885.61it/s]
val: New cache created: ../datasets/coco/val2017.cache
Class Images Labels P R mAP@.5 mAP@.5:.95: 100% 157/157 [07:29<00:00, 2.86s/it]
all 5000 36335 0.718 0.656 0.695 0.503
Speed: 0.2ms pre-process, 80.6ms inference, 2.7ms NMS per image at shape (32, 3, 832, 832) # <--- TTA speed
Evaluating pycocotools mAP... saving runs/val/exp2/yolov5x_predictions.json...
...
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.516 # <--- TTA mAP
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.701
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.562
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.361
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.564
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.656
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.388
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.640
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.696 # <--- TTA mAR
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.553
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.744
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.833
TTA๋ฅผ ํตํ ์ถ๋ก
detect.py
TTA ์ถ๋ก ์ ๋ค์๊ณผ ๋์ผํ๊ฒ ์๋ํฉ๋๋ค. val.py
TTA: ๊ฐ๋จํ ์ถ๊ฐ --augment
๋ฅผ ๊ธฐ์กด detect.py
๋ช
๋ น์ ์ฌ์ฉํฉ๋๋ค:
์ถ๋ ฅ:
YOLOv5 ๐ v5.0-267-g6a3ee7c torch 1.9.0+cu102 CUDA:0 (Tesla P100-PCIE-16GB, 16280.875MB)
Downloading https://github.com/ultralytics/yolov5/releases/download/v5.0/yolov5s.pt to yolov5s.pt...
100% 14.1M/14.1M [00:00<00:00, 81.9MB/s]
Fusing layers...
Model Summary: 224 layers, 7266973 parameters, 0 gradients
image 1/2 /content/yolov5/data/images/bus.jpg: 832x640 4 persons, 1 bus, 1 fire hydrant, Done. (0.029s)
image 2/2 /content/yolov5/data/images/zidane.jpg: 480x832 3 persons, 3 ties, Done. (0.024s)
Results saved to runs/detect/exp
Done. (0.156s)
PyTorch ํ๋ธ TTA
TTA๋ ๋ชจ๋ YOLOv5 PyTorch ํ๋ธ ๋ชจ๋ธ์ ์ก์ธ์คํ ์ ์์ต๋๋ค. augment=True
๋ฅผ ์ถ๋ก ํ ์ ์์ต๋๋ค.
import torch
# Model
model = torch.hub.load("ultralytics/yolov5", "yolov5s") # or yolov5m, yolov5x, custom
# Images
img = "https://ultralytics.com/images/zidane.jpg" # or file, PIL, OpenCV, numpy, multiple
# Inference
results = model(img, augment=True) # <--- TTA inference
# Results
results.print() # or .show(), .save(), .crop(), .pandas(), etc.
์ฌ์ฉ์ ์ง์
์ ์ ์ฉ๋ TTA ์์
์ ์ฌ์ฉ์ ์ง์ ํ ์ ์์ต๋๋ค. YOLOv5 forward_augment()
๋ฉ์๋ ์ฌ๊ธฐ.
์ง์ ํ๊ฒฝ
Ultralytics ๋ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ ๋ค์ํ ํ๊ฒฝ์ ์ ๊ณตํ๋ฉฐ, ๊ฐ ํ๊ฒฝ์๋ ๋ค์๊ณผ ๊ฐ์ ํ์ ์ข ์์ฑ์ด ์ฌ์ ์ค์น๋์ด ์์ต๋๋ค. CUDA, CUDNN, Python, ๋ฐ PyTorch์ ๊ฐ์ ํ์ ์ข ์ ์์๋ฅผ ์ค์นํ์ฌ ํ๋ก์ ํธ๋ฅผ ์์ํ ์ ์์ต๋๋ค.
- ๋ฌด๋ฃ GPU ๋ ธํธ๋ถ:
- Google Cloud: GCP ๋น ๋ฅธ ์์ ๊ฐ์ด๋
- Amazon: AWS ๋น ๋ฅธ ์์ ๊ฐ์ด๋
- Azure: AzureML ๋น ๋ฅธ ์์ ๊ฐ์ด๋
- Docker: Docker ๋น ๋ฅธ ์์ ๊ฐ์ด๋
ํ๋ก์ ํธ ์ํ
์ด ๋ฐฐ์ง๋ ๋ชจ๋ YOLOv5 GitHub Actions ์ง์์ ํตํฉ(CI) ํ ์คํธ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ํต๊ณผ๋์์์ ๋ํ๋ ๋๋ค. ์ด๋ฌํ CI ํ ์คํธ๋ ๊ต์ก, ๊ฒ์ฆ, ์ถ๋ก , ๋ด๋ณด๋ด๊ธฐ ๋ฐ ๋ฒค์น๋งํฌ ๋ฑ ๋ค์ํ ์ฃผ์ ์ธก๋ฉด์์ YOLOv5 ์ ๊ธฐ๋ฅ๊ณผ ์ฑ๋ฅ์ ์๊ฒฉํ๊ฒ ํ์ธํฉ๋๋ค. 24์๊ฐ๋ง๋ค ๊ทธ๋ฆฌ๊ณ ์๋ก์ด ์ปค๋ฐ์ด ์์ ๋๋ง๋ค ํ ์คํธ๋ฅผ ์ํํ์ฌ macOS, Windows ๋ฐ Ubuntu์์ ์ผ๊ด๋๊ณ ์์ ์ ์ธ ์๋์ ๋ณด์ฅํฉ๋๋ค.