pyqt label上的图片旋转_关于CTC在文字识别上的一些理解

写在前面

总觉得自己看了很多知识,但是过一段时间就忘记了。好比这个CTC loss明明记得一个多月前看过的,但是现在重新拾起,和新的没什么区别。所以今天结合github上的某个cnn_lstm_ctc 项目,重新温故一下,记录自己的一些收获。

https://github.com/weinman/cnn_lstm_ctc_ocr​github.com

在这里记录一下。

正文

一、自己的一些疑问

  1. mjsynth dataset的数据集了解

这个数据集的每张图片,表示一个输入,文件命名是144_mgm_48146.jpg,分别表示id_text in image_(??).jpg,最后一串数字不是很清楚,不过目前来看没有用到。如下图所示。

ddd8cebbe80254a11680d06d30875b27.png
训练集中的输入

2.label是如何表示的?

以下代码可以一目了然的知道label的处理方式

out_charset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
out_charset_dict = { key: val for val, key in enumerate( out_charset ) }
int_to_string_dict = dict(enumerate(out_charset))  #{0: 'A', 1: 'B', 2: 'C', 3: 'D'..}

def string_to_label ( string ):
    """Convert a string to a list of labels"""
    label = [out_charset_dict[c] for c in string]
    return label

def label_to_string ( labels ):
    """Convert a list of labels to the corresoponding string"""
    string = ''.join( [int_to_string_dict[c] for c in labels] )
    return string

def get_text_and_labels( filename ):
    # 2697/6/466_MONIKER_49537.jpg --> MONIKER
    text = os.path.basename( filename ).split( '_', 2 )[1]
    labels = charset.string_to_label(text)
    return text, labels

基本逻辑是:提取图片中的文本信息--->分割每一个字符,并转化成标签,标签格式是{key:value},如{1:'B'}表示第1类是字符B. 从这里也可以想象,网络最终不是直接回归每个字符,而是给出一个分类的概率,是一个分类问题。如果了解CTC loss layer 的原理,这里就不会有疑惑啦。

3.所以CTC loss 到底做了什么事情呢?

首先,需要明确,lstm网络的最后一层,会做全连接操作,这个跟一般的分类网络一样,需要注意的是分类会多出一个unit,这个用来表示no label 或者空格。可参考代码。

 #full connection layer
rnn_logits = tf.layers.dense( rnn2,     
                                      num_classes+1, 
                                      activation=logit_activation,
                                      kernel_initializer=weight_initializer,
                                      bias_initializer=bias_initializer,
                                      name='logits' )

接下来,就是CTC loss layer需要干的事情了。

***通过softmax获得每个frame在不同分类上的概率,

***计算不同sequence下的概率

***alignment ,得到和label一样的sequence。(valid sequence)比如原本是cc--a--tt,alignment成cat,包含了遍历、删除、合并这些操作。

3.1 为什么这里需要动态规划?

对于每一个sequence都需要align,这样开销就比较大。所以文章利用动态规划的思想,因为可以根据上一阶段的状态和决策来导出本阶段的状态。那么对于同一时刻t下生成的相同output,我们可以认为是同一个状态,不需要重复计算。

3.2 但是如何体现在代码里呢?判断是相同的output还是少不了那些操作吖?

并不是这样理解,借助图片理解可以发现,对于同样的两个节点,即使第三个节点不一样,但对于前面的状态,不需要计算两次。注意这里生成相同的output是直接通过路径相同来判断的,而不是判断align的结果是否一样。

cb718a9256d630c5588cb22f1095870c.png
利用动态规划计算的路径

***计算负对数似然

实际上tensorflow已经提供了这个API ,应用来说没有问题,api如下。但对于动态规划的推导,以及后向,梯度计算,还没有了解pending for update

losses = tf.nn.ctc_loss( sequence_labels, 
                             rnn_logits, 
                             sequence_length,
                             time_major=True, 
                             ignore_longer_outputs_than_inputs=True )
  • 最后疑惑的问题是,中文如果用这个进行training,因为中文的字很多,怎么样做label呢?

该问题还有待解决。pending for update

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值