Skip to content

Inference

mlops.segmentation.MLOpsInferenceHandler

학습한 Segmentation 모델, Uncertainty 모델, Performance Prediction 모델을 사용하여 검사를 하기 위한 MLOpsInferenceHandler class 입니다.

Usage
# 인퍼런스 모듈 빌드
inferene_build_config = {
    "checkpoint_path": CHECKPOINT_PATH,
    "password": PASSWORD,
    "device": DEVICE,
    "performance_prediction": PERFORMANCE_PREDICTION,
}
error, inference_handler = MLOpsInferenceHandler.build(inferene_build_config)
assert error >= 0

# 모듈 정보 확인
error, metadata = read_metadata(CHECKPOINT_PATH)
assert error >= 0
print("Inference metadata:", metadata)

# 인퍼런스 옵션 초기값 확인
n_classes = CONFIG["n_classes"]
inference_options = {
    "outputs.mask": True,
    "outputs.scoremap": True,
    "outputs.objects": True,
    "params.score_threshold": [50] * n_classes,
    "params.area_threshold": [10] * n_classes,
    "params.wo_background": True,
}
print("Default inference options:")
for key in inference_options:
    error, value = inference_handler.get_default_inference_option(key)
    assert error >= 0
    print(f"  {key}: {value}")

# 디벨로퍼: Analyze 수행
error, _ = inference_handler.set_analysis_data(images=DATA["validation_images"], labeled=False)
assert error >= 0

error, analysis_steps = inference_handler.initialize_analysis()
assert error >= 0

for _ in range(analysis_steps):
    error, _ = inference_handler.step_analysis()
    assert error >= 0

error, analysis_results = inference_handler.finalize_analysis()
assert error >= 0
print("Analysis results:", analysis_results)

# 디벨로퍼: 인퍼런스 옵션 변경
for key, value in inference_options.items():
    error, _ = inference_handler.set_inference_option(key, value)
    assert error >= 0

# 디벨로퍼: metadata에 inference_option 저장 (예시)
metadata["inference_options"] = inference_options
error, _ = write_metadata(CHECKPOINT_PATH, metadata)
assert error >= 0

# 인퍼런스 옵션이 잘 변경되었는지 확인
print("Inference options:")
for key in inference_options:
    error, value = inference_handler.get_inference_option(key)
    assert error >= 0
    print(f"  {key}: {value}")

# 디벨로퍼: 새로운 세팅으로 Analyze 재수행
error, analysis_results = inference_handler.analyze_with_existing_data()
assert error >= 0
print("Analysis results:", analysis_results)

# 런타임: 핸들러 빌드
error, metadata = read_metadata(CHECKPOINT_PATH)
assert error >= 0
inferene_build_config["inference_options"] = metadata["inference_options"]
error, inference_handler = MLOpsInferenceHandler.build(inferene_build_config)
assert error >= 0

# 런타임 검사: 후처리까지 한번에 최적화된 연산으로 수행
image_path = DATA["validation_images"][0]["path"]
error, output = inference_handler.infer_and_postprocess(images=[image_path])
assert error >= 0
print("Runtime (infer_and_postprocess):", output)

build(config) classmethod

MLOpsInferenceHandler class의 instance를 생성합니다. (config의 checkpoint_path에 있는 checkpoint에 uncertainty model weight가 저장되어 있지 않으면 error raise합니다.) config의 performance_prediction boolean 값에 따라 uncertainty model build 여부와 analysis 시 performance prediciton 지원 여부가 바뀝니다.

Parameters:

Name Type Description Default
config Dict

InferenceHandler를 build 하기 위한 config가 담겨 있는 dictionary 입니다.

{
    "checkpoint_path": str,  # 체크포인트 경로
    "inference_options": Optional[Dict], # 인퍼런스 옵션 config (default None). 구조는 `get_default_inference_option`의 Keys 참고.
    "password": Optional[str],  # 체크포인트 패스워드 (default None)
    "device": Union[int, str],  # GPU 번호 (int) or "cpu" (str) (default "cpu")
    "performance_prediction": bool, # 검사 시 performance prediction을 할지 말지 (default False)
}
required

Returns:

Name Type Description
MLOpsInferenceHandler MLOpsInferenceHandler

build가 완료된 MLOpsInferenceHandler class의 instance를 반환합니다.

get_default_inference_option(key)

Inference & postprocess 옵션의 기본 설정 값을 반환합니다.

Parameters:

Name Type Description Default
key str

옵션 key

required

Returns:

Name Type Description
Any Any

옵션 value

Keys

사용 가능한 key와 value 목록: python { "outputs.mask": bool, # (default True, output 중 mask를 계산할 지 여부. True인 경우 계산) "outputs.scoremap": bool, # (default True, output 중 scoremap을 계산할 지 여부. True인 경우 계산) "outputs.objects": bool, # (default True, output 중 objects를 계산할 지 여부. True인 경우 계산) "params.score_threshold": List[int], # 각 클래스의 score threshold 값. 픽셀의 예측된 score가 threshold보다 작은 경우 0으로 치환 됩니다. 각 값은 [0, 255] 범위의 정수. (default [0, ... , 0]) "params.area_threshold": List[int], # 각 클래스의 area threshold 값. 예측 object의 면적이 threshold보다 작은 경우 필터링 됩니다. 각 값은 0 이상의 정수. (default [0, ... , 0]) "params.wo_background": bool, # object 예측 시 background (0번 클래스) 제외 여부. True의 경우 background는 object로 만들지 않습니다. (default True) }

사용 예시: python handler.get_default_inference_option(key="outputs.mask") handler.set_inference_option(key="outputs.mask", value=False)

get_inference_option(key)

현재 설정된 inference & postprocess 옵션 값을 읽습니다.

Parameters:

Name Type Description Default
key str

옵션 key

required

Returns:

Name Type Description
Any Any

옵션 value

Keys

get_default_inference_option과 동일합니다.

set_inference_option(key, value)

Inference & postprocess 옵션을 설정합니다.

Parameters:

Name Type Description Default
key str

설정하고자 하는 옵션 key 입니다.

required
value Any

설정하고자 하는 옵션 value 입니다.

required

Returns:

Name Type Description
None None

None

Keys

get_default_inference_option과 동일합니다.

infer_and_postprocess(images)

image의 List를 입력으로 받아 모델 인퍼런스와 후처리를 수행합니다. (for Runtime) 실시간 검사를 위해 연산 과정이 최적화되어 있으며, 중간 결과를 제거하고 postprocess 최종 결과만을 반환합니다. Runtime에서는 performance prediction을 지원하지 않습니다.

Parameters:

Name Type Description Default
images Union[List[np.ndarray], List[str]]
- List[np.ndarray]: numpy image가 들어있는 List 입니다. 각 image는 다음 제약 조건을 갖습니다.
                    data type: uint8
                    channel: H x W / H x W x 1 - Gray
                             H x W x 3 - RGB
                             H x W x 4 - RGBA
- List[str]: image 경로가 들어있는 List 입니다.
- List[List[np.ndarray]]: multipage인 경우 사용.
- List[List[str]]: multipage인 경우 사용.
required

Returns:

Type Description
List[Dict]

List[Dict]: image의 postprocess 결과들이 들어있는 List 입니다.

[
    {  # 아래 키들 중 inference_options에 설정된 출력 값들만 포함.
        "mask": ndarray(uint8, shape=(H, W)),  # 각 픽셀이 예측된 클래스를 값으로 갖는 array 입니다.
        "scoremap": ndarray(uint8, shape=(C, H, W)),  # 각 클래스별로 픽셀의 score가 저장된 array
        "objects": [  # 클래스별로 contouring을 해서 얻은 object들의 리스트. (List[Dict])
            {  # segmentation object 구조
                "class_index": int,
                "contours": [  # cv2 형식의 contours. 0번째 contour가 outer, 나머지는 모두 inner.
                    ndarray(int32, shape=(52, 1, 2)),
                    ndarray(int32, shape=(44, 1, 2)),
                    ndarray(int32, shape=(11, 1, 2)),
                    ...,  # times number of contours
                ],
            },
            ...,  # times number of objects
        ],
    },
    ...,  # times number of images
]

set_analysis_data(images, labeled)

Analysis를 위한 data를 세팅합니다. (for Developer)

Parameters:

Name Type Description Default
images List[Dict]

analysis에 사용할 데이터 리스트. Trainer 빌드에 사용하는 이미지 리스트와 동일한 구조.

[
    {
        "path": Union[str, List[str]],  # 이미지 경로 (multipage인 경우 경로 리스트)
        "width": int,  # image width
        "height": int,  # image height
        "labels": [  # (labeled = False)인 경우 필요하지 않습니다.
            {
                "class_index": int,  # class index (0: background)
                "bounding_box": List[int],  # [left, top, width, height]
                "bitmap": str,  # base64 encoded png image string (shape: (height, width))
            },
            ...,  # times number of labels in the image
        ],
    },
    ...,  # times number of images
]
required
labeled bool

label 존재 여부. label 존재 여부에 따라 analysis 결과 Dict 구성 요소가 달라집니다.

required

Returns:

Name Type Description
None None

None

Note1

Analysis를 위한 api는 정해진 순서대로 호출되어야 하며, 순서를 벗어나는 경우 에러를 raise합니다.

API호출 예시:

handler.set_analysis_data(images, labeled)  # 데이터 지정
total_steps = handler.initialize_analysis()  # 초기화
for _ in range(total_steps):
    handler.step_analysis()  # 정해진 수 만큼 스텝 수행
results = handler.finalize_analysis()  # 마무리 & 결과 리턴

handler.set_inference_options(options)  # 인퍼런스 옵션 변경
total_steps = handler.initialize_analysis()  # 초기화
for _ in range(total_steps):
    handler.step_analysis()  # 정해진 수 만큼 스텝 수행
results = handler.finalize_analysis()  # 마무리 & 결과 리턴

handler.set_inference_options(options)  # 인퍼런스 옵션 변경
results = handler.analyze_with_existing_data()  # 초기화 - 스텝 - 마무리를 한 번에 수행 후 결과 리턴
Note2

inference_options 세팅에 따라 analysis 결과 Dict 구성 요소가 달라집니다.

ex) inference_options outputs 중 mask: False 인 경우 pixel 관련 metric 값들이 제공되지 않습니다.

따라서 Analysis 도중 (initialize_analysis와 finalize_analysis 사이)에는 set_inference_options를 호출할 수 없습니다.

initialize_analysis()

Analysis를 위한 준비 스텝을 수행.

Returns:

Name Type Description
int int

Analysis 완료를 위해 수행되어야 하는 step_analysis 호출 횟수.

step_analysis()

Analysis를 1스텝 수행.

Returns:

Name Type Description
None None

None

finalize_analysis()

Analysis를 마무리하고 결과를 리턴.

build시 performance_prediction=True이고 set_analysis_data시 labeled=False이면 summary 결과에 pixel/predicted_mean_iou를 같이 반환함.

Returns:

Name Type Description
Dict Dict

Analysis 결과

{
    "images": [
            {
                "labels": [  # **(labeled=True)인 경우에만 나옴**
                    {
                        "correct": bool,  # True면 TP, False면 FN
                        "recall": float,  # recall - 라벨 영역 중 맞은 영역의 비율
                    },
                    ... # 입력으로 넣어준 labels와 동일한 개수
                ],
                "predictions": {  # 아래 키들 중 inference_options에 설정된 출력 값들만 포함.
                    "mask": ndarray(uint8, shape=(H, W)),  # 각 픽셀이 예측된 클래스를 값으로 갖는 array.
                    "scoremap": ndarray(uint8, shape=(C, H, W)),  # 각 클래스별로 픽셀의 score가 저장된 array.
                    "objects": [  # (List[Dict]) 클래스별로 contouring을 해서 얻은 object들의 리스트.
                        {
                            "class_index": int,
                            "contours": [  # cv2 형식의 contours. 0번째 contour가 outer, 나머지는 모두 inner.
                                ndarray(int32, shape=(52, 1, 2)),
                                ndarray(int32, shape=(44, 1, 2)),
                                ndarray(int32, shape=(11, 1, 2)),
                                ...  # contour 개수 만큼 반복
                            ],
                            "correct": bool,  # True면 TP, False면 FP.  **(labeled=True)인 경우에만 나옴**
                            "precision": float,  # precision - 예측 영역 중 맞은 영역의 비율.  **(labeled=True)인 경우에만 나옴**
                        },
                        ... # 이미지 내의 검출된 object 개수만큼 반복
                    ],
                },
            },
            ... # 입력으로 넣어준 이미지 개수만큼 반복
    ],
    "summary": {  # 아래 키들 중 inference_options에서 mask=True인 경우 pixel/* 포함, objects=True인 경우 object/* 포함.
        "pixel/accuracy": float,  # pixel-wise accuracy   **(labeled=True)인 경우에만 나옴**
        "pixel/mean_iou": float,  # pixel-wise mean iou   **(labeled=True)인 경우에만 나옴**
        "pixel/predicted_mean_iou": float #pixel-wise mean iou **(labeled=False)인 경우에만 나옴**
        "pixel/class_{idx}_iou": float,  # 각 {idx} class 별 pixel iou   **(labeled=True)인 경우에만 나옴**
        "object/accuracy": float,  # object-wise accuracy   **(labeled=True)인 경우에만 나옴**
        "object/confusion_matrix": List[List[int]],  # object-wise confusion matrix.  **(labeled=True)인 경우에만 나옴**
            [
                [0, 1, 0, 1],  # 과검. class1로 예측한 과검 1개, class3으로 예측한 과검 1개.
                [1, 2, 0, 0],  # 라벨이 class1인 object 중에 미검 1개, 맞춘 것 2개
                [2, 0, 3, 0],  # 라벨이 class2인 object 중에 미검 2개, 맞춘 것 3개
                ..., # n_classes 만큼 반복
            ]
    },
}

analyze_with_existing_data()

기존에 세팅된 데이터를 이용해 전체 analysis를 루틴을 수행하고 최종 결과를 리턴.

Note

해당 함수는 아래 루틴을 호출하는 것과 동일함:

total_steps = handler.initialize_analysis()  # 초기화
for _ in range(total_steps):
    handler.step_analysis()  # 정해진 수 만큼 스텝 수행
results = handler.finalize_analysis()  # 마무리 & 결과 리턴

Returns:

Name Type Description
Dict Dict

Analysis 결과 (InferenceHandler.finalize_analysis 리턴 값과 동일)