在算所有的候选对齐预测的总和之前,我们先看看一个候选对齐预测是怎么计算的。HMM,RNN-T 和 CTC 的计算方式都是一模一样的。我们往后只用 RNN-T 来当作例子。首先我们找出一条候选对齐,比如 h = ∅c∅∅a∅t∅∅。$P (h|X)$ 就等于每个位置的发射概率和转移概率的连乘
RNN-T 与 CTC 不同的地方在,它另外训练了一个解码的 RNN。这个 RNN 会把解码出来的 token 当作输入,去影响它接下来的输出。一开始我们没有任何输入,就先输入一个 <BOS> 让它产生一个向量。一开始产生的是 $l^0$,我们把编码产生的 $h^1$,与 $l^0$ 一起输入给解码器 MLP,让它产生一个概率 $p_{1,0}$,表示输入第一个隐层,没产生任何 token 时,RNN-T 产生出的概率分布。它是∅放在句首的概率。接下来我们要算,有了这个∅之后,产生下一个 token 为 c 的概率。上面的解码 RNN 也不会造成任何影响。它只在解码器 MLP 生成了实在的 token,它才会往下计算。但产生∅是表示当前由编码器输出的隐层 $h^1$ 的信息模型已经用尽了。接下来我们要计算下一个 token 的隐层 $h^2$。我们把 $h^2$ 和之前的 $l^0$ 一起输入编码器 MLP,输出得到概率 $p_{2,0}$。由于我们解码出了实在的 token c。往后一步这个 c 就会输入给上面的 RNN,来计算一个新的 $l^1$。$l^1$ 和 $h^2$ 一起丢给解码器 MLP 就会得到概率 $p_{2,1}$。以此类推...
我们把这些输出的概率全部相乘,就是最终 $P (h|X)$ 的概率
RNN-T 它神奇的地方是,它把 token 与 token 之间的关系,独立用 RNN 来表示。而这个 RNN 不考虑∅这个 token。这样在训练的时候,会有帮助。图中的每一个格子,都对应到一个固定概率分布。比如 $p_{4,2}$ 表示我们已经读了 4 个声学特征,且已经产生出两个 token 的概率。每个格子上的概率分布,不受到你如何走到这个格子所影响。换句话说就是,当前状态发射出某个观测的概率是独立的。这刚好是 HMM 的独立观测假设
HMM 是用向前和向后传播算法来计算所有候选对齐的概率分数。RNN-T 与 HMM 所用的方法是一模一样的。我们定义 $α_{i,j}$ 为,已经读了第 i 个声学特征且输出了第 j 个 token 的所有对齐分数之和。比如说 $α_{4,2}$ 可以从 $α_{4,1}$ 和 $α_{3,2}$ 转移过来,那么就有 $α_{4,2} = α_{4,1} p_{4,1} + α_{3,2} p_{3,2}$。如此一来,我们就很容易推出动态规划的递推式 $α_{i,j} = α_{i-1,j} p_{i-1,j} + α_{i,j-1} p_{j-1,i}$。这样我们只需要遍历一个 T×N 的网格,我们就能算出所有的分数之和。有了所有候选对齐的概率分数之和,我们就得到了 $P (Y|X)$
接下来是思考要怎么训练了。我们要找到一个模型参数,来让 $logP (\hat {Y}|X)$ 最大。网格中,每一个箭头都代表了一个概率。我们从左上边走到右下角,其中所经过的每一个路径的概率相乘,就是这个对齐方式的分数。所有这些候选对齐方式的和,就是他们相乘和相加的结果得到的
由此 $P (\hat {Y}|X)$ 对参数 θ 的偏微分,就等于总的每个箭头 $p_{i,j}$ 对参数的偏微分,乘以 $P (\hat {Y}|X)$ 对每个箭头 $p_{i,j}$ 的偏微分,再把这些结果相加
对于前一项,每个箭头对参数 θ 的偏微分,计算方式就是经典的 BPTT 时序的反向传播。一开始最右边的结果计算和标签的损失,反向传播传到编码器,再传到上面的解码器 RNN
对于后一项,整个 $P (\hat {Y}|X)$ 对每个箭头的偏微分,我们要先用之前的动态规划算法得到 $P (\hat {Y}|X)$。算的时候,要把包含当前 $p_{i,j}$ 和不包含当前 $p_{i,j}$ 分开来计算。对于前面包含 $p_{i,j}$ 的,求导后就只剩非 $p_{i,j}$ 的概率相乘求和。对于第二项没有包含 $p_{i,j}$ 的求导,它就没了。我们把第一项再整理一下,就可以得到最终的计算式。得到 $P (\hat {Y}|X)$ 后除以当前箭头 $p_{i,j}$ 的概率
这时,我们再引入另一个辅助变量 $β_{i,j}$。它与 $α_{i,j}$ 很像,它表示从第 i 个声学特征开始且输出到第 j 个 token 的所有候选对齐分数之和。$β_{4,2}$ 如上图所示,它表示已经产生了 4 个声学特征和输出两个 token 的情况下,它们当前位置走到结尾为止的所有路径的分数总和。$β_{i,j}$ 刚好是 $α_{i,j}$ 的反过来。前面 $α_{i,j}$ 对应着 HMM 的正向传播算法,这里 $β_{i,j}$ 对应着 HMM 的反向传播算法。通过动态规划算法,于是我们有递推式,$β_{i,j} = β_{i+1,j} p_{i,j} + β_{i,j+1} p_{i,j}$
当我们可以算 $α_{i,j}$ 和 $β_{i,j}$ 之后,我们就可以计算出,所有包含 $p_{4,1}(a)$ 的分数总和。如图示,$P (\hat {Y}|X)$ 的计算方式可以改写为,所有从起始位置到 (4,1) 的候选对齐路径的分数和 $α_{4,1}$ 乘上 $p_{4,1}(a)$ 后,再乘上所有从位置 (4,2) 到终点的候选对齐路径的分数和 $β_{4,2}$。然后我们把它再除以 $p_{4,1}$,就消掉了 $p_{4,1}$。这样 $P (\hat {Y}|X)$ 对某个箭头概率 $p_{i,j}$ 的偏微分就可以改写为 $α_{i,j}β_{i,j+1}$。带入最终的式子后,就能计算全部候选对齐的得分,对模型参数的梯度。然后反向传播更新模型参数进行训练
训练好模型之后,我们要进行推断,即遍历所有可能的候选 $Y$,来使得模型输出的概率 $P (Y|X)$ 最大,从而找到最优的解码 $Y$。但现实中遍历所有可能候选 $Y$ 不大容易。我们只能退一步求其次,通过贪心近似估计的方法。我们不把所有的候选对齐分数加起来,而是比每一个 $Y$ 中,分数最高的那个对齐方式。概率最高的对齐方式叫作 h*。我们要探究 h * 它背后的 Y* 是什么
实际中要怎么找一个概率最高的对齐方式呢?RNN-T 每一个时间步都会跑出一个概率分布。我们把每个概率分布中,概率最大的那个 token 取出来,就是 h * 的一个近似。由于取当前概率最大的未能让整个路径最大的。如果我们想要得到更好的近似,就用 beam search,在精度和计算效率上进行折中和平衡
最后再比较一下这三个模型。在解码部分,LAS 和 RNN-T 会考虑前面的时序对当前时序的影响。而 CTC 没有考虑之前的时间步,已经生成出来的 token。在对齐部分,因为中间的注意力层,LAS 不用显示地考虑对齐。由于注意力一次要看全部,这也导致它不能在线学习。而 CTC 和 RNN-T 没有注意力层,RNN 一步一步地对输入解码,让它可以在线学习。但缺点是需要把输入和输出进行对齐。而且针对需要对齐的训练,会比较麻烦