最近用tensorflow写了个OCR的程序,在实现的过程中,发现自己还是跳了不少坑,在这里做一个记录,便于以后回忆。主要的内容有lstm+ctc具体的输入输出,以及TF中的CTC和百度开源的warpCTC在具体使用中的区别。

正文

输入输出

因为我最后要最小化的目标函数就是ctc_loss,所以下面就从如何构造输入输出说起。

tf.nn.ctc_loss

先从TF自带的tf.nn.ctc_loss说起,官方给的定义如下,因此我们需要做的就是将图片的label(需要OCR出的结果),图片,以及图片的长度转换为label,input,和sequence_length。

ctc_loss(
labels,
inputs,
sequence_length,
preprocess_collapse_repeated=False,
ctc_merge_repeated=True,
time_major=True
)
input: 输入(训练)数据,是一个三维float型的数据结构[max_time_step , batch_size , num_classes],当修改time_major = False时,[batch_size,max_time_step,num_classes]
总体的数据流:
image_batch
->[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]
下面详细解释一下,
假如一张图片有如下shape:[60,160,3],我们如果读取灰度图则shape=[60,160],此时,我们将其一列作为feature,那么共有60个features,160个time_step,这时假设一个batch为64,那么我们此时获得到了一个[batch_size,max_time_step,num_features] = [64,160,60]的训练数据。
然后将该训练数据送入构建的lstm网络中,(需要注意的是dynamic_rnn的输入数据在一个batch内的长度是固定的,但是不同batch之间可以不同,我们需要给他一个sequence_length(长度为batch_size的向量)来记录本次batch数据的长度,对于OCR这个问题,sequence_length就是长度为64,而值为160的一维向量)
得到形如[batch_size,max_time_step,cell.output_size]的输出,其中cell.output_size == num_hidden。
下面我们需要做一个线性变换将其送入ctc_loos中进行计算,lstm中不同time_step之间共享权值,所以我们只需定义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
其中:

  • indices:二维int64的矩阵,代表非0的坐标点
  • values:二维tensor,代表indice位置的数据值
  • dense_shape:一维,代表稀疏矩阵的大小
    比如有两幅图,分别是123,和4567那么
    indecs = [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[1,3]]
    values = [1,2,3,4,5,6,7]
    dense_shape = [2,4]
    代表dense tensor:
    1
    2
    [[1,2,3,0]
    [4,5,6,7]]

seq_len: 在input一节中已经讲过,一维数据,[time_step,…,time_step]长度为batch_size,值为time_step

 

tensorflow LSTM+CTC使用详解的更多相关文章

  1. 【目标检测】SSD+Tensorflow 300&512 配置详解

    SSD_300_vgg和SSD_512_vgg weights下载链接[需要科学上网~]: Model Training data Testing data mAP FPS SSD-300 VGG-b ...

  2. 【pytorch】关于Embedding和GRU、LSTM的使用详解

    1. Embedding的使用 pytorch中实现了Embedding,下面是关于Embedding的使用. torch.nn包下的Embedding,作为训练的一层,随模型训练得到适合的词向量. ...

  3. (数据科学学习手札39)RNN与LSTM基础内容详解

    一.简介 循环神经网络(recurrent neural network,RNN),是一类专门用于处理序列数据(时间序列.文本语句.语音等)的神经网络,尤其是可以处理可变长度的序列:在与传统的时间序列 ...

  4. Tensorflow.nn 核心模块详解

    看过前面的例子,会发现实现深度神经网络需要使用 tensorflow.nn 这个核心模块.我们通过源码来一探究竟. # Copyright 2015 Google Inc. All Rights Re ...

  5. lstm和gru详解

    一.LSTM(长短期记忆网络) LSTM是一种特殊的RNN类型,一般的RNN结构如下图所示,是一种将以往学习的结果应用到当前学习的模型,但是这种一般的RNN存在着许多的弊端.举个例子,如果我们要预测“ ...

  6. RNN 与 LSTM 的原理详解

    原文地址:https://blog.csdn.net/happyrocking/article/details/83657993 RNN(Recurrent Neural Network)是一类用于处 ...

  7. Tensorflow中tf.ConfigProto()详解

    参考Tensorflow Machine Leanrning Cookbook tf.ConfigProto()主要的作用是配置tf.Session的运算方式,比如gpu运算或者cpu运算 具体代码如 ...

  8. torch.nn.LSTM()函数维度详解

    123456789101112lstm=nn.LSTM(input_size,                     hidden_size,                      num_la ...

  9. tensorflow 的tf.where详解

    最近在用到数据筛选,观看代码中有tf.where()的用法,不是很常用,也不是很好理解.在这里记录一下 tf.where( condition, x=None, y=None, name=None ) ...

随机推荐

  1. [转帖]Socat 入门教程

    https://www.hi-linux.com/posts/61543.html 现在安装k8s 必须带 socat 今天看一下socat 到底是啥东西呢. Socat 是 Linux 下的一个多功 ...

  2. Kafka序列化和反序列化与示例

    1.  卡夫卡序列化和反序列化 今天,在这篇Kafka SerDe文章中,我们将学习使用Kafka创建自定义序列化器和反序列化器的概念.此外,我们将了解序列化在Kafka中的工作原理以及为什么需要序列 ...

  3. Netty 面试题解析

    1.Netty 是什么? Netty 是一款基于 NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于 BIO(Blocking I/O,阻塞IO),他的并发性能得到了很大提 ...

  4. dubbo学习之路-SPI机制

    dubbo学习之路-SPI机制 1.SPI 1.1Java SPI 原理 SPI是service provider interface简称.在java JDK中 内置的一种服务提供发现机制.它解决在一 ...

  5. python基础 — 参数组合

    参数组合 >>>def f1(a, b, c=0, *args, **kw): ... print('a =', a, 'b =', b, 'c =', c, 'args =', a ...

  6. leetcode 罗马数字和数字的互相转换

    不知哪个大佬说过: 关于字符串的题都可以用指针或哈希解决. 罗马数字转数字: 思想: 我们能观察到规律: 一般情况下,表示大的字母在前,小字母在后; 特殊情况下,小字母会在大字母之前,但是相应的,得到 ...

  7. 开源图像识别库OpenCV基于Maven的开发环境准备

    1.安装 JDK 8+,并设置 JAVA_HOME 环境变量 2.安装 Maven,并将 “/bin” 子目录设置到 path 环境变量 3.下载 OpenCV,官网传送门 也可以直接下载本人瘦身之后 ...

  8. mabatis缓存

    一级缓存 public static SqlSession getSqlSession() { String resource = "mybatis-config.xml"; In ...

  9. Oracle---使用日常

    一.union和union all union和union all的区别是,union会自动压缩多个结果集合中的重复结果,而union all则将所有的结果全部显示出来,不管是不是重复. Union因 ...

  10. 编译基于obs-studio的阿里巴巴直播工具tblive的过程和常见问题解决

    tblive 简介 tblive开源项目对应的产品是千牛主播,是一个独立的PC端主播工具,基于开源软件OBS Studio来修改定制. 项目说明 tblive是一款优秀的基于obs-studio的直播 ...