CRNN是《An End-to-End Trainable Neural Network for Image-based Sequence
Recognition and Its Application to Scene Text Recognition》中提出的模型,解决图像中文字识别问题。

论文地址:https://arxiv.org/abs/1507.05717 <https://arxiv.org/abs/1507.05717> 

github地址:https://github.com/bgshih/crnn <https://github.com/bgshih/crnn>

1:结构图

主要包括:卷积层(CNN),循环层(RNN),转录层(CTC)



2:整个网络模型的特点

*
可以直接从序列标签学习,不用给每个字符打标签,只需要给一个图片打一个序列标签,例如:图片中是“abc123”,标签即是“abc123”,不用给每个字符单独打标签。
* 利用CNN提取的图片特征
* 利用RNN训练的输入的特征序列,输出的是一个序列标签
* 对要训练的图片没有长度限制,但是要将图片的高度归一化。
* 参数少
* 虽然结合了CNN和RNN,但最后用一个loss函数(CTC LOSS),实现了端到端的训练。
3:CRNN中的重点,也就是CTC(connectionist temporal classification)原文出自《Connectionist
Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent
Neural Networks
<https://link.zhihu.com/?target=ftp%3A//ftp.idsia.ch/pub/juergen/icml2006.pdf>》

首先,CRNN第一步是将训练的图片送入到CNNji进行卷积提取特征,得到feature map

然后,将feature map的每一列(这里先简化处理,认为一列就是一个LSTM时间序列,CRNN网络结构后面分析)
或者每几列作为一个时间序列输入特征,送入RNN(双向LSTM)

先看一下流程图:

                                                 

* CNN feature map
           假设CNN得到的feature map 大小为 ,下文得到的时间序列  都从  开始,即 。

则输入到RNN中的时间序列定义为 :,

其中每一列为:                              

                                                           

* RNN(双向LSTM)
         
 LSTM的每个时间片后接一个softmax,输出的是一个后验概率矩阵,大小为n*T,T代表时间序列总共T列,n代表有词典中有n个标签,定义为:

其中每一列为:

                                                            

           由于是得到的是概率,所以每列的所有字符标签的概率之和为1,即 ,那取每列的最大值,就能得到每一列输出字符的类别,即对每列进行 操作。

           将该LSTM网络看成一个映射  , 其中w为LSTM的参数。m*T 的CNN得到的feature map,输入经LSTM后输出为
n*T, 所以是做了如下变换:

           假设原始的字符标签为L =
{a,b,c,......,x,y,z}的26和字母,由于要加一个默认的空格字符blank(作用类似于目标检测中的默认的背景标签),此时的新的字符标签为L‘。

           定义B变换:

                                                            ,表示简单的压缩

说明:假设T = 12,也就是说有12列,路径为,路径的长度就是T。

   



        如上所示5条路径,看出规律有:若两个字符之间有空格blank 时,则不合并,若没有空格时,相同字符合并为一个。

        当获得LSTM经过softmax(注意是softmax不是softmax loss,因为这里用的是CTC
loss)得到字符概率得分矩阵后,经argmax()操作后得到的输出y,经过B变换后,即可获得输出结果,显然B变换不是一
一映射的关系。现在我们能通过feature
map用每列当做x输入到RNN中,得到概率矩阵,并argmax()操作得到输出,然后用这一步的输出经过B变换规则得到最终的字符预测输出。但是这样的输出和当时的输入的列数不一样(明显不一样,也就是发生了不对齐的现象。),训练需要反向传播来更新参数,所以,怎样利用得到的预测输出来计算loss呢。

        如果输出是用的softmax得到的概率矩阵,每列对应的是输出
都对应标签中的一个字符。那么训练时候每张样本图片都需要标记出每个字符在图片中的位置,再通过CNN感受野对齐到Feature
map的每一列,如图3,才能进行训练。

                           

        在实际应用中,标记这样的对齐样本非常困难,工作量非常大,所以CTC提出了一种不需要对齐的Loss计算方法,用于训练网络。

        先来计算一下,路径的数目:假设T = 30,最后的输出为“state”,五个字符,共有条路径可以被压缩成【state】。路径数目的计算公式为。

CTC的做法:

        对于LSTM给定输入  的情况下,输出为  的概率为:



        上边的式子说明:输入的情况下,输出为的概率为:条件为输入为,进过B变换后输出为的所有路径的概率之和。

那么每一条路径的概率怎么算呢:

上边的式子说明:每一条路径的概率为该条路径的每一个时刻的输出的连乘。

我们的目标函数就相当于是

但是路径数目庞大,是无法直接计算的,所以CTC方法中借用了HMM中向前向后算法(forward-backward algorithm)来计算。

 



CTC的训练过程,本质上是通过梯度  调整LSTM的参数  ,使得对于输入样本为  时有  取得最大。

定义所有经  变换后结果是  且在  时刻结果为 (记为 )的路径集合为  。

求导:





注意上式中第二项与  无关,所以:



首先来理解一下上边的式子:是 时刻 输出字符为 的概率。上边的求导公式中的理解为:由于总归的路线数目巨大,我这里求导只需要计算经过 时刻 输出字符为 
的所有路径。示意图如下:



           假设是t=6时刻,k = a字符。那么依据上图经过这个点的路径有两条(没画出来的还有好几条),假设总共有四条路径经过该点,分别为
,所有类似于  经过  变换后结果是  且在  的路径集合表示为  。

           观察  。记  蓝色为  ,  红色路径为  。那么  可以表示:

                                          

                                          

             可以是 经过交叉点后互换下半段路径:

 

         计算:

                   

         为了观察规律,单独计算  。

                     

                             

                             

                             

                             

            令:

                  

                 

            那么可以表示为:

          

            推广一下,所有经过  变换为  且  的路径(即  )可以写成如下形式:

       

            进一步推广,所有经过  变换为  且  的路径(即  )也都可以写作:

        

     所以,定义forward  :

         对于一个长度为  的路径  ,其中  代表该路径前  个字符,  代表后  个字符。



        其中  表示前  个字符  经过  变换为的  的前半段子路径。

        观察图7会发现对于  有如下递推关系:



                                                                             
            图6



                 那么更一般的:

        

                 上边的怎么理解呢:

                                                                

蓝色矩形标记的时刻字符点,它的forward受到它前一个时刻的三个方向(黄色箭头)的预测。所以有:

                      

      同样,定义backword  :



                                     根据

                                                             

         同理对于  有如下递推关系:

                    

那么forward和backward相乘有:



或:



注意,  可以通过图6的关系对应,如  ,。

对比  :



可以得到:



或:



训练CTC

对于LSTM,有训练集合  ,其中  是图片经过CNN计算获得的Feature map, 
 是图片对应的ocr字符label(label里面没有blank字符)。

现在我们要做的事情就是:通过梯度调整LSTM的参数,使得对于输入样本为时有  取得最大。所以如何计算梯度才是核心。

单独来看LSTM输出  矩阵中的某一个值  (注意  与  含义相同,都是在  时  的概率):



获得梯度  后就好办了,其中的  可以通过递推快速计算,那么梯度下降算法你懂的。

CTC总结

CTC是一种Loss计算方法,用CTC代替Softmax Loss,训练样本无需对齐。

CTC特点:

* 同时引入blank字符,解决有些位置没有字符的问题
* 通过递推,快速计算梯度