当前位置:   article > 正文

文本识别之CRNN+CTC_crnn+ctc训练曲线

crnn+ctc训练曲线


主要参考的文章:
1、https://zhuanlan.zhihu.com/p/43534801
2、https://xiaodu.io/ctc-explained/
学习视频:https://www.bilibili.com/video/BV1Wy4y1473z

CRNN

通过DBNet、EAST等文本检测网络将检测到的文本框输入到CRNN网络中,网络的结构如下图所示。
CRNN网络结构
假设输入的图像大小为(32, 100, 3),整个CRNN网络可以分为三个部分:

  • 卷积层
    这里的卷积层就是一个普通的CNN网络,用于提取输入图像的Convolutional feature maps,即将大小为 ( 32 , 100 , 3 ) (32, 100, 3) (32,100,3)的图像转换为 ( 1 , 25 , 512 ) (1, 25, 512) (1,25,512) 大小的卷积特征矩阵。
  • 循环网络层
    这里的循环网络层是一个深层双向LSTM网络,在卷积特征的基础上继续提取文字序列特征。
    由于CNN输出的Feature map是 ( 1 , 25 , 512 ) (1, 25, 512) (1,25,512)大小,所以对于RNN最大时间长度 T = 25 T=25 T=25 (即有25个时间输入,每个输入 x t x_t xt 列向量有 D = 512 D=512 D=512 )。
  • 转换层
    将RNN的输出做softmax后,为字符输出。

关于代码中输入图片大小的解释:
在本文给出的实现中,为了将特征输入到Recurrent Layers,做如下处理:

  • 首先会将图像在固定长宽比的情况下缩放到 32 × W × 3 32\times W\times 3 32×W×3 大小( W 代表任意宽度)
    然后经过CNN后变为 1 × ( W / 4 ) × 512 1\times (W/4)\times 512 1×(W/4)×512
    针对LSTM设置 T = ( W / 4 ) T=(W/4) T=(W/4),即可将特征输入LSTM。
    所以在处理输入图像的时候,建议在保持长宽比的情况下将高缩放到32,这样能够尽量不破坏图像中的文本细节(当然也可以将输入图像缩放到固定宽度,但是这样由于破坏文本的形状,肯定会造成性能下降)。

CTC Loss

在CRNN的流程中,先通过CNN提取文本图片的Feature map。然后将每一个channel作为D=512的时间序列输入到LSTM。

为了说明问题,我们定义:

  • CNN Feature map
    Feature map的每一列作为一个时间片输入到LSTM中。设Feature map大小为 m × T m\times T m×T(m=512, T=25)。下文中的时间序列t都从t=1开始。
    feature map定义为:
    x = ( x 1 , x 2 , . . . , x T ) x=(x^1, x^2, ..., x^T) x=(x1,x2,...,xT)
    其中x每一列 x t x^t xt为:
    x t = ( x 1 t , x 2 t , . . . , x m t ) x^t=(x^t_1,x^t_2,..., x^t_m) xt=(x1t,x2t,...,xmt)

  • LSTM

LSTM的每一个时间片后接softmax,输出 y 是一个后验概率矩阵,定义为:
y = ( y 1 , y 2 , . . . , y T ) y=(y^1, y^2, ..., y^T) y=(y1,y2,...,yT)
其中,y的每一列 y t y^t yt为:
y t = ( y 1 t , y 2 t , . . . , y n t ) y^t=(y^t_1,y^t_2,..., y^t_n) yt=(y1t,y2t,...,ynt)

n代表需要识别的字符集合长度。(假如对y每一列进行argmax操作,即可获得每一列的输出字符的类别)。

  • 空白blank符号

如果要进行 L = a , b , c , . . . , x , y , z L={a, b, c, ..., x, y, z} L=a,b,c,...,x,y,z 的26个英文字符识别,考虑到有的位置没有字符,定义插入blank的字符集合:
L ′ = L + b l a n k L'=L+{blank} L=L+blank

  • β \beta β变换
    将L‘经过 β \beta β变换后得到原始的L,对于L来说,最大长度为T。

比, 当T=12时:
β ( π 1 ) = β ( − − s t t a − t − − e ) = s t a t e \beta(\pi_1)=\beta(--stta-t--e)=state β(π1)=β(sttate)=state
β ( π 2 ) = β ( s s t − a a a − t e e − ) = s t a t e \beta(\pi_2)=\beta(sst-aaa-tee-)=state β(π2)=β(sstaaatee)=state
β ( π 3 ) = β ( − − s t t a a − t e e − ) = s t a t e \beta(\pi_3)=\beta(--sttaa-tee-)=state β(π3)=β(sttaatee)=state
β ( π 4 ) = β ( s s t − a a − t − − − e ) = s t a t e \beta(\pi_4)=\beta(sst-aa-t---e)=state β(π4)=β(sstaate)=state

可见, β \beta β变换不是单对单映射。

ctc的做法

对于LSTM给定输入 x 的情况下,输出为 l(经过 β \beta β转换) 的概率为:
p ( l ∣ x ) = ∑ π ∈ β − 1 ( l ) p ( π ∣ x ) p(l|x) = \sum_{\pi\in\beta^{-1}(l)}p(\pi|x) p(lx)=πβ1(l)p(πx)
其中, π ∈ β − 1 ( l ) \pi\in\beta^{-1}(l) πβ1(l)代表所有经过 β \beta β变换后是 l l l的路径 π \pi π
对于任意一条路径 π \pi π,都有:
p ( π ∣ x ) = ∏ t = 1 , T y π t t p(\pi|x) = \prod_{t=1,T}y^t_{\pi_t} p(πx)=t=1,Tyπtt
y π t t y^t_{\pi_t} yπtt表示 π \pi π路径下t时刻的概率值。

如对于 T = 12 T=12 T=12的某一条路径 π \pi π 来说:
π = ( − − s t t a − t − − − e ) \pi = (--stta-t---e) π=(sttate)
$ p ( π 1 ∣ x ) = y − 1 ⋅ y − 2 ⋅ y s 3 ⋅ y t 4 ⋅ y t 5 ⋅ y a 6 ⋅ y − 7 ⋅ y t 8 ⋅ y − 9 ⋅ y − 10 ⋅ y − 11 p(\pi_1|x)=y^1_-\cdot y^2_-\cdot y^3_s\cdot y^4_t\cdot y^5_t\cdot y^6_a\cdot y^7_-\cdot y^8_t\cdot y^9_-\cdot y^{10}_-\cdot y^{11}_- p(π1x)=y1y2ys3yt4yt5ya6y7yt8y9y10y11\cdot y^{12}_e$

实际情况下T大于20,所以由非常多条 π \pi π路径,无法逐条求和计算 p ( l ∣ x ) p(l|x) p(lx)。所以需要一种快速的计算方法(动态规划的思想)。

CTC的训练目标以及函数定义

如下图,基于RNN条件独立假设,即可得到CTC Loss函数的定义:
其中,S表示的是一个数据集或者是一个batch
假定选择单层LSTM为RNN结构,则最终的模型结构如下图:
在这里插入图片描述

由于直接暴力计算

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/577312
推荐阅读
相关标签