@@ -20,14 +20,14 @@ def twoGMMcalib_lin(s, niters=20):
20
20
var = np .var (s )
21
21
threshold = np .inf
22
22
for _ in range (niters ):
23
- lls = np .log (weights )- 0.5 * np .log (var ) - 0.5 * (s [:,np .newaxis ]- means )** 2 / var
23
+ lls = np .log (weights ) - 0.5 * np .log (var ) - 0.5 * (s [:, np .newaxis ] - means )** 2 / var
24
24
gammas = softmax (lls , axis = 1 )
25
25
cnts = np .sum (gammas , axis = 0 )
26
26
weights = cnts / cnts .sum ()
27
27
means = s .dot (gammas ) / cnts
28
28
var = ((s ** 2 ).dot (gammas ) / cnts - means ** 2 ).dot (weights )
29
- threshold = - 0.5 * (np .log (weights ** 2 / var )- means ** 2 / var ).dot ([1 ,- 1 ])/ (means / var ).dot ([1 ,- 1 ])
30
- return threshold , lls [:,means .argmax ()]- lls [:,means .argmin ()]
29
+ threshold = - 0.5 * (np .log (weights ** 2 / var ) - means ** 2 / var ).dot ([1 , - 1 ]) / (means / var ).dot ([1 , - 1 ])
30
+ return threshold , lls [:, means .argmax ()] - lls [:, means .argmin ()]
31
31
32
32
33
33
def AHC (sim_mx , threshold = 0 ):
@@ -41,18 +41,19 @@ def AHC(sim_mx, threshold=0):
41
41
cluster labels stored in an array of length N containing (integers in
42
42
the range from 0 to C-1, where C is the number of dicovered clusters)
43
43
"""
44
- dist = - sim_mx ;
44
+ dist = - sim_mx
45
45
dist [np .diag_indices_from (dist )] = np .inf
46
46
clsts = [[i ] for i in range (len (dist ))]
47
47
while True :
48
48
mi , mj = np .sort (np .unravel_index (dist .argmin (), dist .shape ))
49
49
if dist [mi , mj ] > - threshold :
50
50
break
51
- dist [:, mi ] = dist [mi ,:] = (dist [mi ,:]* len (clsts [mi ])+ dist [mj ,:]* len (clsts [mj ]))/ (len (clsts [mi ])+ len (clsts [mj ]))
52
- dist [:, mj ] = dist [mj ,:] = np .inf
51
+ dist [:, mi ] = dist [mi , :] = (dist [mi , :]* len (clsts [mi ]) + dist [mj , :]* len (clsts [mj ])) / \
52
+ (len (clsts [mi ]) + len (clsts [mj ]))
53
+ dist [:, mj ] = dist [mj , :] = np .inf
53
54
clsts [mi ].extend (clsts [mj ])
54
55
clsts [mj ] = None
55
- labs = np .empty (len (dist ), dtype = int )
56
+ labs = np .empty (len (dist ), dtype = int )
56
57
for i , c in enumerate ([e for e in clsts if e ]):
57
58
labs [c ] = i
58
59
return labs
@@ -73,14 +74,14 @@ def PLDA_scoring_in_LDA_space(Fe, Ft, diagAC):
73
74
"""
74
75
# See (7-8) in L. Burget et al.: "Discriminatively trained probabilistic
75
76
# linear discriminant analysis for speaker verification", in ICASSP 2011.
76
- iTC = 1.0 / (1 + diagAC )
77
- iWC2AC = 1.0 / (1 + 2 * diagAC )
78
- ldTC = np .sum (np .log (1 + diagAC ))
77
+ iTC = 1.0 / (1 + diagAC )
78
+ iWC2AC = 1.0 / (1 + 2 * diagAC )
79
+ ldTC = np .sum (np .log (1 + diagAC ))
79
80
ldWC2AC = np .sum (np .log (1 + 2 * diagAC ))
80
- Gamma = - 0.25 * (iWC2AC + 1 - 2 * iTC )
81
- Lambda = - 0.5 * (iWC2AC - 1 )
82
- k = - 0.5 * (ldWC2AC - 2 * ldTC )
83
- return np .dot (Fe * Lambda , Ft .T ) + (Fe ** 2 ).dot (Gamma )[:,np .newaxis ] + (Ft ** 2 ).dot (Gamma ) + k
81
+ Gamma = - 0.25 * (iWC2AC + 1 - 2 * iTC )
82
+ Lambda = - 0.5 * (iWC2AC - 1 )
83
+ k = - 0.5 * (ldWC2AC - 2 * ldTC )
84
+ return np .dot (Fe * Lambda , Ft .T ) + (Fe ** 2 ).dot (Gamma )[:, np .newaxis ] + (Ft ** 2 ).dot (Gamma ) + k
84
85
85
86
86
87
def kaldi_ivector_plda_scoring_dense (kaldi_plda , x , target_energy = 0.1 , pca_dim = None ):
@@ -102,23 +103,21 @@ def kaldi_ivector_plda_scoring_dense(kaldi_plda, x, target_energy=0.1, pca_dim=N
102
103
matrix of pairwise similarities between the input x-vectors
103
104
"""
104
105
plda_mu , plda_tr , plda_psi = kaldi_plda
105
- [ energy ,PCA ] = spl .eigh (np .cov (x .T , bias = True ))
106
+ energy , PCA = spl .eigh (np .cov (x .T , bias = True ))
106
107
if pca_dim is None :
107
- energy = np .cumsum (energy [::- 1 ])
108
- pca_dim = np .sum (energy / energy [- 1 ]<= target_energy ) + 2
109
- # we need at least 2 dimensions, so 2 more dimensions are always added
108
+ energy = np .cumsum (energy [::- 1 ])
109
+ pca_dim = np .sum (energy / energy [- 1 ] <= target_energy ) + 2
110
+ # we need at least 2 dimensions, so 2 more dimensions are always added
110
111
111
- PCA = PCA [:,:- pca_dim - 1 :- 1 ]
112
+ PCA = PCA [:, :- pca_dim - 1 :- 1 ]
112
113
print ("pca_dim:" , pca_dim )
113
114
114
- plda_tr_inv_pca = PCA .T .dot (np .linalg .inv (plda_tr ))
115
+ plda_tr_inv_pca = PCA .T .dot (np .linalg .inv (plda_tr ))
115
116
W = plda_tr_inv_pca .dot (plda_tr_inv_pca .T )
116
117
B = (plda_tr_inv_pca * plda_psi ).dot (plda_tr_inv_pca .T )
117
- acvar , wccn = spl .eigh (B , W )
118
- x = np .dot (x - plda_mu ,PCA ).dot (wccn )
119
- x *= np .sqrt (x .shape [1 ] / np .dot (x ** 2 , 1.0 / (acvar + 1.0 )))[:,np .newaxis ] # kaldi style length-norm
120
- #Lambda, Gamma, c, k = PLDA_params_to_bilinear_form(np.eye(pca_dim), np.diag(acvar), np.zeros((pca_dim,)))
121
- #return bilinear_scoring(Lambda, Gamma, c, k, x, x)
118
+ acvar , wccn = spl .eigh (B , W )
119
+ x = np .dot (x - plda_mu , PCA ).dot (wccn )
120
+ x *= np .sqrt (x .shape [1 ] / np .dot (x ** 2 , 1.0 / (acvar + 1.0 )))[:, np .newaxis ] # kaldi style length-norm
122
121
return PLDA_scoring_in_LDA_space (x , x , acvar )
123
122
124
123
@@ -135,8 +134,8 @@ def read_xvector_timing_dict(kaldi_segments):
135
134
segs_dict[recording_file_name] = (array_of_xvector_names, array_of_start_and_end_times)
136
135
"""
137
136
segs = np .loadtxt (kaldi_segments , dtype = object )
138
- split_by_filename = np .nonzero (segs [1 :,1 ] != segs [:- 1 ,1 ])[0 ]+ 1
139
- return {s [0 ,1 ]: (s [:,0 ], s [:,2 :].astype (float )) for s in np .split (segs , split_by_filename )}
137
+ split_by_filename = np .nonzero (segs [1 :, 1 ] != segs [:- 1 , 1 ])[0 ] + 1
138
+ return {s [0 , 1 ]: (s [:, 0 ], s [:, 2 :].astype (float )) for s in np .split (segs , split_by_filename )}
140
139
141
140
142
141
def merge_adjacent_labels (starts , ends , labels ):
@@ -154,13 +153,13 @@ def merge_adjacent_labels(starts, ends, labels):
154
153
# Merge neighbouring (or overlaping) segments with the same label
155
154
adjacent_or_overlap = np .logical_or (np .isclose (ends [:- 1 ], starts [1 :]), ends [:- 1 ] > starts [1 :])
156
155
to_split = np .nonzero (np .logical_or (~ adjacent_or_overlap , labels [1 :] != labels [:- 1 ]))[0 ]
157
- starts = starts [np .r_ [0 , to_split + 1 ]]
158
- ends = ends [np .r_ [to_split , - 1 ]]
159
- labels = labels [np .r_ [0 , to_split + 1 ]]
160
-
156
+ starts = starts [np .r_ [0 , to_split + 1 ]]
157
+ ends = ends [np .r_ [to_split , - 1 ]]
158
+ labels = labels [np .r_ [0 , to_split + 1 ]]
159
+
161
160
# Fix starts and ends times for overlapping segments
162
- overlaping = np .nonzero (starts [1 :]< ends [:- 1 ])[0 ]
163
- ends [overlaping ] = starts [overlaping + 1 ] = (ends [overlaping ]+ starts [overlaping + 1 ]) / 2.0
161
+ overlaping = np .nonzero (starts [1 :] < ends [:- 1 ])[0 ]
162
+ ends [overlaping ] = starts [overlaping + 1 ] = (ends [overlaping ] + starts [overlaping + 1 ]) / 2.0
164
163
return starts , ends , labels
165
164
166
165
@@ -178,12 +177,12 @@ def segment_to_frame_labels(starts, ends, labels, length=0, frame_rate=100., emp
178
177
frms - array of frame-by-frame labels
179
178
"""
180
179
min_len , max_len = (length , length ) if length > 0 else (- length , None )
181
- starts = np .rint (frame_rate * starts ).astype (int )
182
- ends = np .rint (frame_rate * ends ).astype (int )
180
+ starts = np .rint (frame_rate * starts ).astype (int )
181
+ ends = np .rint (frame_rate * ends ).astype (int )
183
182
if not ends .size :
184
- return np .full (min_len , empty_label )
183
+ return np .full (min_len , empty_label )
185
184
186
- frms = np .repeat (np .r_ [np .c_ [[empty_label ]* len (labels ), labels ].flat , empty_label ],
185
+ frms = np .repeat (np .r_ [np .c_ [[empty_label ]* len (labels ), labels ].flat , empty_label ],
187
186
np .r_ [np .c_ [starts - np .r_ [0 , ends [:- 1 ]], ends - starts ].flat , max (0 , min_len - ends [- 1 ])])
188
187
return frms [:max_len ]
189
188
@@ -194,7 +193,8 @@ def mkdir_p(path):
194
193
except OSError as exc :
195
194
if exc .errno == errno .EEXIST and os .path .isdir (path ):
196
195
pass
197
- else : raise
196
+ else :
197
+ raise
198
198
199
199
200
200
def l2_norm (vec_or_matrix ):
@@ -216,26 +216,26 @@ def l2_norm(vec_or_matrix):
216
216
217
217
218
218
def cos_similarity (x ):
219
- """Compute cosine similarity matrix in CPU & memory sensitive way
220
-
221
- Args:
222
- x (np.ndarray): embeddings, 2D array, embeddings are in rows
223
-
224
- Returns:
225
- np.ndarray: cosine similarity matrix
226
-
227
- """
228
- assert x .ndim == 2 , f'x has { x .ndim } dimensions, it must be matrix'
229
- x = x / (np .sqrt (np .sum (np .square (x ), axis = 1 , keepdims = True )) + 1.0e-32 )
230
- assert np .allclose (np .ones_like (x [:, 0 ]), np .sum (np .square (x ), axis = 1 ))
231
- max_n_elm = 200000000
232
- step = max (max_n_elm // (x .shape [0 ] * x .shape [0 ]), 1 )
233
- retval = np .zeros (shape = (x .shape [0 ], x .shape [0 ]), dtype = np .float64 )
234
- x0 = np .expand_dims (x , 0 )
235
- x1 = np .expand_dims (x , 1 )
236
- for i in range (0 , x .shape [1 ], step ):
237
- product = x0 [:, :, i :i + step ] * x1 [:, :, i :i + step ]
238
- retval += np .sum (product , axis = 2 , keepdims = False )
239
- assert np .all (retval >= - 1.0001 ), retval
240
- assert np .all (retval <= 1.0001 ), retval
241
- return retval
219
+ """Compute cosine similarity matrix in CPU & memory sensitive way
220
+
221
+ Args:
222
+ x (np.ndarray): embeddings, 2D array, embeddings are in rows
223
+
224
+ Returns:
225
+ np.ndarray: cosine similarity matrix
226
+
227
+ """
228
+ assert x .ndim == 2 , f'x has { x .ndim } dimensions, it must be matrix'
229
+ x = x / (np .sqrt (np .sum (np .square (x ), axis = 1 , keepdims = True )) + 1.0e-32 )
230
+ assert np .allclose (np .ones_like (x [:, 0 ]), np .sum (np .square (x ), axis = 1 ))
231
+ max_n_elm = 200000000
232
+ step = max (max_n_elm // (x .shape [0 ] * x .shape [0 ]), 1 )
233
+ retval = np .zeros (shape = (x .shape [0 ], x .shape [0 ]), dtype = np .float64 )
234
+ x0 = np .expand_dims (x , 0 )
235
+ x1 = np .expand_dims (x , 1 )
236
+ for i in range (0 , x .shape [1 ], step ):
237
+ product = x0 [:, :, i :i + step ] * x1 [:, :, i :i + step ]
238
+ retval += np .sum (product , axis = 2 , keepdims = False )
239
+ assert np .all (retval >= - 1.0001 ), retval
240
+ assert np .all (retval <= 1.0001 ), retval
241
+ return retval
0 commit comments