2021AIWIN交通银行手写字体OCR识别小小快乐队伍方案及源码
比赛内容就是手写字体OCR识别.
赛题介绍中有讲到存在的问题有:字体差异性大, 字数不固定, 语义关联性低, 凭证干扰。
建模方案主要有两个,一个是CNN+CTC的结构,一个是CRNN结构,最终在任务一中选用CNN+CTC结构,任务二中选用CRNN结构。 前面也提到了这个赛题的数据语义关联性较低,因而最初的想法就是利用CNN+CTC结构来进行字体识别,它在阶段一表现还是比较出色的;不过在阶段二由于零样本以及一些有一定语义关联性的样本出现,实验中发现CRNN模型相对来说更为有效。
root
- tesk1 任务一代码
- dataset 数据集路径
- recognizer
- models
- densenet Densenet121模型
- resnet Resnet50模型
- myself_net 改进的densenet模型
- tools
- config 超参数设置
- generator.py 数据加载及预处理
- utils.py
- warp_mls.py
- train.py 训练代码
- train_again.py 微调代码
- predict.py 预测推理
- tool_code 包含一些数据集处理等过程性工具代码
- tesk2 任务二代码
- dataset 数据集路径
- PaddleOCR
- ...
- recognizer 任务一代码结构相同
- ...
- recognizer_pp 将keras版本的recognizer迁移到PaddlePaddle框架下
- ...
- run
- ocr-A
- run.sh 官方terminal的testA训练脚本
- ocr-B
- run.sh 官方terminal的testB训练脚本
- tool_code
- Data_exploration 一些数据探索工作
- Generate_dataset 生成外部数据集
- Stage_1 阶段一辅助代码
- Stage_2 阶段二辅助代码
- Post_answer_processing.py 后处理代码
确定模型输入: 对训练集样本的图片宽度高度以及字符个数做了统计,确定了图片输入size为CNN+CTC模型(32,400),后期CRNN模型输入size为(32,320)。
数据增强尝试: 此外还做了一些数据增强尝试,具体包括gauss模糊、norm模糊、锐化、滤波、随机添加干扰线(横线、竖线)、随机调整对比度、颜色随机扰动、随机拼接、随机裁剪、随机缩放、噪点、(扭曲、伸展、透镜)。 根据阶段一的训练经验来看,这些针对性的数据增强操作有一定效果,但是效果并没有很大,使用常规的数据增强方法效果依然差不多。所以在阶段二期间有关数据的扰动为PaddOCR默认的一些增强方法。
阶段一:CNN+CTC结构
阶段一采用了3种CNN+CTC的网络结构进行对比实验,分别是Resnet50+CTC,Densenet121+CTC,改进Densenet+CTC网络,它们都是直接在训练集中从零拉起来一个模型,利用一些相同的数据增强操作训练,超参数也一致,可以从这个表格中看出同等条件下在评分,训练速度,模型大小上改进的Densenet+CTC结构是最优的,唯一的缺点就是它的显存占用比较大.
Batchsize: 64 训练集:8000张 环境:V100S 32G
网络结构 | 评分 | 训练速度 | 模型大小 | 显存占比 |
---|---|---|---|---|
ResNet50+CTC | 0.98868 | 37s/epoch | 94.4M | 11.6G |
Densenet121+CTC | 0.98876 | 53s/epoch | 27.9M | 19.7G |
改进Densenet+CTC | 0.98926 | 32s/epoch | 19.8M | 18.3G |
这个改进的Densenet+CTC网络结构先是经过一个5×5卷积,再经过4个改进Densenet的Block块,之后接上两层卷积、两个FC层以及CTC。
后续精度提升主要靠对预测错的样本作针对性的数据增强过拟合处理,以及11张干扰样本的过拟合来提升精度。
【此外,在阶段一TOP1大佬开源的方案中发现OCR问题中模型找到那个合适的临界值是更为关键的,并不是所有问题都能恰好套到合适的模型,对我也非常有启发。】
阶段二:CRNN结构
阶段二前期依然尝试了阶段一的方案使用CNN+CTC结构从零拉起来一个模型,效果并不是很好,分析数据发现阶段二训练集中有一定量的语义关联样本出现,如date里的陆,柒,实际标签为零陆,零柒,sum里的金额中元角分,万仟佰,元整,角整等都是有一定的序列语义关联性在里面,因而模型需要选用CRNN结构;还有就是零样本小样本的出现使得预训练模型比较重要;此外前面数据分析中也得知训练集样本中80%样本临界图片size为(32,320)左右,label文本最大长度为25,这恰巧是PaddleOCR中文模型的默认参数,因而阶段二改用PaddleOCR的中文预训练CRNN模型作进一步调整.
由于Terminal容器仅有CPU,因而在容器中进行训练之前做了以下一些预处理操作:
- 1)根据3W张训练集标签宽度、高度、文本长度生成一定量的外部数据训练模型;
- 2)将该外部模型放入容器中用原始数据微调,起步准确率即可达到0.9+,若不利用外部生成数据训练直接用原始数据,起步准确率在0.67左右,收敛速度就会非常慢;
- 3)对产生结果进行后处理;
- 4)利用bank地址库生成数据微调;
- 5)再次后处理
数据集 | 网络结构 | 评分 | 后处理 | 模型大小 |
---|---|---|---|---|
原始数据集 | MobileNet | 0.98751 | 0.99381 | 4.88M |
原始数据集 | ResNet34 | 0.99158 | 0.99489 | 118M |
+bank地址库生成数据集 | MobileNet | 0.99501 | 0.99598 | 4.88M |
+bank地址库生成数据集 | ResNet34 | / | 0.99645 | 118M |
后处理方案按照优先级分为以下三种:
-
1)编辑距离: 即获取编辑距离最小的字符串(如year_test1053.jpg 贰零贰肆->贰零贰零)
-
2)字符串长度: 在编辑距离无法筛选出唯一结果时以该后处理方案为主,优先选字符串长度一致的结果,其次看匹配关系(如month_test3532.jpg 零壹柒->零壹拾)
-
3)最长连续匹配字符串: 前两个规则依然无法筛选出唯一结果的话则找出最长连续匹配字符串的结果,这是因为大部分预测错的样本都是两边会预测错,中间预测出错概率相对较低,因而以最长连续匹配的字符串作为集准筛选合适结果(如day_test2747.jpg 零肆贰->零肆)
不同类别数据后处理方案汇总:
类别 | 后处理方案 |
---|---|
Year | 编辑距离 |
Mouth | 编辑距离->字符串长度一致->KMP算法最长连续公共字符长度 |
Date | 编辑距离->字符串长度一致->KMP算法最长连续公共字符长度 |
Bank | 编辑距离 |
Sum | 无需后处理 |
【由于该后处理操作有争议性,后处理操作不具备借鉴意义,因为利用了地址库生成数据,所以即使纯模型得分,预估也会在前2名之内。】
链接:https://pan.baidu.com/s/1L84-YK4xLltRypYo43EYWw
提取码:nrvs