7.15. 직접 작성하기¶
카탈로그가 모델을 포괄하지 못할 때, 즉 출력 레이아웃이 독자적인 연구용 신경망, 기존 아키텍처에 대한 수정, 의미 해석이 애플리케이션에 특화된 텐서 등의 경우, 애플리케이션은 자체 후처리기를 제공합니다. 프로토콜은 단순합니다. (model, inputs, outputs)를 받아 predict()로부터 애플리케이션이 기대하는 것을 무엇이든 반환하는 호출 가능 객체입니다.
__call__을 가진 클래스가 관례적인 형태입니다:
class MyPostprocessor:
def __init__(self, threshold=0.5):
self.threshold = threshold
def __call__(self, model, inputs, outputs):
...
return result
일반 함수도 동작합니다. 엔진은 객체가 호출 가능한지만 확인합니다.
7.15.1. 연결하기¶
두 개의 연결 지점이 있습니다. 생성자의 postprocess= 키워드 인자는 모델의 모든 predict() 호출에 대해 호출 가능 객체를 바인딩합니다:
model = ml.Model("/rom/my_model.tflite",
postprocess=MyPostprocessor())
단일 호출에 대해 바인딩을 재정의하려면(모델을 다시 로드하지 않고 디코더를 교체하려면) callback=을 predict에 직접 전달합니다:
result = model.predict([img], callback=MyOtherPostprocessor())
호출 가능 객체의 시그니처는 두 경우 모두 동일합니다.
7.15.2. 호출 가능 객체가 받는 것¶
model–Model인스턴스로, 양자화 매개변수(output_scale,output_zero_point,output_dtype)와 입력 차원(input_shape)에 유용합니다.inputs– 애플리케이션이predict()에 전달한 입력의 리스트입니다. 첫 번째 요소는 보통 바인딩된Normalization인스턴스이며, 그roi속성은NMS가 상자를 원본 이미지로 다시 매핑하는 데 필요로 하는 것입니다.outputs– 원시 출력 텐서로,ndarray객체의 리스트이며 네이티브 dtype을 가집니다. 부동소수점 출력은 그대로 도착하고, 정수 출력은 양자화된 상태로 도착합니다.
7.15.3. 양자화 연산¶
기본 제공 디코더는 모두 ml.utils의 동일한 헬퍼를 사용하며, 사용자 정의 디코더도 보통 같은 패턴을 원합니다. quantize()는 부동소수점 임계값을 모델의 양자화 공간으로 끌어올리고, threshold()는 전체 텐서를 역양자화하지 않고 필터링하며, dequantize()는 살아남은 것들에 대해 한 번 실행됩니다. sigmoid()와 logit()은 출력 채널이 시그모이드 적용 전의 로짓인 신경망(MediaPipe 검출기가 대표적인 경우)에 사용할 수 있습니다.
부동소수점 출력을 가진 모델(회귀 헤드, 마지막에 역양자화 레이어가 내장된 모델)의 경우, 양자화 헬퍼는 변경 없이 통과하므로 동일한 후처리기 코드가 특별한 처리 없이 어느 dtype에서도 동작합니다.
7.15.4. 반환 값¶
호출 가능 객체가 반환하는 것이 곧 predict()가 반환하는 것입니다. 상자를 출력하는 디코더의 경우 관례는 후보들을 NMS를 통과시키고 그 클래스별 리스트를 반환하는 것입니다. 이는 비최대 억제가 문서화하고 YOLOv8 둘러보기가 맥락 속에서 구성하는 호출 형태입니다. 그 외의 경우에는 애플리케이션이 편리하다고 여기는 것을 무엇이든 반환합니다. 단일 ndarray, 레이블 문자열, (class, score, embedding) 튜플, 딕셔너리 등입니다.