人的发音其实是个渐变过程,在从一个音素转向另一个音素时,会存在协同发音现象,包括同一个音节内部和不同音节的过渡。
本博客主要看洪青阳教授写的《语音识别:原理与应用》而写的笔记。
协同发音
协同发音是指一个音受前后相邻音影响而发生变化。如”好好学习“的“好好”。因此同一个音素在不同位置,发音差异可能较大。
中文: 好 好
音节: hao3 hao3
音素:h ao3 h ao3
每个字都是一个音节,音节内部有发音衔接,音节之间也是有衔接的,其体现就是在语谱图过渡阶段存在交叉。
上下文建模
为了更好地匹配协同发音现象,需要对音素进行上下文建模。
双音子建模
针对普通话,单个音节只有声母和韵母,音节内部最多只能进行双音子建模,也就是只考虑音节(单个字)内部声母和韵母之间的关联,如“灯“的拼音deng,本来是分为d和eng两部分,可拆分成以下两种形式:
deng d+eng
deng d-eng
d+eng表示发音偏向于d,但后面衔接eng;
d-eng表示发音偏向于eng,但前面是d。
假设声母和韵母之间均可以两两组合,则普通话(不带声调)就有27(声母)x38(韵母)x2=2052个双音子,英语有28(辅音)x20(元音)x2=1120个双音子。
三音子建模
三音子建模比双音子建模多一个音子,其根据左右音素来确定发音,形成上下文相关的模型。如”打开灯光“的拼音,可转换为:
d-a+k
k-ai+d
d-eng+g
g-uang+sil
(sil为静音)
三音子可实现对音素上下文更精细的建模,但其数量巨大,例如:
- 普通话:27(声母)x 38(韵母) x 29(声母+sil/sp)=29754个
- 英语:28(辅音) x 20(元音)x 30(元音+sil/sp)=16800个
如果不考虑音素的先后顺序,则N个音素有 N 3 N^3 N3种组合,这还是没考虑声调的情况。
为了解决这一矛盾,可采用模型状态绑定,就是让不同的HMM状态共享模型参数,这样参数量就可大为减少。
绑定的目标就是把发音相似的音素聚在一起,对于普通话是相似的声母、韵母,而对于隐喻是相似的元音、辅音。
状态绑定方法一般使用决策树聚类。
决策树用于音素对音素或音素状态进行聚类
例如,我们给一个音素聚类的例子,输入是音素集合{g,d,t,b,p,k,m,n},通过判断是否为声母、鼻音、塞音,把该集合分成鼻音集合{m,n}和塞音集合{g,d,t,b,p,k}。
每一个叶子节点都是相近音素的集合。
而决策数的生成是基于问题集判断的,问题集说明了这些音素之间的相似性,只有相似才可能合并。
问题集
问题集可以手工设计,也可以通过数据驱动自动生成。
手工设计
需要语言学知识。总体原则是发音相似的,归为一类,尽可能精细化。下面是部分音母的分类。
然后用以下部分声母问题集,我们就可以对音素每个状态建立决策树。
而决策树的叶子节点是相似三音子的聚类,如第一个叶子节点包含d-a+m和b-a+n,均为音素a生成的三音子。同时上下文环境发音类似,它们的中间状态共用观察值概率分布。
以上决策数是只针对音素的中间状态建立的,其他状态需要另外的决策树。例如普通话单音子音素(对应三音子的中间音素)有65个,每个音素有3个状态,则需要195棵决策树。
自动生成
自动生成问题集,是一个无监督过程,完全依赖于训练数据。
基本思路:计算这些数据由聚类前后的状态集产生的似然概率差异,看是否有增益。
一开始,所有的三音子的所有状态都归为一类,并且假定每个状态的观察值概率都符合高斯分布。
设
S
=
{
s
1
,
s
2
,
s
3
,
.
.
.
,
s
N
}
S=\{s_1,s_2,s_3,...,s_N\}
S={s1,s2,s3,...,sN}为一个分类的状态集,N为所有的状态数,状态集整体的均值和方差为
μ
s
\mu_s
μs和
Σ
s
\Sigma_s
Σs。设
X
=
{
x
1
,
x
2
,
x
3
,
.
.
.
,
x
T
}
X=\{x_1,x_2,x_3,...,x_T\}
X={x1,x2,x3,...,xT}为训练数据集,T为所有的帧数。t时刻处于状态
s
n
s_n
sn的概率为
γ
t
(
s
n
)
\gamma_t(s_n)
γt(sn),
γ
t
(
s
n
)
\gamma_t(s_n)
γt(sn)可在帧与状态对齐时,由前向后向算法得到,只需计算一次。
整个数据集X由状态集S产生的似然概率为:
L
(
S
)
=
∑
t
[
l
n
P
(
x
t
∣
μ
S
,
Σ
S
)
∑
n
γ
t
(
s
n
)
]
L(S)=\sum_t[lnP(x_t|\mu_S,\Sigma_S)\sum_n\gamma_t(s_n)]
L(S)=t∑[lnP(xt∣μS,ΣS)n∑γt(sn)]
针对高斯概率魔都函数
P
(
x
t
∣
μ
S
,
Σ
S
)
P(x_t|\mu_S,\Sigma_S)
P(xt∣μS,ΣS),可展开如下:
l
n
P
(
x
t
∣
μ
S
,
Σ
S
)
=
l
n
(
1
(
2
π
)
D
2
1
∣
Σ
S
∣
1
2
exp
{
−
1
2
(
x
t
−
μ
S
)
Σ
S
−
1
(
x
t
−
μ
S
)
T
}
)
=
−
1
2
(
D
l
n
(
2
π
)
+
l
n
(
∣
Σ
S
∣
)
+
(
x
t
−
μ
s
)
Σ
S
−
1
(
x
t
−
μ
S
)
T
)
lnP(x_t|\mu_S,\Sigma_S)=ln(\frac{1}{(2\pi)^{\frac{D}{2}}}\frac{1}{|\Sigma_S|^{\frac{1}{2}}}\exp\{-\frac{1}{2}(x_t-\mu_S)\Sigma_S^{-1}(x_t-\mu_S)^T\})\\ =-\frac{1}{2}(Dln(2\pi)+ln(|\Sigma_S|)+(x_t-\mu_s)\Sigma_S^{-1}(x_t-\mu_S)^T)
lnP(xt∣μS,ΣS)=ln((2π)2D1∣ΣS∣211exp{−21(xt−μS)ΣS−1(xt−μS)T})=−21(Dln(2π)+ln(∣ΣS∣)+(xt−μs)ΣS−1(xt−μS)T)
Σ
S
\Sigma_S
ΣS可计算如下:
Σ
S
=
∑
t
{
(
∑
n
γ
t
(
s
n
)
)
(
x
t
−
μ
S
)
(
x
t
−
μ
S
)
T
}
∑
t
∑
n
γ
t
(
s
n
)
\Sigma_S=\frac{\sum_t{\{(\sum_n\gamma_t(s_n))(x_t-\mu_S)(x_t-\mu_S)^T\}}}{\sum_t\sum_n\gamma_t(s_n)}
ΣS=∑t∑nγt(sn)∑t{(∑nγt(sn))(xt−μS)(xt−μS)T}
进一步推导得到:
∑
t
{
(
x
t
−
μ
S
)
Σ
S
−
1
(
x
t
−
μ
s
)
T
∑
n
γ
t
(
s
n
)
}
=
D
∑
t
(
∑
n
γ
t
(
s
n
)
)
\sum_t\{(x_t-\mu_S)\Sigma_S^{-1}(x_t-\mu_s)^T\sum_n\gamma_t(s_n)\}=D\sum_t(\sum_n\gamma_t(s_n))
t∑{(xt−μS)ΣS−1(xt−μs)Tn∑γt(sn)}=Dt∑(n∑γt(sn))
其中,D是数据特征的维度。
因此,我们有:
L
(
S
)
=
−
1
2
(
D
(
1
+
l
n
(
2
π
)
)
+
l
n
(
∣
Σ
s
∣
)
)
∑
t
(
∑
n
γ
t
(
s
n
)
)
L(S)=-\frac{1}{2}(D(1+ln(2\pi))+ln(|\Sigma_s|))\sum_t(\sum_n\gamma_t(s_n))
L(S)=−21(D(1+ln(2π))+ln(∣Σs∣))t∑(n∑γt(sn))
把状态集S分成两类,得到
S
L
S_L
SL和
S
R
S_R
SR,分别计算新的均值和方差。
分类后的似然增益:
Δ
=
L
(
S
L
)
+
L
(
S
R
)
−
L
(
S
)
\Delta=L(S_L)+L(S_R)-L(S)
Δ=L(SL)+L(SR)−L(S)
如果
Δ
>
0
\Delta > 0
Δ>0,则说明状态集分类后有似然增益。
通过数据自动生成问题集的步骤如下:
- 计算统计量:对于每帧语音𝑥𝑡,由其Viterbi对齐序列可以得知对应哪个音素 的某个状态。对每个单音子做上下文的扩展(如“a”=>“*-a+*”),得到三音 子某个状态𝑠𝑛 对应的特征序列,然后计算该三音子状态对应的统计量𝛾𝑡(𝑠𝑛)。
- 音素状态聚类:首先将每个中间音素(如“*-a+*”)作为树的根节点,进行 二叉树分裂,根据所有可能的划分,分别利用似然度计算公式计算似然概率,得到能带来最大似然度提升的最优划分。然后不断的递归对节点进行二叉树 分裂,就可以得到一颗音素聚类的决策树。一旦某一层两个节点的最优划分带来的似然增益∆的值都小于设定的阈值,则该层终止分裂。
- 终止分裂:最终形成一颗聚类树,每个叶子结点都包含不同的音素集合,一 个叶子结点就是被聚类后的一个类。
- 生成问题集:从根结点开始,向下统计所能到达的所有叶子结点中包含的音素集合,把这个音素集合的统计集合作为一个问题集。
三音子模型训练
小结
本章针对协同发音现象,介绍了音素的上下文建模方法,包括双音子和三音子。
为了减少三音子模型参数,比较有效的方案是让不同模型状态共享概率密度函数。共享的原则是基于决策树,该决策树每个节点对应一个问题。
问题集的产生可人工设计,也可基于训练数据自动生成。自动生成是最常用的方案