最近用tensorflow写了个OCR的程序,在实现的过程当中,发现本身仍是跳了很多坑,在这里作一个记录,便于之后回忆。主要的内容有lstm+ctc具体的输入输出,以及TF中的CTC和百度开源的warpCTC在具体使用中的区别。python
由于我最后要最小化的目标函数就是ctc_loss
,因此下面就从如何构造输入输出提及。git
先从TF自带的tf.nn.ctc_loss提及,官方给的定义以下,所以咱们须要作的就是将图片的label(须要OCR出的结果),图片,以及图片的长度
转换为label,input,和sequence_length。github
[max_time_step , batch_size , num_classes]
,当修改time_major = False时,
[batch_size,max_time_step,num_classes]
。
[batch_size,max_time_step,num_features]
->lstm
[batch_size,max_time_step,cell.output_size]
->reshape
[batch_size*max_time_step,num_hidden]
->affine projection
A*W+b
[batch_size*max_time_step,num_classes]
->reshape
[batch_size,max_time_step,num_classes]
->transpose
[max_time_step,batch_size,num_classes]
[batch_size,max_time_step,num_features] = [64,160,60]
的训练数据。
sequence_length
(长度为batch_size的向量)来记录本次batch数据的长度,对于OCR这个问题,sequence_length就是长度为64,而值为160的一维向量)
[batch_size,max_time_step,cell.output_size]
的输出,其中cell.output_size == num_hidden。
W
的结构为
[num_hidden,num_classes]
,
b
的结构为[num_classes]。而
tf.matmul操做中,两个矩阵相乘阶数应当匹配,因此咱们将上一步的输出reshape成
[batch_size*max_time_step,num_hidden]
(num_hidden为本身定义的lstm的unit个数)记为
A
,而后将其作一个线性变换,因而
A*w+b
获得形如
[batch_size*max_time_step,num_classes]
而后在reshape回来获得
[batch_size,max_time_step,num_classes]
最后因为ctc_loss的要求,咱们再作一次转置,获得
[max_time_step,batch_size,num_classes]
形状的数据做为input
labels: 标签序列
因为OCR的结果是不定长的,因此label其实是一个稀疏矩阵SparseTensor,
其中:api
indices
:二维int64的矩阵,表明非0的坐标点values
:二维tensor,表明indice位置的数据值dense_shape
:一维,表明稀疏矩阵的大小123
,和4567
那么[[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[1,3]]
1
2
|
[[1,2,3,0]
[4,5,6,7]]
|
seq_len: 在input一节中已经讲过,一维数据,[time_step,…,time_step]长度为batch_size,值为time_step网络