|
|
|
|
|
|
|
|
|
|
|
|
|
import numpy as np |
|
|
|
|
|
def compute_map(submission_array, gt_array): |
|
""" Returns mAP, weighted mAP, and AP array """ |
|
m_aps = [] |
|
n_classes = submission_array.shape[1] |
|
for oc_i in range(n_classes): |
|
sorted_idxs = np.argsort(-submission_array[:, oc_i]) |
|
tp = gt_array[:, oc_i][sorted_idxs] == 1 |
|
fp = np.invert(tp) |
|
n_pos = tp.sum() |
|
if n_pos < 0.1: |
|
m_aps.append(float('nan')) |
|
continue |
|
fp.sum() |
|
f_pcs = np.cumsum(fp) |
|
t_pcs = np.cumsum(tp) |
|
prec = t_pcs / (f_pcs+t_pcs).astype(float) |
|
avg_prec = 0 |
|
for i in range(submission_array.shape[0]): |
|
if tp[i]: |
|
avg_prec += prec[i] |
|
m_aps.append(avg_prec / n_pos.astype(float)) |
|
m_aps = np.array(m_aps) |
|
|
|
m_ap = m_aps[~np.isnan(m_aps)] |
|
print(f'num of available classes: {len(m_ap)}') |
|
m_ap = m_ap.mean() |
|
w_ap = (m_aps * gt_array.sum(axis=0) / gt_array.sum().sum().astype(float)) |
|
return m_ap, w_ap, m_aps |
|
|
|
|
|
def charades_map(submission_array, gt_array): |
|
""" |
|
Approximate version of the charades evaluation function |
|
For precise numbers, use the submission file with the official matlab script |
|
""" |
|
fix = submission_array.copy() |
|
empty = np.sum(gt_array, axis=1) == 0 |
|
fix[empty, :] = np.NINF |
|
return compute_map(fix, gt_array) |
|
|
|
|
|
def create_submission(video_list, predictions, out_file): |
|
assert len(video_list) == predictions.shape[0] |
|
with open(out_file, 'w') as f: |
|
for i, video_id in enumerate(video_list): |
|
pred_str = ' '.join(map(lambda x: str(x), predictions[i].tolist())) |
|
f.write('{} {}\n\n'.format(video_id, pred_str)) |
|
|