我尝试使用隐马尔可夫模型实现说话人验证。我遵循了本教程:http://compbio.ucdenver.edu/hunter/cpbs7711/2010_09_09_Rabiner1989_HMMTutorial_Erratum_Leach.pdf
显然,我使用转换矩阵值得到了错误的结果。我想,或者我错了。转换矩阵中每行的概率总和小于1.这应该发生在多个观察中吗?此外,观察结果应该具有相同的长度吗?我使用MFCC并使用Kmeans量化它们。我应该确保它们长度相同吗?任何帮助,将不胜感激。试图寻找其他来源,但有点丢失。
# Function for getting the xi and epsilon values
def ep_xi(self, states, obs, alphabet, init_pi, transition_matrix, emission_matrix, a, b):
ip = deepcopy(init_pi)
tm = deepcopy(transition_matrix)
em = deepcopy(emission_matrix)
coef = deepcopy(a["coef"])
alpha = deepcopy(a["alpha"])
beta = deepcopy(b)
T = len(obs)
epsilon = {}
xi = {}
epsilon[0] = None
for t in range(1, T):
epsilon[t] = {}
for i in states:
epsilon[t][i] = []
for j in states:
below = 0
epsilon_t = alpha[t-1][i] * tm[i][j] * em[j][obs[t]] * beta[t][j]
for k in states:
below += (alpha[t][k] * beta[t][k])
if below > 0: epsilon[t][i].append(epsilon_t/below)
else: epsilon[t][i].append(0)
for t in range(0, T):
xi[t] = []
for i in states:
xi_t = alpha[t][i] * beta[t][i]
below = 0
for j in states:
below += (alpha[t][j] * beta[t][j])
if below == 0: xi_t = 0
else: xi_t /= below
xi[t].append(xi_t)
# Function for reestimating the matrices values
def m_reestimate(self, obs, alphabet, xi_list, epsilon_list, prob_list):
T = len(obs)
xi_list = deepcopy(xi_list)
epsilon_list = deepcopy(epsilon_list)
pi = {}
trans = {}
emis = {}
# Initial matrix
for i in range(0, len(states)): pi[states[i]] = xi_list[0][0][i]
# Transition matrix
for i in range(0, len(states)):
trans[states[i]] = {}
for j in range(0, len(states)):
above = 0
below = 0
for epsilon in epsilon_list:
index = epsilon_list.index(epsilon)
for t in range(1, len(obs[index])):
above += epsilon[t][states[i]][j]
for xi in xi_list:
index = xi_list.index(xi)
for t in range(0, len(obs[index])):
below += xi[t][i]
if below == 0: trans[states[i]][states[j]] = 0
else: trans[states[i]][states[j]] = above / below
# Emission matrix
for j in range(0, len(states)):
emis[states[j]] = []
for char in alphabet:
above = 0
below = 0
for xi in xi_list:
index = xi_list.index(xi)
for t in range(0, len(xi)):
if obs[index][t] == char: above += xi[t][j]
below += xi[t][j]
if below == 0: emis_t = 0
else: emis_t = float(above) / below
emis[states[j]].append(emis_t)
return {"init": init, "trans": trans, "emis": emis}