- 高斯分布
多维的高斯分布形式
高斯分布的最大似然估计:
2.混合高斯分布GMM
π k \pi_k πk:其实表达的意思就是混合高斯的多个模型中,其中第k个高斯模型出现的概率。
为什么要使用GMM对音频信号进行建模?
原始数据经过分帧、DFT处理之后的数据特别适合用GMM进行数学建模,GMM可以拟合任意复杂的、多种形式的分布。只要混合的高斯分布数目足够多,就可以拟合任意精度的概率分布。但是如果把语音的顺序考虑进去GMM便不是一个好的模型,因为其不包含任何顺序信息,HMM模型更加适用对时序信息进行建模。
基于GMM做语音分类,比如:识别0~9十个数字,我们可以将每个数字都建模成一个GMM模型,在测试阶段对于某句话对数似然最大的模型对应的字符为当前的预测值。
GMM的对数似然估计:
3.GMM模型参数估计的EM算法总结:
4.通用的EM算法:
EM算法的目标是寻找潜变量模型的最大似然结,EM算法的通用步骤为:
5.通过EM训练GMM模型的代码:
0~9的以孤立词识别为例
(1)训练模块:
def train(gmms, num_iterations=num_iterations):
# 提取特征
dict_utt2feat, dict_target2utt = read_feats_and_targets('train/feats.scp', 'train/text')
# target表示0~9的一种,为每一种target都建立一个GMM模型
for target in targets:
# 得到当前target的特征
feats = get_feats(target, dict_utt2feat, dict_target2utt)
# 进行几轮EM算法估计
for i in range(num_iterations):
log_llh = gmms[target].em_estimator(feats)
return gmms
(2)定义高斯模型,即下公式:
def gaussian(self, x, mu, sigma):
"""Calculate gaussion probability.
:param x: The observed data, dim*1.
:param mu: The mean vector of gaussian, dim*1
:param sigma: The covariance matrix, dim*dim
:return: the gaussion probability, scalor
"""
D = x.shape[0]
det_sigma = np.linalg.det(sigma)
inv_sigma = np.linalg.inv(sigma + 0.0001)
mahalanobis = np.dot(np.transpose(x - mu), inv_sigma)
mahalanobis = np.dot(mahalanobis, (x - mu))
const = 1 / ((2 * np.pi) ** (D / 2))
return const * (det_sigma) ** (-0.5) * np.exp(-0.5 * mahalanobis)
(3)em算法更新mu、pi、sigma参数:
执行如下步骤:
关键是要搞清每个变量的维度。
def em_estimator(self , X):
"""Update paramters of GMM
param: X: A matrix including data samples, num_samples * D
return: log likelihood of updated model
"""
N, D = X.shape
gamma = np.zeros((N, self.K))
# E
# 计算各高斯模型中所有样本出现的概率,行对应样本,列对应迭代次数
prob = np.zeros((N, self.K))
for k in range(self.K):
prob[:, k] = multivariate_normal.pdf(X, self.mu[k], self.sigma[k])
# 计算每个模型对每个样本的响应度
for k in range(self.K):
gamma[:, k] = self.pi[k] * prob[:, k]
for i in range(N):
gamma[i, :] /= np.sum(gamma[i, :])
mu = np.zeros((self.K, D))
pi = np.zeros(self.K)
sigma = np.zeros((self.K, D, D))
# M
for k in range(self.K):
Nk = np.sum(gamma[:, k])
# 更新mu
# 对每个特征求均值
for d in range(D):
mu[k][d] = np.sum(np.multiply(gamma[:, k], X[:, d])) / Nk
# 更新 sigma
for i in range(N):
left = np.reshape((X[i] - mu[k]), (D, 1))
right = np.reshape((X[i] - mu[k]), (1, D))
sigma[k] += gamma[i, k] * left * right
sigma[k] /= Nk
pi[k] = Nk / N
self.mu = mu
self.sigma = sigma
self.pi = pi
log_llh = self.calc_log_likelihood(X)
return log_llh