YOLO 아키텍처 설명: YOLOv3부터 YOLO26까지#
모든 Ultralytics YOLO 모델은 피처를 추출하는 백본(backbone), 스케일에 걸쳐 이를 융합하는 넥(neck), 그리고 박스와 클래스를 예측하는 **헤드(head)**의 세 가지 단계로 구성됩니다. 이 가이드는 각 단계를 이루는 모듈과 이들이 YOLOv3에서 YOLO26으로 어떻게 변화했는지 설명하며, ultralytics/cfg/models/ 아래의 설정 파일과 ultralytics/nn/modules/의 모듈 클래스에 정의된 모든 컴포넌트를 추적합니다.
각 모델은 YAML 파일에 레이어의 순서 있는 목록으로 선언적 정의되며, 모든 레이어는 [from, repeats, module, args] 형식을 따릅니다: 해당 레이어에 입력을 제공하는 레이어, 모듈 반복 횟수, 레이어 클래스 (Conv, C3k2, SPPF, Detect, …) 및 생성자 인자입니다. Model YAML Configuration Guide에서는 repeats 및 args이 변형의 깊이 및 너비 배수에 따라 스케일링되는 방식을 포함하여 이 형식을 문서화하고 모듈 해상도 시스템을 전체적으로 설명합니다. 본 가이드는 모듈 자체와 버전별 변화에 집중합니다.
세 가지 단계#
모든 Ultralytics YOLO 모델은 이미지를 순차적인 세 단계를 거쳐 처리하며, 각 단계는 고유한 역할을 수행합니다:
| 단계 | 작업 | 출력 |
|---|---|---|
| 백본 | 입력 이미지로부터 다중 해상도로 특징 추출 | 스트라이드 8, 16, 32(P3, P4, P5)에서의 특징 맵 |
| 넥 | 작은 객체와 큰 객체 모두 문맥을 가질 수 있도록 규모별 특징 융합 | 다중 규모 융합 특징 맵 |
| 헤드 | 융합된 특징으로부터 경계 상자 및 클래스 점수 예측 | 앵커 포인트당 탐지 |
기본 단위는 Conv 블록(conv.py에 정의됨)이며, 순서대로 적용되는 2D 합성곱(convolution), 배치 정규화(batch normalization), 그리고 SiLU 활성화 함수로 구성됩니다. 아래의 모든 더 큰 모듈들은 Conv 블록을 조합하여 구축됩니다.
아키텍처 다이어그램#
각 버전은 동일한 backbone → neck → head 스켈레톤을 유지하면서 특정 단계를 변경합니다. 아래 탭은 버전별 구조를 보여줍니다. 백본과 넥 단계는 ultralytics/cfg/models/의 설정(config)을 따르며, YOLOv3 및 YOLOv5 헤드는 패키지 설정이 실제로 탑재하는 앵커 프리(anchor-free) u 변형 헤드가 아니라 원래의 앵커 기반(anchor-based) 형태로 그려져 있습니다. 탭을 차례로 넘겨보면 각 세대에서 추가된 내용을 확인할 수 있습니다. 요약하자면 발전 과정은 다음과 같습니다. YOLOv3은 FPN 전용 앵커 기반 검출기이고, YOLOv5는 상향식 PAN 경로와 SPPF를 추가하며, YOLOv8은 앵커 프리 DFL 헤드가 포함된 C2f 블록으로 전환하고, YOLO11은 C2PSA 어텐션과 C3k2 블록을 삽입하며, YOLO26은 SPPF 레시듀얼(residual)을 추가하고 헤드를 NMS 프리 및 DFL 프리 구조로 만듭니다. 노드 색상은 문서 다이어그램 규칙을 따릅니다. 초록색은 입력, 파란색은 백본, 슬레이트색은 공간 풀링 및 어텐션, 주황색은 넥, 보라색은 헤드 및 출력을 의미합니다.
flowchart TD
IN[Input 640x640]:::start --> ST[Conv stem<br/>5x stride-2 down to P1-P5]:::proc
ST --> BB[Darknet-53 backbone<br/>stacked Bottleneck]:::proc
BB --> FPN[Neck FPN only<br/>top-down Upsample + Concat]:::decide
FPN --> HD[Detect head<br/>3 scales, anchor-based]:::out
HD --> O[Predictions + NMS]:::out
classDef start fill:#4CAF50,color:#fff
classDef proc fill:#2196F3,color:#fff
classDef decide fill:#FF9800,color:#fff
classDef out fill:#9C27B0,color:#fffYOLOv3 및 YOLOv5 다이어그램은 원래의 앵커 기반 헤드를 보여줍니다. ultralytics 패키지는 Detection Head에 설명된 것과 같이 동일한 Darknet-53 및 C3 백본에 YOLOv8의 Detect 헤드가 결합된 앵커 프리 YOLOv3u 및 YOLOv5u 설정을 탑재합니다.
백본 블록: Bottleneck → C3 → C2f → C3k2#
백본은 스트라이드-2(stride-2) Conv 다운샘플링 레이어 사이에 반복되는 CSP(Cross-Stage Partial) 블록을 적층합니다. 이 반복되는 블록이 버전 간에 가장 많이 변경된 부분입니다. 아래의 모든 블록은 block.py에 위치하며, c1/c2는 입력/출력 채널이고 c = 0.5 * c2는 숨겨진 너비입니다.
Bottleneck (YOLOv3)#
기본 단위는 Bottleneck입니다. 이는 두 개의 Conv 레이어(기본 커널 (3, 3))로 구성되며, shortcut=True과 c1 == c2일 때 선택적 잔차(residual) 덧셈이 적용됩니다. YOLOv3의 Darknet-53 백본은 CSP 분할 없이 이를 직접 적층하며, 세 가지 스케일(스트라이드 8, 16, 32)에서 감지합니다.
C3 (YOLOv5)#
YOLOv5의 C3은 입력을 두 개의 1x1 합성곱으로 분할합니다: cv1은 n개의 순차적인 Bottleneck 블록(커널 (1, 1) 이후 (3, 3))에 공급되고, cv2은 이를 우회합니다. 두 경로는 결합(concatenate)된 후 세 번째 1x1 Conv에 의해 융합됩니다:
def forward(self, x):
# C3: bottleneck path m(cv1(x)) concatenated with bypass cv2(x), then fused by cv3
return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))최종 병목(bottleneck) 출력만 융합 합성곱에 도달하므로, cv3은 2개의 피처 맵을 보게 됩니다.
C2f (YOLOv8)#
YOLOv8의 C2f("CSP Bottleneck with 2 convolutions, faster")은 융합 합성곱에 도달하는 피처를 변경합니다:
cv1 = Conv(c1, 2 * c, 1)에 이어,chunk(2)이 출력을 두 개의c채널 텐서로 분할합니다.n개의Bottleneck(c, c)블록(커널(3, 3),(3, 3))이 순차적으로 실행되며, 각각 이전 블록의 출력을 입력받습니다.- 모든
n + 2중간 텐서들이 결합되고cv2 = Conv((2 + n) * c, c2, 1)에 의해 융합됩니다.
C3이 2개의 피처 맵을 융합 합성곱으로 전달하는 것과 달리, C2f은 n + 2개를 전달합니다. 즉, 모든 중간 병목 출력이 재사용됩니다.
C3k2 (YOLO11 및 YOLO26)#
YOLO11과 YOLO26은 반복 단위를 교체하는 C2f의 서브클래스인 C3k2를 사용합니다. 각 n 블록은 생성자 플래그에 따라 다음과 같이 구성됩니다.
- 일반
Bottleneck(기본값,c3k=False), C3k블록(c3k=True) — 커널 크기를 설정할 수 있는C3변형, 또는Bottleneck+PSABlock쌍 (attn=True).
두 번째 YAML 인자는 c3k을 설정합니다. 예를 들어 [-1, 2, C3k2, [512, True]]은 내부 블록이 C3k인(c3k=True 이후) 512 출력 채널의 C3k2 모듈 하나를 빌드합니다. CSP 모듈의 경우, (변형의 깊이 배수로 스케일링되기 전의 값인) 여기서는 2인 repeats 필드가 별도의 모듈을 적층하는 대신 블록의 내부 반복 횟수가 됩니다.
공간 풀링: SPP → SPPF#
백본의 끝에서, 공간 피라미드 풀링(spatial-pyramid-pooling) 블록이 수용 영역(receptive field)을 넓힙니다. YOLOv5는 기존의 다중 커널 SPP을 SPPF(Spatial Pyramid Pooling - Fast)로 대체했습니다: 단일 MaxPool2d(kernel_size=5, stride=1, padding=2)가 연속으로 n = 3번 적용되며, 입력과 세 번의 풀링된 출력이 모두 결합되어 1x1 Conv에 의해 융합됩니다. 이는 수학적으로 SPP(k=(5, 9, 13))과 동일하지만, 체인 형태로 연결된 5x5 풀링이 더 큰 커널의 수용 영역을 커버하기 때문에 더 저렴합니다.
YOLO26은 단축(shortcut) 플래그(SPPF, [1024, 5, 3, True])를 전달합니다. 가장 깊은 레이어의 c1 == c2 == 1024이므로, SPPF은 잔차 연결(return y + x)을 추가합니다.
공간 어텐션: C2PSA (YOLO11+)#
YOLO11은 SPPF 뒤에 **C2PSA**을 추가했습니다. 이는 활성 브랜치가 n PSABlock(위치 민감형 어텐션, Position-Sensitive Attention) 모듈의 스택인 CSP 블록입니다. cv1 = Conv(c1, 2 * c, 1)는 특징을 분할하고, 절반은 PSABlock 스택을 통과하며, cv2 = Conv(2 * c, c1, 1)은 결합(concatenation)을 융합합니다. 각 PSABlock은 멀티헤드 어텐션을 적용한 후 각각 레시듀얼 연결이 있는 2계층 피드포워드 네트워크(Conv(c, 2 * c, 1) → Conv(2 * c, c, 1))를 거칩니다. YOLO26은 동일한 C3k2 + C2PSA 백본을 유지합니다.
넥: FPN + PAN#
넥은 하향식 피처 피라미드 네트워크(FPN)와 상향식 경로 집성 네트워크(PAN)를 사용하여 백본의 P3/P4/P5 피처 맵을 융합합니다. YAML 헤드 섹션에서 FPN은 nn.Upsample + Concat이고(의미 정보를 더 높은 해상도로 아래로 전달), PAN은 스트라이드-2 Conv + Concat입니다(위치 정보를 다시 위로 전달):
# YOLO11 head (FPN top-down, then PAN bottom-up)
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 6], 1, Concat, [1]] # cat backbone P4
- [-1, 2, C3k2, [512, False]] # 13
# ... second upsample + concat to P3 ...
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 13], 1, Concat, [1]] # cat head P4 (PAN)
- [-1, 2, C3k2, [512, False]] # 19넥은 해당 세대의 백본 블록(YOLOv5의 C3, YOLOv8의 C2f, YOLO11 및 YOLO26의 C3k2)을 재사용하므로, 각 병합 지점은 백본이 사용하는 것과 동일한 모듈을 실행합니다. 세 개의 융합된 출력은 헤드에 공급됩니다. YOLOv3은 예외입니다: 넥이 하향식 FPN 전용이며(YAML 헤드에 스트라이드-2 다운샘플링이 없음), YOLOv5가 도입한 상향식 PAN 경로가 없습니다.
탐지 헤드: 앵커 기반 → 앵커 프리 → NMS 프리#
헤드는 세 개의 융합된 피처 맵을 감지 작업(detection task)을 위한 예측으로 변환합니다. 그 디자인은 앵커 기반에서 앵커 프리로, 그리고 NMS 프리로 버전마다 변경되었습니다.
앵커 프리, 분리된 Detect#
기존의 YOLOv3 및 YOLOv5는 사전 정의된 앵커 박스와 박스 및 클래스 예측을 위한 공유 브랜치를 사용하는 앵커 기반 결합형 헤드를 사용했습니다. 독립형 ultralytics/yolov3 및 ultralytics/yolov5 저장소는 해당 앵커 기반 설계를 유지합니다. 대신 메인 ultralytics 패키지는 동일한 Darknet-53 및 C3 백본에 YOLOv8의 앵커 프리 Detect 헤드가 결합된 앵커 프리 YOLOv3u 및 YOLOv5u 변형을 탑재하며, 여기에 문서화된 yolov3.yaml 및 yolov5.yaml 설정은 과거의 설계가 아니라 이러한 u 변형들입니다.
Detect 헤드(head.py)는 앵커 프이며 분리되어 있습니다: 피라미드 레벨마다 두 개의 병렬 브랜치를 실행하며, 앵커 박스가 아닌 그리드 포인트에서 직접 예측합니다.
- 박스 브랜치 (
cv2):Conv(x, c2, 3)→Conv(c2, c2, 3)→Conv2d(c2, 4 * reg_max, 1). - 클래스 브랜치 (
cv3): YOLO11 및 YOLO26에서는 두 개의 깊이별 분리 가능 블록(DWConv+1x1 Conv) →Conv2d(c3, nc, 1); YOLOv8은 레거시 변형인 두 개의3x3 Conv레이어 →Conv2d(c3, nc, 1)를 사용합니다.
따라서 각 앵커 포인트는 no = nc + 4 * reg_max 출력을 생성합니다. 미리 정의된 앵커를 제거함으로써 튜닝해야 하는 하이퍼파라미터에서 앵커 박스 크기와 종횡비(aspect ratio)가 제외됩니다.
DFL (Distribution Focal Loss)#
YOLOv8과 YOLO11은 단일 스칼라 대신 (Generalized Focal Loss의 적분 형식에서 유래한) reg_max = 16 개 빈(bin)에 대한 **확률 분포(distribution)**로 4개의 박스 좌표 각각을 회귀합니다. DFL 모듈은 4 * reg_max 박스 채널을 (4, reg_max)로 형태를 변환하고, reg_max 빈에 대해 소프트맥스(softmax)를 적용한 후, 각 빈 인덱스에 소프트맥스 확률을 가중치로 곱하여 합산한 기대 빈 인덱스를 예측 좌표로 가져옵니다. 이는 가중치가 빈 인덱스 arange(reg_max)인 고정된 1x1 컨볼루션으로 구현되므로, 가중합은 단일 내적(dot product) 연산이 됩니다.
YOLO26: NMS 프리, DFL 프리#
YOLO26은 헤드가 직접 읽는 두 가지 YAML 파라미터를 설정합니다:
end2end: True—Detect은 객체당 단일 예측을 생성하는 일대일 헤드(one2one_cv2/one2one_cv3)로 브랜치들을 깊은 복사(deep-copy)하여, 비최대억제(Non-Maximum Suppression) (NMS) 후처리 단계를 제거합니다. 내보내기 및 마이그레이션 세부 정보는 End-to-End Detection guide를 참조하세요.reg_max: 1— 빈이 하나일 때,self.dfl은nn.Identity()및no = nc + 4이 되며, 헤드는 좌표를 직접 회귀하고 내보낸 ONNX 그래프에 DFL 연산이 나타나지 않습니다.
5가지 모델 크기(n/s/m/l/x)에 걸쳐 YOLO26은 YOLO26 논문에 보고된 바와 같이 1.711.8 ms T4 TensorRT 지연 시간에서 COCO 기준 40.957.5 mAP를 달성합니다.
버전별 요약#
| 버전 | 백본 블록 | 공간 풀링 | 어텐션 | 탐지 헤드 | DFL |
|---|---|---|---|---|---|
| YOLOv3 | Darknet-53 (Bottleneck) | 기본 설정에 없음 | 없음 | 오리지널: 앵커 기반; u 변형: 앵커 프리 | 아니오 / 예 (u) |
| YOLOv5 | C3 (CSP) | SPPF | 없음 | 오리지널: 앵커 기반; u 변형: 앵커 프리 | 아니오 / 예 (u) |
| YOLOv8 | C2f | SPPF | 없음 | 앵커 프리, 디커플드 | 예 (reg_max=16) |
| YOLO11 | C3k2 | SPPF | C2PSA | 앵커 프리, 디커플드 | 예 (reg_max=16) |
| YOLO26 | C3k2 | SPPF + shortcut | C2PSA | 앵커 프리, NMS 프리 (end2end) | 제거됨 (reg_max=1) |
모델별 세부 정보, 성능 표 및 사용 예시는 YOLOv3, YOLOv5, YOLOv8, YOLO11, YOLO26의 개별 페이지를 참조하세요.
직접 아키텍처 검사하기#
model.info() 메서드는 레이어, 파라미터, FLOPs 요약을 출력하며, 파싱된 모듈 목록은 model.model.model에서 확인할 수 있습니다.
from ultralytics import YOLO
# Load a pretrained model
model = YOLO("yolo11n.pt")
# Fuse Conv + BatchNorm layers so counts match the published specs
model.fuse()
# Print a summary: layers, parameters, gradients, GFLOPs
model.info()
# Inspect the detection head (the last module in the network)
head = model.model.model[-1]
print(type(head).__name__, "| reg_max:", head.reg_max, "| end2end:", head.end2end)세 세대에 걸쳐 스니펫을 실행해 보면 변경 사항이 수치로 나타납니다. 이는 ultralytics 패키지의 실제 융합 모델(fused-model) 출력으로, 각 모델 페이지에 게시된 파라미터 및 FLOPs 수치와 일치합니다.
| 모델 | 레이어 | 매개변수 | GFLOPs | reg_max | end2end | DFL 레이어 |
|---|---|---|---|---|---|---|
| YOLOv8n | 72 | 3,151,904 | 8.7 | 16 | False | DFL |
| YOLO11n | 100 | 2,616,248 | 6.5 | 16 | False | DFL |
| YOLO26n | 122 | 2,408,932 | 5.4 | 1 | True | Identity |
YOLO26n은 reg_max=1, end2end=True, 및 Identity DFL 레이어(NMS 프리 및 DFL 프리 헤드의 아키텍처 시그니처)를 보고합니다.
파라미터 및 FLOPs 값은 각 Conv과 해당 배치 정규화 레이어를 병합하는 융합(fused) 모델(model.fuse()) 기준으로 보고됩니다. 이는 게시된 사양과 일치하며, 새로 로드된 체크포인트는 융합하기 전에 약간 더 높은 수치를 보고합니다.
결론#
버전에 걸쳐 YOLO 아키텍처는 한 번에 한 단계씩 변경되었습니다: 백본은 Darknet-53에서 CSP 기반의 C3, C2f, 및 C3k2 블록과 C2PSA 어텐션으로 이동했고; 넥은 SPP가 SPPF가 되는 동안 FPN + PAN 구조를 유지했으며; 헤드는 앵커 기반에서 앵커 프리로, 그 다음에는 YOLO26의 NMS 프리, DFL 프리 엔드투엔드(end-to-end) 디자인으로 이동했습니다.
사용자 정의 아키텍처를 정의하려면 Model YAML Configuration Guide를 참조하거나 model pages에서 모델을 비교하세요. 질문이 있으시면 GitHub나 Discord로 문의해 주세요.
FAQ#
YOLO 모델에는 스트라이드 8, 16, 32에서 이미지의 특징을 추출하는 백본(backbone), FPN과 PAN을 사용하여 스케일 전반에 걸쳐 해당 특징을 융합하는 넥(neck), 그리고 바운딩 박스와 클래스 점수를 예측하는 **헤드(head)**가 있습니다. YOLOv3부터 YOLO26까지의 모든 Ultralytics YOLO 모델은 이러한 3단계 설계를 따릅니다.
C2f(YOLOv8)은 융합 컨볼루션 이전에 모든 내부Bottleneck의 출력(n + 2특징 맵)을 연결(concatenate)하는 CSP 블록이며, 이전 버전인C3은 2개만 전달합니다.C3k2(YOLO11 및 YOLO26)는c3k플래그가 설정된 경우 각Bottleneck을C3k블록(커널 크기 설정이 가능한C3변형)으로 교체할 수 있는C2f의 서브클래스입니다. 둘 다block.py에 정의되어 있습니다.YOLO11은 YOLOv8에 대해 세 가지 구조적 변경을 가했습니다.
C2f백본 및 넥 블록을C3k2로 교체하고,SPPF뒤에C2PSA자기 어텐션(self-attention) 블록을 삽입하며, 헤드의 분류 브랜치를 더 가벼운 깊이별 분리 가능 컨볼루션(depthwise-separable convolutions)으로 전환합니다. 둘 다reg_max=16DFL 회귀가 포함된 동일한 앵커 프리 분리형Detect헤드를 유지하므로, 검출 인터페이스를 재설계하는 대신 정확도를 높이면서 파라미터 및 FLOPs 수를 낮춥니다.최신 Ultralytics YOLO 모델은 앵커 프리입니다. YOLOv8, YOLO11, YOLO26은 박스 회귀와 분류를 위한 별도의 브랜치가 있는 앵커 프리, 분리된
Detect헤드를 사용합니다. 오리지널 YOLOv3와 YOLOv5는 앵커 기반이었지만, Ultralytics는 설정을 통해 YOLOv8과 동일한 앵커 프리 헤드를 사용하는 YOLOv3u 및 YOLOv5u 변형으로 제공합니다.그렇습니다 — YOLO26은
end2end=True을 설정하여Detect에 객체당 단일 예측을 생성하고 이전 모델에 필요했던 비최대억제 후처리 단계를 제거하는 일대일 헤드를 부여합니다. 자세한 내용은 End-to-End Detection guide를 참조하세요.DFL은 단일 스칼라를 예측하는 대신
reg_max빈(bin)(YOLOv8 및 YOLO11에서는 기본값 16)에 대한 소프트맥스 분포로 각 박스 좌표를 회귀하고 기댓값을 좌표로 취합니다. YOLO26은reg_max=1을 설정하므로 DFL 레이어가 항등 연산(identity operation)이 되고, 헤드가 좌표를 직접 회귀하며, 내보낸 ONNX 또는 TensorRT 그래프에 DFL 연산이 나타나지 않습니다.Python에서 모델을 로드하고 레이어, 파라미터, GFLOPs 요약을 위해
model.info()을 호출합니다. 파싱된 레이어는model.model.model에 있습니다 — 예를 들어model.model.model[-1]는Detect헤드이며reg_max및end2end와 같은 속성을 노출합니다. 전체 아키텍처는 모델의 YAML configuration file에 정의되어 있습니다.