Skip to content

Inference

core.InferenceHandler

학습한 AnomalyDetction 모델을 사용하여 검사를 하기 위한 InferenceHandler class 입니다.

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

# 인퍼런스 모듈 빌드
inferene_build_config = {
    "checkpoint_path": checkpoint_path,
    "password": password,
    "device": device,
}
error, inference_handler = InferenceHandler.build(inferene_build_config)
assert error >= 0

# 인퍼런스 옵션 초기값 확인
inference_options = {
    "outputs.score_min": True,
    "outputs.score_max": True,
    "outputs.mask": True,
    "outputs.is_ng": True,
    "outputs.heatmap": True,
    "outputs.objects": True,
    "outputs.time": False,
    "params.anomaly_score_threshold": 0.0,
    "params.heatmap_color_range_max": 0.0,
    "params.heatmap_color_range_min": 0.0,
    "params.calc_object_area_and_apply_threshold": True,
    "params.calc_object_score_and_apply_threshold": True,
    "params.object_boundary_threshold": 0.0,
    "params.object_scoring_method": "mean",
    "params.object_score_threshold": 0.0,
    "params.object_area_method": "fast_plus",
    "params.object_area_threshold": 0,
}

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 수행(use_saved_file=False)
for image_id, image_info in data["validation_images"].items():
    image_info["save_dir"] = os.path.join(SAVE_DIR, str(image_id))
    images = {image_id: image_info}

    error, results = inference_handler.analyze(images=images, labeled=True, use_saved_file=False)
    assert error >= 0

error, summary = inference_handler.summarize_analysis(images=data["validation_images"], labeled=True)
assert error >= 0
print("Analysis summary:", summary)

# model checkpoint에 저장된 인퍼런스 옵션 확인
print("Inference options in model checkpoint:")
for key in inference_options:
    error, value = inference_handler.get_inference_option(key)
    assert error >= 0
    print(f"  {key}: {value}")

# 디벨로퍼: 인퍼런스 옵션 변경
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 재수행(use_saved_file=True)
analyze_results = {}
for image_id, image_info in data["validation_images"].items():
    images = {image_id: image_info}

    error, results = inference_handler.analyze(images=images, labeled=True, use_saved_file=True)
    assert error >= 0
    analyze_results.update(results)

error, summary = inference_handler.summarize_analysis(images=data["validation_images"], labeled=True)
assert error >= 0
print("Analysis summary:", summary)

# 런타임: 저장된 체크포인트로 핸들러 빌드
error, inference_handler = InferenceHandler.build(inferene_build_config)
assert error >= 0

# 런타임: 핸들러 빌드
error, metadata = read_metadata(checkpoint_path)
assert error >= 0
inferene_build_config["inference_options"] = metadata["inference_options"]
error, inference_handler = InferenceHandler.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

InferenceHandler class의 instance를 생성합니다.

Parameters:

Name Type Description Default
config Dict

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

{
    "checkpoint_path": str,  # 체크포인트 경로
    "inference_options": Optional[Dict],  # inference 옵션 (default None)
    "password": Optional[str],  # 체크포인트 패스워드 (default None)
    "device": Union[int, str],  # GPU 번호 (int) or "cpu" (str) (default "cpu")
}

required

Returns:

Name Type Description
InferenceHandler InferenceHandler

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

get_default_inference_option(key)

Inference & postprocess 옵션의 기본 설정 값을 반환합니다. build로 load시 checkpoint안에 있던, 저장된 옵션이 설정됩니다.

Parameters:

Name Type Description Default
key str

옵션 key

required

Returns:

Name Type Description
Any Any

옵션 value

Keys

사용 가능한 key와 value 목록:

{
    "outputs.score_min": bool,  # (default True) scoremap에서 최소값.
    "outputs.score_max": bool,  # (default True) scoremap에서 최대값.
    "outputs.mask": bool,  # (default True)
    "outputs.is_ng": bool,  # (default True)
    "outputs.heatmap": bool,  # (default True)
    "outputs.objects": bool,  # (default True)
    "outputs.time": bool,  # (default False)
    "params.anomaly_score_threshold": float,    # is_ng를 판단할 때 사용됩니다.
                                                # True이면 NG, False이면 OK 이미지를 나타냅니다.
                                                # (-inf, inf) 범위의 소수. (default 0.0)
    # 다음 두 heatmap_color_range_x 파라미터를 사용해 min-max normalization을 수행합니다.
    "params.heatmap_color_range_max": float,    # scoremap을 이용해, heatmap을 만들 때 사용됩니다.
                                                # (default 0.0)
    "params.heatmap_color_range_min": float,    # scoremap을 이용해, heatmap을 만들 때 사용됩니다.
                                                # (default 0.0)
    "params.calc_object_area_and_apply_threshold": bool,  # True인 경우 object마다 area(=픽셀수)를 계산하고 object_area_threshold를 적용합니다.
                                                # outputs.objects가 True일때만 적용.
                                                # (default True)
    "params.calc_object_score_and_apply_threshold": bool,  # True인 경우 object마다 anomaly score를 계산하고 object_score_threshold를 적용합니다.
                                                # outputs.objects가 True일때만 적용.
                                                # (default True)
    "params.object_boundary_threshold": float,  # mask를 만들 때 사용됩니다.
                                                # 픽셀의 예측된 score가 threshold보다 작은 경우 0으로, 큰 경우 1로 치환 됩니다.
                                                # 픽셀값이 1이면 Anomaly part이고, 0이면 Normal part입니다.
                                                # (-inf, inf) 범위의 소수. (default 0.0)
    "params.object_scoring_method": str,        # object별로 score를 나타내기 위해 사용되는 method를 조절합니다.
                                                # "outputs.objects"가 True이고, "params.calc_object_score_and_apply_threshold"가 True일때 동작합니다.
                                                # option중에는 ["mean", "max"]이 있습니다.
                                                # (default "mean")
    "params.object_score_threshold": float,     # object의 score가 threshold보다 작은 경우 필터링 됩니다.
                                                # "outputs.objects"가 True이고, "params.calc_object_score_and_apply_threshold"가 True일때 동작합니다.
                                                # (-inf, inf) 범위의 소수. (default 0.0)
    "params.object_area_method": str,           # object area를 계산할 때 사용되는 method.
                                                # option중에는 ["fast_plus"]만 존재합니다.
                                                # (default "fast_plus")
    "params.object_area_threshold": int,        # object의 area(=픽셀수)가 threshold보다 작은 경우 필터링 됩니다.
                                                # "outputs.objects"가 True이고, "params.calc_object_area_and_apply_threshold"가 True일때 동작합니다.
                                                # 0 이상의 정수. (default 0)
    "params.batch_size": int,                   # `infer_and_postprocess`에 한 번에 입력할 수 있는 최대 이미지 개수 입니다.
                                                # 파라미터가 변경되는 경우 해당 값으로 warmup을 수행합니다.
                                                # (default 1)
}

사용 예시:

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 옵션을 설정합니다.

Note

heatmap_color_range_max과 heatmap_color_range_min을 설정할 때는, 현재 어떤 값으로 설정되어있는지 확인하고, heatmap_color_range_max >= heatmap_color_range_min의 조건을 만족하도록 설정해야 합니다.

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에서 warmup이 필요한 [params.batch_size]를 제외하면 동일합니다.

infer_and_postprocess(images)

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

Parameters:

Name Type Description Default
images Union[List[np.ndarray], List[str]]
- List[np.ndarray]: numpy image가 들어있는 List 입니다. 각 image는 다음 제약 조건을 갖습니다.
                    data type: uint8, uint16
                    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 입니다.
required

Returns:

Type Description
List[Dict]

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

[
    {
        "score": float,  # anomaly score값.
        "scoremap": ndarray(float32, shape=(H, W)),  # 픽셀의 score가 저장된 array
        "score_min": float,  # scoremap에서 최솟값.
        "score_max": float,  # scoremap에서 최솟값.
        "mask": ndarray(uint8, shape=(H, W)),  # 각 픽셀이 예측된 Anomaly를 값으로 갖는 array 입니다. 픽셀값이 1이면 Anomaly part이고, 0이면 Normal part입니다.
        "heatmap":  ndarray(float32, shape=(H, W)),  # scoremap을 heatmap으로 표현한 array 입니다. min=0, max=1로 truncated되었습니다.
        "is_ng": bool,  # anomaly_score_threshold와 score로부터 ng인지 아닌지 나타냅니다.
        "objects": [  # mask에 contouring을 해서 얻은 segmented object들의 리스트. (List[Dict])
            {  # AnomalyDetction object 구조
                "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
                ],
                "area": int,  # object의 픽셀 수. calc_object_score_and_apply_threshold True일때만 존재하는 key입니다.
                "score": float,  # object의 anomaly score. calc_object_score_and_apply_threshold가 True일때만 존재하는 key입니다.
                "bounding_box": List[int],  # [left, top, width, height]
                "bounding_rot_box": List,  # [[center_x, center_y], [width, height], angle, [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]], all items are float
                "fitted_ellipse": List,  # [[center_x, center_y], [width, height], angle], all items are float
            },
            ...,  # times number of objects
        ],
        "time": {  # inference에 소요된 시간을 담고있는 dictionary 입니다. (단위: ms)
            "imread_time": float,  # 실제 image를 load하여 연구팀이 사용하는 image format (PIL)으로 변경하기까지 걸리는 시간 (각 이미지 별로 걸리는 시간)
            "inference_time": float,  # resize, roi, tensorize, network forward 등을 포함하는 시간 (각 이미지 별로 걸리는 시간)
            "post_processing_time": float,  # postprocess에 걸린 시간 (각 이미지 별로 걸리는 시간)
        },
    },
    ...,  # times number of images
]

analyze(images, labeled, use_saved_file)

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

Parameters:

Name Type Description Default
images Dict[str, Dict]

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

{
    "{image_id}": {
        "path": str,  # image path
        "labels": {
            "is_ng": bool,  # ng or not
        },
        "save_dir": str,  # 해당 이미지의 analysis 결과 저장 directory
    },
    ...,  # n times number of images
}

required
labeled bool

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

required
use_saved_file bool

기존 인퍼런스 결과인 saved_file 사용 여부

required

Returns:

Name Type Description
Dict Dict

Analysis 결과

{
    "{image_id}": {
        "correct": bool,  # labeled=True일 때 return. is_ng와, label을 비교하여 같은지 다른지에 따라 True or False를 나타냄
        "prediction": {
            "score": float,  # anomaly score값.
            "scoremap": ndarray(float32, shape=(H, W)),  # 픽셀의 score가 저장된 array
            "score_min": float,  # scoremap에서 최솟값.
            "score_max": float,  # scoremap에서 최솟값.
            "mask": ndarray(uint8, shape=(H, W)),  # 각 픽셀이 예측된 Anomaly를 값으로 갖는 array 입니다. 픽셀값이 1이면 Anomaly part이고, 0이면 Normal part입니다.
            "heatmap":  ndarray(float32, shape=(H, W)),  # scoremap을 heatmap으로 표현한 array 입니다. min=0, max=1로 truncated되었습니다.
            "is_ng": bool,  # anomaly_score_threshold와 score로부터 ng인지 아닌지 나타냅니다.
            "objects": [  # contouring을 해서 얻은 object들의 리스트. (List[Dict])
                {  # AnomalyDetction object 구조
                    "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
                    ],
                    "area": int,  # object의 픽셀 수. calc_object_score_and_apply_threshold True일때만 존재하는 key입니다.
                    "score": float,  # object의 anomaly score. calc_object_score_and_apply_threshold가 True일때만 존재하는 key입니다.
                    "bounding_box": List[int],  # [left, top, width, height]
                    "bounding_rot_box": List,  # [[center_x, center_y], [width, height], angle], all items are float
                    "fitted_ellipse": List,  # [[center_x, center_y], [width, height], angle], all items are float
                },
                ...,  # times number of objects
            ],
            "time": {  # inference에 소요된 시간을 담고있는 dictionary 입니다. (단위: ms)
                "imread_time": float,  # 실제 image를 load하여 연구팀이 사용하는 image format (PIL)으로 변경하기까지 걸리는 시간 (각 이미지 별로 걸리는 시간)
                "inference_time": float,  # resize, roi, tensorize, network forward 등을 포함하는 시간 (각 이미지 별로 걸리는 시간)
                "post_processing_time": float,  # postprocess에 걸린 시간 (각 이미지 별로 걸리는 시간)
            },
        },
    },
    ... # 입력으로 넣어준 이미지 개수만큼 반복
}

summarize_analysis(images, labeled)

Analysis를 마무리하고 결과를 리턴합니다.

Parameters:

Name Type Description Default
images Dict[str, Dict]

analysis에 사용할 데이터 리스트.

{
    "{image_id}": {
        "save_dir": str,  # 해당 이미지의 analysis 결과 저장 directory
    },
    ...,  # times number of images
}

required
labeled bool

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

required

Returns:

Name Type Description
Dict Dict

Analysis summary

{
    # InferenceHandler.summarize_analysis 호출시에 labeled=True였다면 아래 Key들을 return합니다.
    ## 아래 AUROC, AUPR, Best threshold, Best F1-score는 NG와 OK이미지가 모두 적어도 1개 이상 있을때 출력합니다.
    "AUROC": float,  # Area under ROC
    "AUPR": float,  # Area under PR curve
    "Best threshold": float,  # Best threshold
    "Best F1-Score": float,  # F1 score with labels
    ## 아래 이미지 개수에 대한 summary는 anomaly_score_threshold로 계산되었습니다.
    "number_of_images": int,  # number of analyzed images
    "number_of_correct_images": int,  # number of correct images
    "number_of_wrong_images": int,  # number of wrong images
    "number_of_overkill": int,  # number of overkill images(label: OK, prediction: NG)
    "number_of_not_overkill": int,  # number of images(label: OK, prediction: OK)
    "number_of_underkill": int,  # number of images(label: NG, prediction: OK)
    "number_of_not_underkill": int  # number of images(label: NG, prediction: NG)
}

warmup()

현재 설정된 inference 옵션을 바탕으로 warmup을 수행합니다.