CRNN进阶篇 多行文本识别/图像识别/对话模型

110 阅读2分钟

CRNN论文发表于2015年,最初被设计用于单行文本的识别,因为简单有效,所以直到今天依然应用广泛。

其网络结构较为简单:
(B,Cin,Hin,Win)(B, C_{in},H_{in}, W_{in})
-- 特征提取层 -->
(B,C,1,W)(B, C, 1, W)
-- Rearrange -->
(B,W,C)(B, W, C)
-- RNN层+MLP层 -->
(B,W,Cout)(B, W, C_{out})

其中 CinC_{in} 可以是1(灰度图片)或3(彩色图片),HinH_{in} 常见的取值是32、48,特征提取层可以是VGG、ResNet、DenseNet等,WW 通常取 WinW_{in}14\frac 1 4 ,RNN层通常选 BiLSTM 或 BiGRU, CoutC_{out} 等于字符集合的长度 + 1。

比较难以理解的是CRNN所用的损失函数CTCLoss,不过通常情况下我们不需要理解它的原理,只需要知道如何调用。

关于CRNN基础知识本文不过多介绍,下面重点介绍如何改造CRNN以支持多行文本识别/图像识别以及对话模型。

Multiline CRNN: 让CRNN支持多行文本识别/图像识别

先看到Multiline CRNN的网络结构:
(B,Cin,Hin,Win)(B, C_{in},H_{in}, W_{in})
-- 特征提取层 -->
(B,C,H,W)(B, C, H, W)
-- Rearrange -->
(B,H×W,C)(B, H \times W, C)
-- TransformerEncoder层 -->
(B,H×W,C)(B, H \times W, C)
--> RNN层(可选)+MLP层 -->
(B,Wout,Cout)(B, W_{out}, C_{out})

网络结构相对于CRNN添加了TransformerEncoder层,其它部分基本相同,因为有了Transformer学习全局上下文,可以保留RNN层来学习局部上下文,也可以直接去掉RNN层。损失函数依然使用CTCLoss,训练方法跟CRNN相同。

Multiline CRNN可以较好地支持多行文本识别以及图像识别任务。读者可以下载测试代码进行测试:
tr/crnn_for_text_with_multiple_lines at master · myhub/tr
tr/crnn_for_image_recognition at master · myhub/tr

ChatCRNN: 如何将CRNN技术应用于对话模型

首先说一下,这里的对话仅限于“一个输入问题有且仅有一种答案”的场景。例如问题1“《将进酒》的作者是谁?”、问题2“你最喜欢的诗人是谁?”,ChatCRNN只适用于前者。

我们先看看ChatCRNN的网络结构:
(B,T)(B, T)
-- nn.Embedding -->
(B,T,C)(B, T, C)
-- TransformerEncoder层 -->
(B,T,C)(B, T, C)
--> RNN层(可选)+MLP层 -->
(B,T,Cout)(B, T, C_{out})

网络结构相对于Multiline CRNN更简单,特征提取层改成了nn.Embedding。损失函数依然使用CTCLoss,训练方法跟CRNN相同。

ChatCRNN可以很好地解决常见大语言模型无法解决的3位整数乘法问题:
为何简单的乘法ChatGPT会算错?

写在最后,Transformer的出现给经典模型带来了更多的可能性,它就像一双翅膀,让经典模型可以飞得更高,看得更远。