Skip to content

Summary

classification.SummaryHandler

딥러닝 모델 빌드 없이, 저장된 analysis 결과를 이용해서 analysis summary를 수행하는 클래스입니다.

Usage
# AnalysisHandler 및 SummaryHandler 빌드
n_classes = CONFIG["n_classes"]
analysis_build_config = {
    "n_classes": n_classes,
}
error, message, analysis_handler = AnalysisHandler.build(analysis_build_config)
assert error >= 0, f"[CODE] ({error}) {message}"

summary_build_config = {
    "n_classes": n_classes,
}
error, message, summary_handler = SummaryHandler.build(summary_build_config)
assert error >= 0, f"[CODE] ({error}) {message}"

# 모듈 정보 확인
error, message, metadata = read_metadata(CHECKPOINT_PATH)
assert error >= 0, f"[CODE] ({error}) {message}"
print("Inference metadata:", metadata)

# 인퍼런스 옵션 초기값 확인
inference_options = {
    "params.additional_scores": [10] * n_classes,
}
print("Default inference options:")
for key in list(inference_options):
    error, message, value = analysis_handler.get_default_inference_option(key)
    assert error >= 0, f"[CODE] ({error}) {message}"
    print(f"  {key}: {value}")

# 디벨로퍼: Analyze 수행
for image_id, image_info in DATA["validation_images"].items():
    image_info["save_dir"] = os.path.join("./demo/inference_results", str(image_id))
    image = {image_id: image_info}

    error, message, results = analysis_handler.analyze(images=image, labeled=True)
    assert error >= 0, f"[CODE] ({error}) {message}"

error, message, results = summary_handler.summarize_analysis(images=DATA["validation_images"], labeled=True)
assert error >= 0, f"[CODE] ({error}) {message}"
print("Analysis summary:", results)

# 디벨로퍼: 인퍼런스 옵션 변경
for key, value in inference_options.items():
    error, message, _ = analysis_handler.set_inference_option(key, value)
    assert error >= 0, f"[CODE] ({error}) {message}"

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

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

# 디벨로퍼: 새로운 세팅으로 Analyze 재수행
for image_id, image_info in DATA["validation_images"].items():
    image = {image_id: image_info}

    error, message, results = analysis_handler.analyze(images=image, labeled=True)
    assert error >= 0, f"[CODE] ({error}) {message}"

error, message, results = summary_handler.summarize_analysis(images=DATA["validation_images"], labeled=True)
assert error >= 0, f"[CODE] ({error}) {message}"
print("Analysis summary:", results)
Note

위 예시처럼 AnalysisHandler가 아니라, InferenceHandler여도 상관 없습니다.

build(config) classmethod

SummaryHandler class의 instance를 생성합니다.

Parameters:

Name Type Description Default
config dict

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

{
    "n_classes": int,  # number of data classes (including background class)
}

required

Returns:

Name Type Description
SummaryHandler SummaryHandler

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

summarize_analysis(images, labeled)

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 결과

# Case1: **(labeled=True)인 경우**
{
    "confusion_matrix": list[list[int]],  # confusion matrix. 아래는 총 class가 4개일 때 예시
        [
            [2, 0, 0, 1],  # 라벨이 class1인 image 중에 미검 1개 (class4로 예측), 맞춘 것 2개
            [1, 2, 0, 0],  # 라벨이 class2인 image 중에 미검 1개 (class1로 예측), 맞춘 것 2개
            [0, 1, 0, 0],  # 라벨이 class3인 image 중에 미검 1개 (class2로 예측), 맞춘 것 0개
            [0, 0, 0, 1],  # 라벨이 class4인 image 중에 미검 0개, 맞춘 것 1개
        ]

    # Class-wise Results
    "class_{idx}_precision": float,  # 각 {idx} class 별 precision 값(0~1). (class_{idx}_num_correct / class_{idx}_num_predictions) 으로 계산됩니다.
    "class_{idx}_recall": float,  # 각 {idx} class 별 recall 값 (0~1). (class_{idx}_num_correct / class_{idx}_num_labels) 으로 계산됩니다.
    "class_{idx}_f1": float,  # 각 {idx} class 별 f1 값 (0~1).
    "class_{idx}_num_labels": int,  # 각 {idx} class 별 실제로 해당 클래스인 이미지 개수.
    "class_{idx}_num_predictions": int, # 각 {idx} class 별 해당 클래스로 예측된 이미지 개수.
    "class_{idx}_num_correct": int, # 각 {idx} class 별 해당 클래스로 예측된 이미지 중 실제로 해당 클래스인 이미지 개수.

    # Overall Results
    "num_total": int,  # 검사한 이미지 개수.
    "num_correct": int,  # 검사한 이미지 중 맞은 것의 개수.
    "num_wrong": int,  # 검사한 이미지 중 틀린 것의 개수.
    "accuracy": float,  # accuracy (0~1). (correct / total)
    "mean_f1": float,  # average f1 score (0~1).
},

# Case2: **(labeled=False)인 경우**
{} # 빈 dict