forked from qqueing/DeepSpeaker-pytorch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
eval_metrics.py
89 lines (63 loc) · 2.9 KB
/
eval_metrics.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import numpy as np
from sklearn.model_selection import KFold
from scipy import interpolate
def evaluate(distances, labels):
# Calculate evaluation metrics
thresholds = np.arange(0, 30, 0.01)
tpr, fpr, accuracy = calculate_roc(thresholds, distances,
labels)
thresholds = np.arange(0, 30, 0.001)
val, far = calculate_val(thresholds, distances,
labels, 1e-3)
return tpr, fpr, accuracy, val, far
def calculate_roc(thresholds, distances, labels):
nrof_pairs = min(len(labels), len(distances))
nrof_thresholds = len(thresholds)
tprs = np.zeros((nrof_thresholds))
fprs = np.zeros((nrof_thresholds))
acc_train = np.zeros((nrof_thresholds))
accuracy = 0.0
indices = np.arange(nrof_pairs)
# Find the best threshold for the fold
for threshold_idx, threshold in enumerate(thresholds):
tprs[threshold_idx], fprs[threshold_idx], acc_train[threshold_idx] = calculate_accuracy(threshold, distances, labels)
best_threshold_index = np.argmax(acc_train)
return tprs[best_threshold_index], fprs[best_threshold_index], acc_train[best_threshold_index]
def calculate_accuracy(threshold, dist, actual_issame):
predict_issame = np.less(dist, 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)
acc = float(tp+tn)/dist.size
return tpr, fpr, acc
def calculate_val(thresholds, distances, labels, far_target=0.1):
nrof_pairs = min(len(labels), len(distances))
nrof_thresholds = len(thresholds)
indices = np.arange(nrof_pairs)
# Find the threshold that gives FAR = far_target
far_train = np.zeros(nrof_thresholds)
for threshold_idx, threshold in enumerate(thresholds):
_, far_train[threshold_idx] = calculate_val_far(threshold, distances, labels)
if np.max(far_train)>=far_target:
f = interpolate.interp1d(far_train, thresholds, kind='slinear')
threshold = f(far_target)
else:
threshold = 0.0
val, far = calculate_val_far(threshold, distances, labels)
return val, far
def calculate_val_far(threshold, dist, actual_issame):
predict_issame = np.less(dist, 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)
far = float(false_accept) / float(n_diff)
return val, far