7.12. 후처리기(Post-processors)¶
검출 신경망은 상자를 출력하지 않습니다. 모델이 학습된 아키텍처에 따라 레이아웃이 달라지는 하나 이상의 텐서를 출력합니다. YOLO 계열 검출기의 경우 후보 예측의 2차원 텐서, MediaPipe 검출기의 경우 (boxes, scores) 텐서 쌍, 포즈 신경망의 경우 키포인트 좌표의 평면 리스트 등입니다. 애플리케이션은 이들 중 어느 것도 직접 읽을 수 없습니다. 애플리케이션이 원하는 것, 즉 상자의 리스트, 키포인트의 리스트, 클래스별 분류는 원시 텐서로부터 디코딩되어야 합니다.
그 디코더가 후처리기입니다. ml.postprocessing 모듈은 이들을 출처 생태계별로 묶습니다.
7.12.1. Darknet¶
ml.postprocessing.darknet은 초기 YOLO 시대의 모델을 디코딩합니다. YOLO v2는 이후 대부분의 검출기가 어떤 형태로든 물려받은 그리드와 앵커 개념을 도입했으므로, v2 레이아웃이 가장 깔끔한 출발점입니다.
YOLO v2는 입력 이미지를 거친 그리드로 나누는 것으로 시작합니다. 표준 416픽셀 입력의 경우 13x13 레이아웃이며 더 작은 모델의 경우 더 작아집니다. 그리고 각 그리드 셀이 중심이 그 안에 들어오는 모든 객체의 검출을 담당하도록 신경망을 학습시킵니다. 출력 텐서의 공간 레이아웃은 입력의 레이아웃을 반영합니다. 이미지의 셀마다 출력에 하나의 위치가 대응됩니다.
각 그리드 셀에서 신경망은 박스를 무에서 만들어 내지 않습니다. anchors라고 불리는 몇 개의 미리 선택된 기준 형상 중에서 고르는데, 이는 학습 세트의 박스 크기를 클러스터링하여 오프라인에서 도출한 고정된 (width, height) 쌍으로, 모델이 보게 될 것으로 예상되는 일반적인 객체들을 포괄하도록 만들어집니다. 각 셀에서 신경망이 하는 일은, 각 앵커에 대해 셀 내에서의 박스 중심에 대한 작은 오프셋, 앵커의 너비와 높이에 대한 스케일, objectness 점수(무언가가 존재할 가능성), 그리고 클래스별 확률 벡터를 예측하는 것입니다. 따라서 기본값인 앵커 5개와 클래스 20개를 사용하는 13×13 그리드는 추론 한 번당 13 * 13 * 5 * (4 + 1 + 20) = 21,125 개의 숫자를 출력합니다.
YoloV2는 그 레이아웃을 디코딩합니다. 셀들을 순회하며 각 앵커의 오프셋과 스케일을 적용하여 절대 상자 좌표를 복원하고, 객체성과 클래스 확률을 결합하여 클래스별 점수를 만들고, 임계값을 적용한 다음, 살아남은 것들을 NMS로 보냅니다. 이 클래스는 모델이 사용자 정의 앵커 테이블로 학습된 경우 anchors= 생성자 인자를 받으며, 그렇지 않으면 내장된 기본값을 사용합니다. 특정 클래스 집합에 맞게 조정된 변형들도 같은 하위 모듈에 포함되어 있습니다.
7.12.2. Ultralytics¶
ml.postprocessing.ultralytics는 더 최신의 YOLO 세대를 디코딩합니다. YoloV8은 열 우선(column-major) 출력을 읽으며, 각 열은 상자 좌표와 클래스별 점수 벡터를 담은 하나의 앵커 예측입니다. 이전 YOLO 출력이 담고 있던 객체성 채널은 v8에서 제거되었고, 클래스 점수가 단독으로 존재합니다. YOLOv8 둘러보기는 디코드를 텐서 단위로 살펴봅니다. 더 오래된 Ultralytics 시대의 버전들도 해당 레이아웃으로 학습된 모델을 위해 같은 하위 모듈에 포함되어 있습니다.
7.12.3. MediaPipe¶
ml.postprocessing.mediapipe는 Google의 경량 온디바이스 계열을 디코딩합니다. BlazeFace는 hello-blazeface에서 다룬 얼굴 검출기입니다. 이는 얼굴마다 상자와 여섯 개의 랜드마크 좌표를 출력하는 빠른 앵커 기반 검출기로, 랜드마크가 별도의 출력 리스트가 아니라 각 상자에 부착된 (box, score, keypoints) 튜플로 반환됩니다. 같은 계열의 손 검출, 랜드마크, 포즈 모델도 함께 포함되어 있으며 동일한 부착형 키포인트 반환 형태를 따릅니다.
7.12.4. 하나를 선택하기¶
올바른 후처리기는 애플리케이션이 원하는 것이 아니라 모델이 학습된 아키텍처에 의해 결정됩니다. YOLOv8 .tflite는 YoloV8을 통해서만 올바르게 디코딩되고, BlazeFace .tflite는 BlazeFace를 통해서만 디코딩됩니다. 후처리기를 선택하는 것은 모델을 선택하는 일의 일부입니다. 모델의 아키텍처가 기본 제공 후처리기로 표현되지 않는 경우, 직접 작성하기는 어렵지 않습니다.
분류 신경망은 예외입니다. 단일 출력 텐서가 이미 애플리케이션이 원하는 것, 즉 클래스별 점수의 리스트이므로 후처리기가 필요하지 않습니다. postprocess= 없이 모델을 로드하고 예측 결과를 평면 ndarray로 읽는 것이 올바른 방법이며, 이는 텐서 I/O에서 다루었습니다.