Paddleocr⽂本识别数据集的合成与制作----超级详细
⽬录
前⾔
由于官⽅提供的Paddleocr模型是⼀个通⽤的OCR识别模型,在很多的⽇常的场景中识别准确还是可以的,但是在⼀些⽐较特殊的场景中,识别的精确度就不是很好。如果要让我们的模型更加符合⾃⼰的业务需要,那么就需要训练我们⾃⼰的OCR识别模型。OCR识别分为⽂本检测和⽂本识别,⽂本检测就是让模型到⽂字所在的位置,⽽⽂本识别是在⽂本检测到的位置上进⾏⽂本识别。训练⾃⼰的模型第⼀步就是需要数据集,从理论上来说,只要给模型喂⼊数据集越庞⼤那么,那么模型的效果就会越好。
对于精度要求不⾼的场景,检测任务和识别任务需要的数据量是不⼀样的。对于检测任务,500张图像可以保证基本的检测效果。对于识别任务,需要保证识别字典中每个字符出现在不同场景的⾏⽂本图像数⽬需要⼤于200张(举例,如果有字典中有5个字,每个字都需要出现在200张图⽚以上,那么最少要求的图像数量应该在200-1000张之间),这样可以保证基本的识别效果。
由此可见⽂本识别所需要的数据集要⽐⽂本检测的数据集⼤的多的多。因此我们不仅要获得⼤量的真实数据,⽽且还要合成⼤量的数据。百度官⽅通⽤模型中的⽂本识别模型⽤了520W左右的数据集(真实数据26W+合成数据500W)。所以该⽂章就来讲讲怎么批量合成⽂本识别模型的数据集。
⼀、数据集的总体概括
1.1 训练集和测试集
训练OCR⽂本识别模型的数据集是训练集和测试集组成的测试集和训练集应有如下⽂件结构:
训练集的⽂件结构:
|-train_data
|-rec
|- rec_
|- train
|- word_001.png
|- word_002.jpg
|- word_003.jpg
与星星有关的诗句| ...
测试集的⽂件结构:
|-train_data
|-rec
|- rec_
|- test
|- word_001.jpg
|- word_002.jpg
|- word_003.jpg
| ...
其实测试集和训练的⽂件结构是相同的,都是由图⽚⽂件和标签⽂件所组成的。标签内容如下所⽰:
" 图像⽂件名图像标注信息 "
train_data/rec/train/word_001.jpg 简单可依赖
train_data/rec/train/word_002.jpg ⽤科技让复杂的世界更简单
标签⽂件的左边记录的是图⽚⽂件⾥⾯的保存路径,⽅便模型在训练的时候到对应的图⽚,⽂件的右边记录的是对应路径下的图⽚⽂件的标签,就是⽂本识别的内容。让我们来直观的感受⼀下图⽚的图⽚和标签
由上图可以很直观的看到数据集⾥⾯的图⽚⽂件和⾥⾯的图⽚⽂件和对应的标签⽂件。
1.2 ⽂本识别所需字典
⽂本识别需要⼀个字典,使模型在训练时,可以将所有出现的字符映射为字典的索引。因此字典需要包含所有希望被正确识别的字符,{word_dict_name}.txt需要写成如下格式,并以 utf-8 编码格式保存:
每⾏有⼀个单字,将字符与数字索引映射在⼀起,“and” 将被映射成 [2 5 1]
因此要训练我们⾃⼰的⽂本识别模型的训练就需要两个东西,⼀个是数据集,⼀个是希望被正确识别的字符的字典。废话不多说,就让我们开始数据集的合成还有字典的制作吧。
怎样查电信手机流量⼆、⽂本识别数据集的合成前期准备
2.1 数据集合成概括
⾸先⽂本识别数据集的合成需要两个东西,⼀个是⽂本语料,⼀个是⽬标场景图⽚,如下图所⽰,可以很直观的知道数据集的合成是怎么做的,就是将输⼊的⽂本语料通过⽂本风格迁移到指定的背景模板中。
2.2 语料和⽬标场景图像模板的准备和处理
之所以要训练我们⾃⼰的模型,就是因为百度的官⽅模型不适合某些特定的场景,⽐如我现在所做的船号识别项⽬,就是要识别船舶号,所以就会有对应的语料,如图所⽰:
这些语料⼤家通过⾃⼰的项⽬需求去获取,可以通过爬⾍或者别的⼿段,总之我们要⼤量的语料来合成数据。
下⾯就是对语料数据进⾏处理了,⾸先将语料数据⾥⾯的汉⼦和数字分开,分成如下图所⽰ :
有些⼈会问,为什么要把汉字和数字分开呢,因为我在合成的时候发现,汉字和数字在⼀⾏的时候合成的效果特别差,就合成不了数字,⼤家仔细看下下⾯两图的对⽐,发现汉字是可以合成的,但是后⾯的数字的合成效果是很差的。
⽽数字和汉字分开,合成的效果就会很好,如下图所⽰:
铁海棠
所以我们要将语料中的数字和汉字分开去合成数据集。
2.3 制作语料
我这⾥有⼀份原始的语料,都是关于船舶号的,上⾯已经给⼤家展⽰过了。现在我们的第⼀件事就是将数字和汉字分开,可以⽤以下脚本进⾏处理:
# 以只读模式读取⽂件
file = open("C:/Users/86159/", "r", encoding='utf-8')
# 创建⼀个列表
lines = []
# 逐⾏将⽂本存⼊列表lines中
立夏的经典古诗for i in file:
lines.append(i)
file.close()
# 创建⼀个新的列表
new = []
# 逐⾏遍历,将列表中的每⼀个元素中的数字和特殊符号剔除
for line in lines:
line = place('0', '')
line = place('1', '')
line = place('2', '')
line = place('3', '')
line = place('4', '')
line = place('5', '')
line = place('6', '')
99事件line = place('7', '')
line = place('8', '')
line = place('9', '')
line = place('-', '')
line = place('.', '')
line = place('#', '')
new.append(line)
# 将剔除数字和特殊符号的列表转化为集合,这样可以将剔除字母和特殊符号的汉字去重
# 集合中可以将重复元素去重
new = list(set(new))
# print(new)
# 以写的⽅式打开⽂件,如果⽂件不存在,就会⾃动创建,如果存在就会覆盖原⽂件
file_write_obj = open("C:/Users/86159/", 'w')
# 将处理完的列表写到⼀个新的txt⽂件中
for var in new:
file_write_obj.writelines(var)
# file_write_obj.writelines('\n')
file_write_obj.close()
原始数据和处理完的数据对⽐:
怪物猎人p2可以看到语料中的数字已经被剔除了(包括⼀些不必要的特殊符号),下⾯就需要将原始语料数据中的数字提取出来。脚本如下:import re
# 以只读模式读取⽂件
file = open("C:/Users/86159/", "r", encoding='utf-8')
# 创建⼀个列表
lines = []
# 逐⾏将⽂本存⼊列表lines中
for i in file:
lines.append(i)
file.close()
# 创建⼀个新的列表
new = []
# 逐⾏遍历,将每⾏中的数字提取出来,放⼊到新的列表中
for line in lines:
pattern = repile(r'\d+')
res = re.findall(pattern, line)
for a in res:
new.append(a)
# 将列表转化为集合,将列表中的重复内容去重,再转化为列表
new = list(set(new))
# 以写的⽅式打开⽂件,如果⽂件不存在,就会⾃动创建,如果存在就会覆盖原⽂件
file_write_obj = open("C:/Users/86159/", 'w')
for var in new:
file_write_obj.writelines(var)
file_write_obj.writelines('\n')
file_write_obj.close()
如下图所⽰,提取的数字去重后如下图。
将去除数字的汉字⽂本和去除汉字的数字⽂本合并起来,然后将⽂本打乱(⽣成的语料⽂本就没有规律了,这样⽐较科学),合成语料⽂本脚本如下:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论