Spaces:
Runtime error
Runtime error
| import numpy as np | |
| from hotr.metrics.utils import _compute_ap, compute_overlap | |
| import pdb | |
| class APAgent(object): | |
| def __init__(self, act_name, iou_threshold=0.5): | |
| self.act_name = act_name | |
| self.iou_threshold = iou_threshold | |
| self.fp = [np.zeros((0,))] * len(act_name) | |
| self.tp = [np.zeros((0,))] * len(act_name) | |
| self.score = [np.zeros((0,))] * len(act_name) | |
| self.num_ann = [0] * len(act_name) | |
| def add_data(self, box, act, cat, i_box, i_act): | |
| for label in range(len(self.act_name)): | |
| i_inds = (i_act[:, label] == 1) | |
| self.num_ann[label] += i_inds.sum() | |
| n_pred = box.shape[0] | |
| if n_pred == 0 : return | |
| ###################### | |
| valid_i_inds = (i_act[:, 0] != -1) # (n_i, ) # both in COCO & V-COCO | |
| overlaps = compute_overlap(box, i_box) # (n_pred, n_i) | |
| assigned_input = np.argmax(overlaps, axis=1) # (n_pred, ) | |
| v_inds = valid_i_inds[assigned_input] # (n_pred, ) | |
| n_valid = v_inds.sum() | |
| if n_valid == 0 : return | |
| valid_box = box[v_inds] | |
| valid_act = act[v_inds] | |
| valid_cat = cat[v_inds] | |
| ###################### | |
| s = valid_act * np.expand_dims(valid_cat, axis=1) # (n_v, #act) | |
| for label in range(len(self.act_name)): | |
| inds = np.argsort(s[:, label])[::-1] # (n_v, ) | |
| self.score[label] = np.append(self.score[label], s[inds, label]) | |
| correct_i_inds = (i_act[:, label] == 1) | |
| if correct_i_inds.sum() == 0: | |
| self.tp[label] = np.append(self.tp[label], np.array([0]*n_valid)) | |
| self.fp[label] = np.append(self.fp[label], np.array([1]*n_valid)) | |
| continue | |
| overlaps = compute_overlap(valid_box[inds], i_box) # (n_v, n_i) | |
| assigned_input = np.argmax(overlaps, axis=1) # (n_v, ) | |
| max_overlap = overlaps[range(n_valid), assigned_input] # (n_v, ) | |
| iou_inds = (max_overlap > self.iou_threshold) & correct_i_inds[assigned_input] # (n_v, ) | |
| i_nonzero = iou_inds.nonzero()[0] | |
| i_inds = assigned_input[i_nonzero] | |
| i_iou = np.unique(i_inds, return_index=True)[1] | |
| i_tp = i_nonzero[i_iou] | |
| t = np.zeros(n_valid, dtype=np.uint8) | |
| t[i_tp] = 1 | |
| f = 1-t | |
| self.tp[label] = np.append(self.tp[label], t) | |
| self.fp[label] = np.append(self.fp[label], f) | |
| def evaluate(self): | |
| average_precisions = dict() | |
| for label in range(len(self.act_name)): | |
| if self.num_ann[label] == 0: | |
| average_precisions[label] = 0 | |
| continue | |
| # sort by score | |
| indices = np.argsort(-self.score[label]) | |
| self.fp[label] = self.fp[label][indices] | |
| self.tp[label] = self.tp[label][indices] | |
| # compute false positives and true positives | |
| self.fp[label] = np.cumsum(self.fp[label]) | |
| self.tp[label] = np.cumsum(self.tp[label]) | |
| # compute recall and precision | |
| recall = self.tp[label] / self.num_ann[label] | |
| precision = self.tp[label] / np.maximum(self.tp[label] + self.fp[label], np.finfo(np.float64).eps) | |
| # compute average precision | |
| average_precisions[label] = _compute_ap(recall, precision) * 100 | |
| print('\n================== AP (Agent) ===================') | |
| s, n = 0, 0 | |
| for label in range(len(self.act_name)): | |
| label_name = "_".join(self.act_name[label].split("_")[1:]) | |
| print('{: >23}: AP = {:0.2f} (#pos = {:d})'.format(label_name, average_precisions[label], self.num_ann[label])) | |
| s += average_precisions[label] | |
| n += 1 | |
| mAP = s/n | |
| print('| mAP(agent): {:0.2f}'.format(mAP)) | |
| print('----------------------------------------------------') | |
| return mAP |