文本识别CTC算法

目录

CTC解决的问题

从网络输出到标签

构造目标函数

前向传播

反向传播

预测过程


CTC解决的问题


CTC Loss要解决的问题就是当label长度小于模型输出长度时,如何做损失函数。
一般做分类时,已有的softmax loss都是模型输出长度和label长度相同且严格对齐,而语音识别或者手写体识别中,无法预知一句话或者一张图应该输出多长的文字,这时做法有两种:seq2seq+attention机制,不限制输出长度,在最后加一个结束符号,让模型自动和gt label对齐;另一种是给定一个模型输出的最大长度,但是这些输出并没有对齐的label怎么办呢,这时就需要CTC loss了。

在这里插入图片描述

所以,如果要计算某个输出概率,可以累加其对应的全部输出序列o (也即映射到最终label的“路径”)的概率即可,如下图。 

在这里插入图片描述

从网络输出到标签


由于我们没有每个时刻输出对应的label,因此CTC使用最大似然进行训练(CTC 假设输出的概率是(相对于输入)条件独立的)
给定输入x,输出序列 \pi 的条件概率是:

\pi_{t}是序列 \pi 中的一个元素 ;

y为模型在所有时刻输出各个字符的概率,shape为C*T(T是时刻,提前已固定。C是字符类别数,所有字符+blank(不是空格,是空) ;

y_{\pi_{t}}^{t} 是模型t时刻输出为\pi_{t}的概率;

{L}'^{T}是一个长度为T的输出序列;

论文中说,把{L}'^{T}中的元素称之为paths,并用 \pi 表示。这个公式就是定义了在输入为x的时候,输出为某个路径 \pi 的概率,这个概率的算法,就是把对应的每个时刻的网络输出的对应元素的概率乘起来。论文里说,公式假设了不同时刻网络的输出概率是条件独立的,并且这一点通过给定的网络的输出层与网络不存在反馈连接来保证,原文是:This is ensured by requiring that no feedback connections exist from the output layer to itself or the network。疑惑的是RNN的输出在时间上是存在依赖性的,这里说不同时刻是独立的,总觉得哪里不太对。我的理解是,当RNN的输出确定之后,这时候对于CTC网络来说,每个时刻的输出是独立的,这样似乎可以解释得通。

从网络的输出映射为一个唯一的label的方法,其实就是把输出串的blank删掉,并且相邻的重复字符合并起来就好了。

B:{L}'^{T}\rightarrow L^{\leq T} :这个就是上面说的映射函数,方法就向上面说的那样。{L}^{\leq T}表示可能输出的序列集合,集合元素的长度小于或等于T。

如:B(a−ab−)=B(−aa−−abb)=aab

这个公式定义了在输入为 x 的时候,输出一个给定label的值 l 的概率,计算方法就是把所有可以用 B 函数映射为ll的路径的概率相加。 

构造目标函数

 最终的目标就是最大化标签

 然而没有一个好的解法的,因为要枚举所有的可能的 l 的话,时间复杂度就爆炸了。所以论文中给出了两个求近似的解法。

前向传播

两个求近似的解法。
best path decoding求解
其实就是把每个时刻的最大概率值输出,每个时刻连接在一起作为最终的输出。这种方式计算简单,但不保证能找到最大概率的label。用这个输出序列来求出最后的label:

prefix search decoding求解:

其实我们可以遍历算出所有输出序列,相同标签label的再相加,然后找出最大概率的label,但是很耗时,有指数级别的路径可能性。为了降低时间复杂度,CTC算法处理时采用了动态规划方法。算法的主要思想是,在筛选可能的paths时,只选取前缀与label对应前缀是相同的那些paths。

\alpha _{t}(s): 称为前向变量(forward variable)。表示 前缀末端 在 t 时刻到达序列的第 s 个位置的所有可能子路径的概率和。

第一种情况:

(注意对于特殊情况,s=2,t=2其实只有一条路径到达该位置,因为t=1时序列为"a-"这种情况是不存在的,只有为"a"这一种情况,但不影响通用表达式,因为此时\alpha _{t-1}(s)的概率为0)

第二种情况:

第三种情况:

 最后结果:

 于是有论文里的公式:

反向传播

定义βt(s)为 后缀起始于序列末端, t 时刻到达第 s 个符号的所有可能子路径的概率和。

 则有

l_{s}^{'}表示t时刻path经过的节点。

l^{'}表示插入空格的序列,其长度是2*len(label)+1。

y_{k}^t求偏导有:

 过程如下:对于

 若t时刻过k,则t时刻时不可能经过其他字符的。也就是,在求偏导时,如下图只有红色部分是包含y_{k}^t的,其他项可以看做常数项。 \alpha _{t}(s)和 \beta _{t}(s) 是和 y_{k}^t 相关的。 

设 \alpha _{t}(s) = m * y_{k}^t\beta _{t}(s) = n * y_{k}^t.  则有\alpha _{t}(s)\beta _{t}(s) = m*n*{y_{k}^{t}}^2

 

  

CTC Loss函数相对于RNN输出层元素的求导过程如下图所示:

CTC代码示例http://blog.prince2015.club/2020/03/30/ctc/http://blog.prince2015.club/2020/03/30/ctc/

预测过程

前面提到,在预测阶段,给定一个输入 x ,计算最大概率对应的输出序列。如果假设时间片之间相互独立,那么只需将每一时间片对应概率最大的字符作为预测值,然后组成序列,最后做去重等处理得到最终结果。不过这样并没有考虑多个序列经过对齐对应同一个输出结果。例如,假如  [c,c,\epsilon ]和 [公式] 各自的概率都低于 [公式] ,而二者的概率之和高于后者。前者对齐后的结果均为 [公式] ,而后者对齐的结果仍为 [公式] ,显然输出 [公式] 比 [公式] 更合理些。所以为了避免这一问题的发生,又引入了另一种算法,称为Beam Search。

里面有个参数 B ,用来指定每次保留的前缀序列的个数。假如设置 B = 3 ,则每次选取概率最大的3个前缀序列,比如 [公式] 时选取概率最大的3个字符, [公式] 时也选取概率最大的3个字符,这样便有9种组合方式。当然对齐之后可能会对应相同的输出,所以要将结果相同的前缀序列进行合并(概率也要相加),然后挑出概率最大的3个作为下一次的输出,以此类推。以序列 [公式] 为例,具体过程如下图所示。

这里要注意的是,当前缀序列的末尾字符与下一个字符相同时,合并可以产生两种有效输出。

比如上图中 t = 3 时前缀序列为 a , 而合并的字符同样为 [公式] ,这样既可以输出 [公式] ,也可以输出 [公式] ,二者都是可能的。因为在 [公式] 时,其中一个结果占位符 [公式] 在对齐时被移除了,但是在这里后面又遇到了相同的字符,按照前面定义的规则,此时合并的结果应该为 [公式] 。 [公式] 的两种计算情况如下图所示。

所以,这两种结果应作为两种序列分别进行概率计算。当然,为了能够计算这两种情况对应的概率,需要分别记录以 \epsilon 结尾的前缀序列的概率,以及不以 \epsilon 结尾的前缀序列的概率。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AICVer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值