객체 인식 평가
경계 상자의 위치 평가
객체 인식은 예측한 클래스뿐 아니라 경계 상자의 위치도 평가. 교집합 영역 비율(Intersection over Union, IoU)은 예측 상자와 정답 상자가 얼마나 겹치는지를 나타내는 값.
IoU=합집합 면적교집합 면적1에 가까울수록 두 상자가 많이 겹침0이면 두 상자가 겹치지 않음


올바른 탐지의 기준
예측 클래스가 정답 클래스와 같고 IoU가 정해진 임계값 이상이면 올바른 탐지로 판정.
- 참 양성(True Positive, TP): 올바르게 탐지한 객체
- 거짓 양성(False Positive, FP): 객체라고 예측했지만 틀린 결과
- 거짓 음성(False Negative, FN): 모델이 놓친 실제 객체
신뢰도(confidence) 임계값은 남길 예측을 정하고, IoU 임계값은 예측 위치를 정답으로 인정할 기준을 정함.
정밀도와 재현도
- 정밀도(Precision): 모델이 탐지한 결과 중 올바른 탐지의 비율
- 재현도(Recall): 실제 객체 중 모델이 찾아낸 객체의 비율
- 정밀도-재현도 곡선(Precision-Recall Curve): 가로축을 재현도, 세로축을 정밀도로 그린 그래프
신뢰도 임계값을 바꾸면 정밀도와 재현도도 함께 변함. PR 곡선은 여러 신뢰도 임계값에서 두 지표의 관계를 보여 줌.
AP와 mAP
- 평균 정밀도(Average Precision, AP): 한 클래스와 한 IoU 기준에서 PR 곡선 아래의 면적을 요약한 값
- 평균 AP(mean Average Precision, mAP): 클래스별 AP의 평균
- mAP50: IoU 임계값
0.5에서 계산한 mAP - mAP50-95: IoU 임계값을
0.5부터0.95까지0.05씩 바꾸어 계산한 mAP의 평균

실습 준비
from PIL import Image
from ultralytics import YOLO
성능 측정
사전 학습된 YOLO 모델을 coco128 데이터셋으로 검증. plots=True로 설정하면 혼동 행렬과 평가 곡선도 함께 저장.
model = YOLO("yolo26n.pt")
metrics = model.val(data="coco128.yaml", plots=True)
실행 결과
Class Images Instances Box(P R mAP50 mAP50-95)
all 128 929 0.665 0.559 0.644 0.479
검증 결과에서 정밀도 P, 재현도 R, mAP50, mAP50-95를 확인할 수 있음.
혼동 행렬
cm = metrics.confusion_matrix.to_df()
ncm = metrics.confusion_matrix.to_df(normalize=True) # 비율로 표시
곰 인형을 실제 클래스로 가지는 객체가 어떤 클래스로 예측되었는지 확인.
column = "teddy_bear"
ncm[["Predicted", column]].sort(column, descending=True)

정밀도(Precision) 곡선
신뢰도 임계값에 따른 정밀도 곡선.
Image.open(metrics.save_dir / "BoxP_curve.png")

재현도(Recall) 곡선
신뢰도 임계값에 따른 재현도 곡선.
Image.open(metrics.save_dir / "BoxR_curve.png")

F1 곡선
F1은 정밀도와 재현도의 조화평균. F1 곡선에서 두 지표의 균형이 좋은 신뢰도 임계값을 확인할 수 있음.
Image.open(metrics.save_dir / "BoxF1_curve.png")

PR 곡선
재현도에 따른 정밀도 곡선. 한 클래스의 곡선 아래 면적은 AP이고, 클래스별 AP를 평균하면 mAP가 됨.
Image.open(metrics.save_dir / "BoxPR_curve.png")

퀴즈
예측 경계 상자와 정답 경계 상자의 교집합이 40픽셀이고 합집합이 100픽셀입니다. IoU는 얼마입니까?
퀴즈를 풀려면 대화형 기능을 불러와야 합니다.