语音识别 CTC Loss

(以下内容搬运自 PaddleSpeech)

Derivative of CTC Loss

关于CTC的介绍已经有很多不错的教程了,但是完整的描述CTCLoss的前向和反向过程的很少,而且有些公式推导省略和错误。本文主要关注CTC Loss的梯度是如何计算的,关于CTC的介绍这里不做过多赘述,具体参看文末参考。

CTC主要应用于语音和OCR中,已语音Deepspeech2模型为例,CTC的网络一般如下图所示,包含softmax和CTCLoss两部分。反向传播需要求得loss L相对于logits u i u^i ui​的梯度。下面先介绍CTCLoss的前向计算。

图片来源于文末参考

image-20211104200811966

CTC Loss 的计算

CTC中path的定义与概率的计算如下:

image-20211104200811966

path 是 $ L’^T$​​的元素,用 π \pi π​​表示。 x \textbf{x} x​​ 是输入特征, y \textbf{y} y​​ 是输出label, 都是序列。 L L L​​ 是输出的 vocab, L‘ 是 L ∪ b l a n k L \cup {blank} Lblank​​。 y π t t y_{\pi_{t}}^t yπtt​​ 表示在t时刻, π t \pi_{t} πt​​ label时的观察概率。其中 π t \pi_{t} πt​​ 表示 π \pi π​​ path在t时刻的label。 π \pi π​​ 是 y \textbf{y} y​​ 与 x \textbf{x} x​​ 的一个alignment,长度是 T T T​​,取值空间为 L ′ L' L​​​。path也称为alignment。

公式(2)解释了给定输入 x \textbf{x} x​ ,输出 π \pi π​ path 的概率,即从时间t=1到T每个时间点的概率 y π t t y_{\pi_{t}}^t yπtt​ 相乘。

求出单条path后,就可以计算 p ( l ∣ x ) p(l \mid x) p(lx)​ 的概率,计算如下:

image-20211104202358513

这里边 B \mathcal{B} B 就是映射, 即所有多对一的映射(many-to-one mapping )的集合。 这样就算出来对应一个真正的 label l \textbf{l} l 的概率了,这里是求和。 求和的原因就是 aab 和 abb 都是对应成ab, 所以 aab 的概率 + abb 的概率才是生成ab的概率。

公式(3)解释了给定输入 x \mathbf{x} x​​​​​​ ,求输出 l \mathbf{l} l​​​​​​ 的概率, 即所有集合 B − 1 ( l ) \mathcal{B}^{-1} (\mathbf{l}) B1(l)​​​​​​​​​​ 中 path的概率和。

CTC forward-backward 算法

CTC的优化采用算最大似然估计MLE (maximum likelihood estimation), 这个和神经网络本身的训练过程是一致的。

这个CTC 计算过程类似HMM的 forward-backward algorithm,下面就是这个算法的推导过程:

image-20211104203040307

上图中的定义很清楚, 但是 α t − 1 ( s ) \alpha_{t-1}(s) αt1(s) and α t − 1 ( s − 1 ) \alpha_{t-1}(s-1) αt1(s1) α t ( s ) \alpha_t(s) αt(s) 的关系也不那么好看出来,下图给出了具体的关于 α t ( s ) \alpha_t(s) αt(s) 的推导过程:

image-20211108155714843 image-20211109153011816

这里的公式比较适合用下面的图来理解, α 1 ( 1 ) \alpha_1(1) α1(1)​​​​ 其实对应的就是下图中左上角白色的圆圈。 就是上来第一个是blank 的概率, 而 α 1 ( 2 ) \alpha_1(2) α1(2)​​​​是label l 的第一个字母。 这里边我们假设每个字母之间都插入了空白,即label l扩展成l’,例如,l=[a, b, b, c], l’=[-, a, -, b, -, b, -, c, -]。 然后对于其他圆点,在时间是1 的情况下概率都是 0. Figure 3中横轴是时间 t,从左到右是1到T;纵轴是s(sequence),从上到下是 1 到 ∣ l ′ ∣ \mathbf{\mid l' \mid} l​​​​.

image-20211108155918442

接下来我们分析递归公式 (resursion),更多介绍可以参看 [2]. 公式6分情况考虑:

  • 第一种情况就是当前的label是blank, 或者 l ′ s = l ′ s − 2 \mathbf{l'}_{s}= \mathbf{l'}_{s-2} ls=ls2​​​​​​​(相邻是重复字符):
image-20211108155918442

这个时候他的概率来自于过去t-1的两个label 概率, 也就是 a t − 1 ( s ) a_{t-1} (s) at1(s)​​ 和 a t − 1 ( s − 1 ) a_{t-1} (s-1) at1(s1)​​​ 。

a t − 1 ( s ) a_{t-1} (s) at1(s)​​ 就是说当前的 sequence 已经是 s 了,figure 3中表现为横跳, blank -->blank(例如t=3, s=3);

a t − 1 ( s − 1 ) a_{t-1} (s-1) at1(s1)是说明当前的字符还不够, 需要再加一个, 所以在figure 3中就是斜跳,从黑色圆圈到白色圆圈(例如,t=3, s=5)。

仔细观察figure 3, 除了第一排的白色圆圈, 其他白色圆圈都有两个输入, 就是上述的两种情况。 当然判断blank 的方法也可以是判断 I s − 2 ′ = I s ′ I'_{s-2} = I'_{s} Is2=Is​. 这种情况也是说明 I s ′ I'_{s} Is​​​ 是blank, 因为每一个字符必须用 blank 隔开, 即使是相同字符。

  • 第二章情况 也可以用类似逻辑得出, 只不过当前的状态s 是黑色圆圈, 有三种情况输入。
image-20211108155918442

最终的概率就如公式8 所示, 这个计算过程就是 CTC forward algroirthm, 基于 Fig. 3 的左边的初始条件。

image-20211108162544982

基于Fig. 3 右边的初始条件,我们还是可以计算出一个概率, 那个就是 CTC backward. 这里我就不详细介绍了, 直接截图。

image-20211108162859876

这样一直做乘法, 数字值越来越小,很快就会underflow。 这个时候就需要做 scaling.

image-20211108163526616

算出了forward probability 和 backward probability 有什么用呢, 解释如下图。

image-20211108164110404

上图是说 forward probability and backward probability 的乘积, 代表了这个 sequence l \mathbf{l} l t时刻,是s label 的 所有paths 的概率。 这样的话 我们就计算了 Fig. 3 中的每个圆圈的概率。为什么 α t ( s ) β t ( s ) \alpha_t(s)\beta_t(s) αt(s)βt(s) 中多出一个 y l s ′ t y^t_{\mathbf{l'_s}} ylst ,这是因为它在 α \alpha α β \beta β 中都包含该项,合并公式后就多出一项。

image-20211109143104052

p ( l ∣ x ) p(\mathbf{l}|\mathbf{x}) p(lx)​ 可以通过任意时刻 t 的所有 s 的 foward-backward 概率计算得来。取负对数后就是单个样本的NLL(Negative Log Likelihood)。

总结

总结一下,根据前向概率计算CTCLoss函数,可以得出如下结论:

  1. 对于时序长度为T的输入序列x和输出序列z,前向概率:
    α t ( s ) = ∑ π ∈ B − 1 ( z ) π t = l s ′ p ( π 1 : t ∣ x ) α 1 ( 1 ) = y − 1 ; α 1 ( 2 ) = y l 2 ′ 1 , α 1 ( s ) = 0 , ∀ s > 2 α t ( s ) = 0 , ∀ s < ∣ l ′ ∣ − 2 ( T − t ) − 1 , or ∀ s < 1 α t ( s ) = { ( α t − 1 ( s ) + α t − 1 ( s − 1 ) ) y l s ′ t if  l s ′ = b  or  l s − 2 ′ = l s ′ ​ ( α t − 1 ( s ) + α t − 1 ( s − 1 ) + α t − 1 ( s − 2 ) ) y l s ′ t otherwise \begin{split} \alpha_t(s) &= \sum_{ \underset{\pi_t=l'_s}{\pi \in \mathcal{B}^{-1}(z)} } p(\pi_{1:t}|x) \newline \alpha_1(1) &= y_{-}^1 ; \quad \alpha_1(2)=y^1_{l'_2}, \quad \alpha_1(s)=0, \forall s > 2 \newline \alpha_t(s) &= 0, \quad \forall s < |l'| - 2(T-t) - 1 ,\quad \text{or} \quad \forall s < 1 \newline \alpha_t(s) &= \begin{cases} (\alpha_{t-1}(s) + \alpha_{t-1}(s-1) ) y^t_{l'_s} & \text{if $l'_s=b$ or $l'_{s-2} = l'_s$​} \newline (\alpha_{t-1}(s) + \alpha_{t-1}(s-1) + \alpha_{t-1}(s-2))y^t_{l'_s} & \text{otherwise}\newline \end{cases} \end{split} αt(s)α1(1)αt(s)αt(s)=πt=lsπB1(z)p(π1:tx)=y1;α1(2)=yl21,α1(s)=0,s>2=0,s<l2(Tt)1,ors<1={ (αt1(s)+αt1(s1))ylst(αt1(s)+αt1(s1)+αt1(s2))ylstif ls=b or ls2=lsotherwise

  2. 利用 α t ( s ) \alpha_t(s) αt(s) 计算CTCLoss:
    − l n ( p ( l ∣ x ) ) = − l n ( α T ( ∣ l ′ ∣ ) + α T ( ∣ l ′ ∣ − 1 ) ) -ln(p(l \mid x)) = -ln(\alpha_{T}(|l'|)+\alpha_{T}(|l'|-1)) ln(p(lx))=ln(αT(l)+αT(l1))

根据后向概率计算CTCLoss函数,可以得出如下结论:

  1. 对于时序长度为T的输入序列x和输出序列z,后向概率:
    β t ( s ) = ∑ π ∈ B − 1 ( z ) π t = l s ′ p ( π t : T ∣ x ) β T ( ∣ l ′ ∣ ) = y − T ; β T ( ∣ l ′ ∣ − 1 ) = y l ∣ l ′ ∣ − 1 ′ T , β T ( s ) = 0 , ∀ s < ∣ l ′ ∣ − 1 β t ( s ) = 0 , ∀ s > 2 t  or  ∀ s < ∣ l ′ ∣ β t ( s ) = { ( β t + 1 ( s ) + β t + 1 ( s + 1 ) ) y l s ′ t if  l s ′ = b  or  l s + 2 ′ = l s ′ ( β t + 1 ( s ) + β t + 1 ( s + 1 ) + β t + 1 ( s + 2 ) ) y l s ′ t otherwise \begin{split} \beta_t(s) &= \sum_{ \underset{\pi_t=l'_s}{\pi \in \mathcal{B}^{-1}(z)} } p(\pi_{t:T}|x) \newline \beta_T(|l'|) &= y_{-}^T ; \quad \beta_T(|l'|-1)=y^T_{l'_{|l'|-1}}, \quad \beta_T(s)=0, \forall s < |l'| - 1 \newline \beta_t(s) &= 0, \text{$\forall s > 2t$ or $\forall s < |l'|$} \newline \beta_t(s) &= \begin{cases} (\beta_{t+1}(s) + \beta_{t+1}(s+1) ) y^t_{l'_s} & \text{if $l'_s=b$ or $l'_{s+2} = l'_s$} \newline (\beta_{t+1}(s) + \beta_{t+1}(s+1) + \beta_{t+1}(s+2))y^t_{l'_s} & \text{otherwise}\newline \end{cases} \end{split} βt(s)βT(l)βt(s)βt(s)=πt=lsπB1(z)p(πt:Tx)=yT;βT(l1)=yll1T,

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值