YCG09 / chinese_ocr

CTPN + DenseNet + CTC based end-to-end Chinese OCR implemented using tensorflow and keras
Apache License 2.0
2.73k stars 1.08k forks source link

Densnet+CTC 和Densenet+BLSTM+CTC #1

Open Lesley96-11 opened 6 years ago

Lesley96-11 commented 6 years ago

你好,请问直接densnet连接ctc和加上lstm再连ctc哪个效果会比较好,作者有试过吗? 如果想加lstm的话,训练代码需要做什么改变吗

YCG09 commented 6 years ago

加了blstm或bgru后收敛会比较慢,predict时也会变慢,训练时val loss基本差不多,实际应用效果也不多,所以我没有加

如果要加只需改densenet.py中的dense_cnn函数,在最后的dense层前加几行代码,例如加两层blstm:

from keras.layers import Bidirectional, LSTM
rnnunit = 256
x = Bidirectional(LSTM(rnnunit, return_sequences=True, implementation=2), name='blstm1')(x)
x = Dense(rnnunit, name='blstm1_out', activation='linear')(x)
x = Bidirectional(LSTM(rnnunit, return_sequences=True, implementation=2), name='blstm2')(x)
phybrain commented 6 years ago

我自己的densenet+blstm+ctc https://github.com/phybrain/efficientdensenet_crnn,为什么我训练acc 这么低....

YCG09 commented 6 years ago

@phybrain acc达到多少?数据怎么生成的,学习率多大?

phybrain commented 6 years ago

@YCG09 acc 0.4 左右,数据用脚本生成,lr=0.005

YCG09 commented 6 years ago

@phybrain 降低学习率试试,用0.001或者0.0005

hhk123 commented 6 years ago

请问两层双向LSTM层之间为啥要加个全链接层?不加可以不? x = Dense(rnnunit, name='blstm1_out', activation='linear')(x)

YCG09 commented 6 years ago

@hhk123 其实不用加,加了反而比较慢

Jiakui commented 5 years ago

我感觉 ocr 还是需要语言模型的,这个必须要 lstm 来学习 。。。可能对于印刷体, lstm 不是那么重要。。。但是对于手写体,很多字 必须要根据上下文来进行推断的时候, 语言模型的重要性就会体现出来了。。。 我记得用百度 ocr 经常识别出 “boo元” 这样的结果,如果结合语言模型,应该可以推断 “600元” 是个更可能的组合。。。。

YCG09 commented 5 years ago

@Jiakui 你说的没错

phybrain commented 5 years ago

ctc loss训练其实包含了一部分语言模型

Jiakui commented 5 years ago

@phybrain 但是 predict 的时候没有用 ctc 啊。。。 所以 目前的项目 肯定是没有任何 语言模型的

phybrain commented 5 years ago

@Jiakui 你没看过ctc论文吗?他是按照路径的概率写的loss公式 (即某种程度上的语言模型),训练网络的参数也是按照gt路径来的,loss不是predict时用的, 一个模型拟合的函数跟loss是相关的。这不是单纯的图片分类的loss,分类输出的是字分类的概率 你可以试下交叉熵识别 肯定很差。加上rnn 只是某种程度上增强了前后关联的概率,但其实nn本身就能拟合任意函数 理论要好好看啊

Jiakui commented 5 years ago

@phybrain ctc loss 比 cross entropy 的效果好,这个我非常承认,但是这个恐怕是因为 cross entropy 无法很好的处理 token 对齐的问题造成的吧~~

Jiakui commented 5 years ago

@phybrain 所谓的语言模型,指的是 t+1 时刻的 token 输出依赖于 t 时刻的 token 输出。。。。对于这个项目而言, predict 的过程 是 cnn 的直接输出,也就是说, 所有的 token 都是并行输出的,不存在任何前后依赖关系。。。。

phybrain commented 5 years ago

@Jiakui 看来你是真没读过论文,理论也不行 自己慢慢学吧

Jiakui commented 5 years ago

我不知道cnn 能否拟合任意函数, 反正我没见过基于 cnn 的语言模型。。。

Jiakui commented 5 years ago

每个人有自己的理解~ 不必因为自己看懂了某个细节就贬低别人 ~ 世界上牛人多的是,我见得多了。。。 @phybrain

phybrain commented 5 years ago

@Jiakui 嗯你说的对,你都是对的。大神

yunhai0920 commented 5 years ago

@phybrain 杠精 你那看不起的语气 更是大神

Szy-Young commented 5 years ago

@Jiakui 其实不能说predict时没用到ctc...在处理DNN模型输出结果的decode函数里作者自己实现了最简单的基于Best Path Decoding的ctc解码,你会发现用英文句子做测试输出结果单词之间没有空格...

AirFishWang commented 5 years ago

我的理解是,cnn直接输出也存在前后依赖关系的,因为有全连接的结构存在,引入lstm只是增强前后依赖而已,当识别清晰的文字时,有没有lstm可能影响不大,但是对于难以识别的字时候,lstm会存在一定的作用,但是起决定作用的仍然是cnn, lstm只是辅助

Jiakui commented 5 years ago

我最近试了 CNN + LSTM + attention ,贼有意思,发现就算完全识别错误的图片,输出的语句语法都是通顺的。。。。说明了 LSTM + attention 对于语言本身的学习能力是很强的。。。。我用过很多 CNN + ctc_loss 的 OCR 工具,发现 他们 致命的弱点就是对形近字的识别很差,经常会把 “他 地” 这些识别混淆。。。但是如果 OCR 模型有一定的上下文语法推断能力,这个 形近字识别错的问题 应该是可以避免的。。。。

Jiakui commented 5 years ago

CNN + LSTM + attention 还没试好,还有很多问题。。。但是我感觉 比 CNN + ctc_loss 应该更有潜力成为 更好的 OCR 技术 。。。

Jiakui commented 5 years ago

楼上各位专家其实可以想一下,如果 CNN + ctc_loss 对语法有学习能力的话, “他 地” 混淆的情况就不会出现,因为二者出现的语境完全不一样。。。“他是个好人” 和 ”地是个好人“,语言模型层面上很容易区分出来。。。。。

cvnli commented 5 years ago

CNN + LSTM + attention 还没试好,还有很多问题。。。但是我感觉 比 CNN + ctc_loss 应该更有潜力成为 更好的 OCR 技术 。。。

进度怎么样?能看到效果吗

jewelcai commented 5 years ago

楼上各位专家其实可以想一下,如果 CNN + ctc_loss 对语法有学习能力的话, “他 地” 混淆的情况就不会出现,因为二者出现的语境完全不一样。。。“他是个好人” 和 ”地是个好人“,语言模型层面上很容易区分出来。。。。。

家奎你好, 我对attention这块的方案也有兴趣,请问您有什么新进展嘛?

jewelcai commented 5 years ago

加了blstm或bgru后收敛会比较慢,predict时也会变慢,训练时val loss基本差不多,实际应用效果也不多,所以我没有加

如果要加只需改densenet.py中的dense_cnn函数,在最后的dense层前加几行代码,例如加两层blstm:

from keras.layers import Bidirectional, LSTM
rnnunit = 256
x = Bidirectional(LSTM(rnnunit, return_sequences=True, implementation=2), name='blstm1')(x)
x = Dense(rnnunit, name='blstm1_out', activation='linear')(x)
x = Bidirectional(LSTM(rnnunit, return_sequences=True, implementation=2), name='blstm2')(x)

加两层的话 是不是调一下input的shape效果会好一些?

lzneu commented 4 years ago

加了blstm或bgru后收敛会比较慢,predict时也会变慢,训练时val loss基本差不多,实际应用效果也不多,所以我没有加

如果要加只需改densenet.py中的dense_cnn函数,在最后的dense层前加几行代码,例如加两层blstm:

from keras.layers import Bidirectional, LSTM
rnnunit = 256
x = Bidirectional(LSTM(rnnunit, return_sequences=True, implementation=2), name='blstm1')(x)
x = Dense(rnnunit, name='blstm1_out', activation='linear')(x)
x = Bidirectional(LSTM(rnnunit, return_sequences=True, implementation=2), name='blstm2')(x)

您好,这里unit为什么设置为256呢,按照32的输入height来算的化,换算到bilstm之前的unit是4*192=768,256不是相当于降采样了? @YCG09

NNUCJ commented 4 years ago

我按照上面的做法,在densenet后接了Blstm,但是在训练的时候acc为0,我尝试更换优化方法,但是效果还是一样的。这个是为什么?

tangzhongliang commented 4 years ago

我按照上面的做法,在densenet后接了Blstm,但是在训练的时候acc为0,我尝试更换优化方法,但是效果还是一样的。这个是为什么?

降低学习率到0.005,把双层lstm中间的全连接去掉,最好把lstm改成gru或者CUDNNGRU。 开始的时候损失度会震荡,等lstm的学习到一个比较好的权重后,损失度就能够下降的比较快

tangzhongliang commented 4 years ago

请问两层双向LSTM层之间为啥要加个全链接层?不加可以不? x = Dense(rnnunit, name='blstm1_out', activation='linear')(x)

中间没有加全连接,对准确度有影响吗?

NNUCJ commented 4 years ago

谢谢,我打算用之前densenet训练的模型fine tune加了Gru的网络.(设置网络densenet的层为不可训练的)发现训练时loss只有0.07左右,Acc为0

发自我的iPhone

------------------ 原始邮件 ------------------ 发件人: leonard <notifications@github.com> 发送时间: 2019年11月6日 11:30 收件人: YCG09/chinese_ocr <chinese_ocr@noreply.github.com> 抄送: NNUCJ <616151263@qq.com>, Comment <comment@noreply.github.com> 主题: 回复:[YCG09/chinese_ocr] Densnet+CTC 和Densenet+BLSTM+CTC (#1)

我按照上面的做法,在densenet后接了Blstm,但是在训练的时候acc为0,我尝试更换优化方法,但是效果还是一样的。这个是为什么?

降低学习率到0.005,把双层lstm中间的全连接去掉,最好把lstm改成gru或者CUDNNGRU。 开始的时候损失度会震荡,等lstm的学习到一个比较好的权重后,损失度就能够下降的比较快

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

tangzhongliang commented 4 years ago

加了blstm或bgru后收敛会比较慢,predict时也会变慢,训练时val loss基本差不多,实际应用效果也不多,所以我没有加

如果要加只需改densenet.py中的dense_cnn函数,在最后的dense层前加几行代码,例如加两层blstm:

from keras.layers import Bidirectional, LSTM
rnnunit = 256
x = Bidirectional(LSTM(rnnunit, return_sequences=True, implementation=2), name='blstm1')(x)
x = Dense(rnnunit, name='blstm1_out', activation='linear')(x)
x = Bidirectional(LSTM(rnnunit, return_sequences=True, implementation=2), name='blstm2')(x)

请问lstm层之前是否需要进行批量归一化处理?

v-smwang commented 4 years ago

+1

WangXuanBT commented 4 years ago

@Jiakui 嗨~不管从理论上还是从现象上来看,确实rnn+ctc并没有起到语言模型的效果。我觉得原因在于rnn+ctc学习到的"语言模型"是像素级的上下文(毕竟前面cnn提取出的feature map是像素信息)而不是语言层面的上下文,我认为在ctc decode映射出来one hot字符数据之后才可以谈语言层面的上下文。cnn+rnn+attention的方式摈弃了ctc,有较强的语言能力,着实很有潜力。不用被 @phybrain 这样的人影响,保持一颗客观冷静的心态继续加油呀!

phybrain commented 4 years ago

@WangXuanBT Your math is terrible,have you studied random processes and time series analysis?

junthy-me commented 4 years ago

楼上各位专家其实可以想一下,如果 CNN + ctc_loss 对语法有学习能力的话, “他 地” 混淆的情况就不会出现,因为二者出现的语境完全不一样。。。“他是个好人” 和 ”地是个好人“,语言模型层面上很容易区分出来。。。。。

请问关于注意力这块,目前结果如何呢,我遇到了一些问题,请问能帮助一下吗?

xinyvz commented 4 years ago

我个人感觉,ctc对于语义的影响实在是很小,加ctc的最大效果,就是不定长识别,但会影响重复字符的识别,不过也可以调参优化。 而lstm, 或是GRU是有语义作用的,只是要看这个作用有多大了,我用densenet+ctc训练英文+数字的识别,经常会把相近的字符识别错,比如数字0,和字母O, 加了GRU后这个错误就少很多了。