对于其中一个样本\((x,z)\),\(x=(x_1,x_2,x_3,...,x_T)\)表示一个长度为T帧的数据,每一帧的数据是一个维度为m的向量,即每个\(x_i \in R^m\)。 \(x_i\)可以理解为对于一段语音,每25ms作为一帧,其中第\(i\)帧的数据经过MFCC计算后得到的结果。
\(z=(z_1,z_2, z_3,...z_U)\)表示这段样本语音对应的正确的音素。比如,一段发音“你好”的声音,经过MFCC计算后,得到特征\(x\), 它的文本信息是“你好”,对应的音素信息是\(z=[n,i,h,a,o]\)(这里暂且将每个拼音的字母当做一个音素)。
特征\(x\)在经过RNN的计算之后,在经过一个\(softmax\)层,得到音素的后验概率\(y\)。 \(y^t_k(k=1, 2,3,...n,t=1,2,3,...,T)\)表示在\(t\)时刻,发音为音素\(k\)的概率,其中音素的种类个数一共\(n\)个, \(k\)表示第\(k\)个音素,在一帧的数据上所有的音素概率加起来为1。即:
\(\sum_{t-1}^{T}y^t_k=1, y^t_k\geq0\)
这个过程可以看做是对输入的特征数据\(x\)做了变换\(N_w\):\((R^m)^T \rightarrow (R^n)^T\),其中\(N_w\)表示RNN的变换,\(w\)表示RNN中的参数集合。
过程入下图所示:
以一段“你好”的语音为例,经过MFCC特征提取后产生了30帧,每帧含有12个特征,即\(x \in R^{30\times14}\)(这里以14个音素为例,实际上音素有200个左右),矩阵里的每一列之和为1。后面的基于CTC-loss的训练就是基于后验概率\(y\)计算得到的。
路径π和B变换在实际训练中并不知道每一帧对应的音素,因此进行训练比较困难。可以先考虑一种简单的情况,已知每一帧的音素的标签\(z\prime\), 即训练样本为\(x\)和\(z\prime\),其中\(z\prime\)不再是简单的\([n,i,h,a,o]\)标签,而是:
\(z\prime = [\underbrace{n,n,n,...,n}_{T_1},\underbrace{i,i,i,...i}_{T_2},\underbrace{h,h,h,...h}_{T_3},\underbrace{a,a,a,...,a}_{T_4},\underbrace{o,o,o,...,o}_{T_5}]\)
$ T_1+T_2+T_3+T_4+T_5 = T $
在我们的例子中, \(z\prime =[n,n,n,n,n,n,n,i,i,i,i,i,i,h,h,h,h,h,h,h,a,a,a,a,a,a,o,o,o,o,o,o,o]\), $z\prime $包含了每一帧的标签。在这种情况下有:
\(p(z\prime|x) = p(z\prime| y = N_w(x)) = y^1_{z\prime_1}y^2_{z\prime_2}y^3_{z\prime_3}....y^T_{z\prime_T}\) \(\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\) (1)
该值即为后验概率图中用黑线圈起来的部分相乘。我们希望相乘的值越大越好,因此,数学规划可以写为:
\(min_w -log(y^1_{z^\prime_1}.y^2_{z^\prime_2}.y^3_{z^\prime_3}...y^T_{z^\prime_T})\) \(\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\) (2)
subject to: $ y = N_w(x) \($\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\) (3)
目标函数对于后验概率矩阵\(y\)中的每个元素\(y^t_k\)的偏导数为:
$\frac{\partial - log(y^1_{z^\prime_1}.y^2_{z^\prime_2}.y^3_{z^\prime_3}...y^T_{z^\prime_T})}{\partial y^t_k} = \($\begin{cases} -\frac{y^1_{z\prime_1}...y^{i-1}_{z\prime_{i-1}}.y^{i+1}_{z\prime_{i+1}}....y^T_{z\prime_T}}{y^1_{z^\prime_1}.y^2_{z^\prime_2}.y^3_{z^\prime_3}...y^T_{z^\prime_T}} , \qquad if \qquad k = z\prime_i \qquad and \qquad t=i \\ 0 \qquad 其他\end{cases}\)
也就是说,在每个时刻\(t\)(对应矩阵的一列),目标只与\(y^t_{z\prime_t}\)是相关的,在这个例子中是与被框起来的元素相关。
其中\(N_w\)可以看做是RNN模型,如果训练数据的每一帧都标记了正确的音素,那么训练过程就很简单了,但实际上这样的标记过的数据非常稀少,而没有逐帧标记的数据很多,CTC可以做到用未逐帧标记的数据做训练。
首先定义几个符号:
\(L=\lbrace a, o, e, i, u, \check{u},b,p,m,...\rbrace\)
表示所有音素的集合
\(\pi= (\pi_1, \pi_2, \pi_3, ..., \pi_T), \pi_i \in L\)
表示一条由\(L\)中元素组成的长度为\(T\)的路径,比如\(z\prime\)就是一条路径,以下为几个路径的例子:
\(\pi^1= (j,j,i,n,y,y,e,e,w,w,u,u,u,r,r,e,e,n,n,r,r,u,u,sh,sh,u,u,i,i)\)
\(\pi^2= (n,n,n,n,i,i,i,i,h,h,h,h,a,a,a,a,a,a,a,a,a,o,o,o,o,o,o,o,o,o)\)
\(\pi^3= (h,h,h,h,h,h,a,a,a,a,a,a,a,o,o,o,o,n,n,n,n,n,n,i,i,i,i,i,i,i)\)
\(\pi^4= (n,i,h,a,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o)\)
\(\pi^5= (n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,i,h,a,o)\)
\(\pi^6= (n,n,n,i,i,i,h,h,h,h,h,a,,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o)\)