annotate utils/GmmMetrics.py @ 19:890cfe424f4a tip

added annotations
author mitian
date Fri, 11 Dec 2015 09:47:40 +0000
parents 26838b1f560f
children
rev   line source
mi@0 1 #!/usr/bin/env python
mi@0 2 # encoding: utf-8
mi@0 3 """
mi@0 4 GmmFeature.py
mi@0 5
mi@0 6 Created by George Fazekas on 2014-05-30.
mi@0 7 Copyright (c) 2014 . All rights reserved.
mi@0 8 """
mi@0 9
mi@0 10 import sys, os, math, wave, struct, cPickle
mi@0 11 from pprint import pprint
mi@0 12 from os.path import join, isdir, isfile, abspath, dirname, basename, split, splitext
mi@0 13 from itertools import *
mi@0 14 import matplotlib.pyplot as plt
mi@0 15 from numpy import sum,isnan, log, power, pi, exp, transpose
mi@0 16 from numpy.random import rand
mi@0 17 import numpy as np
mi@0 18 from sklearn.mixture import GMM
mi@0 19 from sklearn.metrics.pairwise import pairwise_distances
mi@0 20 from scipy.linalg import *
mi@0 21 from scipy.io.wavfile import read
mi@0 22 # from wavebender import *
mi@0 23 from gmmdist import skl_models
mi@0 24
mi@0 25 outFile = '/Users/mitian/Documents/hg/seg/test/distance.txt'
mi@0 26 audioDir = '/Users/mitian/Documents/hg/seg/audio'
mi@0 27
mi@0 28
mi@0 29 class GaussianComponent(object):
mi@0 30 '''GMM representations of data.'''
mi@0 31 __slots__ = ['weight','means','covars']
mi@0 32
mi@0 33 def __getstate__(self):
mi@0 34 d = {}
mi@0 35 for obj in GaussianComponent.__slots__ :
mi@0 36 d.update({obj:getattr(self,obj)})
mi@0 37 return d
mi@0 38
mi@0 39 def __setstate__(self,d):
mi@0 40 for k,v in d.iteritems() :
mi@0 41 setattr(self,k,v)
mi@0 42
mi@0 43 class AudioObj(object):
mi@0 44 '''A class to store generated audio samples.'''
mi@0 45 __slots__ = ['name', 'data']
mi@0 46
mi@0 47 class FeatureObj(object):
mi@0 48 '''A class to store extracted features for audio samples.'''
mi@0 49 __slots__ = ['audio', 'mean', 'std', 'sc', 'sl']
mi@0 50
mi@0 51 class DistanceObj(object):
mi@0 52 '''A class to store calculated GMM distances.'''
mi@0 53 __slots__ = ['audio1', 'audio2', 'nComponents', 'skl_diag', 'skl_full', 'c2', 'euclidean', 'bhattacharyya']
mi@0 54
mi@0 55 def save(self, filename=None):
mi@0 56 '''Save distance objects.'''
mi@0 57 if filename == None:
mi@0 58 filenmae = outFile
mi@0 59 f = open(filenmae,'a+')
mi@0 60 f.write(cPickle.dumps(self.__dict__))
mi@0 61 f.close()
mi@0 62
mi@0 63 class GmmDistance(object):
mi@0 64 '''Calculating distances between two pdfs using different distance metrics.'''
mi@0 65
mi@0 66 def __init__(self, feature_array, components = 1, save_data=False):
mi@0 67 self.n_components = components
mi@0 68 self.gmm = GMM(n_components = components, covariance_type='full')
mi@0 69 feature_array = np.nan_to_num(feature_array)
mi@0 70 feature_array[np.isinf(feature_array)] = 0.0
mi@0 71 feature_array[np.isnan(feature_array)] = 0.0
mi@0 72 self.model = self.gmm.fit(feature_array)
mi@0 73 if save_data :
mi@0 74 self.data = feature_array
mi@0 75 else :
mi@0 76 self.data = None
mi@0 77 if not self.model.converged_ :
mi@0 78 print "Warning: model fitting did not converge."
mi@0 79 self.means = self.model.means_
mi@0 80 self.covars = self.model.covars_
mi@0 81 self.weights = self.model.weights_
mi@0 82 self.label = -1 # used only for clustering
mi@0 83 self.components = []
mi@0 84 for c in range(self.n_components) :
mi@0 85 g = GaussianComponent()
mi@0 86 g.weight = self.weights[c]
mi@0 87 g.means = self.means[c]
mi@0 88 g.covars = self.covars[c]
mi@0 89 self.components.append(g)
mi@0 90
mi@0 91 def update(self):
mi@0 92 for c in range(self.n_components) :
mi@0 93 self.weights[c] = self.components[c].weight
mi@0 94 self.means[c] = self.components[c].means
mi@0 95 self.covars[c] = self.components[c].covars
mi@0 96
mi@0 97 def __str__(self):
mi@0 98 self.update()
mi@0 99 return "GMM object:\nmeans:%(means)s\ncovariances:%(covars)s\nweights%(weights)s" %vars(self)
mi@0 100
mi@0 101 def kl_div(self, p1, p2):
mi@0 102 '''Compute KL divergence between p1 and p2 with diagonal covariances.'''
mi@0 103 if p1.means is None or p2.means is None:
mi@0 104 return np.finfo(np.float64).max
mi@0 105 # d = ((0.5 * log(p2.covars**2/p1.covars**2)) - 0.5 + p1.covars**2/(2*p2.covars**2) + (abs(p2.means - p1.means)**2) / (2*p2.covars**2))
mi@0 106 d = -2.0 * p1.means.shape[0]
mi@0 107 d += sum( (p1.covars / p2.covars) + (p2.covars / p1.covars) + ((p1.means - p2.means) * ((1.0 / p1.covars) + (1.0 / p2.covars)) * (p1.means - p2.means)), dtype = np.float64 )
mi@0 108 if isnan(d) :
mi@0 109 return np.finfo(np.float64).max
mi@0 110 return d
mi@0 111
mi@0 112 def skl_distance_diag(self,other):
mi@0 113 '''Estimate the symmetrised Kullback–Leibler divergence between this and an other model.'''
mi@0 114 # TODO: the components are sorted so this works but still theoretically not quite correct to do this...
mi@0 115 assert (self.n_components == other.n_components), "Number of components must be equal."
mi@0 116 kl12 = kl21 = 0.0
mi@0 117 for i in range(self.n_components) :
mi@0 118 kl12 += self.weights[i] * self.kl_div(self.components[i],other.components[i])
mi@0 119 kl21 += other.weights[i] * self.kl_div(other.components[i],self.components[i])
mi@0 120 return (kl12 + kl21 ) / 2.0
mi@0 121
mi@0 122 def skl_distance_full(self,other):
mi@0 123 return skl_models(self,other)
mi@0 124
mi@0 125 def skl_distance_full_orig(self,other):
mi@0 126 '''Estimate the symmetrised Kullback–Leibler divergence between this and an other model.'''
mi@0 127 n = len(self.components) # number of components
mi@0 128 d = len(self.components[0].means) # number of dimensions
mi@0 129
mi@0 130 ixm = np.ones((n,1),dtype=int).T # selector of mean matrix components
mi@0 131 ixd = range(0,d*d,d+1) # indices of diagonal elements of DxD matrix
mi@0 132 t1 = self.covars.swapaxes(1,2).reshape(d,n*d) # concatenate gmm1 covariance matrices
mi@0 133 t2 = other.covars.swapaxes(1,2).reshape(d,n*d) # concatenate gmm2 covariance matrices
mi@0 134 loopn = xrange(n)
mi@0 135
mi@0 136 logdet1 = np.zeros((n,1))
mi@0 137 kl11 = np.zeros((n,n))
mi@0 138 for i in loopn :
mi@0 139 # step 1) precompute log(determinant()) of covariance matrices of gmm1
mi@0 140 logdet1[i] = log(det(self.covars.swapaxes(0,2)[:,:,i]))
mi@0 141
mi@0 142 # step 2) compute reference kldiv between individual components of gmm1
mi@0 143 inv1 = inv(self.covars.swapaxes(0,2)[:,:,i])
mi@0 144 mm1 = self.means - self.means[i*ixm,:][0]
mi@0 145 b1 = np.dot(inv1,t1).swapaxes(0,1).reshape(n,power(d,2)).T
mi@0 146 kl11[:,i] = 0.5 * ( (logdet1[i]-d-logdet1)[:,0] + sum(b1[ixd,:],0).T + sum(np.dot(mm1,inv1) * mm1,1))
mi@0 147 # print kl11
mi@0 148
mi@0 149 logdet2 = np.zeros((n,1))
mi@0 150 kl22 = np.zeros((n,n))
mi@0 151 for i in loopn :
mi@0 152 # step 3) precompute log(determinant()) of covariance matrices of gmm2
mi@0 153 logdet2[i] = log(det(other.covars.swapaxes(0,2)[:,:,i]))
mi@0 154 inv2 = inv(other.covars.swapaxes(0,2)[:,:,i])
mi@0 155 mm2 = other.means - other.means[i*ixm,:][0]
mi@0 156 b2 = np.dot(inv2,t2).swapaxes(0,1).reshape(n,power(d,2)).T
mi@0 157 kl22[:,i] = 0.5 * ( (logdet2[i]-d-logdet2)[:,0] + sum(b2[ixd,:],0).T + sum(np.dot(mm2,inv2) * mm2,1))
mi@0 158
mi@0 159 # step 4) compute pair-wise kldiv between components of gmm1 and gmm2
mi@0 160 kl12 = np.zeros((n,n))
mi@0 161 kl21 = np.zeros((n,n))
mi@0 162 for i in loopn :
mi@0 163 inv1 = inv(self.covars.swapaxes(0,2)[:,:,i])
mi@0 164 inv2 = inv(other.covars.swapaxes(0,2)[:,:,i])
mi@0 165 m12 = self.means - other.means[i*ixm,:][0]
mi@0 166 m21 = other.means - self.means[i*ixm,:][0]
mi@0 167 b1 = np.dot(inv1,t1).swapaxes(0,1).reshape(n,power(d,2)).T
mi@0 168 b2 = np.dot(inv2,t2).swapaxes(0,1).reshape(n,power(d,2)).T
mi@0 169 kl12[:,i] = 0.5 * ( (logdet2[i]-d-logdet1)[:,0] + sum(b2[ixd,:],0).T + sum(np.dot(m12,inv2) * m12,1))
mi@0 170 kl21[:,i] = 0.5 * ( (logdet1[i]-d-logdet2)[:,0] + sum(b1[ixd,:],0).T + sum(np.dot(m21,inv1) * m21,1))
mi@0 171
mi@0 172 # step 5) compute the final variational distance between gmm1 and gmm2
mi@0 173 kl_full_12 = np.dot(self.weights.T, (log(sum(exp(-kl11)*self.weights,1))) - log(sum(exp(-kl12)*other.weights,1)))
mi@0 174 kl_full_21 = np.dot(other.weights.T, (log(sum(exp(-kl22)*other.weights,1))) - log(sum(exp(-kl21)*self.weights,1)))
mi@0 175 return (kl_full_12 + kl_full_21 ) / 2.0
mi@0 176
mi@0 177 def emd(self, p1, p2):
mi@0 178 '''Compute earth movers distance between component p1 and p2'''
mi@0 179
mi@0 180 pass
mi@0 181
mi@0 182 def c2(self, p1, p2):
mi@0 183 d = power(det(p1.covars), -0.5) * power(det(p2.covars), -0.5)
mi@0 184 return d
mi@0 185
mi@0 186 def c2_distance(self, other):
mi@0 187 '''Compute the c2 pdf distance metric
mi@0 188 G. Sfikas etc. An analytic distance metric for Gaussian Mixture Models with application in image retrieval. ICANN 2005.
mi@0 189 '''
mi@0 190 d12 = d11 = d22 = 0.0
mi@0 191 for i in xrange(self.n_components) :
mi@0 192 for j in xrange(self.n_components) :
mi@0 193 V = inv(inv(self.covars[i]) + inv(other.covars[j]))
mi@0 194 K = self.means[i].T.dot(inv(self.covars[i])) * (self.means[i] - other.means[j]) + other.means[j].T.dot(inv(other.covars[j])) * (other.means[j] - self.means[i])
mi@0 195
mi@0 196 d12 += sum(self.weights[i] * other.weights[j] * power((det(V) / (exp(K) * self.c2(self.components[i], other.components[j]))), 0.5))
mi@0 197 d11 += sum(self.weights[i] * other.weights[j] * power((det(V) / (exp(K) * self.c2(self.components[i], self.components[j]))), 0.5))
mi@0 198 d22 += sum(self.weights[i] * other.weights[j] * power((det(V) / (exp(K) * self.c2(other.components[i], other.components[j]))), 0.5))
mi@0 199
mi@0 200 dist = -log(2 * d12 / (d11 + d22))
mi@0 201
mi@0 202 if isnan(dist) :
mi@0 203 return np.finfo(np.float64).max
mi@0 204 return dist
mi@0 205
mi@0 206 def euclidean(self, p1, p2):
mi@0 207 '''Compute euclidean distance between p1 and p2'''
mi@0 208 if p1.means is None or p2.means is None:
mi@0 209 return np.finfo(np.float64).max
mi@0 210 d = sum(power(2 * pi * (power(p1.covars, 2) + power(p2.covars, 2)), -0.5) * exp(-0.5 * power(p1.means - p2.means, 2) / (power(p1.covars, 2) + power(p2.covars, 2))))
mi@0 211
mi@0 212 if isnan(d) :
mi@0 213 return np.finfo(np.float64).max
mi@0 214 return d
mi@0 215
mi@0 216 def euclidean_distance(self, other):
mi@0 217 '''Compute the pdf distance metric'''
mi@0 218 e11 = e22 = e12 = 0.0
mi@0 219 for i in range(self.n_components) :
mi@0 220 e11 += self.weights[i] * self.weights[i] * self.euclidean(self.components[i],self.components[i])
mi@0 221 e22 += other.weights[i] * other.weights[i] * self.euclidean(other.components[i],other.components[i])
mi@0 222 e12 += self.weights[i] * other.weights[i] * self.euclidean(self.components[i],other.components[i])
mi@0 223
mi@0 224 dist = e11 + e22 - 2 * e12
mi@0 225
mi@0 226 if isnan(dist) :
mi@0 227 return np.finfo(np.float64).max
mi@0 228 return dist
mi@0 229
mi@0 230 def bhattacharyya(self, p1, p2):
mi@0 231 '''Compute the Bhattacharyya based distance following:
mi@0 232 K. Fukunaga. Introduction to statistical pattern recognition. Academic Press 1990
mi@0 233 '''
mi@0 234 B_dev = 0.125 * ((p1.means - p2.means).T.dot( inv((p1.covars + p2.covars) / 2))).dot(p1.means - p2.means)\
mi@0 235 + 0.5 * log( abs(inv((p1.covars + p2.covars) / 2)) / power(abs(inv(p1.covars) * inv(p2.covars)), 0.5) )
mi@0 236
mi@0 237 d = sum(B_dev)
mi@0 238 if isnan(d) :
mi@0 239 return np.finfo(np.float64).max
mi@0 240 return d
mi@0 241
mi@0 242 def bhattacharyya_distance(self, other):
mi@0 243 '''Compute the pdf distance metric'''
mi@0 244 dist = 0.0
mi@0 245 for i in xrange(self.n_components) :
mi@0 246 dist += self.weights[i] * other.weights[i] *self.bhattacharyya(self.components[i], other.components[i])
mi@0 247 return dist
mi@0 248
mi@0 249
mi@0 250 class AudioGenerator(object):
mi@0 251 '''Generate simple audio data (sinusoidal etc. and noise and their combinations).'''
mi@0 252
mi@0 253 def sine(self, freq=440.0, framerate=44100, amplitude=0.5, length=0.02):
mi@0 254 n = int(length * framerate)
mi@0 255 return np.array([amplitude * math.sin(2.0*math.pi * float(freq) * (float(i)/float(framerate))) for i in xrange(n)])
mi@0 256
mi@0 257 def noise(self, framerate=44100, amplitude=0.1, length=0.02):
mi@0 258 n = int(length * framerate)
mi@0 259 return np.array([float(amplitude) * np.random.uniform(-1, 1) for i in xrange(n)])
mi@0 260
mi@0 261 def square(self, freq=440.0, framerate=44100, amplitude=0.5, length=0.02):
mi@0 262 for s in self.sine(freq, framerate, amplitude, length):
mi@0 263 if s > 0:
mi@0 264 yield amplitude
mi@0 265 elif s < 0:
mi@0 266 yield -amplitude
mi@0 267 else:
mi@0 268 yield 0.0
mi@0 269
mi@0 270 def damped(self, freq=440.0, framerate=44100, amplitude=0.5, length=0.02):
mi@0 271 n = int(length*framerate)
mi@0 272 return (exp(-(float(i%n)/float(framerate))) * s for i, s in enumerate(self.sine(frequency, framerate, amplitude, length)))
mi@0 273
mi@0 274 def write_wav_file(self, samples,filename) :
mi@0 275 '''Create a wav file and write it to disk.'''
mi@0 276 nchannels, sampwidth, framerate, nframes = 1, 2, 44100, len(samples)
mi@0 277 max_amplitude = 32767.0
mi@0 278 w = wave.open(filename, 'w')
mi@0 279 w.setparams((nchannels, sampwidth, framerate, nframes, 'NONE', 'not compressed'))
mi@0 280 frames = str().join(struct.pack('h', int(max_amplitude * s)) for s in samples)
mi@0 281 w.writeframesraw(frames)
mi@0 282 w.close()
mi@0 283 print "wav file: %s written." %filename
mi@0 284
mi@0 285 class FeatureExtractor(object):
mi@0 286 '''Extract low level features of input audio samples for compare distance computation.'''
mi@0 287 def main():
mi@0 288
mi@0 289 # ag = AudioGenerator()
mi@0 290 # fe = FeatureExtractor()
mi@0 291 #
mi@0 292 # # Create a "test1.wav" file which is 10s length and contains two sinusoids + noise
mi@0 293 # length = 10.0 # unit = sG
mi@0 294 # samples = ag.sine(440.0,length=length) + ag.sine(240.0,length=length) + ag.noise(length=length)
mi@0 295 # samples = samples / (max(samples) + 0.05)
mi@0 296 # ag.write_wav_file(samples, "audio/test1.wav")
mi@0 297 # # Create a file indentical to 'test1.wav
mi@0 298 # ag.write_wav_file(samples,"audio/test1a.wav")
mi@0 299 # # Create a file with the same componentes as "test1.wav" but the freq of one sinusouid different
mi@0 300 # samples = ag.sine(440.0,length=length) + ag.sine(480.0,length=length) + ag.noise(length=length)
mi@0 301 # samples = samples / (max(samples) + 0.05)
mi@0 302 # ag.write_wav_file(samples, "audio/test1b.wav")
mi@0 303 # # Create a file with the same componentes as "test1.wav" but the freq of both sinusouids different
mi@0 304 # samples = ag.sine(880.0,length=length) + ag.sine(480.0,length=length) + ag.noise(length=length)
mi@0 305 # samples = samples / (max(samples) + 0.05)
mi@0 306 # ag.write_wav_file(samples, "audio/test1c.wav")
mi@0 307 #
mi@0 308 # # Create a file with one more sinusouid componentes as "test1.wav"
mi@0 309 # samples = ag.sine(440.0,length=length) + ag.sine(240.0,length=length) + ag.sine(880.0,length=length) + ag.noise(length=length)
mi@0 310 # samples = samples / (max(samples)+0.05)
mi@0 311 # ag.write_wav_file(samples, "audio/test2a.wav")
mi@0 312 # # Create a file with changed freq and one more sinusouid componentes as "test1.wav"
mi@0 313 # samples = ag.sine(440.0,length=length) + ag.sine(240.0,length=length) + ag.sine(1320.0,length=length) + ag.noise(length=length)
mi@0 314 # samples = samples / (max(samples)+0.05)
mi@0 315 # ag.write_wav_file(samples, "audio/test2b.wav")
mi@0 316 #
mi@0 317 # # Create a file with longer length than "test1.wav"
mi@0 318 # samples = ag.sine(440.0,length=15) + ag.sine(240.0,length=15) + ag.noise(length=15)
mi@0 319 # samples = samples / (max(samples)+0.05)
mi@0 320 # ag.write_wav_file(samples, "audio/test3a.wav")
mi@0 321 # # Create a file with longer length and one more sinusoid than "test1.wav"
mi@0 322 # samples = ag.sine(440.0,length=15) + ag.sine(240.0,length=15) + ag.sine(880.0,length=15) + ag.noise(length=15)
mi@0 323 # samples = samples / (max(samples)+0.05)
mi@0 324 # ag.write_wav_file(samples, "audio/test3b.wav")
mi@0 325
mi@0 326
mi@0 327 # plt.plot(samples[:1000])
mi@0 328 # plt.show()
mi@0 329
mi@0 330
mi@0 331 # print "Testing Gaussian Feature: Generating random features."
mi@0 332 feature_array_1 = np.zeros((20,100),dtype=np.float64)
mi@0 333 feature_array_2 = np.zeros((20,100),dtype=np.float64)
mi@0 334
mi@0 335 r = rand(2)
mi@0 336
mi@0 337 for x in xrange(100) :
mi@0 338 feature_array_1[:,x] = rand(20) + r[0]
mi@0 339 feature_array_2[:,x] = rand(20) + r[1]
mi@0 340
mi@0 341 f1 = GmmDistance(feature_array_1)
mi@0 342 f2 = GmmDistance(feature_array_2)
mi@0 343
mi@0 344 print f1,f2,"\n"
mi@0 345
mi@0 346 print "KL2 distance between f1-f2 using diag covariance:", f1.skl_distance_diag(f2)
mi@0 347 print "KL2 distance between f1-f1 using diag covariance:", f1.skl_distance_diag(f1)
mi@0 348 print "KL2 distance between f2-f2 using diag covariance:", f2.skl_distance_diag(f2)
mi@0 349 print "KL2 distance between f2-f1 using diag covariance:", f2.skl_distance_diag(f1)
mi@0 350 print '\n'
mi@0 351 print "KL2 distance between f1-f2 using full covariance:", f1.skl_distance_full(f2)
mi@0 352 print "KL2 distance between f1-f1 using full covariance:", f1.skl_distance_full(f1)
mi@0 353 print "KL2 distance between f2-f2 using full covariance:", f2.skl_distance_full(f2)
mi@0 354 print "KL2 distance between f2-f1 using full covariance:", f2.skl_distance_full(f1)
mi@0 355 print '\n'
mi@0 356 print "c2 distance between f1-f2:", f1.c2_distance(f2)
mi@0 357 print "c2 distance between f1-f1:", f1.c2_distance(f1)
mi@0 358 print "c2 distance between f2-f2:", f2.c2_distance(f2)
mi@0 359 print "c2 distance between f2-f1:", f2.c2_distance(f1)
mi@0 360 print '\n'
mi@0 361 print "euclidean distance between f1-f2:", f1.euclidean_distance(f2)
mi@0 362 print "euclidean distance between f1-f1:", f1.euclidean_distance(f1)
mi@0 363 print "euclidean distance between f2-f2:", f2.euclidean_distance(f2)
mi@0 364 print "euclidean distance between f2-f1:", f2.euclidean_distance(f1)
mi@0 365 print '\n'
mi@0 366 print "bhattacharyya distance between f1-f2:", f1.bhattacharyya_distance(f2)
mi@0 367 print "bhattacharyya distance between f1-f1:", f1.bhattacharyya_distance(f1)
mi@0 368 print "bhattacharyya distance between f2-f2:", f2.bhattacharyya_distance(f2)
mi@0 369 print "bhattacharyya distance between f2-f1:", f2.bhattacharyya_distance(f1)
mi@0 370
mi@0 371 # ag = AudioGenerator()
mi@0 372 # sound = ag.synthesisor(nChannels = 2, framerate=44100, amplitude=0.5, length=0.02)
mi@0 373 # ag.write_wav_file(samples=sound, nframes=None, length=0.02, filename='audio/test.wav')
mi@0 374 #
mi@0 375 # l = dir(__builtins__)
mi@0 376 # d = __builtins__.__dict__
mi@0 377 # pprint(l)
mi@0 378 # pprint(d)
mi@0 379
mi@0 380 # # Load audio data
mi@0 381 # audio_files = [i for i in os.listdir(audioDir) if i.endswith('wav') and not i.startswith('.')]
mi@0 382 # audio_list = []
mi@0 383 # for i in audio_files:
mi@0 384 # ao = AudioObj()
mi@0 385 # ao.name = splitext(i)[0]
mi@0 386 # ao.data = np.array(read(join(audioDir, i))[1], dtype=float)
mi@0 387 # audio_list.append(ao)
mi@0 388 #
mi@0 389 # # Calculate pairwise ditances between audio data using listed metrics
mi@0 390 # res_list = []
mi@0 391 # for a1, a2 in combinations(audio_list, 2):
mi@0 392 # # basic info
mi@0 393 # res = DistanceObj()
mi@0 394 # f1 = GmmDistance(a1.data)
mi@0 395 # f2 = GmmDistance(a2.data)
mi@0 396 # res.audio1 = a1.name
mi@0 397 # res.audio2 = a2.name
mi@0 398 # res.nComponents = len(f1.components)
mi@0 399 #
mi@0 400 # # distances between two samples should be symmetric
mi@0 401 # res.skl_full = f1.skl_distance_full(f2)
mi@0 402 # res.skl_diag = f1.skl_distance_diag(f2)
mi@0 403 # res.c2 = f1.c2_distance(f2)
mi@0 404 # res.euclidean = f1.euclidean_distance(f2)
mi@0 405 # res.bhattacharyya = f1.bhattacharyya_distance(f2)
mi@0 406 #
mi@0 407 # res.save()
mi@0 408 # res_list.append(res)
mi@0 409
mi@0 410
mi@0 411
mi@0 412 if __name__ == '__main__':
mi@0 413 main()
mi@0 414
mi@0 415
mi@0 416
mi@0 417