CTC是什么,有什么用?
CTC(Connectionist Temporal Classification),用来解决输入序列和输出序列难以一一对应的问题。
在语音识别中,我们希望音频中的音素和翻译后的字符可以一一对应。但是对齐是一个很困难的事,有人说话快,有人说话慢,每个人说话快慢不同,手动对齐太耗时。
在OCR中,使用RNN时,RNN的每一个输出要对应字符图像中的每一个位置,要手工做这样的标记工作量太大,而且图像中的字符数量不同,字体样式不容,大小不同,导致输出不一定能和每一个字符一一对应。
CTC基本原理
假设一个RNN,用r表示RNN的参数,则RNN可以表示为一个函数:
y=Nw(x)。
定义输入x的时间步长为T,每个时间步长的特征维度记作m,表示m维特征。
x=(x1,x2,...,xT)
xt=(x1t,x2t,...,xmt)
输出时间步也为T,和输入可以一一对应,每个时间步的输出维度作为n,表示n维的输出,实际上是n个概率。
y=(y1,y2,...,yT)
yt=(y1t,y2t,...,ymt)
假设要对26个英文字符进行识别,考虑到有些位置没有字符,定义一个 blank(用 - 代替) 作为空白符加入到字符集合中,
L′={a,b,c,...,z}∪{−}=L∪{−},那么对于RNN而言每个
时间步长的输出维度n就是27,表示27个字符在时间步长上输出的概率。
如果根据这些概率进行选取,每个时间步选取一个元素,就可以得到输出序列,其输出空间可以记作
L′T。
定义一个转换函数B,对RNN的输出序列进行变换,变换成真实的输出,把连续的相同字符删减为1个并删去空白符。如下:
B(π1)=B(−−stta−t−−−e)=state
B(π2)=B(sst−aaa−tee−)=state
B(π3)=B(−−sttaa−tee−)=state
B(π4)=B(sst−aa−t−−−e)=state
其中
π表示RNN的一种输出序列。当我们在优化RNN时,需要最大化以下概率,即给定输入x的情况下,输出为l的概率,l表示真实的输出,对下式取负号,就可以使用梯度下降求最小。
p(l∣x)=B(π)=l∑p(π∣x)假设时间步之间输出独立,那么对任意一个输出序列
π的概率计算如下:
p(π∣x)=t=1∏Tyπtt其中下标
πt表示的是,输出序列在t时间步选取元素对应的索引,比如该序列在第一时间步选取的元素是a,那么的到值就是1,。选取的是z,那么得到的值就是26,。选取的是空白符,那么得到的值就是27。
对于某一个真实的输出,如state,是有过个RNN输出序列通过B转换得到,这些序列都是我们想要的结果,我们要给定x,这些输出序列的概率加起来最大。如果逐条遍历,时间复杂度使指数级,因为有T个位置,每个位置有n种选择(字符集合的大小),那么就有
nT种可能,因此CTC使用HMM中的前向-后向算法来计算。
CTC中的前向后向算法
由于真实输出
l是一个序列,序列可以通过一个路径图中的一条路径来表示,我们也称输出序列
l为路径
l。定义路径
l′为:在路径
l每两个元素之间以及头尾插入空白符。如下:
l=state
l′=−s−t−a−t−e−对某个时间步长的某个字符求导(这里用k表示字符集合中的某个字符或者字符索引)恰好是与概率
ykt相关的路径。
∂ykt∂p(l∣x)=∂ykt∂∑B(π)=l,πt=kp(π∣x)以前面的
π1,π2,π3,π4为例子,简单绘制如下示意图:

4条路径都在t=6时经过了字符a,观察4条路径,可以得到如下式子。
π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)=y1−⋅y2−⋅y3⋅y4+y5t⋅y6⋅y7−⋅y8+y9−y10−y11−y12e+y1s⋅y2s⋅y3t⋅y4−y5⋅y6⋅y7a⋅y8−y9t⋅y10⋅y11e⋅y12+y1−⋅y2−⋅y3⋅y4+y510⋅y11e⋅y12+y1−⋅y2−⋅y3⋅y4+y5t5⋅y6⋅y7⋅y8−y9t9⋅y10⋅y11e−y12−+y1s⋅y2−x3s3⋅y4+y5t5+y1−⋅y2−⋅y3⋅y4+y5t5⋅y6⋅y7⋅y8−y9t9⋅y10⋅y11e−y12−+y1s⋅y2−x3s3⋅y4+y5t5+y6a7⋅y8−y