Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Networks
Date :2021.04.21
Author: Xin Pan
背景
CTC是ICML2016年的论文今天依旧在被使用,而我一致也没有读过使用过,正巧现在想系统阅读下这些论文就记录下自己的收获。
讲真的这个论文是够难懂的,很多的内容第一次读完之后真的没有理解。但是之前看过HMM(隐马尔科夫模型)感觉CTC可以做和HMM几乎一样的工作,为什么这么说呢?
语音识别的工作是将语音(一个数字序列,假设长度N)识别为字(一个字的序列,长度为T)。而我们知道这里的N和T之间没有任何的关系。在DNN-HMM的识别阶段我们会将语音分为长度为10ms的语音帧,这时帧数一般远远大于T。从神经网络训练或者说监督学习的角度去考虑,那么一个输入需要有一个标签,而实际上这个标签是不存在的。那么DNN-HMM完成的就是这个工作,它会将字的序列往下降到帧这个维度。CTC目前看完成的也是这个工作。简单的说CTC就是利用神经网络进行时序序列的分类。据此我们可以引出如下部分。
问题
使用神经网络进行训练的时候我们需要每个输入有一个对应的标签,但是这个标签和现有的文字序列不在一个层次上,曾经我们使用GMM-HMM来处理这个问题(我现在的阶段是这么理解的),但是我们现在可以使用CTC了。
CTC的使用让我们可以将训练工作可以直接在输入序列和文字序列这两个层次上完成。
方法
今天我理解的CTC更多的是一种对于序列的处理方式,通过去掉邻近重复的字符以及加入<blank>
符号使得网络的输出不需要额外的后处理可以得到直接可用的label序列。同时使用特殊的损失函数训练就能让输出的序列概率最大。
突然我想到CTC的过程中,其实是有逐帧标签的只不过通过删除重复以及加入blank就让没用的部分被去掉了。~~只留下了认为真的有区分的结果。~~因为删除重复以及加入blank这个操作,现在我们很难再反过来进行one-to-many的映射(下文使用 β − 1 \beta^{-1} β−1表示这一过程),因而我们认为所有的可以处理为label sequence的序列都是正确的,我们只要把所有正确的概率加在一起就可以作为预测正确的概率。
在CTC训练的过程中也是用前后向算法(Forward-backward algorithm)这波操作和HMM是一致的。因为在CTC中认为任何的一个时刻都可以进行label sequence 的inference。
在这个图里边,CTC那行虚线就是输出blank的概率。
CTC计算过程
对于一个长度为T的输入序列X,和它对应的输出序列S,以及输出label序列
π
=
{
π
1
,
π
2
,
π
3
,
.
.
.
,
π
T
}
\pi=\{\pi_1,\pi_2,\pi_3,...,\pi_T\}
π={π1,π2,π3,...,πT}。输出概率
P
r
(
π
∣
X
)
=
∏
t
=
1
T
P
r
(
π
t
,
t
∣
x
)
(1)
Pr(\pi|X)=\prod_{t=1}^TPr(\pi_{t},t|x)\tag{1}
Pr(π∣X)=t=1∏TPr(πt,t∣x)(1)
也就是说当输出序列为S时,每个时刻的label序列概率想乘就可以了。其实上式和论文中的原公式时一样的。
CTC的损失函数
上边的公式(1)计算的是当输出序列为S时的概率,可以产生S这个序列的一个label序列 π \pi π的概率。其实如果一个label序列 π n \pi_n πn只要能经过去重复和blank以后是S序列就认为是正确的。那么我们其实需要将所有的 P r ( π n ) Pr(\pi_n) Pr(πn)相加即是正确的概率。举例来说F(a-abb-)=F(a-aab-)=aab。像里边F的组合可以很多种,但他们的label sequence(aab)都是正确的。
P r ( l ∣ X ) = ∑ π ∈ β − 1 ( l ) P r ( π ∣ X ) (2) Pr(l|X)=\sum_{\pi\in\beta^{-1}(l)}Pr(\pi|X)\tag{2} Pr(l∣X)=π∈β−1(l)∑Pr(π∣X)(2)
其中
β
−
1
(
l
)
\beta^{-1}(l)
β−1(l)表示label序列经过one-to-many的映射后会产生的结果,该结果一般并不是唯一的。这里仅仅是抽象表示。等于左边现在就是我们的目标X被识别为l的概率,我们希望该值尽可能大,那么损失函数就是最小化公式(2)的负对数,即
o
s
s
(
S
)
=
−
∑
π
∈
β
−
1
(
l
)
P
r
(
π
∣
X
)
=
−
l
n
∑
π
∈
β
−
1
(
l
)
P
r
(
π
∣
X
)
(3)
\begin{alignedat} Loss(S)&=-\sum_{\pi\in\beta^{-1}(l)}Pr(\pi|X) \\ &=-ln\sum_{\pi\in\beta^{-1}(l)}Pr(\pi|X)\tag{3}\\ \end{alignedat}
oss(S)=−π∈β−1(l)∑Pr(π∣X)=−lnπ∈β−1(l)∑Pr(π∣X)(3)
=
−
l
n
∏
(
x
,
z
)
∈
S
p
(
z
∣
x
)
=
−
∑
(
x
,
z
)
∈
S
l
n
p
(
z
∣
x
)
(4)
=-ln\prod_{(x,z)\in S}p(z|x)=-\sum_{(x,z)\in S} lnp(z|x)\tag{4}
=−ln(x,z)∈S∏p(z∣x)=−(x,z)∈S∑lnp(z∣x)(4)
上式(4)可以这么理解,给定输入序列X输出正确的label序列的概率乘积再取负对数,就是当前错误的概率,这部分应该尽可能小。最后这个函数是可微的。损失函数这么定义的原因是进行最大似然的训练(maximum likelihood)。
损失函数在设计的时候从(3)到(4)是因为,我们希望所有的 P r ( π ∣ x ) Pr(\pi|x) Pr(π∣x)的和最小那么我们只需要让和最大取个负号就可以了,之后每个 P r ( π ∣ x ) Pr(\pi|x) Pr(π∣x)的和就转换为 p ( z ∣ x ) p(z|x) p(z∣x)的积。
HMM与CTC的对比
类别 | HMM | CTC |
---|---|---|
作为对齐标签 | NO | YES |
建模层次 | 一般理解为label序列的字空间 | 任意层次 |
通过数学公式发现CTC和HMM之间在一些前提之下是可以互相变换的,这在[4]写的很好,推荐一看。
总体上CTC和HMM,它们在假设条件上一样(都是基于一阶马尔科夫假设),可以达到的效果也一样。现在我还是认为他们是很相似的。如果各为读者有不同的意见欢迎评论交流。
个人总结
论文读起来我觉得晦涩难懂,所以先看一些博客,昨天看了台大李宏毅老师的视频讲的CTC和后续的RNA以及RNN-T,感觉受益匪浅,而且明白了其中一些问题在那里以及如何可以解决那些问题,这对我感觉很重要,看到一个新的东西我知道如何思考它的缺点,以及怎么去fix。视频的链接在这,看其中的P4,同时配套的课程ppt链接在这。最后也感谢各位网友和同学们的整理和分享。