모델 튜닝
사전 학습된 YOLO 모델을 철도 도메인에 맞게 최적화하는 과정이다. 하이퍼파라미터 조정, 데이터 증강, 소형 객체 특화 기법, 앙상블을 체계적으로 적용하면 성능을 크게 향상시킬 수 있다.
핵심 요약
| 튜닝 기법 | 적용 시점 | 예상 성능 향상 | 난이도 |
|---|---|---|---|
| 학습률 스케줄링 | 학습 초기 | +2~5% mAP | 하 |
| 데이터 증강 강화 | 학습 전 | +3~8% mAP | 중 |
| SAHI 슬라이싱 | 추론 시 | +5~15% (소형 객체) | 중 |
| Attention 모듈 추가 | 아키텍처 수정 | +3~7% mAP | 고 |
| WBF 앙상블 | 추론 후처리 | +2~5% mAP | 중 |
| Ultralytics 자동 튜닝 | 하이퍼파라미터 탐색 | +3~10% mAP | 하 |
문서 탐색
하이퍼파라미터 튜닝
주요 하이퍼파라미터
# 철도 도메인 권장 하이퍼파라미터 (railway_hyp.yaml)
# 학습률
lr0: 0.001 # 초기 학습률 (기본 0.01 대비 낮게 설정 — 도메인 특화)
lrf: 0.01 # 최종 학습률 비율 (cosine annealing 종점)
momentum: 0.937 # SGD 모멘텀
weight_decay: 0.0005 # L2 정규화
# 배치 및 에포크
batch: 16 # GPU 메모리에 따라 조정 (16GB → 32, 8GB → 16)
epochs: 200 # 조기 종료(patience=50) 적용 권장
imgsz: 640 # 입력 해상도 (소형 객체: 1280 권장)
patience: 50 # 조기 종료 에포크 수
# IoU 및 신뢰도
iou: 0.7 # 학습 시 NMS IoU 임계값
conf: 0.001 # 학습 시 신뢰도 임계값 (낮게 → 더 많은 예측 평가)
# Warm-up
warmup_epochs: 5.0 # 첫 5 에포크 동안 학습률 선형 증가
warmup_momentum: 0.8
# 손실 가중치
box: 7.5 # 바운딩박스 손실 가중치
cls: 0.5 # 분류 손실 가중치 (철도: 클래스 적을 경우 낮춤)
dfl: 1.5 # Distribution Focal Loss 가중치학습률 스케줄 비교
| 스케줄 | 특징 | 추천 상황 |
|---|---|---|
| Cosine Annealing | 부드러운 감소, 수렴 안정 | 대부분의 경우 (기본값) |
| Linear Decay | 단순 선형 감소 | 빠른 실험 |
| OneCycleLR | 초반 증가 후 감소, 빠른 수렴 | 데이터 많을 때 |
| CyclicLR | 주기적 반복, 로컬 미니마 탈출 | 데이터 적을 때 |
Freeze (전이 학습 전략)
from ultralytics import YOLO
model = YOLO("yolo11m.pt")
# 데이터 적을 때: backbone 고정, head만 학습
model.train(
data="railway.yaml",
epochs=100,
freeze=10, # 첫 10 레이어 고정 (backbone 대부분)
lr0=1e-4, # 낮은 학습률 (head 미세 조정)
batch=16,
)
# 데이터 충분할 때: 전체 학습
model.train(
data="railway.yaml",
epochs=200,
freeze=0, # 전체 레이어 학습
lr0=1e-3,
batch=16,
)데이터 증강 전략
| 증강 기법 | 효과 | 철도 적합성 | 사용법 |
|---|---|---|---|
| Mosaic | 4개 이미지 합성, 소형 객체 증가 | 매우 높음 | mosaic=1.0 (기본값) |
| Mixup | 두 이미지 혼합 학습 | 중간 | mixup=0.15 |
| Copy-Paste | 객체를 다른 배경에 붙여넣기 | 높음 (지장물) | copy_paste=0.3 |
| CLAHE | 대비 제한 적응 히스토그램 균등화 | 높음 (야간·터널) | clahe=True |
| 합성 데이터 | GAN/디지털 트윈으로 이미지 생성 | 높음 (데이터 부족) | 별도 파이프라인 |
| Random Flip | 수평 뒤집기 | 낮음 (레일 방향성 있음) | fliplr=0.0 (비권장) |
| Rotate | 회전 | 중간 (드론 기울어짐) | degrees=15 |
| HSV 변환 | 색조·채도·명도 변환 | 높음 (날씨·조명) | hsv_h=0.015, hsv_s=0.7 |
주의: 철도 레일은 방향성이 있어 수평 뒤집기(
fliplr)를 적용하면 비현실적 이미지가 생성될 수 있다. 드론 시점 이미지는 조심스럽게 적용한다.
Albumentations 커스텀 증강
import albumentations as A
railway_transforms = A.Compose([
# 날씨 시뮬레이션
A.RandomRain(slant_lower=-10, slant_upper=10,
drop_length=20, drop_width=1,
drop_color=(200, 200, 200), p=0.2),
A.RandomFog(fog_coef_lower=0.1, fog_coef_upper=0.4, p=0.15),
A.RandomSunFlare(flare_roi=(0, 0, 1, 0.5),
src_radius=200, p=0.1),
# 조명 변화
A.CLAHE(clip_limit=4.0, tile_grid_size=(8, 8), p=0.3),
A.RandomBrightnessContrast(
brightness_limit=0.3, contrast_limit=0.3, p=0.4),
# 블러 (카메라 흔들림 시뮬레이션)
A.MotionBlur(blur_limit=7, p=0.2),
A.GaussNoise(var_limit=(10.0, 50.0), p=0.2),
# 기하학적 변환
A.ShiftScaleRotate(shift_limit=0.05, scale_limit=0.1,
rotate_limit=15, p=0.3),
], bbox_params=A.BboxParams(format='yolo', label_fields=['class_labels']))소형 객체 탐지 개선
SAHI 슬라이싱 추론
from sahi import AutoDetectionModel
from sahi.predict import get_sliced_prediction
from sahi.utils.cv import read_image_as_pil
# 모델 로드
detection_model = AutoDetectionModel.from_pretrained(
model_type="ultralytics",
model_path="best.pt",
confidence_threshold=0.25,
device="cuda:0",
)
# 단일 이미지 슬라이싱 추론
image = read_image_as_pil("railway_scene.jpg")
result = get_sliced_prediction(
image=image,
detection_model=detection_model,
slice_height=640,
slice_width=640,
overlap_height_ratio=0.2,
overlap_width_ratio=0.2,
postprocess_type="NMS", # 슬라이스 병합 방식: NMS 또는 NMW
postprocess_match_threshold=0.5,
)
# 결과 저장
result.export_visuals(export_dir="./output/")
object_list = result.object_prediction_list
print(f"탐지된 객체 수: {len(object_list)}")
# 배치 처리 (디렉토리 전체)
from sahi.predict import predict
predict(
model_type="ultralytics",
model_path="best.pt",
source="./railway_images/",
slice_height=640, slice_width=640,
overlap_height_ratio=0.2, overlap_width_ratio=0.2,
export_dir="./output/",
)Multi-scale Fusion 비교
| 기법 | 원리 | 성능 향상 | 속도 영향 | 구현 난이도 |
|---|---|---|---|---|
| SAHI 슬라이싱 | 타일 분할 추론 후 병합 | +5~15% (소형) | 슬라이스 수만큼 느림 | 하 (라이브러리) |
| FPN (Feature Pyramid) | 다중 스케일 피처맵 | +3~7% | 경미한 영향 | 중 (기본 내장) |
| P2 레이어 추가 | 고해상도 탐지 헤드 | +4~9% | 약간 느림 | 중 |
| TTA (테스트 증강) | 여러 변환 후 결과 평균 | +2~4% | 2~8배 느림 | 하 |
| Super-resolution | SR로 해상도 향상 후 탐지 | +3~8% | 매우 느림 | 고 |
앙상블 기법
WBF (Weighted Boxes Fusion)
WBF는 여러 모델의 탐지 결과를 가중 평균으로 병합하는 기법이다. NMS보다 박스 위치가 더 정확하고 신뢰도가 잘 보정된다.
from ensemble_boxes import weighted_boxes_fusion
# 세 모델의 탐지 결과
boxes_list = [
[[0.1, 0.1, 0.5, 0.5], [0.6, 0.6, 0.9, 0.9]], # 모델 1
[[0.11, 0.09, 0.51, 0.51], [0.61, 0.59, 0.91, 0.91]], # 모델 2
[[0.09, 0.11, 0.49, 0.49]], # 모델 3
]
scores_list = [
[0.9, 0.85], # 모델 1 신뢰도
[0.85, 0.88], # 모델 2 신뢰도
[0.78], # 모델 3 신뢰도
]
labels_list = [
[0, 1], # 모델 1 클래스
[0, 1], # 모델 2 클래스
[0], # 모델 3 클래스
]
weights = [2, 1, 1] # 모델별 가중치 (성능 좋은 모델에 높은 가중치)
# WBF 실행
boxes, scores, labels = weighted_boxes_fusion(
boxes_list,
scores_list,
labels_list,
weights=weights,
iou_thr=0.5, # 같은 객체로 판단하는 IoU 임계값
skip_box_thr=0.0001, # 이 신뢰도 미만 박스 제외
)
print(f"병합된 박스 수: {len(boxes)}")TTA (Test Time Augmentation)
from ultralytics import YOLO
model = YOLO("best.pt")
# TTA 적용 추론 (원본 + 수평뒤집기 + 스케일 변환 평균)
results = model.predict(
source="railway_image.jpg",
augment=True, # TTA 활성화
conf=0.30,
iou=0.5,
)Ultralytics 자동 튜닝
Ultralytics는 Ray Tune 기반의 하이퍼파라미터 자동 탐색 기능을 내장하고 있다.
from ultralytics import YOLO
model = YOLO("yolo11m.pt")
# 자동 하이퍼파라미터 튜닝
result_grid = model.tune(
data="railway.yaml",
epochs=50, # 각 시도당 학습 에포크
iterations=100, # 탐색 반복 횟수
optimizer="AdamW", # 최적화 알고리즘
plots=True, # 결과 시각화
save=True, # 최적 모델 저장
val=True, # 각 시도 후 검증
# 탐색 공간 정의 (선택적)
# lr0=(1e-5, 1e-1),
# momentum=(0.6, 0.98),
# weight_decay=(0.0, 0.001),
)
# 최적 하이퍼파라미터 확인
print("최적 하이퍼파라미터:", result_grid.best_config)
print("최적 mAP@50:", result_grid.best_result["metrics/mAP50(B)"])자동 튜닝 결과 활용
# 탐색된 최적 하이퍼파라미터로 전체 학습
best_hyp = result_grid.best_config
model_final = YOLO("yolo11m.pt")
model_final.train(
data="railway.yaml",
epochs=200,
**best_hyp, # 최적 하이퍼파라미터 적용
)문서 탐색
참고 자료
- Ultralytics 하이퍼파라미터 튜닝 가이드
- SAHI GitHub
- ensemble-boxes (WBF) GitHub
- Albumentations 공식 문서
- Ray Tune 공식 문서
- Zhu, X. et al. “Slicing Aided Hyper Inference and Fine-tuning for Small Object Detection.” ICCV 2021.