# Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. 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 = np.mean(m_aps) m_ap = m_aps[~np.isnan(m_aps)] print(f'num of available classes: {len(m_ap)}') m_ap = m_ap.mean() # compute mean w/o nan 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))