当前位置: 首页 > news >正文

内涵:文本识别论文CRNN

目录

  • 1. 解读文本识别论文CRNN
    • 1.1 CRNN文字识别整体流程
    • 1.2 理解CTC Loss
      • 1.2.1 CTC loss是如何做的
      • 1.2.2 以一个具体的例子来展现CTC loss的过程
  • 2. 总结
  • 3. 参考资料
  • 4. 其他好的相关博客推荐

1. 解读文本识别论文CRNN

本文解读的是一篇来自2015年的一篇文字识别论文[ 1 ] ^{[1]}[1]。里面的CTC Loss相关内容的理解有一定的挑战性,本文是对自己当前理解的一份记录。

1.1 CRNN文字识别整体流程

首先,先看一下CRNN的前向推理过程,来了解其文字识别的整体流程,如下图所示。

action1: 一张10 ∗ 40 ∗ 3 10*40*310403的文字图片块,经过CNN层特征提取,下采样为1 ∗ 10 ∗ 512 1*10*512110512的特征图。高度压缩为1,宽度下采样4倍,每一个特征是维度为512。
action2: 通过深度双向LSTM网络将10 ∗ 512 10*51210512的Feature sequence做了一个特征的进一步转换和提取变为一个10 ∗ ( 26 + 1 ) 10*(26+1)10(26+1)的预测分布概率矩阵。这里使用双向LSTM是期待特征序列做更加充分的贯通,例如在预测“state”
中“a”的时候既采纳了“st”的信息又采纳了"te"的信息。
action3: 通过转录层操作,根据分布概率矩阵可以获得最终的预测结果。例如a r g m a x ( y , d i m = 1 ) argmax(y, dim=1)argmax(y,dim=1),可以得到预测值的初始形态:

-s-t-aatte

然后合并成为最终的预测结果: state。合并的基本规则是:

  1. 属于占位符所割出来的同一个block中,如果有紧邻的相同元素进行合并。
  2. 消除占位符。

前向推理过程比较明晰,然而,训练过程会遇到如下疑惑,如果按照上述例子,我们会把这一个序列作为预测概率矩阵y yy的GT。然后就相当于并行做10个(26+1)类的分类任务学习。

-s-t-aatte

这样的问题在于:
抛出问题1: 对于同一张图片可以有不同的GT方案。
例如,下列序列作为“state”对应的的分布概率矩阵GT,也是不违背任何逻辑的。事实上,这种不违背逻辑的方案还有很多。

--st-aatte

尝试解决问题1:尝试列举出所有可能的方案, 在训练的过程中随机给出一个gt。
这样做理论上是可行的。但是会有一个时间复杂度问题。采用暴力求解的方法罗列出所有可能是( 26 + 1 ) 10 (26+1)^{10}26+110。即使模型的最大预测字符串长度为10,仅为26个字母这种简易场景,这种级别的时间复杂度是不可以接受的。
但不管怎样,至此,上述整个过程是一种理论上完备的训练、推理流程,只不过训练速度会很慢(或者说慢到不可接受)。

1.2 理解CTC Loss

1.2.1 CTC loss是如何做的

CTC Loss 或者说CTC 算法是来源于HMM(隐马尔可夫),用一句话总结:就是通过“动态规划”算法来替代“暴力求解”来解决所有方案的概率和。并将问题的loss定义为一个最大似然问题:使得学到尽可能的网络参数使得p ( l x ) p(\frac{l}{x})p(xl)最大,论文中将loss定义为− l o g ( p ( l x ) ) -log(p(\frac{l}{x}))log(p(xl))。CTC的过程可以总结为以下四步骤:

  1. p ( l x ) = ∑ s = 1 s = 2 ∣ l ∣ + 1 α t ( s ) ∗ β t ( s ) y t ( s ) p(\frac{l}{x}) = \sum_{s=1}^{s=2|l|+1} \frac{\alpha_t(s)*\beta_t(s)}{y_{t}(s)}p(xl)=s=1s=2∣l+1yt(s)αt(s)βt(s)
  2. y yy概率矩阵—>计算α 矩阵 \alpha矩阵α矩阵,β \betaβ矩阵—>计算 p ( l x ) 计算p(\frac{l}{x})计算p(xl)
  3. α \alphaα矩阵的计算是通过动态规划算法由y yy来计算的。
  4. β \betaβ矩阵的计算是通过动态规划由y yy来计算的。

1.2.2 以一个具体的例子来展现CTC loss的过程

以下例子来自于torch官网。为了便于描述,将参数的规模进行了缩小。

>>>importtorch>>>importtorch.nnasnn>>># Target are to be padded>>>T=5# torch 官网为50 # Input sequence length>>>C=7# torch 官网为20 # Number of classes (including blank, 0 class)>>>N=1# torch 官网为16 # Batch size>>>S=3# 30 # Target sequence length of longest target in batch (padding length)>>>S_min=2# 10 # Minimum target length, for demonstration purposes>>>>>># Initialize random batch of input vectors, for *size = (T,N,C)>>>input=torch.randn(T,N,C).log_softmax(2).detach().requires_grad_()>>>>>># Initialize random batch of targets (0 = blank, 1:C = classes)>>>target=torch.randint(low=1,high=C,size=(N,S),dtype=torch.long)>>>>>>input_lengths=torch.full(size=(N,),fill_value=T,dtype=torch.long)>>>target_lengths=torch.randint(low=S_min,high=S,size=(N,),dtype=torch.long)>>>ctc_loss=nn.CTCLoss()>>>loss=ctc_loss(input,target,input_lengths,target_lengths)>>>loss.backward()

其中,input表示的是预测概率的l o g loglog矩阵:

预测概率矩阵y = e i n p u t y=e^{input}y=einput,如下所示:

举一个简单的例子target为f e fefe: 根据1.2.1节中步骤3可以根据y yy矩阵动态递归算得α s ( t ) α_s(t)αs(t)矩阵:

根据1.2.2节,步骤4可以根据y yy矩阵动态递归算得β s ( t ) β_s(t)βs(t)矩阵:

根据1.2.1节中步骤1可以根据α矩阵和β矩阵计算得到两者的联合概率:

l o s s = − l o g ( 0.001247115 / 3 ) = 3.38 loss = -log(0.001247115/3)=3.38loss=log(0.001247115/3)=3.38, 与pytorch的输出一致。

2. 总结

本文主要以CTC是如何做的角度来写,并通过pytorch和自己手算结果的对比来验证自己理解的正确性。后续如果有新的理解,应该会补充上一些更多的细节。

3. 参考资料

[1] 原始论文:An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition
[2]Pytorch ctc demo example
[3]公式

4. 其他好的相关博客推荐

[1] breaking-down-ctc-loss

http://www.jsqmd.com/news/619055/

相关文章:

  • 保姆级避坑指南:在Ubuntu 20.04 + ROS Noetic下,用PX4和Gazebo给Livox Mid360雷达跑通Faster-LIO建图仿真
  • translategemma-27b-it效果展示:中文合同关键条款图→英文法律术语精准映射
  • GenomicSEM实战指南:从GWAS摘要数据到复杂遗传模型的完整解析
  • OpenClaw语音交互:Qwen3-14B实现本地语音指令识别
  • 如何一键智能优化浏览器字体渲染:告别模糊文字,享受Mac级阅读体验
  • AI原生研发不是“加AI”,而是重写研发契约(附百度文心、讯飞星火、通义千问团队签署的《AI-Native开发宪章》核心条款)
  • Redis持久化:从AOF到RDB,如何实现数据不丢失?偬
  • .NET 诊断技巧 | 日志框架原理、手写日志框架学习赡
  • STM32H7实战指南:Cache配置与性能调优
  • 如何快速获取百度网盘提取码:开源工具的终极实战指南
  • 如何通过Win11Debloat实现Windows 11终极优化:完整指南与实战技巧
  • 测试左移×AI原生×实时反馈:2026奇点大会验证的“零缺陷交付”新公式——含GitHub Star超1.2k的开源工具链实测对比
  • Allegro 23.1 快速放置报错?手把手教你用DB Doctor批量更新旧版封装(附脚本)
  • coze
  • 在超大数据集下 DuckDB 与 MySQL 查询速度对比匝
  • MongoDB(90)如何使用Mongoose进行ORM操作?
  • Linux部署DVWA实战:从Access Denied到数据库用户权限全解析
  • Java面试题47:一文深入了解Nginx
  • Python Scrcpy Client实战解析:构建高效的Android设备远程控制方案
  • ROS话题订阅模型实战:从零搭建一个简单的发布-订阅系统(附完整代码)
  • 【AI原生研发债务治理白皮书】:20年架构师亲授3类隐性技术债识别法+4步自动化清偿路径
  • MOOTDX:Python量化投资的完整通达信数据解决方案指南
  • OneTime Secret开发者入门指南:项目结构与代码贡献流程
  • 家庭媒体中心:OpenClaw+Gemma-3-12b-it自动整理影视库与生成字幕
  • WebPShop:Photoshop WebP插件终极指南 - 如何完美处理现代图像格式
  • 终极Windows 11瘦身指南:如何用Win11Debloat让你的电脑飞起来
  • KMS_VL_ALL_AIO:3分钟彻底解决Windows与Office激活难题的智能方案
  • 激活函数调参指南:如何根据你的任务选择ReLU、GELU或其他变体(附性能测试数据)
  • Win7 64 位 + MinGW64 + CMake + OpenCV 之二
  • DRM框架深度解析:从fbdev到atomic commit的显存绑定全流程