❗️ 공지:
(11/13) 11월 13일 14:00 기점으로 결과 스코어가 0점일 경우 ‘제출중’으로 표시되는 버그가 수정되었습니다.
(11/10) (재공지) 11월 10일 14:30 기점으로 Pre-trained 모델 사용 규칙을 아래와 같이 공지합니다.
본 대회의 Pre-trained 모델 사용 규칙에 대한 재공지를 드립니다, 대회 기간 중에 혼선을 드려 정말 대단히 죄송합니다..!
금일 오전에 공지한 Pre-trained 모델 사용 불가 규정은 취소하고, 아래와 같이 재공지합니다
(11/10) (해당 공지 내용은 취소되었습니다.)11월 10일 10:00 기점으로 Pre-trained 모델 사용이 금지됩니다.
■ (11/2) 11월 2일 13:30 기점으로 참가자격 조건이 완화되었으며 참가접수 기간 또한 연장되었습니다
각 항목별 개념은 다음과 같습니다.
실제 사용되는 커스텀 스코어 코드는 다음과 같습니다.
import sys
import json
import numpy as np
def intersection_over_union(boxes_labels, boxes_preds):
# coco type label (x0, y0, w, h)
x, y, w, h = boxes_labels
x, y, w, h = float(x), float(y), float(w), float(h)
box1_x1 = float(x)
box1_y1 = y
box1_x2 = x + w
box1_y2 = y + h
x, y, w, h = boxes_preds
box2_x1 = x
box2_y1 = y
box2_x2 = x + w
box2_y2 = y + h
x1 = np.max([float(box1_x1), float(box2_x1)])
y1 = np.max([float(box1_y1), float(box2_y1)])
x2 = np.min([float(box1_x2), float(box2_x2)])
y2 = np.min([float(box1_y2), float(box2_y2)])
intersection = max((x2 - x1), 0) * max((y2 - y1), 0)
box1_area = abs((box1_x2 - box1_x1) * (box1_y2 - box1_y1))
box2_area = abs((box2_x2 - box2_x1) * (box2_y2 - box2_y1))
epsilon = 1e-6 if box1_area + box2_area - intersection == 0 else 0
return intersection / (box1_area + box2_area - intersection + epsilon)
def macro_f1(gt, pr, th=0.5):
tp = np.zeros(len(gt['categories']), dtype=int)
fp = np.zeros(len(gt['categories']), dtype=int)
fn = np.zeros(len(gt['categories']), dtype=int)
tp_p = np.zeros(len(gt['categories']), dtype=int)
fp_p = np.zeros(len(gt['categories']), dtype=int)
fn_p = np.zeros(len(gt['categories']), dtype=int)
for img in gt['images']:
gt_img = [i for i in gt['annotations'] if i['image_id'] == img['id']]
pr_img = [i for i in pr['annotations'] if i['image_id'] == img['id']]
# print(pr_img)
tp_temp = np.zeros(len(gt['categories']), dtype=int)
fp_temp = np.zeros(len(gt['categories']), dtype=int)
fn_temp = np.zeros(len(gt['categories']), dtype=int)
# 해당 GT 이미지에 object가 있고
if len(gt_img) > 0:
gt_classes = [i['category_id'] for i in gt_img]
# 해당 GT 이미지에 대한 예측이 있는 경우
if len(pr_img) > 0:
ious = [intersection_over_union(i['bbox'], j['bbox']) for i in gt_img for j in pr_img]
# pr을 iou가 최대인 gt에 할당
ioumat = np.array(ious).reshape(len(gt_img), -1) # gt_dim:0, pr_dim:1
# assigned_indices = np.argmax(ioumat, axis=0) # pr을 gt에 할당해야 하므로
ioumat = ioumat * (ioumat.max(axis=0, keepdims=True) == ioumat)
# TP / FP / FN
pr_classes = [i['category_id'] for i in pr_img]
for i in range(len(gt_classes)):
assigned = sum(ioumat[i] >= th) # 할당 기준은 th 이상일 것
if assigned == 0: # 아무 오브젝트에도 예측되지 않은 정답은 해당 클래스 FN에 더함
fn_temp[gt_classes[i]] += 1
else:
if assigned > 1:
fp_temp[gt_classes[i]] += assigned - 1 # 중복 예측은 FP에 할당
if gt_classes[i] == pr_classes[ioumat[i].argmax()]:
tp_temp[gt_classes[i]] += 1
# 무엇에도 assign되지 않은 예측(모든 obj와 iou가 th 미만)은 해당 예측의 class에 FP로 더함
unassigned = np.where([np.all(ioumat[:,i] < th) for i in range(len(pr_classes))])[0]
if len(unassigned) > 0:
for j in unassigned:
fp_temp[pr_classes[j]] += 1
# 해당 GT 이미지에 대한 예측이 없는 경우 모든 object를 FN에 추가
else:
for i in range(len(gt_classes)):
fn_temp[gt_classes[i]] += 1
# 해당 GT 이미지에 아예 object가 없는 경우
else:
# 해당 GT 이미지에 대한 예측이 있는 경우 모든 예측을 FP에 추가
if len(pr_img) > 0:
pr_classes = [i['category_id'] for i in pr_img]
for i in range(len(pr_classes)):
fp_temp[pr_classes[i]] += 1
# 전체 TP, FN, FN에 결과 추가
if img['id'] in public_id:
tp_p += tp_temp
fp_p += fp_temp
fn_p += fn_temp
else:
tp += tp_temp
fp += fp_temp
fn += fn_temp
# macro 계산
precision_p = tp_p / (tp_p + fp_p)
recall_p = tp_p / (tp_p + fn_p)
f1_score_p = (2 * precision_p * recall_p) / (precision_p + recall_p)
# nan -> 0 추가
f1_score_p[np.isnan(f1_score_p)] = 0
f1_score_p = np.nanmean(f1_score_p)
precision = tp / (tp + fp)
recall = tp / (tp + fn)
f1_score = (2 * precision * recall) / (precision + recall)
# nan -> 0 추가
f1_score[np.isnan(f1_score)] = 0
f1_score = np.nanmean(f1_score)
return f1_score_p, f1_score
※ 본 대회는 http://aifactory.space 의 회원가입을 완료한 회원이 아래 규칙에 대해 동의한 경우에만 참가 가능합니다.
※ 대회 참여 중 규칙에 위배되는 상황이 발생한 경우, 입상이 취소될 수 있습니다.
스코어 관련
이번 대회는 Public 스코어와 Private 스코어 total 점수로 최종 순위가 결정됩니다
팀 참가 관련
대회 제출 관련