
입력은 보통 H×W×3 이미지이고, 출력은 여러 예측 박스이며, 각 박스는 보통 다음과 같은 정보를 지닌다.
Object Detection은 Proposal-based model(Two-stage model)과 Proposal-free model(One-stage model)로 구분된다.

Two-stage Detector(=Proposal-based model)은 후보 영역(Region Proposal)들을 명시적으로 만들고, 2차적으로 후보 박스들을 분류하는 모델을 의미한다. R-CNN 계열 모델(Fast R-CNN, Faster R-CNN)처럼 Region Proposal을 먼저 찾은 후 분류하는 방식을 지니는 모델들이 이에 해당한다.
Two-stage Detector은 객체를 탐지하기 위해 먼저 Region Proposal 단계에서 객체가 있을 가능성이 높은 후보 영역을 찾고, 이후 Classification 단계에서 후보 영역을 정제하여 최종적으로 객체를 분류한다.
하지만, 이러한 Two-stage Detector는 일반적으로 높은 정확도를 보인다는 장점이 있으나, 구조가 상대적으로 복잡하고, 속도가 느릴 수 있고, 각 단계가 모듈화되어 end-to-end 학습이 어렵다는 단점이 존재한다.
Two-stage Detector의 단계
- 후보 영역(region proposals)을 만든다.
- 각 후보 영역에 대해 분류 + 박스 보정을 수행한다.

One-stage Detector(=Proposal-free model)은 별도의 Region Proposal 과정 없이, 이미지를 한 번만 처리하여 객체를 탐지하는 방식을 의미한다. 즉, Region Proposal 단계를 분리하지 않고 이미지에서 바로 클래스와 박스를 예측하는 것이다. YOLO, SSD, RetinaNet 같은 모델들이 이에 해당한다. 이때, Dectector는 밀집된(dense) 후보 위치들에 대해 한 번에 예측하므로 구조가 단순하고 빠르다는 특징이 있다.

쉽게 설명해서, Two-stage Detector는 수상한 곳 몇 군데를 뽑고, 그 부분만 확대하여 자세히 보는 방법인데 반해, One-stage Detector는 사진 전체에 격자를 촘촘히 깔고 모든 칸에서 동시에 “여기 물체 있나? 있으면 뭐고 박스는 어디지?”를 바로 판단하는 것임.
YOLO는 객체 탐지를 단일 회귀(Single Regression) 문제로 바라본 대표 모델로, 원 논문은 객체탐지 파이프라인 전체를 하나의 네트워크로 묶어 end-to-end로 최적화하는 관점을 제시하였다.
다시 말해, YOLO는 이미지 전체를 입력으로 받아 별도의 proposal 단계 없이, 하나의 네트워크가 bounding box 좌표와 클래스 확률을 직접 한 번에 예측하는 구조를 지닌다.
Image -> Proposal -> Classifier/Regressor -> OutputImage -> Dense Prediction -> NMS -> OutputYOLO의 출발점은 Proposal을 별도로 두지 않고 바로 예측하자는 철학이며, 이러한 특성으로 인해 빠르다는 장점이 있어 실시간 객체 탐지의 대표 계열이 되었다. 과거에는 One-stage의 정확도가 Two-stage보다 낮은 경향성이 있었으나, 현대의 YOLO 계열은 정확도와 속도를 모두 크게 개선했다. 또한, One-stage는 내부적으로 많은 위치/스케일에서 예측하므로 일종의 Dense Candidates 개념이 남아 있긴 하기에 후보 박스가 전혀 없는 것은 아니다. 하지만, Two-stage처럼 명시적 Proposal 단계가 분리되지는 않았다는 특징이 있다. YOLO가 빠른 이유는 단순히 One-stage여서가 아니라, RPN 같은 별도 proposal 생성 모듈이 따로 분리되어 있지 않고, backbone이 뽑은 feature에서 바로 detection head가 예측하는 구조이기 때문이다.

YOLOv1은 입력 이미지를 S × S grid로 나누고, 각 grid cell이 자신의 영역에 속한 객체 중심(center)를 담당하게 한다. 원 논문에서 대표적으로 소개되는 설정은 다음과 같다.

최종 출력 텐서 크기는 다음과 같다.
위 설정이면
이 된다.

각 grid cell은 다음을 예측한다.
B개의 Bounding box
bbox 표기에서의 핵심은 좌상단과 우하단 좌표를 저장하는 것이 아니라, 중심과 크기를 기반으로 위치를 기술한다는 것이다. YOLO Detection 라벨은 대게 class x_center, y_center, width, height 형식을 따름.
정규화 좌표를 쓰면 이미지 해상도가 달라도 같은 표현을 유지할 수 있고, 추론 결과를 해석할 때는 이 값들이 다시 픽셀 좌표로 복원되어 화면에 그려짐.
이때, YOLO 형식의 기본 detection 라벨은 xyxy가 아니라 normalized wywh이다.

각 bounding box에 대한 confidence score
C개의 conditional class probabilities
Objectness : 물체인지 아닌지 여부
Class Probability : 물체라면 어떤 클래스인지 확률
YOLO의 score를 해석할 때는 objectness, class probability, 즉 클래스를 맞추는 것과 그 박스가 실제 객체를 담고 있는가 라는 문제의 축이 결합되어 최종 순위가 결정된다.

• Detection score는 단순한 분류 확률이 아니라 박스의 신뢰성과 클래스 정보가 결합된 값이다.
• class probability가 높아도 objectness가 낮으면 최종 score는 낮아지고, objectness가 높아도 클래스 구분이 불명확하면 특정 클래스의 score는 높지 않다.
• 실제 후처리에서는 이 score를 기준으로 thresholding과 NMS가 이어진다.
• 이때, confidence와 class probability를 같은 값으로 생각하면 안 되며, score가 높다는 사실만으로 localization 품질이 자동으로 보장되는 것은 아니다.
• Detection score는 단순한 분류 확률이 아니라 박스의 신뢰성과 클래스 정보가 결합된 값이다.
• class probability가 높아도 objectness가 낮으면 최종 score는 낮아지고, objectness가 높아도 클래스 구분이 불명확하면 특정 클래스의 score는 높지 않다.
• 실제 후처리에서는 이 score를 기준으로 thresholding과 NMS가 이어진다.
• 이때, confidence와 class probability를 같은 값으로 생각하면 안 되며, score가 높다는 사실만으로 localization 품질이 자동으로 보장되는 것은 아니다.
Bounding box 하나는 보통 다음과 같이 요약한다.

이전 계열은 “영역 후보 → 분류”의 파이프라인이 강했다. 반면, YOLO는 이미지 전체를 보고 한 번에 예측하기 때문에, 전역 문맥(global context)를 활용하기 쉽고 속도도 매우 빨랐다.
하지만, YOLOv1은 각 grid cell이 강한 공간 제약을 가지므로, 작은 객체나 촘촘히 모여 있는 객체에 약했다. 원 논문도 localization error가 상대적으로 많음을 언급한다.

NMS는 객체당 대표 박스 하나만 남기기 위해 사용하는 대표적인 후처리 방식이다. 객체 감지 모델에서 겹치는 Bounding Box를 제거하여 최종 결과를 정리한다. 이러한 NMS은 “최대가 아닌 것을 억제한다”라는 뜻으로, 높은 score의 대표 박스를 하나 남기고 겹치는 중복 박스를 줄이는 알고리즘이다. 이는 간단하고 효과적이며, 중복 탐지를 크게 줄여준다는 장점이 있으나, 서로 가까이 있는 객체가 많으면 박스를 과하게 제거할 수 있고, 임계값 τ와 confidence threshold에 민감할 수 있다.
실제 YOLO에서는 Image → Model Prediction → Score Filtering → NMS → Final Detection의 흐름으로 진행된다. NMS는 학습 과정이라기보다는 보통 추론 후처리의 과정이며, IoU threshold를 낮춘다고 해서 무조건 좋은 것이 아니라, 너무 낮으면 서로 다른 객체까지 제거될 수 있다.
NMS 절차
NMS는 같은 객체 주변에 여러 박스가 생성되었을 때, 대표 박스를 남기고 중복 박스를 제거하는 절차이다. score가 가장 높은 박스를 먼저 선택한 뒤, IoU가 큰 나머지 박스를 차례로 제거한다.


IoU는 예측 박스와 정답 박스의 겹침 정도를 나타내는 대표 지표로, 예측 박스와 정답 박스가 얼마나 겹치는지를 정량화하기 위해 다음과 같은 수식을 활용한다.

Object Detection(객체 검출) 모델의 성능을 측정하기 위해선 Precision(정밀도), Recall(재현율), Average Precision(AP)에 대해 알아야 한다. 객체 검출과 작업에서는 Precision, Recall 등의 개념이 중요한데, 그 이유는 객체 검출 성능이 좋지 않을 때 오검출을 많이 했을 수도 있고, 검출 자체가 잘 안됐을 수도(미검출) 있기 때문이다.

Precision (정밀도)
Recall (재현율)
Precision이 낮다는 것은 오검출이 많다는 것이고, Recall이 낮다는 것은 미검출이 많다는 것이다. 때문에 일반적으로 Confidence threshold에 따라 Precision과 Recall은 변화하며, 두 수치 간의 관계는 반비례이다. Threshold를 낮춰 많이 검출하다 보면 미검출(Recall)은 적어지지만 오검출(Precision)이 많아지고, Threshold를 높여 보수적으로 검출하다보면 놓치는 객체가 많아져 오검출(Precision)은 적어지지만 미검출(Recall)이 많아지기 때문이다..
Precision이 중요한 경우 (Precision이 낮으면 안되는 경우)
Recall이 중요한 경우 (Recall이 낮으면 안되는 경우)

이러한 AP를 봐야하는 이유는, Threshold를 바꾸면 Precision과 Recall이 함께 바뀌기 때문이다. 따라서 하나의 지점에서의 Precision, Recall만을 보는 게 아니라 그 변화 전체를 봐야 한다. 일반적으로 Precision과 Recall은 Trade-off 관계이다. 위의 오른쪽 그림은 PR curve이며, 이는 threshold 0.3일 때의 (recall, precision), threshold 0.5일 때의 (recall, precision), threshold 0.7일 때의 (recall, precision)과 같은 점들을 이어서 만든 곡선이다. 즉, Recall이 0~1까지 변하는 동안 Precision이 전반적으로 얼마나 높게 유지되는지를 나타낸다. 그래서 이 면적이 클수록 Recall을 높여도 Precision이 잘 유지되고, Precision이 높을 때 Recall도 잘 유지된다는 것이므로 모델이 전반적으로 균형 있게 잘 검출한다는 의미가 된다.
Detection 성능은 threshold 하나만으로 요약하기 어렵다. 예를 들어 threshold를 0.5로 정했을 때 precision 0.8, recall 0.7이 나왔다고 해도 이는 그 Threshold에서만의 성능일 뿐이다. 실제로 Threshold는 계속 변화시킬 수 있는 값이므로 모델 자체의 성능을 제대로 보려면 Threshold를 움직였을 때 전체적으로 어떤 모습인지를 봐야 한다.
Precision, Recall, AP는 객체 검출 모델의 성능을 종합적으로 평가하기 위해 사용된다. 고정된 Threshold에서 측정되는 Precision과 Recall은 모델의 성능을 특정한 조건에서 평가하는 데 사용되며, AP는 모델의 성능을 다양한 Threshold 값에서 평균화하여 측정한 값이다.
PR curve를 읽을 때는 precision과 recall이 서로 경쟁 관계에 있다는 점을 먼저 떠올리면 된다.
- threshold를 높이면 보통 precision은 올라가고 recall은 내려간다.
- threshold를 낮추면 더 많은 객체를 잡을 수 있지만 false positive도 늘 수 있다.
- AP는 이런 변화 전체를 하나의 면적으로 요약한 값이다.
오해하기 쉬운 점
- precision이 높다고 해서 항상 좋은 모델은 아니다. recall이 지나치게 낮을 수 있다.
- AP는 하나의 threshold에서 읽은 값이 아니라, curve 전체의 요약값이다.
- AP: 한 클래스에 대한 평균 정밀도
- mAP: 여러 클래스의 AP를 평균낸 값
**정리
- Precision** : “헛검출(오탐, FP)을 얼마나 줄였는가?”
- Recall : “놓친 객체(미탐, FN)를 얼마나 줄였는가?”
- AP : PR Curve 요약
- mAP : 클래스별 평균 성능
- mAP@0.50과 mAP@0.50 : 0.90은 엄격도가 다르다.
- Precision이 높아도 Recall이 매우 낮을 수 있기에 Precision이 높을 수록 무조건 좋은 모델은 아니다.
- mAP50이 높다고 무조건 Localization이 좋은 것은 아니다. 더 엄격한 Localization 평가는 mAP@0.50 : 0.95를 같이 봐야 한다.

Anchor Box(= Template, Prior Box)는 미리 정해 둔 박스 prior(template) box이다. Anchor-based 방식은 미리 정해둔 prior box를 기준으로 오프셋을 예측한다. 모델은 “처음부터 완전히 새로운 박스를 직접 내기”보다 anchor를 기준으로 offset을 예측한다. 즉, 어떤 Feature Map의 한 위치마다 기본 박스들을 여러 개 두고, 박스를 처음부터 완전히 새로 만들기보다 이 Anchor에서 중심을 얼마나 옮길지, 너비와 높이를 얼마나 늘리거나 줄일지를 예측해 offset을 보정하는 방식을 택한다.
YOLOv2는 anchor box를 도입하고, anchor 크기를 hand-crafted가 아니라 clustering 기반으로 정하는 개선을 포함했다. 또한 feature fusion, multi-scale training 등을 통해 original YOLO의 약점을 보완했다.
직관적으로 보면 anchor box는 다음 문제를 완화한다.
Anchor-free 방식은 미리 정한 anchor prior에 덜 의존하거나, anchor 없이 center/box를 직접 예측하려는 경향을 말한다. 즉, 미리 정한 박스 템플릿에 덜 의존하거나, 아예 없이 객체 위치를 더 직접적으로 예측하자는 흐름이다. (정답 객체의 center와 box side들과의 거리(width, height)를 구하는 방식) 예를 들어, 객체 중심점이 어디인지 그 중심에서 좌/우/위/아래 경계까지의 거리 예측, 좌상단 우하단 좌표 예측을 통해 박스를 만든다. 기본 박스를 수정하는 대신 물체를 바로 설명해 박스를 만드는 방식이다. 따라서 중심점이나 경계 거리 등 보다 직접적인 표현으로 박스를 예측하는 방식이라고 할 수 있다.
Anchor-free와 Anchor-based 중 절대적으로 하나가 항상 더 좋다고 말하기는 어려우나, 최근 계열은 구조 단순화, 유연성, 성능 향상을 위해 anchor-free 또는 objectness/head 구조의 재설계를 적극적으로 활용하는 흐름을 보인다. (YOLO 계열은 anchor 기반 설계에서 출발해, 최근에는 anchor-free 흐름을 적극적으로 받아들였으며, Ultralytics의 YOLOv8 문서는 YOLOv8의 핵심 특징으로 anchor-free split head를 강조한다.)
Anchor-based와 Anchor-free의 결과물은 모 bounding box지만, 출발점과 label assignment 방식이 다르다. 다시 말해, 결과는 둘 다 Bounding Box이지만, Anchor-based는 기준 박스와의 차이를 학습하고, Anchor-Free는 객체 자체의 위치/크기 표현을 학습한다는 차이가 있다. Anchor-based의 label-assignment는 정답 박스(GT Box)와 각 Anchor의 IoU를 계산해 Positive Anchor를 찾고(IoU 기반 label assignment), Anchor Free는 어떤 위치가 객체 중심인지 예측해 그 중심에서 박스 크기를 예측하거나, 특정 위치 (x, y)를 기반으로 좌우상하 경계까지의 거리를 예측해 박스를 만들어 예측하며, 어떤 위치가 객체 중심/내부/주변에 있느냐에 따라 label-assignment를 한다. (IoU가 아니라 중심 영역, 박스 내부 위치, 거리 기반 규칙 등 공간적 기준에 더 크게 의존)
요약
- anchor 설계는 단순한 구현 디테일이 아니라, 모델이 박스를 어떻게 parameterize하고 학습하느냐와 연결된다.
- anchor-based는 prior box와의 차이를 학습한다.
- anchor-free는 기준 박스를 덜 의존하고, 중심점 기반 할당과 직접 회귀를 강조한다. 최근 계열은 복잡한 anchor tuning 부담을 줄이기 위해 anchor-free 방향으로 이동하는 경향이 뚜렷하다.
- 중심점 기반 할당 : 객체의 중심점을 Positive Sample로 정의하고, 객체의 중심 근처 픽셀은 해당 객체를 학습하고, 배경 근처 픽셀은 배경으로 학습하는 것
- 직접 회귀 : 특정 픽셀(중심점 근처)에서 해당 객체의 경계 박스까지의 거리(좌, 우, 상, 하, 또는 중심점으로부터의 상대 좌표)를 딥러닝 모델이 직접 회귀(Regression)하여 찾아내는 것
**오해하기 쉬운 점
Anchor-based는 사전 정의 다양한 크기의 박스(Anchor)를 활용해 객체 위치를 조정하는 전통적 방식(Faster R-CNN, YOLOv3 등)이다. 반면, Anchor-free는 사전 정의된 박스 없이 객체의 중심점, 특징점(Keypoint) 또는 영역을 직접 예측하는 방식(FCOS, CenterNet 등)이다.
- Anchor-based : “기준 박스(anchor)를 놓고 얼마나 수정할지 예측하는 것” / 즉, 미리 준비된 박스 후보(anchor)를 기준으로 조금씩 수정해서 정답 박스를 만드는 방식
- Anchor-free : “객체 중심/경계 정보를 더 직접적으로 예측하는 것” / 즉, 미리 준비된 박스 없이, 물체의 중심이나 경계까지의 거리를 직접 예측해서 박스를 만든다.
이때, Anchor-free도 최종 출력은 여전히 Bounding Box이며, Anchor를 없앤다고 무조건 단순하고 좋은 것도 아니라는 것을 알아야 한다. 구현과 학습 안정성은 모델 설계 전체와 함께 봐야한다.
YOLOv1은 객체탐지를 단일 회귀 문제로 공식화하여, 이미지 전체를 한 번에 입력받고 bounding box와 class probability를 직접 예측했다. 하나의 네트워크로 end-to-end 추론이 가능해 실시간 탐지가 가능했지만, 작은 객체 탐지와 localization 정확도에서는 한계가 있었다.
YOLO9000 논문은 YOLOv2 개선과 더불어 9000개 이상의 클래스 검출 아이디어를 제시했다. 핵심 포인트는 다음과 같다. (YOLOv2는 anchor 도입과 multi-scale training으로 중요한 전환점을 만들었다.)
YOLOv3는 여러 작은 설계 변경으로 성능을 높였다. 대표 포인트는 다음과 같다.
즉, 작은 객체 처리를 더 강화하고, backbone과 multi-scale 전략을 개선했다.
YOLOv5는 Ultralytics가 널리 보급시킨 실용적 구현 계열이다. 공식 문서는 YOLOv5에 대해 formal research paper는 없고, 최신 정보는 문서와 저장소를 참고하라고 명시한다.
즉, YOLOv5는 “논문보다는 실무 생태계와 사용성 측면에서 중요성이 매우 큰 버전”이라고 볼 수 있다.
“YOLOv5가 YOLOv4의 공식 후속 논문인가요?” → 반드시 그렇게 단순화할 수는 없고, Ultralytics 구현 계열로 이해하는 것이 안전하다.
Ultralytics 문서는 YOLOv8의 특징으로 다음을 강조한다.
anchor-free split head
향상된 backbone / neck
detection뿐 아니라 segmentation, pose, classification 등 다양한 task 지원
accuracy-speed tradeoff 개선
따라서 YOLOv8은 단순히 detector 하나가 아니라, 현대 Ultralytics 비전 프레임워크의 중심 모델로 이해하는 것이 좋다.
“YOLOv8은 그냥 v5보다 조금 좋아진 버전인가요?” → head 설계 철학과 task 확장성이 더 크다.

정리
YOLO의 발전은 단순히 “버전 번호 증가”가 아니라,
1. 예측 방식 개선
2. backbone 개선
3. multi-scale 처리 강화
4. 학습/배포 사용성 향상
의 흐름이다.
버전별 흐름을 읽을 때는 각 세대가 해결하려 한 문제를 함께 보는 것이 중요하다.
1. YOLOv1은 end-to-end one-stage detection의 관점을 정립했다.
2. YOLOv2는 anchor와 multi-scale training으로 성능과 안정성을 높였다.
3. YOLOv3는 multi-scale prediction과 Darknet-53으로 작은 객체 대응을 강화했다.
4. YOLOv5는 실무 친화적인 구현과 사용 편의성 측면에서 큰 영향을 주었다.
5. YOLOv8은 anchor-free split head와 다양한 task 지원을 전면에 내세운다.
오해하기 쉬운 점
Backbone은 이미지에서 시각 특징(feature)을 추출하는 부분이다. edge, texture, shape, semantic feature를 점점 추상적으로 추출하고, 다운샘플링을 통해 receptive field를 넓힌다.
Neck은 서로 다른 해상도의 feature를 결합한다. (서로 다른 해상도의 특징을 융합한다) 큰 객체는 깊은 레벨 feature가 유리하고, 작은 객체는 상대적으로 고해상도 feature가 중요하기 때문이다.
Head는 최종적으로 bounding box, class score, objectness / confidence에 해당하는 값(버전에 따라 구조 차이 존재)을 예측한다. (최종 box, class, objectness 관련 예측을 생성한다.) YOLOv8 문서는 anchor-free split head를 강조한다.
YOLO 계열을 이해할 때는 모델을 하나의 CNN 덩어리로 보기보다, 특징 추출–특징 융합–최종 예측의 세 부분으로 나누어 보는 것이 훨씬 유용하다. 이는 Backbone이 표현을 만들고, Neck이 서로 다른 해상도의 feature를 결합하며, Head가 각 위치에서 box/class/objectness 관련 출력을 생성하는 흐름을 지닌다. 이때, Backbone이 약하면 표현력이 부족하고, Neck이 약하면 multi-scale 객체를 잘 다루기 어려우며, Head가 약하면 최종 detection 품질이 떨어진다.
또한, 작은 객체 검출이나 multi-scale detection을 설명할 때는 Backbone 뿐만 아니라 Neck의 역할을 함께 강조하는 것이 중요하다. 저수준 Feature map은 해상도가 높아 작은 객체 위치를 잘 살리고, 깊은 Feature map은 추상적 의미가 강해 이게 무엇인지를 잘 판단할 수 있다. 이때, Neck은 이 둘을 연결해 작지만 중요한 물체도 놓치지 않게 해주는 역할을 한다. 여러 scale의 feature를 연결하고 융합해주기 때문이다. 다시 말해, 작은 객체 검출 성능이 단순히 여러 scale에서 예측한다는 점만으로 설명하기 어려운 이유는 서로 다른 해상도의 feature를 융합하는 Neck이 있기 때문에 작은 객체와 큰 객체를 모두 더 잘 탐지할 수 있다.
- “Backbone이 곧 YOLO 전체인가요?” → 아니다. detector는 backbone만으로 끝나지 않는다. 따라서 Backbone만 좋아도 Detector 전체가 좋아진다고 볼 수는 없다.
- “Head는 classifier랑 같은 건가요?” → detection head는 class뿐 아니라 box 관련 예측도 함께 수행하므로 classifier와는 차이가 있다. (Head를 단순 classifier로 이해하면 안 된다. detection head는 box와 score까지 함께 다룬다.)

YOLO의 loss는 버전에 따라 구현이 달라지지만, 교육적으로는 보통 다음 세 부분으로 나누어 이해하면 좋다.


*.txt 파일을 사용하며, 각 줄은 class x_center, y_center width, height 형식을 따른다. 단, 이미지에 객체가 없으면 txt 파일이 없어도 된다.
my_data/
├── images/
│ ├── train/
│ ├── val/
│ └── test/
├── labels/
│ ├── train/
│ ├── val/
│ └── test/
└── data.yaml
data.yaml 예시*.txt 파일을 사용하며, 각 줄은 class x_center, y_center width, height 형식을 따른다 에서 class 와 data.yaml의 names를 매칭해 이름을 읽어옴.path: /content/my_dataset
train: images/train
val: images/val
test: images/test
names:
0: person
1: helmet
2: vest

