SW중심대학 공동 AI 경진대회 2023

SW중심대학 | 알고리즘 | 비전 | 객체분할 | DiceScore

  • moneyIcon 상금 : 총 1,700만원
  • 1,041명 마감

 

[평가 산식] Dice Coefficient(Score) 관련

2023.07.03 10:11 3,314 조회

이번 SW중심대학 공동 AI 경진대회 2023에 실제 적용되고 있는 평가 산식(Dice Coefficient) 코드를 공개합니다.

참가자 여러분들께서는 모델 성능 개선에 해당 평가 산식 코드를 활용하실 수 있습니다.


[중요]

또한 이번 평가 산식(Dice Coefficient)에서 추가된 가장 중요한 점은,

Ground Truth (정답)에 건물이 없고, Prediction (예측) 또한 건물이 없다고 맞춘 경우에는 샘플들의 Dice Coefficient 평균 계산에서 '제외' 됩니다.

다른 케이스로, Ground Truth (정답)에 건물이 없으나, Prediction (예측)에는 건물이 있다고 하는 경우에는 해당 샘플의 Dice Coefficient는 0점이 됩니다.

import numpy as np
import pandas as pd
from typing import List, Union
from joblib import Parallel, delayed


def rle_decode(mask_rle: Union[str, int], shape=(224, 224)) -> np.array:
    '''
    mask_rle: run-length as string formatted (start length)
    shape: (height,width) of array to return 
    Returns numpy array, 1 - mask, 0 - background
    '''
    if mask_rle == -1:
        return np.zeros(shape)
    
    s = mask_rle.split()
    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]
    starts -= 1
    ends = starts + lengths
    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)
    for lo, hi in zip(starts, ends):
        img[lo:hi] = 1
    return img.reshape(shape)


def dice_score(prediction: np.array, ground_truth: np.array, smooth=1e-7) -> float:
    '''
    Calculate Dice Score between two binary masks.
    '''
    intersection = np.sum(prediction * ground_truth)
    return (2.0 * intersection + smooth) / (np.sum(prediction) + np.sum(ground_truth) + smooth)


def calculate_dice_scores(ground_truth_df, prediction_df, img_shape=(224, 224)) -> List[float]:
    '''
    Calculate Dice scores for a dataset.
    '''


    # Keep only the rows in the prediction dataframe that have matching img_ids in the ground truth dataframe
    prediction_df = prediction_df[prediction_df.iloc[:, 0].isin(ground_truth_df.iloc[:, 0])]
    prediction_df.index = range(prediction_df.shape[0])


    # Extract the mask_rle columns
    pred_mask_rle = prediction_df.iloc[:, 1]
    gt_mask_rle = ground_truth_df.iloc[:, 1]


    def calculate_dice(pred_rle, gt_rle):
        pred_mask = rle_decode(pred_rle, img_shape)
        gt_mask = rle_decode(gt_rle, img_shape)


        if np.sum(gt_mask) > 0 or np.sum(pred_mask) > 0:
            return dice_score(pred_mask, gt_mask)
        else:
            return None  # No valid masks found, return None


    dice_scores = Parallel(n_jobs=-1)(
        delayed(calculate_dice)(pred_rle, gt_rle) for pred_rle, gt_rle in zip(pred_mask_rle, gt_mask_rle)
    )


    dice_scores = [score for score in dice_scores if score is not None]  # Exclude None values


    return np.mean(dice_scores)
로그인이 필요합니다
0 / 1000
zmzmzmzmz
2023.07.13 13:35

test.csv파일에 mask_rle의 ground_truth가 없는데 어떻게 평가산식을 하나요 ???

DACON.GM
2023.07.13 13:57

안녕하세요 zmzmzmzmz님,
평가 데이터의 ground_truth는 참가자분들에게는 공개하지 않습니다.
참가자분들이 예측한 결과와 실제 ground_truth로 계산된 결과가 리더보드로 표시됩니다.
대회 진행 중 본인이 학습시킨 모델의 성능을 평가하기 위해서는 제공드린 학습 데이터 내에서 검증 데이터셋을 분리하여 진행하실 수 있습니다.
즉, test.csv는 참가자분들의 추론을 위한 입력데이터만 주어지며 label은 제공하지 않습니다.
감사합니다.