|
import numpy as np |
|
|
|
|
|
def evaluate(sims, labels): |
|
|
|
thresholds = np.arange(0, 1.0, 0.001) |
|
fm, tpr, acc = calculate_roc(thresholds, sims, labels) |
|
eer = calculate_eer(thresholds, sims, labels) |
|
return fm, tpr, acc, eer |
|
|
|
|
|
def calculate_roc(thresholds, sims, labels): |
|
nrof_thresholds = len(thresholds) |
|
|
|
tprs = np.zeros((nrof_thresholds)) |
|
fprs = np.zeros((nrof_thresholds)) |
|
acc_train = np.zeros((nrof_thresholds)) |
|
precisions = np.zeros((nrof_thresholds)) |
|
fms = np.zeros((nrof_thresholds)) |
|
|
|
|
|
|
|
for threshold_idx, threshold in enumerate(thresholds): |
|
tprs[threshold_idx], fprs[threshold_idx], precisions[threshold_idx], fms[threshold_idx], acc_train[ |
|
threshold_idx] = calculate_accuracy(threshold, sims, labels) |
|
|
|
bestindex = np.argmax(fms) |
|
bestfm = fms[bestindex] |
|
besttpr = tprs[bestindex] |
|
bestacc = acc_train[bestindex] |
|
|
|
return bestfm, besttpr, bestacc |
|
|
|
|
|
def calculate_accuracy(threshold, sims, actual_issame): |
|
predict_issame = np.greater(sims, threshold) |
|
tp = np.sum(np.logical_and(predict_issame, actual_issame)) |
|
fp = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame))) |
|
tn = np.sum(np.logical_and(np.logical_not(predict_issame), np.logical_not(actual_issame))) |
|
fn = np.sum(np.logical_and(np.logical_not(predict_issame), actual_issame)) |
|
|
|
tpr = 0 if (tp + fn == 0) else float(tp) / float(tp + fn) |
|
fpr = 0 if (fp + tn == 0) else float(fp) / float(fp + tn) |
|
precision = 0 if (tp + fp == 0) else float(tp) / float(tp + fp) |
|
fm = 2 * precision * tpr / (precision + tpr + 1e-12) |
|
acc = float(tp + tn) / (sims.size + 1e-12) |
|
return tpr, fpr, precision, fm, acc |
|
|
|
|
|
def calculate_eer(thresholds, sims, labels): |
|
nrof_thresholds = len(thresholds) |
|
|
|
|
|
far_train = np.zeros(nrof_thresholds) |
|
frr_train = np.zeros(nrof_thresholds) |
|
eer_index = 0 |
|
eer_diff = 100000000 |
|
for threshold_idx, threshold in enumerate(thresholds): |
|
frr_train[threshold_idx], far_train[threshold_idx] = calculate_val_far(threshold, sims, labels) |
|
if abs(frr_train[threshold_idx] - far_train[threshold_idx]) < eer_diff: |
|
eer_diff = abs(frr_train[threshold_idx] - far_train[threshold_idx]) |
|
eer_index = threshold_idx |
|
|
|
frr, far = frr_train[eer_index], far_train[eer_index] |
|
|
|
eer = (frr + far) / 2 |
|
|
|
return eer |
|
|
|
|
|
def calculate_val_far(threshold, sims, actual_issame): |
|
predict_issame = np.greater(sims, threshold) |
|
true_accept = np.sum(np.logical_and(predict_issame, actual_issame)) |
|
false_accept = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame))) |
|
n_same = np.sum(actual_issame) |
|
n_diff = np.sum(np.logical_not(actual_issame)) |
|
if n_diff == 0: |
|
n_diff = 1 |
|
if n_same == 0: |
|
return 0, 0 |
|
val = float(true_accept) / float(n_same) |
|
frr = 1 - val |
|
far = float(false_accept) / float(n_diff) |
|
return frr, far |
|
|