🤖 AI/ML

YOLO

You Only Look Once

실시간 객체 탐지 알고리즘. 한 번의 순전파로 객체 검출.

📖 상세 설명

YOLO(You Only Look Once)는 2015년 Joseph Redmon이 제안한 실시간 객체 탐지(Object Detection) 알고리즘입니다. 기존의 R-CNN 계열이 영역 제안(Region Proposal)과 분류를 두 단계로 수행했던 것과 달리, YOLO는 전체 이미지를 한 번의 신경망 순전파로 처리하여 바운딩 박스와 클래스 확률을 동시에 예측합니다. 이러한 단일 단계(Single-stage) 접근법 덕분에 실시간 처리가 가능해졌습니다.

YOLO의 핵심 아이디어는 이미지를 S x S 그리드로 나누고, 각 그리드 셀이 B개의 바운딩 박스와 C개의 클래스 확률을 예측하는 것입니다. 각 바운딩 박스는 (x, y, w, h, confidence) 5개의 값을 가지며, confidence는 박스 내 객체 존재 확률과 IoU(Intersection over Union)의 곱입니다. 이 회귀 문제로 변환된 탐지 작업은 GPU에서 매우 빠르게 처리됩니다.

YOLO는 다양한 버전으로 발전해왔습니다. YOLOv1(2015)에서 YOLOv3(2018, Darknet-53 백본)까지 원저자가 개발했고, 이후 커뮤니티 주도로 YOLOv4, YOLOv5가 등장했습니다. Ultralytics가 개발한 YOLOv8(2023)은 Anchor-free 방식과 분리된 Head 구조로 정확도와 속도를 개선했습니다. YOLOv9(2024)은 PGI(Programmable Gradient Information)와 GELAN 아키텍처로 정보 손실 문제를 해결했고, YOLO11(2024)은 22% 적은 파라미터로 더 높은 정확도를 달성했습니다.

YOLO는 자율주행 차량, CCTV 분석, 드론 영상 처리, 스포츠 분석, 제조업 품질 검사 등 실시간 객체 탐지가 필요한 분야에서 널리 사용됩니다. 탐지(Detection) 외에도 세그멘테이션(Segmentation), 포즈 추정(Pose Estimation), 추적(Tracking) 등 다양한 컴퓨터 비전 태스크를 지원합니다. 엣지 디바이스 배포를 위한 TensorRT, ONNX, CoreML 등 다양한 포맷으로 내보내기가 가능합니다.

💻 코드 예제

# YOLO11 객체 탐지 예제 (Ultralytics)
from ultralytics import YOLO
import cv2

# ============================================
# 1. 모델 로드 및 추론
# ============================================
# 사전 학습된 YOLO11 모델 로드 (n, s, m, l, x 크기)
model = YOLO("yolo11n.pt")  # nano 버전 (가장 빠름)
# model = YOLO("yolo11s.pt")  # small
# model = YOLO("yolo11m.pt")  # medium
# model = YOLO("yolo11l.pt")  # large (정확도 최대)

# 이미지 추론
results = model("image.jpg")

# 결과 확인
for result in results:
    boxes = result.boxes  # 바운딩 박스
    print(f"탐지된 객체 수: {len(boxes)}")

    for box in boxes:
        # 좌표, 클래스, 신뢰도
        x1, y1, x2, y2 = box.xyxy[0].tolist()
        conf = box.conf[0].item()
        cls_id = int(box.cls[0].item())
        cls_name = model.names[cls_id]
        print(f"  - {cls_name}: {conf:.2f} at ({x1:.0f}, {y1:.0f}, {x2:.0f}, {y2:.0f})")

# 결과 시각화 및 저장
result.save("result.jpg")

# ============================================
# 2. 비디오/웹캠 실시간 추론
# ============================================
# 웹캠 실시간 탐지
results = model.predict(source=0, show=True, stream=True)
for r in results:
    pass  # 실시간 화면 표시

# 비디오 파일 처리
results = model.predict(
    source="video.mp4",
    save=True,            # 결과 저장
    conf=0.5,             # 신뢰도 임계값
    iou=0.45,             # NMS IoU 임계값
    device="cuda:0"       # GPU 사용
)

# ============================================
# 3. 커스텀 데이터셋 학습
# ============================================
# YAML 형식의 데이터셋 설정 필요
# data.yaml 예시:
# train: ./train/images
# val: ./val/images
# nc: 3  # 클래스 수
# names: ['cat', 'dog', 'bird']

model = YOLO("yolo11n.pt")  # 사전 학습 가중치로 시작

# 학습 시작
results = model.train(
    data="data.yaml",
    epochs=100,
    imgsz=640,
    batch=16,
    device="cuda:0",
    patience=20,          # Early stopping
    save=True,
    project="runs/detect",
    name="my_model"
)

# ============================================
# 4. 모델 내보내기 (배포용)
# ============================================
# ONNX 포맷 (범용)
model.export(format="onnx", simplify=True)

# TensorRT (NVIDIA GPU 최적화)
model.export(format="engine", device=0)

# CoreML (Apple 디바이스)
model.export(format="coreml")

# TFLite (모바일/엣지)
model.export(format="tflite")

# ============================================
# 5. 다양한 태스크
# ============================================
# 인스턴스 세그멘테이션
seg_model = YOLO("yolo11n-seg.pt")
seg_results = seg_model("image.jpg")

# 포즈 추정
pose_model = YOLO("yolo11n-pose.pt")
pose_results = pose_model("image.jpg")

# 이미지 분류
cls_model = YOLO("yolo11n-cls.pt")
cls_results = cls_model("image.jpg")

# 객체 추적 (BoT-SORT, ByteTrack)
track_results = model.track(
    source="video.mp4",
    tracker="botsort.yaml",  # 또는 "bytetrack.yaml"
    persist=True
)

📊 성능 & 비용: 버전별 비교 (YOLOv8, YOLOv9, YOLO11)

COCO val2017 벤치마크 (640x640 해상도, NVIDIA T4 GPU 기준)

모델 mAP@50-95 파라미터 FLOPs 추론 속도
YOLOv8n 37.3% 3.2M 8.7G ~16ms (~61 FPS)
YOLOv8s 44.9% 11.2M 28.6G ~21ms (~48 FPS)
YOLOv8m 50.2% 25.9M 78.9G ~33ms (~30 FPS)
YOLOv9t 38.3% 2.0M 7.7G ~15ms (~67 FPS)
YOLOv9s 46.8% 7.2M 26.7G ~18ms (~56 FPS)
YOLOv9c 53.0% 25.5M 102.8G ~28ms (~36 FPS)
YOLO11n 39.5% 2.6M 6.5G ~17ms (~57 FPS)
YOLO11s 47.0% 9.4M 21.5G ~24ms (~42 FPS)
YOLO11m 51.5% 20.1M 68.0G ~27ms (~37 FPS)
YOLO11l 53.4% 25.3M 86.9G ~33ms (~30 FPS)

버전별 주요 특징:

권장 선택:

* 비용: Ultralytics YOLO는 AGPL-3.0 오픈소스 (무료). 상업용 라이선스는 Ultralytics Enterprise 문의 필요.

🗣 실무에서 이렇게 말하세요

"실시간 탐지가 필요하면 YOLO11n으로 해보고, 정확도가 부족하면 s나 m으로 올려요."

-> 모델 크기 선택 논의 시

"TensorRT로 변환해서 배포하면 추론 속도가 2-3배 빨라져요."

-> 프로덕션 배포 최적화 시

"커스텀 데이터로 fine-tuning할 때 pretrained weight에서 시작하세요."

-> 커스텀 학습 가이드 시

"YOLO11이 파라미터 대비 성능이 제일 좋아서 새 프로젝트는 이걸로 시작해요."

-> 버전 선택 조언 시

⚠ 흔한 실수 & 주의사항

입력 이미지 크기 불일치

학습 시 640x640으로 했는데 추론 시 다른 크기를 쓰면 성능이 떨어집니다. imgsz 파라미터를 일치시키세요.

conf 임계값을 너무 낮게 설정

conf=0.1처럼 낮으면 오탐(False Positive)이 급증합니다. 보통 0.25~0.5 사이에서 시작하세요.

데이터 증강 과다

mosaic, mixup 등 과도한 증강은 작은 객체 탐지에 오히려 해롭습니다. 마지막 10 에폭은 증강을 끄세요 (close_mosaic 옵션).

올바른 접근: 점진적 최적화

1) 기본 설정으로 baseline 확립 2) conf/iou 임계값 조정 3) 모델 크기 변경 4) 하이퍼파라미터 fine-tuning 5) 배포 포맷 최적화 (ONNX/TensorRT)

🔗 관련 용어

📚 더 배우기