解读CTC LOSS原理

版权声明:站在巨人的肩膀上学习。 https://blog.csdn.net/zgcr654321/article/details/84789889

为什么要使用CTC(Connectionist temporal classification)

在传统的语音识别的声学模型训练中,对于每一帧的数据,我们需要知道对应的label才能进行有效的训练,在训练数据之前需要做语音对齐的预处理。对齐的预处理要花费大量的人力和时间,而且对齐之后,模型预测出的label只是局部分类的结果,而无法给出整个序列的输出结果,往往要对预测出的label做一些后处理才可以得到我们最终想要的结果。

如:

上图是“你好”这句话的声音的波形示意图, 每个红色的框代表一帧数据,传统的方法需要知道每一帧的数据是对应哪个发音音素。比如第1,2,3,4帧对应n的发音,第5,6,7帧对应i的音素,第8,9帧对应h的音素,第10,11帧对应a的音素,第12帧对应o的音素。(这里暂且将每个字母作为一个发音音素)

我们能不能让我们的神经网络自己去学习对齐方式呢?

CTC(Connectionist temporal classification,连接时序分类)就是为了解决这个问题。

与传统的声学模型训练相比,采用CTC作为损失函数的声学模型训练,是一种完全端到端的声学模型训练,不需要预先对数据做对齐,只需要一个输入序列和一个输出序列即可以训练。这样就不需要对数据对齐和一一标注,并且CTC直接输出序列预测的概率,不需要外部的后处理。

CTC的方法是关心一个输入序列到一个输出序列的结果,那么它只关心预测输出的序列是否和真实的序列是否接近(相同),而不会关心预测输出序列中每个结果在时间点上是否和输入的序列正好对齐。

CTC引入了blank(该帧没有预测值),每个预测的分类对应的一整段语音中的一个spike(尖峰),其他不是尖峰的位置认为是blank。对于一段语音,CTC最后的输出是spike(尖峰)的序列,并不关心每一个音素持续了多长时间。

对一段音频使用文本对齐和使用CTC的例子: 

上图中首行是原始的音频数据,阴影线是在特定时间观察音素的概率对应的输出激活。中间行是使用了文本对齐的方法(Framewise方法),即对每个音素做标记 (对输入序列的每个时间步长或帧进行独立标记) 。最后一行是CTC方法,CTC并不需要这样的标记,而是预测了一系列峰值 (spikes),紧接着一些空白 (blanks)用来区分字母。我们可以看到基于Framewise的方法出现了 misallignling segment boundaries error(错误的分段边界错误)。就是说两个因素的label的概率分布图太近了, 比如在发音 dh, dh 和ax 有明显重叠,而CTC的方法却没有出现这种现象。

CTC网络的计算:

论文:Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Networks

论文地址:http://people.idsia.ch/~santiago/papers/icml2006.pdf

另外有一个网站上也很好地阐述了CTC的原理:https://distill.pub/2017/ctc/

一个CTC网络有一个softmax输出层,除了序列的输出外,还增加了一个额外的输出单元,最开始激励的|L|个单元被解释成在这个时刻对应标签的观察概率,激励的额外的单元是一个空白的观察概率或者无标签的观察概率。这些输出定义为在给定输入序列的情况下,所有可能的对齐所有标记序列的方式。标记序列的概率是所有可能对齐方式的概率和。

输入序列x,长度为T,定义一个RNN,有m个输入,n个输出,权重向量w作为一个连续映射

假如序列目标为字符串(词表大小为 n),即 Nw 输出为 n 维多项概率分布。

为网络的序列输出,是单元k在时刻t的激励。解释为输出序列在第t个时间步输出为k的概率。

如:当输出的序列为(a-ab-)时,代表了在第3步输出的字母为a的概率。

这定义了一个在集合的长度为T的序列分布,L’=L+{blank}:

是所有路径的集合,π表示其中的一个路径。上式中隐含有一个假设,给定网络的内部状态,网络在不同时刻的输出是条件独立的。代表了给定输入x,输出路径为 π 的概率,由于假设在每一个时间步输出的label的概率都是相互独立的,那么 ,可以理解为每一个时间步输出路径π的相应label的概率的乘积。

下一步是定义多到一的映射β:

序列学习任务一般而言是多对多的映射关系(如语音识别中,上百帧输出可能仅对应若干音节或字符,并且每个输入和输出之间,也没有清楚的对应关系)。CTC 通过引入一个特殊的 blank 字符(用 % 表示),解决多对一映射问题。

扩展原始词表L为 L′=L∪{blank}。定义多对一映射β是可能标记的集合。

β映射可以认为是将输出路径π映射到标签序列L的一种变换。集合中定义操作:合并连续的相同字符;去掉 blank 字符。

如:(其中-代表了空格)

上面两种B都代表字符aab。

最终,β定义为一个给定序列L属于的条件概率,条件概率是所有路径的概率和。

通过引入blank 及β,可以实现变长的映射: ,也因为这个原因,CTC 只能建模输出长度小于输入长度的序列问题。

和大多数有监督学习一样,CTC 使用最大似然估计进行训练。

给定输入x,输出L的条件概率为: 

B−1(l) 表示了长度为T 且示经过B结果为L字符串的集合。代表给定输入x,输出为序列L的概率。

CTC 假设输出的概率是(相对于输入)条件独立的,因此有: 


然而,直接按上式我们没法有效计算似然值。我们可以用动态规划解决似然的计算及梯度计算, 涉及前向算法和后向算法。请看后面的前向和后向算法部分。

构造分类器:

分类器的输出应该是在给定输入序列下的最可能的标记输出:

利用HMMs算法,我们把寻找这个标记的过程记为解码,但是我们找不到一个通用并且tractable的解码算法。

下面是两个近似的算法,在实践中给出了良好的结果。

最佳路径解码(best path decoding):

基于的假设:最可能的路径会对应最可能的标签。

最佳路径解码非常容易计算,π*仅仅就是每个时间步的最可能的输出的连接。但是它不能保证找到最有可能的标记。

前缀查找解码(prefix search decoding):

这个方法据说给定足够的计算资源和时间, 能找到最优解。 但是复杂度会随着输入sequence长度的变化呈指数增长。这里推荐用有限长度的prefix search decode 来做。 但是具体考虑多长的sequence做判断还需具体问题具体分析。这里的理论基础就是每一个节点都是条件,在上一个输出的前提下算出整个序列的概率。

如上图,前缀查找解码字母X,Y,在标签alphabet(x,y)上,每个节点要么以(“e”)结束,要么在其父节点上扩展前缀。扩展节点上面的数字是所有以该前缀开头的标签的总概率。结束节点上方的数字是单个标签在其父节点结束的概率。在每一次迭代中,都将探索最可能剩余前缀的扩展。搜索结束时,一个标签(这里'XY ')比任何剩余的前缀更有可能。

一个训练的CTC网络的输出倾向于形成一系列的尖状物(spikes),尖状物被预测的blanks分隔开,我们把输出的序列分为几部分,这几个部分可能都是是以一个blank开始和结尾。我们选择边界点,这些边界点的是blank标记的观察概率超过一个给定的阈值,然后我们对每个部分计算器最可能的标记序列,然后把他们连接起来得到最终的分类。
实践中,前缀搜索在这个启发式下工作得很好,通常超过了最佳路径解码,但是在有些情况下,效果不佳,例如,当相同的标签在一个部分边界的两侧概率都很低时(if the same label is predicted weakly on both sides of a section boundary)。

详细算法过程可以看这篇文章:https://blog.csdn.net/zgcr654321/article/details/84872872

CTC网络的训练:

loss函数是从最大似然估计的规则中衍生出来的,即最小化log似然估计目标序列。给定目标函数,它的导数和网络输出有关,因此我们可以通过标准的反向传播计算权重梯度,网络可以通过任何基于梯度优化算法进行训练。

loss函数:

CTC的forward-backward算法:

前向传播:

CTC的前向传播就是要去计算每一个标记的条件概率代表给定输入x,输出为序列L的概率。)。由于一个序列L通常可以有多条路径经过映射后得到,而随着序列L长度的增加,相对应的路径的数目是成指数增加的,因此我们需要一种高效的算法来计算它。

这个问题可以用动态规划算法(dynamic programming algorithm)解决,类似于HMMs的前向后向算法,核心思想是对一个标记的所有路径求和可以被分解为一个迭代路径的求和,路径对应标记的前缀,这个迭代过程可以用递归的前向和后向变量高效的计算。

对于一个长度为r的序列q,用表示开始的p个符号,表示最后的p个符号。然后对于一个标记L,定义前向变量,表示在时刻t,的概率和。

可以递归地用αt-1(s)和αt-1(s-1)进行递归计算。

考虑到输出路径中还有空白(blanks),我们在每一对标签之间插入了空白,在开始和末尾也加入了空白,这样我们用L‘表示这个新的标记,L’的长度就为2|l|+1(比如序列L是五个字母,在每个字母前后插上一个空白,L'的长度就是11)。

在计算l’前缀的概率中,我们允许空白和非空白标签之间转移,我们允许所有的前缀要么以一个空白(b)开始,要么是l的第一个标签开始。

加入这个条件是因为这些变量对应的状态没有留下足够的时间步去完成这个序列,如下图右上角中未连接的圆圈:

这里的例子是输入数据的对应标签为CAT,每个字母前后都加了blank。

图中黑圈代表标签(labels),白圈代表空白。箭头代表允许的转移。前向变量往箭头方向进行更新,后向变量往箭头的反方向更新。

L的概率是L'所有概率的求和,并且去除了T时刻的最后的blank得到的。

假设T=3,s=4:

这里尾部元素为A,并且把除尾部以外所有的blank都去掉得到的sequence是CA,注意这里的概率是尾部不为blank的 l=CA 的概率。

假设T=3,s=5:

这里尾部元素为blank,并且把除尾部以外所有的blank都去掉得到的sequence是CA,注意这里的概率是尾部为blank的 l=CA 的概率。

反向传播: 

反向变量是t时刻的概率和。

实际上,上面的递归将会迅速导致任何电脑的下溢,因此,我们需要变换一下。用α^代替α,用β^代替β:

为了评估最大似然误差,我们需要用到自然对数。

极大似然估计的训练:

训练的目标是同时最大化训练集上所有正确分类的log概率,即优化下式:

这个就是损失函数。可以写成下面的形式:

代表给定输入x,输出序列z的概率,S为训练集。

损失函数可以解释为:给定样本x后输出正确label的概率的乘积,再取负对数就是损失函数了。取负号之后我们通过最小化损失函数,就可以使输出正确的label的概率达到最大了。

为了用梯度下降训练网络,我们需要就对损失函数进行微分,得到下式:

上式可以用前向变量与反向变量计算。

主要思想是:对于一个标记L,在给定s和t的情况下,前向和后向变量的内积(这里内积其实就是相乘)就是对应的L所有可能路径的概率。

故可得:

由于这些路径经过了时刻t的,对于任意时刻t,我们可以求得:

由于网络的输出是条件独立的,我们需要考虑在时刻t经过标记k的那些路径,得到p(L|x)的偏导数,这是对于而言的。相同的标签可能会重复几次在一个标记L中,我们定义了一个标签k出现的位置集合,记为。它可能是空的。我们然后去求微分:

当L=z时,我们可以利用前面的公式

推导出下式:

最后,对于softmax层的反向传播的梯度,我们需要目标函数对未归一化的输出求偏导:

上式就是网络训练期间的误差信号“errorsignal”,如下图:

这是训练期间对CTC误差信号的评估,左边的一列是训练不同阶段同一个序列的输出激活(虚线是blank单元),右边一列与之对应的是误差信号,误差在水平轴上的增加了与之对应的输出激活,在水平轴下面的代表减少了与之对应的输出激活。

一开始网络有少量的随机权重,误差仅由目标序列决定。随后网络开始做预测,错误开始呈现局部化。最后网络强烈的预测正确的标签,错误几乎消失了。

CTC Loss的局限性:

CTC loss在计算时假设每个label相互独立,在这样的假设下概率才可以相乘来计算条件概率。但是实际上,每个label之间的概率不是相互独立的。 比如说语言中, the bird is fly in the sky. 最后一个单词根据上下文很容易猜到是sky。 这个问题可以通过beam search , language modeling来解决。当然这个也未必是坏事, 比如希望模型能识别多个语言, 那language modelling可能就不需要了。

CTC的应用:

神经网络+CTC的结构除了可以应用到语音识别的声学模型训练上以外,也可以用到任何一个输入序列到一个输出序列的训练上(要求:输入序列的长度大于输出序列)

比如,OCR识别也可以采用RNN+CTC的模型来做,将包含文字的图片每一列的数据作为一个序列输入给RNN+CTC模型,输出是对应的汉字,因为要好多列才组成一个汉字,所以输入的序列的长度远大于输出序列的长度。而且这种实现方式的OCR识别,也不需要事先准确的检测到文字的位置,只要这个序列中包含这些文字就好了。

CTC计算举例:

假设训练集为 表示有N个训练样本,x是输入样本,z是对应的真实label。一个样本的输入是一个序列,输出的label也是一个序列,输入的序列长度大于输出的序列长度。

对于其中一个样本表示一个长度为T帧的数据,每一帧的数据是一个维度为m的向量,即每个。 xi可以理解为对于一段语音,每25ms作为一帧,其中第i帧的数据是经过MFCC计算后得到的结果。

表示这段样本语音对应的正确的音素。比如,一段发音“你好”的声音,经过MFCC计算后,得到特征x, 它的文本信息是“你好”,对应的音素信息是z=[n,i,h,a,o]z=[n,i,h,a,o](这里暂且将每个拼音的字母当做一个音素)。

特征x在经过RNN的计算之后,在经过一个softmax层,得到音素的后验概率y。表示在t时刻,发音为音素k的概率,其中音素的种类个数一共n个, k表示第k个音素,在一帧的数据上所有的音素概率加起来为1。即:

这个过程可以看做是对输入的特征数据x做了变换,其中表示RNN的变换,w表示RNN中的参数集合。

过程如下图:

以一段“你好”的语音为例,经过MFCC特征提取后产生了30帧,每帧含有12个特征,即(这里以14个音素为例,实际上音素有200个左右),矩阵里的每一列之和为1。后面的基于CTC-loss的训练就是基于后验概率y计算得到的。

路径π和B变换:

在实际训练中我们并不知道每一帧对应的音素,因此进行训练比较困难。我们可以先考虑一种简单的情况,已知每一帧的音素的标签z′, 即训练样本为x和z′,其中z′不再是简单的[n,i,h,a,o][n,i,h,a,o]标签,而是:


在我们的例子中:

z′包含了每一帧的标签。

在这种情况下有:

该值即为后验概率图中用黑线圈起来的部分相乘。我们希望相乘的值越大越好,因此,数学规划可以写为:

目标函数对于后验概率矩阵y中的每个元素的偏导数为:

也就是说,在每个时刻t(对应矩阵的一列),目标只与是相关的,在这个例子中是与被框起来的元素相关。

其中可以看做是RNN模型,如果训练数据的每一帧都标记了正确的音素,那么训练过程就很简单了,但实际上这样的标记过的数据非常稀少,而没有逐帧标记的数据很多,CTC可以做到用未逐帧标记的数据做训练。

首先定义几个符号:

表示所有音素的集合

表示一条由L中元素组成的长度为T的路径,比如z′就是一条路径,以下为几个路径的例子:

这6条路径中,π1可以被认为是“今夜无人入睡”, π2可以被认为是在说“你好”,π3可以被认为是在说“好你”,π4,π5,π6都可以认为是在说“你好”。

定义B变换,表示简单的压缩,例如:

以上面6条路径为例:

因此,如果有一条路径π有,则可以认为π是在说“你好”。即使它是如π4所示,有很多“o”的音素,而其他音素很少。路径的概率为它所经过的矩阵y上的元素相乘:

因此在没有对齐的情况下,目标函数应该为中所有元素概率之和。 即:

如在T=30,音素为[n,i,h,a,o]的情况下,共有条路径可以被压缩为[n,i,h,a,o]。路径数目的计算公式为,量级大约为。一段30秒包含50个汉字的语音,其可能的路径数目可以高达10的8次方,显然这么大的路径数目是无法直接计算的。因此CTC方法中借用了HMM中的向前向后算法来计算。

训练实施方法:

CTC的训练过程是通过调整w的值使得4中的目标值最大,计算的过程如下:

因此,只要得到,即可根据反向传播,得到,即可根据反向传播,得到。下面以“你好”为例,介绍该值的计算方法。

首先,根据前面的例子,找到所有可能被压缩为z=[n,i,h,a,o]的路径,记为。 可知所有π均有的形式,即目标函数只与后验概率矩阵y中表示n,i,h,a,o的5行相关,因此为了简便,我们将这5行提取出来,如下图所示

在每一个点上,路径只能向右或者向下转移,画出两条路径,分别用q和r表示,这两条路径都经过这个点,表示这两点路径均在第14帧的时候在发“h”音。因为在目标函数4的连加项中,有的项与无关,因此可以剔除这一部分,只留下与有关的部分,记为

这里的q和r就是与相关的两条路径。用分别表示q在之前和之后的部分,同样的,用分别表示r在之前和之后的部分.。可以发现,同样也是两条可行的路径。

、q、r这四条路径的概率之和为:

可以发现,该值可以总结为:(前置项)(后置项)。由此,对于所有的经过的路径,有:

定义:

该值可以理解为从初始到这一段里,所有正向路径的概率之和。并且发现,可以由递推得到,即:

该递推公式的含义是,只有在t=13时发音是“h”或“i”,在t=14时才有可能发音是“h”。那么在t=14时刻发音是“h”的所有正向路径概率就等于在t=13时刻,发音为“h”的正向概率加上发音为“i”的正向概率,再乘以当前音素被判断为“h”的概率。由此可知,每个都可以由两个值得到。α的递推流程如下图所示:

即每个值都由上一个时刻的一个或者两个值得到,总计算量大约为2.T.音素个数。类似的,定义, 递推公式为:

因此有:

然后:

得到此值后,就可以根据反向传播算法进行训练了。

可以看到,这里总的计算量非常小,计算α和β的计算量均大约为(2.T.音素个数),(加法乘法各一次),得到α和β之后,在计算对每个的偏导值的计算量为(3.T.音素个数),因此总计算量大约为(7.T.音素个数),这个计算量很小。因此这个算法在计算量上很有优势。

猜你喜欢

转载自blog.csdn.net/zgcr654321/article/details/84789889
CTC