![981d55dd32277295761966df9242e1ce.png](https://i-blog.csdnimg.cn/blog_migrate/8c71543d5d934296d57f0402d4f9f9bd.jpeg)
文本识别就是将一张精确裁剪的只包含文本的图像作为输入,通过模型识别出对应的计算机可处理的文本内容。
传统的文本识别方法需要将每一个字符单独切割出来进行多分类。 对于文字的标注和对齐是很困难的,毕竟要花费大量的时间精力,并且即使同一个文字的宽度也不总是一样大。
而使用神经网络模型,可以帮助我们提取非常好的特征。
使用CTC操作,我们只关心哪些文字在图中出现了,而不必关心文字具体的位置和宽度,CTC损失会引导NN模型进行训练,那么,CTC是如何实现的呢?
文本如何编码
为了了解CTC的编码方式,得先看看CTC是如何解码的。 对于一串字符,比如“bbbbbeeeeeeee”,CTC会将重复的字符移除掉,所以这一串字符解码出来就是"be"。
不知你发现没有,这会导致一个问题,如果目标文本是bee呢? 被解码成be就不对了啊。
为了解决这个问题,CTC引入了一个特别的字符,为了方便就用“-”表示(但它不是真的"-"符号,在源码中编码为0),有了这个字符就可以很好的分隔文本 中的重复字符了,
比如要编码"be",可以是“bbbbee”或"---bb-e"或“b-e”等,
那"bee"就可以表示为“---bbee-ee--”或"b-e-eee"或"bee---ee"等 相信你已经知道其中的意思了。
损失如何计算
神经网络模型的输出是一个序列,比如使用一个矩阵(24, 37)来表示,其中24是序列长度或时间步长,37表示字符个数(比如10个数字26个小写字母加上一个特殊字符)。
以一个略缩版的矩阵为例,其中时间步为2,字符数为3(包括特殊字符),如图所示:
![a955798dd5fa74d6587194704daa6178.png](https://i-blog.csdnimg.cn/blog_migrate/588749c5e7769305d0fee092bf21c27d.png)
- 在每个时间步每个字符的概率之和为1(softmax),即矩阵axis为列的和为1
- 每一种走向(或者路径)的得分通过将相应字符的概率相乘得到,比如aa的得分为0.4x0.4=0.16,a-为0.24,以此类推
- 损失通过对应于标签文本的所有可能路径得分之和计算得到。在这个例子中,如果标签为a,对应a的所有可能路径为aa,a-,-a,将这三条路径的得分相加为0.64
- 如果该例的标签为空格(使用-表示)呢?对应的路径只有一条,即--,所以得分为0.6x0.6=0.36
- 以上计算的是概率值,而不是损失。损失可以通过概率的负对数计算得到(以2为底数,在[0,1]区间递减且非负,即得分越大,损失越小)
Q:如果标签是b呢?得分是多少?????
计算出了损失,NN模型就能不断进行优化,输出一个更好的序列表示矩阵
如何根据模型输出矩阵进行解码
通过上面损失的计算,模型的训练,能够找到一个很好的矩阵来表示输入的图像,我们最终的目的是能够通过这个矩阵得到图像对应的文本,也就是解码。
最简单直接的方法就是最佳路径解码:
1. 获取每一个时间步最大得分对应的字符作为该时间步的预测结果
2. 将所有时间步得到的输出组合成为一串字符,首先移除掉所有重复字符,然后移除特殊分隔字符,与编码阶段的操作正好相反。剩下的字符就是最终识别结果。
这种方法只能得到近似结果,比如上一个例子,假设那个矩阵是模型的输出,以最佳路径解码出来是“--”,也就是空,其概率为0.36,而实际上应该是"a",因为"a"的概率为0.64
还有其他更佳的解码方法,比如束搜索,后面在深入介绍下。
pytorch中的 CTC LOSS 如何使用
假设CNN+RNN模型的输入图像大小为32x100,输出概率矩阵的大小为24x37(如上所述,24为时间步长,37为字符类别个数),忽略掉batch size。
在最后一维需要执行softmax变成0~1之间的概率值。
criterion = torch.nn.CTCLoss(zero_infinity=True)
loss = criterion(preds, text, preds_size, length)
CTCLoss的zero_infinity代表是否将无限大的损失和梯度归零,无限损失主要发生在输入太短而无法与目标对齐时。
其中,假设模型输出的shape为(batch size,24, 37),而CTCLoss 输入的preds要求shape为(24, batch size,37)所以需要将模型输出的第0,1维交换;
preds_size是一个列表,长度为batch size,元素为该batch内每个输入序列的长度,在本例中也就是24;
text和length分别是通过对原始label进行编码得到的文本索引和每个文本的长度(一个batch的文本)
References
POSTtowardsdatascience.com laygin:OCR: WHAT AND HOWzhuanlan.zhihu.com![a547ba13569872f57d62de892ec14497.png](https://i-blog.csdnimg.cn/blog_migrate/d5df1b2e0254176b7ea33a34f73553a8.jpeg)