CRNN学习记录
开发环境
时间:2019年4月15日17:15:00
- python:3.5
python版本影响读取数据时候编码格式问题,详情参考bug修正中的encode/decode部分。 - pytorch:1.0.1
pytorch 1.0.1中自带CTCloss函数,可以不再使用百度warpCTC。现在pytorch的CTC函数存在loss可能为nan的情况,需要用钩子将错误loss清零。百度的warpCTC一直提示安装失败。具体CTC问题参考bug修正中的CTC选择。 - 需要lmdb
源码数据存储格式基于lmdb。需要安装相应的的库支持:pip install lmdb。 lmdb的数据有点在于:lmdb读取效率高(原因不了解,可以提升硬盘IO利用率),lmdb支持多程序同时读取,数据一致性,使用lmdb可以一次性读取整个batch。 - 基于linux环境
基于windows环境已知会产生如下问题:a. lmdb预留空间会被完全分配,导致初始化失;b. 模型训练中worker数量大于2会报错。
由于b问题完全无法解决,并且在某次实验中直接所有worker数量都无法训练了。导致我直接放弃windows环境了。
其他需要环境没有特定要求。本人基于anaconda自带的所有库和图像AI必须的几个库。版本没有在这次实验中更新,也未遇到问题。故不详述。
源码下载
本实验代码基于:
很有帮助的参考资料:
测试过但没有使用的代码:
下面两个代码由于在运行过程中出现了不同的问题,在本实验中被放弃,没有继续使用。
bug修正
- encode/decode: 读取图片不能直接读取,需要改为二进制形式读取。其他情况下报错要将不能读取的格式编码,即后面加.encode();或解码,即后面加decode(). 另特别注意在create_dataset.py中,不能简单增加encode,会导致其他格式被误编码,应当根据以下格式修改:
if type(v) == str:
v = v.encode()
txn.put(k.encode(), v) #txn.put(k.encode(), v)
- CTC选取:源码中使用warpCTC,本人实验中未能将warpCTC成功安装在任何平台上。所以只有采用升级pytorch版本使用pytorch自带CTC。需要注意使用钩子函数将其中错误的loss梯度设为0。其他可能存在bug点在于两者的默认输入参数不一样,还没有进行测试。现在实验均使用默认参数。
另外还有一整合的的pip库去替代warpCTC。本人测试直接使用pip install方法在linux环境下安装失败。没有测试用下载轮子的方式安装。在windows环境下安装成功了(也是用的下载轮子的方式)。与另外两个CTC函数不同,这个CTC注意要在函数定义的时候定义其所需参数、由于windows环境被抛弃,没有进行进一步测试。 - 读取保存的模型:注意由于torch版本更新,读取保存的模型时候要修改为:(参考资料)
crnn.load_state_dict(torch.load(PATH), strict=False)#crnn.load_state_dict(torch.load(PATH))
- 其他:trainroot/valroot代码中小写r;选取没有选取特定GPU的选项。模型不收敛调小learning rate等
- 猜测模型可能存在问题:字典集不全,训练时候报错。尚未测试;LSTM层过大,影响训练速度。
- 猜测算法可能存在的问题:小数点,除号识别困难,*/x 不分等。
目前成果
2019年4月15日:运用6000张训练集和1000张测试集,排除一些包含中文等特定字符的数据。现在最大准确率45%
2019年4月16日:未修改模型。持续训练。现在最大准确率51%
算法
- CRNN网络分为:
a. 卷积层:提取图像特征。
b. 循环层:深层双向LSTM网络,在卷积层的基础上提取文字序列特征
c. CTC: 解决字符无法对其的问题 - 卷积层:
(略) - 循环层:
双向定义: 考虑前后文问题。可以简单理解为将网络从后往前又多设置了一遍。
双向优点:考虑了前后文
双向缺点:所需内存为RNN两倍
深层定义:增加若干隐藏层。
深层优点:可以将更多的信息存储在隐藏层中。
深层缺点:所需权重数目大大增加。 - CTC:
优点:可以整体进行比对,不需要单个标注,极大节约标注成本
缺点:连续字符识别不准。(推导困难)