์ฝ˜ํ…์ธ ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

ํ”„๋กœ์ฆŒ ๋ ˆ์ด์–ด๋ฅผ ์‚ฌ์šฉํ•œ ์ „์ด ํ•™์Šต

์ด ๊ฐ€์ด๋“œ์—์„œ๋Š” ์ „์ด ํ•™์Šต ์‹œ 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

๋ฐฑ๋ณธ ๋™๊ฒฐ

train.py์™€ ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ๋ ˆ์ด์–ด freeze ๋ชฉ๋ก์€ ํ›ˆ๋ จ์ด ์‹œ์ž‘๋˜๊ธฐ ์ „์— ๊ทธ๋ผ๋ฐ์ด์…˜์„ 0์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค.

# Freeze
freeze = [f"model.{x}." for x in range(freeze)]  # layers to freeze
for k, v in model.named_parameters():
    v.requires_grad = True  # train all layers
    if any(x in k for x in freeze):
        print(f"freezing {k}")
        v.requires_grad = False

๋ชจ๋“ˆ ์ด๋ฆ„ ๋ชฉ๋ก์„ ๋ณด๋ ค๋ฉด

for k, v in model.named_parameters():
    print(k)

"""Output:
model.0.conv.conv.weight
model.0.conv.bn.weight
model.0.conv.bn.bias
model.1.conv.weight
model.1.bn.weight
model.1.bn.bias
model.2.cv1.conv.weight
model.2.cv1.bn.weight
...
model.23.m.0.cv2.bn.weight
model.23.m.0.cv2.bn.bias
model.24.m.0.weight
model.24.m.0.bias
model.24.m.1.weight
model.24.m.1.bias
model.24.m.2.weight
model.24.m.2.bias
"""

๋ชจ๋ธ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ดํŽด๋ณด๋ฉด ๋ชจ๋ธ ๋ฐฑ๋ณธ์ด 0-9 ๋ ˆ์ด์–ด์ž„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

# YOLOv5 v6.0 backbone
backbone:
    # [from, number, module, args]
    - [-1, 1, Conv, [64, 6, 2, 2]] # 0-P1/2
    - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
    - [-1, 3, C3, [128]]
    - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
    - [-1, 6, C3, [256]]
    - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16
    - [-1, 9, C3, [512]]
    - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32
    - [-1, 3, C3, [1024]]
    - [-1, 1, SPPF, [1024, 5]] # 9

# YOLOv5 v6.0 head
head:
    - [-1, 1, Conv, [512, 1, 1]]
    - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
    - [[-1, 6], 1, Concat, [1]] # cat backbone P4
    - [-1, 3, C3, [512, False]] # 13

    - [-1, 1, Conv, [256, 1, 1]]
    - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
    - [[-1, 4], 1, Concat, [1]] # cat backbone P3
    - [-1, 3, C3, [256, False]] # 17 (P3/8-small)

    - [-1, 1, Conv, [256, 3, 2]]
    - [[-1, 14], 1, Concat, [1]] # cat head P4
    - [-1, 3, C3, [512, False]] # 20 (P4/16-medium)

    - [-1, 1, Conv, [512, 3, 2]]
    - [[-1, 10], 1, Concat, [1]] # cat head P5
    - [-1, 3, C3, [1024, False]] # 23 (P5/32-large)

    - [[17, 20, 23], 1, Detect, [nc]] # Detect(P3, P4, P5)

๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฆ„์— 'model.0'์ด ์žˆ๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ์„ ํฌํ•จํ•˜๋„๋ก ๊ณ ์ • ๋ชฉ๋ก์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - 'model.9.'๋ฅผ ์ด๋ฆ„์— ํฌํ•จํ•˜๋„๋ก ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

python train.py --freeze 10

๋ชจ๋“  ๋ ˆ์ด์–ด ๊ณ ์ •

Detect()์—์„œ ์ตœ์ข… ์ถœ๋ ฅ ์ปจ๋ณผ๋ฃจ์…˜ ๋ ˆ์ด์–ด๋ฅผ ์ œ์™ธํ•œ ์ „์ฒด ๋ชจ๋ธ์„ ๊ณ ์ •ํ•˜๋ ค๋ฉด, ์ด๋ฆ„์ด 'model.0'์ธ ๋ชจ๋“  ๋ชจ๋“ˆ์„ ํฌํ•จํ•˜๋„๋ก ๊ณ ์ • ๋ชฉ๋ก์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. - 'model.23'์ด ํฌํ•จ๋œ ๋ชจ๋“  ๋ชจ๋“ˆ์„ ํฌํ•จํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค:

python train.py --freeze 24

๊ฒฐ๊ณผ

์šฐ๋ฆฌ๋Š” ์œ„์˜ ๋‘ ๊ฐ€์ง€ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ๊ธฐ๋ณธ ๋ชจ๋ธ(๋™๊ฒฐ ์—†์Œ)๊ณผ ํ•จ๊ป˜ ๊ณต์‹ COCO ์‚ฌ์ „ ํ›ˆ๋ จ์—์„œ ์‹œ์ž‘ํ•˜์—ฌ YOLOv5m์„ VOC์— ๋Œ€ํ•ด ํ›ˆ๋ จํ•ฉ๋‹ˆ๋‹ค. --weights yolov5m.pt:

train.py --batch 48 --weights yolov5m.pt --data voc.yaml --epochs 50 --cache --img 512 --hyp hyp.finetune.yaml

์ •ํ™•๋„ ๋น„๊ต

๊ทธ ๊ฒฐ๊ณผ ๋™๊ฒฐํ•˜๋ฉด ํ›ˆ๋ จ ์†๋„๊ฐ€ ๋นจ๋ผ์ง€์ง€๋งŒ ์ตœ์ข… ์ •ํ™•๋„๋Š” ์•ฝ๊ฐ„ ๋–จ์–ด์ง€๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค.

๋™๊ฒฐ ํ›ˆ๋ จ mAP50 ๊ฒฐ๊ณผ

๋™๊ฒฐ ํ›ˆ๋ จ mAP50-95 ๊ฒฐ๊ณผ

ํ‘œ ๊ฒฐ๊ณผ

GPU ์‚ฌ์šฉ๋ฅ  ๋น„๊ต

ํฅ๋ฏธ๋กญ๊ฒŒ๋„ ๋” ๋งŽ์€ ๋ชจ๋“ˆ์ด ๊ณ ์ •๋ ์ˆ˜๋ก ํ›ˆ๋ จ์— ํ•„์š”ํ•œ GPU ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ค„์–ด๋“ค๊ณ  GPU ์‚ฌ์šฉ๋ฅ ๋„ ๋‚ฎ์•„์ง‘๋‹ˆ๋‹ค. ์ด๋Š” ๋” ํฐ ๋ชจ๋ธ ๋˜๋Š” ๋” ํฐ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋กœ ํ›ˆ๋ จ๋œ ๋ชจ๋ธ์ด ๋” ๋น ๋ฅด๊ฒŒ ํ›ˆ๋ จํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋ฆฌ์ง•์˜ ์ด์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

ํŠธ๋ ˆ์ด๋‹ GPU ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋น„์œจ

ํŠธ๋ ˆ์ด๋‹ GPU ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋ฅ 

์ง€์› ํ™˜๊ฒฝ

Ultralytics ๋Š” ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜๋ฉฐ, ๊ฐ ํ™˜๊ฒฝ์—๋Š” CUDA, CUDNN๊ณผ ๊ฐ™์€ ํ•„์ˆ˜ ์ข…์†์„ฑ์ด ์‚ฌ์ „ ์„ค์น˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค, Python๋ฐ PyTorch์™€ ๊ฐ™์€ ํ•„์ˆ˜ ์ข…์† ์š”์†Œ๊ฐ€ ์‚ฌ์ „ ์„ค์น˜๋˜์–ด ์žˆ์–ด ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ์ƒํƒœ

YOLOv5 CI

์ด ๋ฐฐ์ง€๋Š” ๋ชจ๋“  YOLOv5 GitHub Actions ์ง€์†์  ํ†ตํ•ฉ(CI) ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ํ†ต๊ณผ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ CI ํ…Œ์ŠคํŠธ๋Š” ๊ต์œก, ๊ฒ€์ฆ, ์ถ”๋ก , ๋‚ด๋ณด๋‚ด๊ธฐ ๋ฐ ๋ฒค์น˜๋งˆํฌ ๋“ฑ ๋‹ค์–‘ํ•œ ์ฃผ์š” ์ธก๋ฉด์—์„œ YOLOv5 ์˜ ๊ธฐ๋Šฅ๊ณผ ์„ฑ๋Šฅ์„ ์—„๊ฒฉํ•˜๊ฒŒ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. 24์‹œ๊ฐ„๋งˆ๋‹ค ๊ทธ๋ฆฌ๊ณ  ์ƒˆ๋กœ์šด ์ปค๋ฐ‹์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ macOS, Windows ๋ฐ Ubuntu์—์„œ ์ผ๊ด€๋˜๊ณ  ์•ˆ์ •์ ์ธ ์ž‘๋™์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.



Created 2023-11-12, Updated 2024-06-10
Authors: glenn-jocher (7)

๋Œ“๊ธ€