博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CTC算法讲解
阅读量:733 次
发布时间:2019-03-21

本文共 10615 字,大约阅读时间需要 35 分钟。

目录

CTC是什么,有什么用?

CTC(Connectionist Temporal Classification),用来解决输入序列和输出序列难以一一对应的问题。

在语音识别中,我们希望音频中的音素和翻译后的字符可以一一对应。但是对齐是一个很困难的事,有人说话快,有人说话慢,每个人说话快慢不同,手动对齐太耗时。

在OCR中,使用RNN时,RNN的每一个输出要对应字符图像中的每一个位置,要手工做这样的标记工作量太大,而且图像中的字符数量不同,字体样式不容,大小不同,导致输出不一定能和每一个字符一一对应。

CTC基本原理

假设一个RNN,用r表示RNN的参数,则RNN可以表示为一个函数: y = N w ( x ) y = N_w(x) y=Nw(x)

定义输入x的时间步长为T,每个时间步长的特征维度记作m,表示m维特征。
x = ( x 1 , x 2 , . . . , x T ) x = (x^1 , x^2, ... , x^T) x=(x1,x2,...,xT) x t = ( x 1 t , x 2 t , . . . , x m t ) x^t = (x^t_1 , x^t_2, ... , x^t_m) xt=(x1t,x2t,...,xmt)
输出时间步也为T,和输入可以一一对应,每个时间步的输出维度作为n,表示n维的输出,实际上是n个概率。
y = ( y 1 , y 2 , . . . , y T ) y = (y^1 , y^2, ... , y^T) y=(y1,y2,...,yT) y t = ( y 1 t , y 2 t , . . . , y m t ) y^t = (y^t_1 , y^t_2, ... , y^t_m) yt=(y1t,y2t,...,ymt)
假设要对26个英文字符进行识别,考虑到有些位置没有字符,定义一个 blank(用 - 代替) 作为空白符加入到字符集合中, L ′ = { a , b , c , . . . , z } ∪ { − } = L ∪ { − } L'= \{a, b, c, ... , z\} \cup \{-\} = L \cup \{-\} L={
a,b,c,...,z}
{
}=
L{
}
,那么对于RNN而言每个
时间步长的输出维度n就是27,表示27个字符在时间步长上输出的概率。
如果根据这些概率进行选取,每个时间步选取一个元素,就可以得到输出序列,其输出空间可以记作 L ′ T L'^T LT
定义一个转换函数B,对RNN的输出序列进行变换,变换成真实的输出,把连续的相同字符删减为1个并删去空白符。如下:
B ( π 1 ) = B ( − − s t t a − t − − − e ) = s t a t e B(\pi^1)=B(--stta-t---e)=state B(π1)=B(sttate)=state B ( π 2 ) = B ( s s t − a a a − t e e − ) = s t a t e B(\pi^2)=B(sst-aaa-tee-)=state B(π2)=B(sstaaatee)=state B ( π 3 ) = B ( − − s t t a a − t e e − ) = s t a t e B(\pi^3)=B(--sttaa-tee-)=state B(π3)=B(sttaatee)=state B ( π 4 ) = B ( s s t − a a − t − − − e ) = s t a t e B(\pi^4)=B(sst-aa-t---e)=state B(π4)=B(sstaate)=state
其中 π \pi π表示RNN的一种输出序列。当我们在优化RNN时,需要最大化以下概率,即给定输入x的情况下,输出为l的概率,l表示真实的输出,对下式取负号,就可以使用梯度下降求最小。
p ( l ∣ x ) = ∑ B ( π ) = l p ( π ∣ x ) p(l|x)=\sum^{}_{B(\pi)=l }{p(\pi|x)} p(lx)=B(π)=lp(πx)假设时间步之间输出独立,那么对任意一个输出序列 π \pi π的概率计算如下: p ( π ∣ x ) = ∏ t = 1 T y π t t p(\pi|x)=\prod_{t=1}^T{y^t_{\pi_t}} p(πx)=t=1Tyπtt其中下标 π t \pi_t πt表示的是,输出序列在t时间步选取元素对应的索引,比如该序列在第一时间步选取的元素是a,那么的到值就是1,。选取的是z,那么得到的值就是26,。选取的是空白符,那么得到的值就是27。
对于某一个真实的输出,如state,是有过个RNN输出序列通过B转换得到,这些序列都是我们想要的结果,我们要给定x,这些输出序列的概率加起来最大。如果逐条遍历,时间复杂度使指数级,因为有T个位置,每个位置有n种选择(字符集合的大小),那么就有 n T n^T nT种可能,因此CTC使用HMM中的前向-后向算法来计算。

CTC中的前向后向算法

由于真实输出 l l l是一个序列,序列可以通过一个路径图中的一条路径来表示,我们也称输出序列 l l l为路径 l l l。定义路径 l ′ l' l为:在路径 l l l每两个元素之间以及头尾插入空白符。如下: l = s t a t e l=state l=state l ′ = − s − t − a − t − e − l'=-s-t-a-t-e- l=state对某个时间步长的某个字符求导(这里用k表示字符集合中的某个字符或者字符索引)恰好是与概率 y k t y^t_k ykt相关的路径。 ∂ p ( l ∣ x ) ∂ y k t = ∂ ∑ B ( π ) = l , π t = k p ( π ∣ x ) ∂ y k t \frac{\partial p(l | x)}{\partial y_{k}^{t}}=\frac{\partial \sum_{B(\pi)=l, \pi_{t}=k} p(\pi | x)}{\partial y_{k}^{t}} yktp(lx)=yktB(π)=l,πt=kp(πx)以前面的 π 1 , π 2 , π 3 , π 4 \pi^{1}, \pi^{2}, \pi^{3}, \pi^{4} π1,π2,π3,π4为例子,简单绘制如下示意图:

在这里插入图片描述
4条路径都在t=6时经过了字符a,观察4条路径,可以得到如下式子。
π 1 = b = b 1 : 5 + a 6 + b 7 : 12 π 2 = r = r 1 : 5 + a 6 + r 7 : 12 π 3 = b 1 : 5 + a 6 + r 7 : 12 π 4 = r 1 : 5 + a 6 + b 7 : 12 \begin{aligned} &\pi^{1}=b=b_{1: 5}+a_{6}+b_{7: 12}\\ &\pi^{2}=r=r_{1: 5}+a_{6}+r_{7: 12}\\ &\pi^{3}=b_{1: 5}+a_{6}+r_{7: 12}\\ &\pi^{4}=r_{1: 5}+a_{6}+b_{7: 12} \end{aligned} π1=b=b1:5+a6+b7:12π2=r=r1:5+a6+r7:12π3=b1:5+a6+r7:12π4=r1:5+a6+b7:12 p ( π 1 , π 2 , π 3 , π 4 ∣ x ) = y 1 − ⋅ y 2 − ⋅ y 3 ⋅ y 4 + y 5 t ⋅ y 6 ⋅ y 7 − ⋅ y 8 + y 9 − y 10 − y 11 − y 12 e + y 1 s ⋅ y 2 s ⋅ y 3 t ⋅ y 4 − y 5 ⋅ y 6 ⋅ y 7 a ⋅ y 8 − y 9 t ⋅ y 10 ⋅ y 11 e ⋅ y 12 + y 1 − ⋅ y 2 − ⋅ y 3 ⋅ y 4 + y 5 t 5 ⋅ y 6 ⋅ y 7 ⋅ y 8 − y 9 t 9 ⋅ y 10 ⋅ y 11 e − y 12 − + y 1 s ⋅ y 2 − x 3 s 3 ⋅ y 4 + y 5 t 5 + y 6 a 7 ⋅ y 7 ⋅ y 8 − y 9 t 9 ⋅ y 10 ⋅ y 11 e ⋅ y 12 − + y 1 s ⋅ y 2 s ⋅ y 3 t ⋅ y 4 − y a 5 ⋅ y 6 ⋅ y 7 − y 8 ⋅ 9 − y 10 − y 11 − y 12 e \begin{aligned} p\left(\pi^{1}, \pi^{2}, \pi^{3}, \pi^{4} | x\right) &=y^{1}-\cdot y^{2}-\cdot y^{3} \cdot y^{4}+y^{5} t \cdot y^{6} \cdot y^{7}-\cdot y^{8}+y^{9}-y^{10}-y^{11}-y^{12} e \\ &+y^{1} s \cdot y^{2} s \cdot y^{3} t \cdot y^{4}-y^{5} \cdot y^{6} \cdot y^{7} a \cdot y^{8}-y^{9} t \cdot y^{10} \cdot y^{11} e \cdot y^{12} \\ &+y^{1}-\cdot y^{2}-\cdot y^{3} \cdot y^{4}+y^{5} t^{5} \cdot y^{6} \cdot y^{7} \cdot y^{8}-y^{9} t^{9} \cdot y^{10} \cdot y^{11} e^{-y^{12}}-\\ &+y^{1} s \cdot y^{2}-x^{3} s^{3} \cdot y^{4}+y^{5} t^{5}+y^{6} a^{7} \cdot y^{7} \cdot y^{8}-y^{9} t^{9} \cdot y^{10} \cdot y^{11} e \cdot y^{12}-\\ &+y^{1} s \cdot y^{2} s \cdot y^{3} t \cdot y^{4}-y^{5}_{a} \cdot y^{6} \cdot y^{7}-y^{8} \cdot^{9}-y^{10}-y^{11}-y^{12} e \end{aligned} p(π1,π2,π3,π4x)=y1y2y3y4+y5ty6y7y8+y9y10y11y12e+y1sy2sy3ty4y5y6y7ay8y9ty10y11ey12+y1y2y3y4+y5t5y6y7y8y9t9y10y11ey12+y1sy2x3s3y4+y5t5+y6a7y7y8y9t9y10y11ey12+y1sy2sy3ty4ya5y6y7y89y10y11y12e
令:  forward  = p ( b 1 : 5 + r 1 : 5 ∣ x ) = y 1 ⋅ y 2 − y 3 ⋅ y 4 ⋅ t 5 + y 1 ⋅ y 2 ⋅ y 2 ⋅ y 3 ⋅ y 4 − y 5 a  backward  = p ( b 7 : 12 + r 7 : 12 ∣ x ) = y 7 − ⋅ y t 8 ⋅ y 9 − ⋅ y 10 − ⋅ y e 11 + y a 7 ⋅ y − 8 ⋅ y t 9 ⋅ y e 10 ⋅ y e 11 ⋅ y 12 \begin{aligned} &\text { forward }=p\left(b_{1: 5}+r_{1: 5} | x\right)=y^{1} \cdot y^{2}-y^{3} \cdot y^{4} \cdot t^{5}+y^{1} \cdot y^{2} \cdot y^{2} \cdot y^{3} \cdot y^{4}-y^{5} a\\ &\text { backward }=p\left(b_{7: 12}+r_{7: 12} | x\right)=y^{7}-\cdot y^{8}_{t} \cdot y^{9}-\cdot y^{10}-\cdot y^{11}_{e}+y^{7}_{a} \cdot y^{8}_{-} \cdot y_{t}^{9} \cdot y^{10}_{e} \cdot y^{11}_{e} \cdot y^{12} \end{aligned}  forward =p(b1:5+r1:5x)=y1y2y3y4t5+y1y2y2y3y4y5a backward =p(b7:12+r7:12x)=y7yt8y9y10ye11+ya7y8yt9ye10ye11y12
那么可以做如下表示:
p ( π 1 , π 2 , π 3 , π 4 ∣ x ) =  forward  ⋅ y a t ⋅  backward  p\left(\pi^{1}, \pi^{2}, \pi^{3}, \pi^{4} | x\right)=\text { forward } \cdot y_{a}^{t} \cdot \text { backward } p(π1,π2,π3,π4x)= forward yat backward 上述forward和backward只包含了四条路径,如果推广一下forward和backward的含义,考虑所有路径,可以做如下表示: ∑ B ( π ) = l , π 6 = a p ( π ∣ x ) =  forward  ⋅ y a t ⋅  backward  \sum_{B(\pi)=l, \pi_{6}=a} p(\pi | x)=\text { forward } \cdot y_{a}^{t} \cdot \text { backward } B(π)=l,π6=ap(πx)= forward yat backward 定义forward为 α t ( l k ′ ) \alpha_{t}\left(l_{k}^{\prime}\right) αt(lk),表示t时刻经过 l k ′ l_{k}^{\prime} lk字符的路径概率中1-t的概率之和,式子定义如下: α t ( l k ′ ) = ∑ B ( π ) = l , π t = l k ′ ∏ t ′ = 1 t y π t ′ t ′ \alpha_{t}\left(l_{k}^{\prime}\right)=\sum_{B(\pi)=l, \pi_{t}=l_{k}^{\prime}} \prod_{t^{\prime}=1}^{t} y_{\pi_{t^{\prime}}}^{t^{\prime}} αt(lk)=B(π)=l,πt=lkt=1tyπtt
t=1时,符号只能是空白符或者 l 1 l_{1} l1,可以得到以下初始条件:
α 1 ( − ) = y 1 − α 1 ( l 1 ) = y l 1 1 α 1 ( l t ) = 0 , ∀ t > 1 \begin{aligned} \alpha_{1}(-) &=y^{1}-\\ \alpha_{1}\left(l_{1}\right) &=y_{l_{1}}^{1} \\ \alpha_{1}\left(l_{t}\right)=0, \forall t>1 \end{aligned} α1()α1(l1)α1(lt)=0,t>1=y1=yl11
在这里插入图片描述
观察上图可以看出,如果t=6时字符是a,那么t=5时只能是字符a,t,空白符三选一。
可以得到如下递推关系: α 6 ( a ) = ( α 5 ( a ) + α 5 ( t ) + α 5 ( − ) ) ⋅ y a 6 \alpha_{6}(a)=\left(\alpha_{5}(a)+\alpha_{5}(t)+\alpha_{5}(-)\right) \cdot y_{a}^{6} α6(a)=(α5(a)+α5(t)+α5())ya6更一般: α t ( l k ′ ) = ( α t − 1 ( l k ′ ) + α t − 1 ( l k − 1 ′ ) + α t − 1 ( − ) ) ⋅ y l k t \alpha_{t}\left(l_{k}^{\prime}\right)=\left(\alpha_{t-1}\left(l_{k}^{\prime}\right)+\alpha_{t-1}\left(l_{k-1}^{\prime}\right)+\alpha_{t-1}(-)\right) \cdot y_{l_{k}}^{t} αt(lk)=(αt1(lk)+αt1(lk1)+αt1())ylkt
定义backward为 β t ( s ) \beta_{t}(s) βt(s),表示t时刻经过 l k ′ l_{k}^{\prime} lk字符的路径概率中t~T的概率之和,式子如下: β t ( l k ′ ) = ∑ B ( π ) = l , π t = l k ′ ∏ t ′ = t T y π t ′ t ′ \beta_{t}\left(l_{k}^{\prime}\right)=\sum_{B(\pi)=l, \pi_{t}=l_{k}^{'}} \prod_{t'=t}^{T} y_{\pi_{
{t}^{\prime}}}^{t^{\prime}}
βt(lk)=B(π)=l,πt=lkt=tTyπtt
t=T时,符号只能是空白符或者 l ∣ l ′ ∣ − 1 l_{\left|l^{\prime}\right|-1} ll1,可以得到以下初始条件: β T ( − ) = y − T β T ( l ∣ l ′ ∣ − 1 ′ ) = y l ∣ l ′ ∣ − 1 ′ T β T ( l ∣ l ′ ∣ − i ) = 0 , ∀ i > 1 \begin{aligned} \beta_{T}(-) &=y^{T}_{-} \\ \beta_{T}\left(l_{\left|l^{\prime}\right|-1}^{\prime}\right) &=y_{l_{|l^{\prime}|-1}^{\prime} }^{T} \\ \beta_{T}\left(l_{\left|l^{\prime}\right|-i}\right) &=0, \forall i>1 \end{aligned} βT()βT(ll1)βT(lli)=yT=yll1T=0,i>1
同理,可以得到如下递归条件: β t ( l k ′ ) = ( β t + 1 ( l k ′ ) + β t + 1 ( l k + 1 ′ ) + β t + 1 ( − ) ) ⋅ y l k t t k \beta_{t}\left(l_{k}^{\prime}\right)=\left(\beta_{t+1}\left(l_{k}^{\prime}\right)+\beta_{t+1}\left(l_{k+1}^{\prime}\right)+\beta_{t+1}(-)\right) \cdot y_{l_{k}^{t}}^{t_{k}} βt(lk)=(βt+1(lk)+βt+1(lk+1)+βt+1())ylkttk
根据forward和backward的式子定义,它们相乘可以得到: α t ( l k ′ ) β t ( l k ′ ) = ∑ B ( π ) = l , π t = l k t y l k t ∏ t = 1 T y π t t \alpha_{t}\left(l_{k}^{\prime}\right) \beta_{t}\left(l_{k}^{\prime}\right)=\sum_{B(\pi)=l, \pi_{t}=l_{k}^{t}} y_{l_{k}^{t}} \prod_{t=1}^{T} y_{\pi_{t}}^t αt(lk)βt(lk)=B(π)=l,πt=lktylktt=1Tyπtt
又因为 p ( l ∣ x ) p(l | x) p(lx) l k ′ l_{k}^{\prime} lk求导时,只跟那些 π t = l k ′ \pi_{t}=l_{k}^{\prime} πt=lk的路径有关,那么求导时可以简写如下式子: p ( l ∣ x ) = ∑ B ( π ) = l , π t = l k ′ p ( π ∣ x ) = ∑ B ( π ) = l , π t = l k ′ ∏ t = 1 T y π t t p(l | x)=\sum_{B(\pi)=l, \pi_{t}=l_{k}^{\prime}} p(\pi | x)=\sum_{B(\pi)=l, \pi_{t}=l_{k}^{\prime}} \prod_{t=1}^{T} y_{\pi_{t}}^{t} p(lx)=B(π)=l,πt=lkp(πx)=B(π)=l,πt=lkt=1Tyπtt结合上面两个式子,得到: p ( l ∣ x ) = ∑ B ( π ) = l , π t = l k ′ α t ( l k ′ ) β t ( l k ′ ) y l k ′ t p(l | x)=\sum_{B(\pi)=l, \pi_{t}=l_{k}^{\prime}} \frac{\alpha_{t}\left(l_{k}^{\prime}\right) \beta_{t}\left(l_{k}^{\prime}\right)}{y_{l_{k}^{\prime}}^{t}} p(lx)=B(π)=l,πt=lkylktαt(lk)βt(lk)最后可以得到求导式(这里用k来表示字符,和 l k ′ l_{k}^{\prime} lk)的含义相同: ∂ p ( l ∣ x ) ∂ y k t = ∂ ∑ B ( π ) = l , π t = k α t ( k ) β t ( k ) y k t ∂ y k t \frac{\partial p(l | x)}{\partial y_{k}^{t}}=\frac{\partial \sum_{B(\pi)=l, \pi_{t}=k} \frac{\alpha_{t}(k) \beta_{t}(k)}{y_{k}^{t}}}{\partial y_{k}^{t}} yktp(lx)=yktB(π)=l,πt=kyktαt(k)βt(k)求导式里,forward和backward可以用前面的dp递推公式计算出来,时间复杂度是nT,大大减小了计算量。
这样对RNN的输出y求导之后,再根据y对RNN里面的权重参数w进行链式求导,就可以使用梯度下降的方法来更新参数了。

CTC预测

一种方法是Best Path search。计算概率最大的一条输出序列,但是这样没有考虑多个输出序列对应一个真实输出。如: [ s , s , − ] [s, s,-] [s,s,] [ s , s , s ] [s, s, s] [s,s,s]的概率比 [ s , t , a ] [s, t, a] [s,t,a]低,但是他们的概率之和会高于 [ s , t , a ] [s, t, a] [s,t,a]

第二种方法,是Beam Search。假设指定B=3,预测过程如下图所示。在第一时间步长选取概率最大的三个字符,然后在第二个时间步也选取概率最大的三个字符,两两组合可以组合成9个序列,这些序列在B转换之后会得到一些相同输出,把具有相同输出的序列进行合并,比如有三个序列都可以转换为a,把他们合并,计算出概率最大的三个序列,然后继续和下一个时间步长的字符进行相同的合并。在这里插入图片描述
有一点需要注意的是合并相同字符,比如上图,T=3时,第一个前缀序列a,在跟相同字符a合并的时候,除了产生a之外,还会产生一个aa的有效输出,这是因为这个前缀序列a在T=2的时候曾经把空白符号合并掉了,实际上这个前缀序列a后面是跟着一个空白符的,所以它在跟相同字符a合并的时候中间是有一个隐藏的空白符,合并之后得到的应该是两个a。
因此合并相同字符的时候,如果要合并成aa,需要统计在这之前以空白符结尾的那些序列的概率,如果要合并成a,计算的是不以空白符结尾的那些序列的概率。出于这个事实,我们需要跟踪前两处的输出,以便后续的合并运算。在这里插入图片描述

CTC的性质

  1. 条件独立假设。CTC做了一个假设是不同时间步的输出之间是独立的。这个假设对于很多序列问题来说并不成立,输出序列之间往往存在联系。
  2. 单调对齐。CTC只允许单调对齐,在语音识别中可能是有效的,但是在机器翻译中,比如目标语句中的一些比较后的词,可能与源语句中前面的一些词对应,这个CTC无法做到。
  3. 多对一映射。CTC的输入和输出是多对一的关系。这意味着输出长度不能超过输入长度,这在手写字体识别或者语音中不是什么问题,因为通常输入都会大于输出,但是对于输出长度大于输入长度的问题,CTC就无法处理。

参考文章

转载地址:http://grjgz.baihongyu.com/

你可能感兴趣的文章