摘要:精读 CRNN and CTC 论文: 《An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition》and 《Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Networks》 《Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Networks》—— CTC 核心问题:解决对齐的问题。假设现在要训练音频——文字的模型,如果有标注,即能精准分割多长时间对应一个单词那是很好的。但是一般不做到这样的标注,也就是很难对齐训练数据;或者说OCR领域,在RNN的训练里面,要将图片进行切分输入RNN,这几乎是不可能的,人为标注成本极大。 TC 是一种 不需要显式知道 “输入”和“输出”之间的“对齐”的方法。或者说, 它是可以自己使用动态规划的方法,覆盖输入和输出之间的所有可能的对齐,然后计算loss的一种方法 。 正如我们将看到的,它特别适合语音和手写识别等应用。 而CTC提出了一种算法,用于预测token序列可以看这一张图: 也就是对于每一个位置 x_i 都会预测一个字母/数字… 或者blank,也就是每一位是 |L|+1 分类的任务。连续两个相同字符会消除一个。blank会消除。最后输出对应的字符序列。 如果仅考虑语音转文字,如果考虑对齐方法,对于一段固定时长的音频一定要转化为一个文字的话,这即使可以,那么最后的结果可能是hheeeello这样,没办法知道到底连续的字符是保留还是全部合并,如果全部合并为helo就不对。 所以为此引入了一个blank空白符,算法规则就变成了,如果连续两个相同字符有blank就保留,不然就合并,并且最后去掉所有blank 。 以下是一位博主总结的流程,训练的时候是取所有的该单词的可能概率: ​ 推理时,因为不可能计算所有可能路径的所有概率,所以论文提供了两种解码方法: Best path decoding: 每次取当前时间步最大概率的那个字符,即贪心策略。 Prefix search decoding:逐步维护标签前缀。 ​ 图中: 每一个节点上方的数字,表示所有以该前缀开头的标签概率总和;例如第二行的X表示,以X开头的序列的概率,例如有XX,XY,XXX… 结束节点 ​ e ​ 上方的数字,表示在父前缀处结束的完整标签概率; 每一步优先扩展当前概率最大的前缀; 当某个完整标签的概率大于所有未完成前缀时,就可以停止。 理论上,只要给足时间,prefix search 可以找到真正概率最大的标签。但需要扩展的前缀数量最坏会随输入长度指数增长,因此作者又使用 blank 峰值把长序列切成若干段,分别搜索,再拼接结果。 动态规划(CTC的核心): 论文定义前向变量: \alpha_t(s) \overset{\mathrm{def}}{=} \sum_{\substack{\pi\\ B(\pi_{1:t})=l_{1:s}}} \prod_{t'=1}^{t}y_{\pi_{t'}}^{t'}. \tag{5} 其中 B(\pi_{1:t})=l_{1:s} 表示路径的前 t 个时间步经过 CTC 合并后,恰好得到目标字符串的前 s 个标签。 而 \prod_{t'=1}^{t}y_{\pi_{t'}}^{t'} 就是这条路径前缀的概率。因此前向变量 \alpha_t(s) 表示,到时间步 t 为止,所有能够映射为目标标签前缀 l_{1:s} 的路径前缀概率之和。它将大量不同的对齐方式聚合为一个动态规划状态。CTC 随后在原标签之间及首尾插入 blank,构造长度为 2|l|+1 的扩展标签序列 l' ,从而把合法路径求和转化为状态递推。 转移方程:每个 CTC 状态可以从原地停留、前一状态前进,或者在当前字符不是 blank 且不等于前一个字符时,从前两个状态跨过 blank 直接进入。 \boxed{ \text{来源}= \{s,\ s-1\} + \begin{cases} \{s-2\},&l'_s\neq b\ \text{且}\ l'_s\neq l'_{s-2}\\ \varnothing,&\text{其他情况} \end{cases} } 公式8: p(l∣x) =最终停在末字符的路径总概率+最终停在末尾 blank 的路径总概率 论文随后提到,一些 \alpha_t(s) 必然为 0。例如时间已经很晚,但状态仍然过于靠前,剩余时间步不足以走完整个标签序列。这只是为了减少不可能状态的计算,不会改变递推逻辑。 随后定义反向变量: β_t(s) 是从时间 t 的状态 s 出发,合法完成剩余目标序列的所有后缀路径概率之和,并且包含当前时间 t 的输出概率。 所以: \boxed{ \alpha_t(s)=\text{到达该节点的全部概率} } \boxed{ \beta_t(s)=\text{从该节点完成任务的全部概率} } \boxed{ \frac{\alpha_t(s)\beta_t(s)}{y_{l'_s}^t} = \text{所有在时间 }t\text{ 经过该节点的完整正确路径概率} } 由于长序列中大量概率连乘会导致数值下溢,原论文在每个时间步对前向和后向变量进行缩放,并保存缩放因子;标签的对数概率可以由这些缩放因子的对数之和得到。现代实现通常直接在 log-space 中使用 log-sum-exp 完成等价计算。 公式12定义了CTC loss,总的来说 CTC loss 不要求网络选择某一条固定对齐路径,而是要求所有能够输出正确字符串的合法路径总概率尽可能大。 后面13-16公式是在处理如何处理梯度。利用前向变量和后向变量,计算所有正确路径在每个时间步、每个类别上的后验占用概率。CTC 对 softmax 前 logit 的梯度可以概括为: \frac{\partial\mathcal L_{\mathrm{CTC}}}{\partial u_k^t} = y_k^t-\gamma_t(k), 其中 y_k^t 是模型预测概率, \gamma_t(k)=P(\pi_t=k\mid x,z) 是在正确标签条件下,由所有合法对齐路径得到的软目标概率。它与普通交叉熵的“预测概率减真实目标”形式一致,只是 CTC 的目标不是人工提供的逐时间步 one-hot 标签,而是动态规划计算出的软对齐后验。 《An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition》—— CRNN 问题:研究场景文本识别问题,将其转化为了图像的序列识别问题而不是分类问题。分类问题可能会导致泛化性的降低。 以前的OCR,要么字符检测 + 分类,但是这种需要字符级的标注。或者用RNN的方法,但是需要人为把图片转化为序列(这里的序列是有两种的,一种标签序列是已经提供;另一种是视觉特征序列,以前会通过人工的方式设计生成一系列的特征,输送给RNN)。 贡献: CNN+RNN+CTC,端到端的训练。CNN负责看图片,学习图像的细节。RNN负责序列,大概是语义类的东西。输入给CTC是概率的东西。 不需要字符切割的标注。 支持任意长度,泛化性强。 不依赖词典(运用词典的是分类模型)。 方法 大致的流程是:input image → CNN layers 会从每个 input image 中提取 feature sequence。-> RNN 对 feature sequence 的每个 frame 进行预测 → transcription layer 把 per-frame predictions by the 循环层 into a label sequence. Feature Sequence Extraction CNN 的 convolutional and max-pooling layers 被保留,fully-connected layers 被移除。 feature vectors 会从 feature maps 中按 列 提取,因为文字一般都是横向排列(就算不是一般也会转化成这样)。这样一些 feature vectors 就代表了一个字母。 RNN: 多层双向 LSTM。字符大概率是前后有一定的关系的,所以使用了双向。 ​ Transcription: CRNN 采用 CTC 定义的条件概率。它要计算的是,在已经得到逐位置预测 y=y_1,\ldots,y_T 的情况下,最终标签序列 l 出现的概率。例如可能对某一个位置 t ,有 y_t = [p(a) = 0.1,p(b)=0.05,\cdots,p(\text {blank}=0.1)] 。所以 y=y_1,\ldots,y_T 表示宽度方向一共存在 T 个时间步,并且每个时间步都预测一次字符分布。 假设正常字符集合是: \mathcal L=\{a,b,\ldots,z,0,\ldots,9\}. CTC 在此基础上增加一个 blank 符号: \mathcal L'=\mathcal L\cup\{\text{blank}\}. blank 可以理解为这个位置暂时没有输出字符,或者用于分隔两个相同字符。 随后论文定义了一条路径: \pi=(\pi_1,\pi_2,\ldots,\pi_T),\qquad \pi_t\in\mathcal L'. 路径 \pi 的长度必须和网络输出长度 T 相同。比如网络共有 12 个时间步,那么一条路径可能是: \pi= (-,-,h,h,-,e,-,l,-,l,o,o), 其中 - 表示 blank。函数 B 负责把这种长度为 T 的路径变成最终字符串。论文规定先合并连续重复符号,再删除 blank。这里要特别注意,同一个字符连续出现会被合并,所以要识别两个连续的 l ,路径中间必须存在 blank 或其他符号。(同 CTC 论文) 接下来是路径概率: p(\pi\mid y)=\prod_{t=1}^{T}y_{\pi_t}^{t}. 其中 y_{\pi_t}^{t} 表示第 t 个时间步预测符号 \pi_t 的概率。 假设某条路径是: \pi=(h,-,e), 三个位置对应的概率分别是: P_1(h)=0.8,\qquad P_2(-)=0.7,\qquad P_3(e)=0.9. 那么这条路径的概率是: p(\pi\mid y)=0.8\times0.7\times0.9=0.504. 这条公式隐含了 CTC 的一个重要假设,也就是在给定网络输出后,各时间步的标签概率按照乘积计算。最终标签序列的概率不能只看其中一条路径,而要把所有能映射为的路径概率加起来,因为可能会有很多路径对应某一个标签 l 。这就是论文公式 1 的含义。但是直接枚举会特别慢,这里就要用到 CTC 里面的动态规划了。 p(l\mid y) = \sum_{\pi:B(\pi)=l}p(\pi\mid y). Lexicon-free transcription: 这一节说的是 没有词典限制时,推理阶段怎样输出字符串 。 理论上,我们希望找到概率最高的最终标签序列: l^=\arg\max_l p(l\mid y). 也就是说,在所有可能字符串中寻找总概率最大的一个。 但这里仍然很难计算,因为每个字符串又对应很多路径。精确搜索全部字符串和全部路径在计算上不可行,所以论文采用了一种近似方法: l^ \approx B\left( \arg\max_\pi p(\pi\mid y) \right). 这句话可以拆成两步理解。 第一步是在每个时间步独立选择概率最大的符号。比如网络输出是: \begin{array}{c|ccc} t & \text{最大概率符号} & \text{概率}\\ \hline 1 & - & 0.8\\ 2 & h & 0.9\\ 3 & h & 0.7\\ 4 & - & 0.6\\ 5 & e & 0.8 \end{array} 那么最可能路径就是: \pi^=(-,h,h,-,e). 第二步使用映射 B ,先合并连续重复,再删除 blank: (-,h,h,-,e) \rightarrow (-,h,-,e) \rightarrow he. 这就是常说的 CTC greedy decoding 或 best-path decoding。 这里要注意,概率最高的单条路径经过 B 得到的结果,不一定严格等于总概率最高的标签序列。因为一个标签序列可能对应很多条中等概率路径,把它们加起来以后,可能超过另一条单独概率最高的路径。 也就是说: B\left(\arg\max_\pi p(\pi\mid y)\right) 不一定等于: \arg\max_l\sum_{\pi:B(\pi)=l}p(\pi\mid y). 论文也因此使用了约等号。只是 best-path decoding 非常简单、速度快,而且实践中通常效果不错,所以 CRNN 在 lexicon-free 模式下使用它。 Lexicon-based transcription 在词典模式下,每个测试样本都有一个对应的词典 \mathcal D 。最终结果只能从这个词典中选择,模型要找的是词典中 CTC 条件概率最高的单词: l^=\arg\max_{l\in\mathcal D}p(l\mid y). 这里 y 是 CRNN 对整张文字图像产生的逐时间步字符概率, l 是词典中的某个候选字符串。假设图像中写的是 hello ,词典中有: \{\text{hello},\text{help},\text{hero},\


  • 情报分类:综合情报
  • 分类依据:内容未命中明确的垂直分类规则,归入综合情报
  • 信息来源:服务器 / LINUX DO - 最新话题
  • 发布时间:2026/9/30 18:57:58