CTC 算法详解之训练篇

本来想把关于CTC的所有东西都写在一篇文章,但后面发现内容太多,遂拆分成如下几个部分:
CTC算法详解之训练篇
CTC算法详解之测试篇
CTC算法详解之总结展望篇(待更)

引言

在日常生活中,许多数据是序列化的,比如语音、文字和图像文本等。在处理序列任务时,一个经典的思路是“分而治之”,把输入序列拆分成最小语义单元,然后将序列任务转换成对单元的分类任务。然而在实际应用中,把序列中的单元精准地分开是很难的,人工标注的代价也很大,可不可以直接对序列数据进行“端到端”地预测呢?CTC(Connectionist Temporal Classification)则是解决了这样一个问题。CTC算法可以让以端到端地方式对序列数据进行学习,在语音识别、图像文字识别等领域取得了很好的应用效果。

图1 基于字符分割的文字识别 vs CTC文字识别

本文先对CTC用于序列任务的流程做了大致介绍,并定义了相关的符号。然后再训练一节中介绍了如何通过前后向算法计算CTC的损失函数。yudonglee的博客[2]给了我很多帮助,训练一节中的很多图也是采用他的。我在写的过程中也是在不断学习,有错误和不到位的地方希望大家指出。

任务定义

CTC用于序列任务,流程大致如下:神经网络把输入序列转换成序列在字典上的概率分布,从这个分布中我们可以得到若干条路径,每个路径都可以转换成输出序列,我们的任务就是找到输出概率最大的序列。具体的符号定义如下:

输入序列x长度为T,用{{N}_{w}}表示神经网络,用于提取序列特征,网络的输出为y={{N}_{w}}(x),长度也为T,用y_{k}^{t} 表示输出单元的激活概率,即序列在t时刻被分类成k的概率,k定义在类别集合{{L}^{'}}=L\cup \{blank\}上,L为任务字典符号集,比如在文字识别任务中可以定义成中英文字符,blank为CTC的 保留符号,用于分隔标签中的不同符号单元。CTC是一种过分割的序列解码算法,比如标签中的一个字符a可能在译码路径中被切分成多个连续的a,而标签中也可能存在连续但应该被区分的字符,比如apple中出现了两个p,那这时候译码路径要在这两个不同的p之间插入至少一个blank。由网络的输出y可以计算任意译码路径\pi的概率p(\pi \text{ }\!\!|\!\!\text{ }x)=\prod\limits_{t=1}^{T}{y_{{{\pi }_{t}}}^{t}},\ \ \forall \pi \in {{L}^{'}}^{T}\pi与输入x等长,我们最终是要得到标签ll的长度小于\pi的长度,所以还要定义一个映射B:{{L}^{'}}^{T}\to {{L}^{\le T}}来将译码路径\pi转换为标签l。映射规则为:移除所有空白符号合并所有的重复连续符号,比如B(a-ab-)=B(-aa--abb)=aab。可以看到,这个映射是多对一映射(many-to-one),也就是说正确的标签l可以来自许多不同的路径(不管是黑猫还是白猫,只要能捉到耗子就是好猫),后面我们会重点研究many-to-one所带来的计算速度和可微问题,尤其是在训练阶段。整个序列识别的流程可以参见下图:

图2 序列识别流程

训练

为了使整个网络可用梯度下降优化,训练过程中必须算出可导的CTC损失函数,CTC也采用了常规的分类任务的最大似然误差(maximum likelihood error):\ln (p(l|x))。因为B是many-to-one映射的缘故,p(l|x)=\sum\limits_{\pi \in {{B}^{-1}}(l)}{p(\pi |x)},计算Loss要穷举所有可行路径,然而穷举所有的路径是非常困难的,因为其空间复杂度为O\{{{N}^{T}}\}(N为字典大小,T为路径长度),所以[1]借鉴了HMM中的前后向算法(Forward-Backward Algorithm,FBA),这是一种动态规划算法,下面我们来说一下算法思路。

{{N}^{T}}种路径中,只有很少的一部分路径是有效的,我们只需要考虑这一小部分路径就行了。当我们把所有可行路路径列出来,会发现,如果按时间展开译码过程,我们可以以递推的方式计算出某个节点的前向(时间增大的方向)或后向(时间减小的方向)路径概率总和。这也是算法名称的由来。我们会先用一个”apple”的例子来直观解释FBA算法的递推关系,最后给出计算式。

给定一个标签l,长度为T,为了找出所有满足l=B(\pi )的路径\pi,我们要构建一个拓展标签{{l}^{'}},它是在原始标签的首尾和每个字符中间加上空格符号得到的,长度为2T+1,比如当l=apple{{l}^{'}}=-a-p-p-l-e-。我们接下来的搜索过程都在由{{l}^{'}}展开的搜索栅格上进行。

图3 搜索栅格
图4 路径--ap-ple

然而并不是在图3上的任意一条路径都是合法的,合法的路径要满足如下几点条件:
(1)转换只能向右或右下(纵轴上单调非减)
(2)相同的字符间至少有一个空格,否则标签中的连续相同字符会被错误地合并;
(3)除{blank}符号外不能跳过;
(4)路径起点必须从前两个符号开始,即l_{1}^{'}l_{2}^{'}
(5)路径必须在最后两个符号结束。

最终所有可能的路径如下:

图5 所有能被译码成apple的可行路线

读者可以自行验证,在由{{l}^{'}}构成的搜索栅格上,遵守上述5条规则可以得到所有的正确的路径。我们并不需要穷举所有的{{11}^{8}}种路径就能计算出想要的结果,这就是动态规划的核心思想:提前剔除掉不可能的结果,在更小的搜索空间上进行计算

如何计算图5路径的概率总和呢?我们首先定义{{a}_{t}}(s)为t时刻取值为s的全部前缀路径概率总和:a_{t}(s)\overset{def}=\sum_{\pi\in N^{t}:B(\pi_{1:t})=l_{1:s}}\prod_{{t}'=1}^{t}y_{\pi_{{t}'}}^{{t}'}
累乘符号表示同一路径上的不同节点概率相乘,累加符号表示不同路径的概率相加。比如(t2,a)这个点的左边和左上角各有一条前向路径,{{a}_{l_{2}^{'}}}(2)即为这两条路径的概率之和。

图6 前向概率的三种情况,分布用红圈,篮圈,黑圈表示

{{a}_{t}}(s)可以用递推方式求得,我们分三种情况讨论,在t时刻:

(1)s取值为blank时,{{a}_{t}}(s)=({{a}_{t-1}}(s)+{{a}_{t-1}}(s-1))y_{l_{s}^{'}}^{t},参见图6的红圈节点,有效的前向路径可来自左边或左上,左侧没有有效路径意味着{{a}_{t-1}}(s)=0

(2)s取值和s-2取值一样时,{{a}_{t}}(s)=({{a}_{t-1}}(s)+{{a}_{t-1}}(s-1))y_{l_{s}^{'}}^{t},参见图6的蓝圈节点。

(3)其余情况下,{{a}_{t}}(s)=({{a}_{t-1}}(s)+{{a}_{t-1}}(s-1)+{{a}_{t-1}}(s-2))y_{l_{s}^{'}}^{t},参见图6的黑色圈。

所有情况可汇总如下:

a_{t}(s)=\left\{\begin{matrix} [a_{t-1}(s)+a_{t-1}(s-1)]y_{{{l_s}'}}^t \qquad \mbox{if} \;{l_{s}}'=b \; \mbox{or} \; {l_{s-2}}'={l_{s}}' \\ [a_{t-1}(s)+a_{t-1}(s-1)+a_{t-1}(s-2)]y_{{{l_s}'}}^t \qquad \mbox{otherwise} \end{matrix}\right.

初态:

a_{t}(s)=\left\{\begin{matrix} a_1(1)=y_b^1 \\ a_1(2)=y_{l_1}^1 \\ a_1(s)=0, \; \forall s>2 \end{matrix}\right.

最终的CTC损失函数为:-\ln (p(l|x))=-[\ln ({{a}_{T}}(2T+1)+{{a}_{T}}(2T))]。因为整个计算过程涉及到的运算都是可微的,所以可以用链式求导计算导数,进行反向传播。类似的,也可以用反向路径概率和{{b}_{t}}(s)来表示损失函数,读者可在[1]或[2]中找到相应内容。

参考资料
[1] Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Networks
[2] CTC Algorithm Explained Part 1:Training the Network(CTC算法详解之训练篇)
[3] Facebook大规模文本检测与识别系统Rosetta
[4] CTC Networks and Language Models: Prefix Beam Search Explained

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352