引自:https://blog.csdn.net/huobanjishijian/article/details/76212214
原文:https://github.com/tesseract-ocr/tesseract/wiki/TrainingTesseract-4.00
tesseract 4.0之后开始使用机器学习来进行字符识别,其训练模型的方法与以前的版本有所不同,现将其官网的手册翻译如下
(未完成)
一、引言
Tesseract 4.0中包含了一个新的基于神经元网络的识别引擎,使得识别的精度比以前的版本大大提高了,相应的,对机器的计算能力要求也有了一个显著的提高。当然对于复杂的语言,它实际上比基本Tesseract要运行得更快
和基本的Tesseract相比,神经元网络要求大量的训练数据,训练速度也慢了很多。对于拉丁语系的语言,版本中提供的训练好的模型是在400000个文本行,4500种字体上训练得到的。对于 其他语言,可能没有这么多 的字体,但它们训练的文本行数是差不多的。Tesseract的训练将需要几天到2周的时间,而不是几分钟到几个小时。即使使用了这么多的训练数据,你可能还是发现,它并不适合你特定的问题,因此你还需要重新训练模型
训练有几个可选项:
- Fine tune:从一个已经训练过的语言开始,训练你特定的数据。对那种和已有训练数据很接近、但在一些细微的地方有差别,如特定的不常用的字体的场景,这种方式是一种好的选择。即使只有少量的训练数据,这种方式也可以运行得很好
- 去掉网络的最上层(或任意层)重新训练一个新的最上层,并使用新的数据。如果fine tuning不能很好地工作,这可能是一个最好选项。对于训练一个全新的语言,如果你从一种看上去相似的语言开始的话,去掉网络的最上层仍然可以工作。
- 从零开始训练。这是一个艰巨的任务,除非你有非常充分的理由和大量的训练集。如果不是,你可能最终得到一个过拟合的网络模型,它在训练数据上表现得很好,但在实际数据上表现很差
上面几个选项看上去很不一样,实际上训练步骤几乎是一样的,除了命令行有一些不同。所以几种选项都试一下是相当容易的,考虑到时间或硬件的话,可以让它们并行执行
对于4.00版本,老的识别引擎仍然保留,也可以被训练,但它是过时了的,除非有正当的理由,以后发布的版本中可能会删除它
二、开始之前
为了训练tesseract4.0,你不需要任何神经元网络的背景知识,但这些知识可以帮助理解不同训练选项之间的差异。在深陷训练过程之前 ,请先阅读“实现简介”和tesseract3.04版本训练过程中的一些注意事项
重要提示:在你花时间和精力去训练tesseract之前,强烈推荐你阅读“质量改进”页
三、训练要求的额外库
从3.03版本开始,训练工具需要以下一些额外的库:
sudo apt-get install libicu-dev
sudo apt-get install libpango1.0-dev
sudo apt-get install libcairo2-dev
四、构建训练工具
从3.03开始,如果你从源代码编译Tesseract,那你需要使用单独的命令来创建和安装训练工具。安装好上面的额外库后,就可以在Tessercat源代码目录下运行下面的命令来生成训练 工具:
make make training sudo make training-install
下面两条命令是用来生成ScrollView.jar的,这个不是必须的(用来查看训练过程中的结果)
make ScrollView.jar export SCROLLVIEW_PATH=$PWD/java
五、软/硬件要求
在写这篇文章的时候,训练只能在小端字节序(little-endian)机器(如intel)的linux上运行。为了训练tesseract 4.0,最好是使用多核的机器(最好是4核),支持OpenMP和intel的SSE/AVX指令扩展。基本上只要有足够的内存它就可以运行,但是你的处理器越高端,它运行得更快。GPU目前还不支持。内存的使用可以使用--max_image_MB命令行参数来控制,除操作系统占用部分,你可能至少还需要1GB内存
六、训练文本要求:
对于拉丁语系的语言而言,现在版本中提供的训练好的模型数据,是经过了400000个文本行,在4500种字体训练而来,对于 其它的语言,可能没有这么多的字体,但他们也已经训练了同样多的文本行
拥有更多的训练文本、生成更多的页将是有益的,虽然神经元网络并不总是能很好的泛化,并且需要和他们运行时遇到的东西相类似的东西来进行训练。如果目标领域是一个非常限制的领域,那么所有需要大量数据的告警都可以忽略,但神经元网络配置可能需要调整
七、训练过程概述
整体的训练过程和3.04是一样的,都包括以下几步:
1. 准备训练数据
2. 渲染文本成图像+box文件(或者为已经存在的图像文件手工创建box文件)
3. 创建unicharset文件
4. (可选)创建字典数据
5. 运行tesseract来处理图像+box文件来创建训练数据集
6. 在训练集上训练
7. 合并数据文件
主要的不同是:
1. box只在文本行这一级需要,因此当从已经存在的图片数据进行训练时,它更加容易
2. .tr文件已经被.lstmf文件代替
3. 字体可以,也应该被*地混合,而不需要分开
4. 原来的多步(mf训练,cn训练,形状簇),现在改成一个单一的lstm训练
训练还不能像3.04版本那样自动化,原因如下:
1. 慢速训练过程如果停止,它很难从中间重新开始,很难自动地告诉他什么时候停止训练
2. 在如何训练一个网络时,有很多的选项(参见下文)
3. 训练模型和unicharset可以是不同的,来自基本的tesseract,但并不是必须如此
4. 理论上,对于同一种语言来说,神经元网络版的tesseract并不需要一个基本的tesseract,但是当前如果没有基本版本的tesseract,神经元网络版的tesseract不能被加载
创建训练数据的过程已经写在下面了,后面是lstm训练的指南,介绍了训练主体过程。在Linux上,你可以拷贝-粘贴这些命令到你的终端上。为了让tesstrain.sh脚本能工作,你必须 设置你的PATH到你本地的training和api路径,或者使用make install
八、创建训练数据
和基本tesseract一样,你可以从字体中渲染合成训练数据,也可以对已有的图片(如古人的手稿)进行标注。两种情况下都要求tiff/box文件对
有两种可能的方法来格式化一个box文件
1. box文件格式——选项一
在这种格式中,box文件的每一行匹配tiff图片中的一个字符
在行的结尾处,需要插入一个特殊的行来标识一行的结束
2. box文件格式——选项二(还没有实现)
在这种格式下box只需要覆盖一行文件,而不是覆盖一个单独的字符
WordStr <left> <bottom> <right> <top> <page> #<text for line including spaces>
WordStr是一个标识字符串,它指示box文件分析器从这一行的后部,#之后获取实际的文本字符串
如,文件行”What a nice sunny day!“,应该被写成
#W h a t a n i c e s u n n y d a y !
原来的单词之间的空格被省略
需要注意的是,在任何情况下,即使是像阿拉伯语这种从右向左的语言,文本的抄写(代表着box序列或者一个WordStr字符串)也应该是从左到右的顺序。换句话说,网络将从左到右来进行学习,无论哪种语言,从右到左/双向 处理将在tesseract的更高层进行
这些说明仅仅覆盖了从字体文件中渲染的情况,所以需要安装必须的字体
运行tesstrain.sh的设置和基本tesseract一样,使用--linedata_only选项来进行LSTM训练
运行如下的tesstrain.sh命令将创建训练数据,注意你的字体路径可能需要调整:
training/tesstrain.sh --fonts_dir /usr/share/fonts --lang eng --linedata_only \
--noextract_font_properties --langdata_dir ../langdata \
--tessdata_dir ./tessdata --output_dir ~/tesstutorial/engtrain
上面的命令创建LSTM训练数据,相当于训练基本tesseract时英语数据。为了创建通用目的的基于LSTM的OCR引擎,它还远远不够,但是这是一个很好的演示教程
现在试着为Impack字体创建验证数据:
training/tesstrain.sh --fonts_dir /usr/share/fonts --lang eng --linedata_only \
--noextract_font_properties --langdata_dir ../langdata \
--tessdata_dir ./tessdata \
--fontlist "Impact Condensed" --output_dir ~/tesstutorial/engeval
我们将在在后面的优化演示时使用这些数据
九、lstmtraining使用指南
1. lstmtraining命令行
lstmtraining是一个多任务的训练神经元网络工具,下面列出了它的命令行参数:
标志 | 类型 | 默认值 | 说明 |
U | string | 无 | 指向到unicharset的路径 |
script_dir | string | 无 | 指向langdata路径,用来获取unicharset和基本笔画表 |
net_spec | string | 无 | 指定网络拓扑结构 |
model_output | string | 无 | 输出文件/检查点的输出的基本路径 |
max_image_MB | int | 6000 | 缓冲图像时使用的最大内存 |
learning_rate | double | 1e-4 | SGD算法的初始学习率 |
train_mode | int | 80 | 训练模型,64为压缩的unicharset,16用于循环训练 |
net_mode | int | 192 | 网络模型 |
perfect_sample_delay | int | 4 | 当网络变好,仅仅反向传播一个好的样本在很多不好的样本被看到之后,从上一个好的样本允许通过 |
debug_interval | int | 0 | 如果不为0,则每过这么多轮后显示调试信息 |
weight_range | double | 0.1 | 初始权重的随机数取值范围 |
momentum | double | 0.9 | alpha平滑梯度时的动量值 |
max_iterations | int | 0 | 经过这么多轮训练后停止 |
target_error_rate | double | 0.01 | 如果平均错误率低于此值,则停止训练 |
continue_from | string | none | 指向之前的检查点以便继续训练或fine tune |
stop_training | bool | false | 转换训练中的检查点到一个识别模型 |
append_index | int | -1 | 去掉网络的上面几层,追加上--net_spec指定的网张来代替 |
train_listfile | string | none | 训练数据文件的列表文件 |
eval_listfile | string | none | 验证数据文件的列表文件,用来独立于训练数据对模型进行评估 |
多数flags使用默认值就可以工作,有几个是在特殊操作时要求的,但是有几个选项需要特别说明一下:
1.1 unicode字符集压缩和train_mode
LSTM在学习序列时非常好,但是当状态数变得太大时会大幅减慢。有一个经验性建议是:让LSTM学习一个长序列,要比学习许多类的短序列要好,所以对于复杂的语言(如汉语,韩语,印度语),对每个符号重新编码成一个短的序列码,比一个少数的类大类集的效果要好。--train_mode 使用64将打开这个功能开关,它也包含在默认值中。它将每一个汉字字符编码成一个3code的序列,韩文使用Jamo编码,印度文使用syllables作为他们的unicode序列。对于字符集更小的语言(如拉丁文),这些被折叠进不同的单引号形状到一个类,而双引号到一个不同的类
1.2 随机化训练数据和train_mode
为了让随机梯度下降算法能顺利工作,训练数据要求所有的样本文件可以随机打乱组合,所以训练器可以轮流读取每个文件,当到到尾时可以返回到从头开始 。这和基本tesseract训练是完全不同的
如果使用渲染代码(通过tesstrain.sh),它将打乱每个样本文件中的文本行,但你可以得到一组文件,每个包含了单一字体的训练样本。为了增加一个更多混合,你应该使用train_mode 16,即使你不想uncicharset压缩
1.3 模型输出
训练器周期性保存checkpoints文件,使用--model_output作为一个基本名字。因此它可以在任何点上停止训练,并且重新开始,使用相同的命令行,它将继续。为了强制重新开始,使用一个不同的--model_output,或者删除这个目录下的所有文件
1.4 网络模型及优化
128打开Adam优化,这似乎比平坦动量优化会更好一点。代码称它为Adagrad,但并不是说Adagrad就不用动量优化,动量优化还在。没有动量优化的平坦Adagrad完全不能工作
使用64将自动化每层的学习率,当处理过程中,训练器独立地检查每一层是否应该减少学习率,可能更小或更大的学习率来继续学习
1.5 完善采样延迟(?)
在容易的样本上训练并不是一个好主意,它只是在浪费时间,但网络并不能因此不能处理他们,所以可能会丢弃一些训练样本如果样本出现过于频繁。--perfect_sample_delay参数丢弃完好的样本,如果没有发现许多不完好的样本
1.6 调试间隔(?)
--debug_interval,默认值为0,训练器输出每100轮输出一个进展报告
如果--debug_interval -1,训练器将每轮都会输出详细的调试信息
如果--debug_interval 大于0,训练器显示几个窗口的,显示这一层的调试信息。特别的,当--debug_interval 1时,它每进入下一轮之前需要LSTMForward窗口点击一次,但在其它情况下,它将继续并且按要求的频率显示信息
注意:--debug_interval大于0时,你必须构建了ScrollView.jar,还有其它训练工具,详细参见”Building the Training Tools“
2. 从零开始训练
下面的例子是从头开始训练的命令,使用上面的命令行创建的数据
mkdir -p ~/tesstutorial/engoutput
training/lstmtraining -U ~/tesstutorial/engtrain/eng.unicharset \
--script_dir ../langdata --debug_interval 100 \
--net_spec '[1,36,0,1 Ct5,5,16 Mp3,3 Lfys64 Lfx128 Lrx128 Lfx256 O1c105]' \
--model_output ~/tesstutorial/engoutput/base \
--train_listfile ~/tesstutorial/engtrain/eng.training_files.txt \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt \
--max_iterations 5000 &>~/tesstutorial/engoutput/basetrain.log
可以打开另外一个窗口监控日志输出:
tail -f ~/tesstutorial/engoutput/basetrain.log
你应该可以观察 到,每500轮,空白将开始在CTC输出窗口,而800轮绿线将出现在LSTMForward窗口中,那有空格在图片上
到600轮时,有一个的非空格的碰撞在CTC输出中。注意这个CTC目标,它开始以同样 的高度现在高度发生变化,因为空白的输出。同时,字符和绿线的位置在LSTMTraining窗口也不精确像他们普通的那样,因为从这个网络的特殊输出,弄乱了CTC算法(CTC假定在不同的x-坐标统计独立 ,但们们很清楚不是独立 的)
到2000轮,它应该是很清楚在输出窗口中:一些微弱的黄色标志将出现,表示有一些正在成长的输出对非空和非空格,并且字符正在开始出现 在LSTMForward窗口中
到3200轮,字符错误率跌入50以下到5000轮到18%
注意,这个引擎训练部分数据与基础Tesseract使用的训练数据是相同的,但是它们的精度在其它字体上是很差的。它在训练5000轮之后停止(目前高端的机器上大约需要半个小时),此时它的字符错误率大约是25%。使用下面的命令可以运行一个单独的测试
training/lstmeval --model ~/tesstutorial/engoutput/base_checkpoint \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
76%的字符错误率?不太好
现在基础Tesseract在Impact字体上做的并不太好,但是它包含了4500多种字体,所以如果你从eng.traineddata中抽取出eng.lstm文件的话,你可以比较一下:
mkdir -p ~/tesstutorial/impact_from_full
training/combine_tessdata -e tessdata/eng.traineddata \
~/tesstutorial/impact_from_full/eng.lstm
training/lstmeval --model ~/tesstutorial/impact_from_full/eng.lstm \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
1.7%的字符错误率?非常好
为了下一节引用,我们在训练集上也运行了一个全模型集的测试
training/lstmeval --model ~/tesstutorial/impact_from_full/eng.lstm \
--eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt
字符错误率是0.047221785,单词错误率是0.24679659
你可以再训练5000轮,可以得到一个更低的错误率,但这对Impact字体并没有多少帮助
mkdir -p ~/tesstutorial/engoutput
training/lstmtraining -U ~/tesstutorial/engtrain/eng.unicharset \
--script_dir ../langdata \
--net_spec '[1,36,0,1 Ct5,5,16 Mp3,3 Lfys64 Lfx128 Lrx128 Lfx256 O1c105]' \
--model_output ~/tesstutorial/engoutput/base \
--train_listfile ~/tesstutorial/engtrain/eng.training_files.txt \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt \
--max_iterations 10000 &>>~/tesstutorial/engoutput/basetrain.log
Impact字体的字符错误率还是75%,即使当训练集的错误率已经达到字符错误率为0.86%/单词错误率为3.1%
training/lstmeval --model ~/tesstutorial/engoutput/base_checkpoint \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
training/lstmeval --model ~/tesstutorial/engoutput/base_checkpoint \
--eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt
总的来说,从头开始训练需要一个非常限制的问题,大量的训练数据,或你需要减小网络的结构使用--net_spec。否则你应该用微调方式
3. Fine Tuning
Fine Tuning就是在不改变任何网络结构、字符集的情况下,使用新的数据训练一个已有模型的过程。不需要一个unicharset,script_dir或net_spec,因为它们都可以从已有的模型中得到
training/lstmtraining --model_output /path/to/output [--max_image_MB 6000] \
--continue_from /path/to/existing/model \
[--perfect_sample_delay 4] [--debug_interval 0] \
[--max_iterations 0] [--target_error_rate 0.01] \
--train_listfile /path/to/list/of/filenames.txt
注意:--continue_from参数可以指向一个训练中的checkpoint,也可以是一个识别模型,即使文件格式不同。训练中的checkpoint文件是参model_output 开头、以checkpoint或lstm结尾的文件,像我们上面做的。让我们在上面创建的模型上开始fine tuning,来看看我们能否在Impact上工作得更好:
mkdir -p ~/tesstutorial/impact_from_small
training/lstmtraining --model_output ~/tesstutorial/impact_from_small/impact \
--continue_from ~/tesstutorial/engoutput/base_checkpoint \
--train_listfile ~/tesstutorial/engeval/eng.training_files.txt \
--max_iterations 1200
这一次训练100轮后,字符/单词的错误率达到27%/56.2%,1200轮后达到了1.4%/4.8%。现在我们做一个单独的测试:
training/lstmeval --model ~/tesstutorial/impact_from_small/impact_checkpoint \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
数据显示出一个更低的字符/单词的错误率:0.18%/0.92%,因为训练 器平均超过1000轮了,它已经改进了。这不是Impact这种字体特有的结果,我们是在整个训练集上进行测试
这是一个很有趣的例子。fine tuning是真的可以应用到全训练模型中的一个
mkdir -p ~/tesstutorial/impact_from_full
training/lstmtraining --model_output ~/tesstutorial/impact_from_full/impact \
--continue_from ~/tesstutorial/impact_from_full/eng.lstm \
--train_listfile ~/tesstutorial/engeval/eng.training_files.txt \
--max_iterations 1200
在100轮之后 ,它已经达到 了1.26%/3.98%的字符/单词错误率,在1200轮时更是达到了0.31%/1,18%的错误率。再一次,全单独的测试给出了更好的结果
training/lstmeval --model ~/tesstutorial/impact_from_full/impact_checkpoint \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
字符错误率0.2%,单词错误率0.7%。更有趣的是其它字体的影响,所以运行一个测试在之前我们用的基础训练 集上
training/lstmeval --model ~/tesstutorial/impact_from_full/impact_checkpoint \
--eval_listfile ~/tesstutorial/engtrain/eng.training_files.tx
字符错误率是0.04552459,单词错误率是0.22928254
似乎在那个数据集的结果更好。这可能是因为最初的模型已经被训练在人工降级的图片上,为了使它能学习降级的文本
总的来说,预训练好的模型可以被fine-tuned或适匹到小的数据集上,不需要做大的损害对它的一般精度
4. 只训练几层
如果你不打算修改字符集,Fine-tuning是非常好的选择。但是如果你想增加一个新的字符到一个语言中,或者你想训练克林贡语,你不太可能有大量的训练数据而且它也不太像别的东西,这时你该怎么办?你可以删除掉已有网络模型中上面的若干层,用新的随机层来代替他们,并且训练你的数据。这个命令行几乎与“从零开始训练”节中介绍的一致,只是你必须提供一个unicharset和net_spec,你也可以提供一个模型给--continue_from和--append_index参数
--append_index参数告诉训练器它将删除掉给定的索引值以上的层(从0开始,在最外层),附加的层通过--net_spec参数哪些将保存。虽然这些索引系统并不是完美地引用网络层的方式,它是一个网络规范刘品言大大简化后的结果。这个构建器将输出一个字符串代表它生成的网络,使它可以很容易地检查索引引用到想要的层
作为参考,4.0alpha版本中,chi_sim, chi_tra, guj, hin, jpn, mal, mar, pan, tel这些语言是这样训练的:
--learning_rate 10e-5
--net_spec '[1,0,0,1 Ct5,5,16 Mp3,3 Lfys64 Lfx128 Lrx128 Lfx384 O1c1]'
--net_mode 192
--perfect_sample_delay 19
其它的语言使用下面的参数训练:
--learning_rate 10e-5
--net_spec '[1,0,0,1 Ct5,5,16 Mp3,3 Lfys64 Lfx128 Lrx128 Lfx256 O1c1]'
--net_mode 192
--perfect_sample_delay 19
这两者唯一的不同是最外一个LSTM层的大小。因此在这些模型中,--append_index将保存与相关联的最外层,并且附加 上
Index layer
0 input
1 ct5,5,16
2 mp3,3
3 lfys64
4 lfx128
5 lrx128
6 lfx256/384
已有模型剩下部分的权重开始并不修改,但是允许被新的训练数据修改
例如,让我们将一个已经存在的chi_sim模型转成eng。我们将删除最外一个LSTM层(它在chi_sim模型中比在eng模型中更大)和softmax,换成一个更小的LSTM层和一个新的softmax
mkdir -p ~/tesstutorial/eng_from_chi
training/combine_tessdata -e tessdata/chi_sim.traineddata \
~/tesstutorial/eng_from_chi/eng.lstm
training/lstmtraining -U ~/tesstutorial/engtrain/eng.unicharset \
--script_dir ../langdata --debug_interval 100 \
--continue_from ~/tesstutorial/eng_from_chi/eng.lstm \
--append_index 5 --net_spec '[Lfx256 O1c105]' \
--model_output ~/tesstutorial/eng_from_chi/base \
--train_listfile ~/tesstutorial/engtrain/eng.training_files.txt \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt \
--max_iterations 5000 &>~/tesstutorial/eng_from_chi/basetrain.log
因为低层已经训练过了,这个学习比从零开始 训练要快。到400轮,已经有一些空格被输出,到500轮,一些正确的字符被输出,到1000轮,已经所有的字符几乎都正确了。到这时,它就完成了,它应该是2.6%的字符错误率和8.6%的单词错误率
试着使用全训练数据进行一个独立 测试在IMpact字体:
training/lstmeval --model ~/tesstutorial/eng_from_chi/base_checkpoint \
--eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt
training/lstmeval --model ~/tesstutorial/eng_from_chi/base_checkpoint \
--eval_listfile ~/tesstutorial/engeval/eng.training_files.txt
在全训练集,我们得到2.24%/7.36%,而在Impact上23.9%/59.3%,这已经比从头开始训练要好很多了,但是它还是过拟合了
总的来说,删除掉一个已有网络的上面几层是可以的,和从零开始 训练一样,但是需要大师的训练数据作准备,而剩余的是保留下来避免过拟合的
5. 训练过程中的错误信息
训练过程中会出现 几种错误消息,其中有些是比较重要的,而其它的则不太重要
Encoding of string failed! 当训练图像中的文本字符串不能用给定的字符集进行编码时,产生此错误。可能的原因是
1)文本中有一个不可表达的字符,如一个英镑的符号,而你的字符集中没有
2)对文本中的不可打印字符(如表格或控制字符)出现错误
3)文本中有一个不可表达的印度语字母
无论哪种原因,训练器都将训练图片忽略掉。如果这个错误不是很频繁,那它是无关紧要的,但可能指示,对于你正在训练的语言来说,你的字符集是不够的
unichar xxx is too long to encode!!(只在印度语时出现)。为了简化LSTM引擎,编码器对于unicode字符的长度有一个上限。它会把这个字母排除在可识别集之外然后继续,但是如果有很多这个的错误,那你就麻烦了
Bad box coordinates in boxfile string! LSTM训练器只需要一个完整文本行的边界信息,而不需要每个字符的,如果你在box字符串中间放入了空格,像下面这样:
<text for line including spaces> <left> <bottom> <right> <top> <page>
分析器将被弄糊涂,于是给出错误提示。对这个的boxfile字符串有一个不同的格式要求:
WordStr <left> <bottom> <right> <top> <page> #<text for line including spaces>
当训练输入不是以LSTM格式或文件不可读,并行化头就会失败。检查你的文件列表文件,看看它是否包含一个有效的文件名
No block overlapping textline: 对给定的训练数据进行布局分析,来进行分段,如果失败,将出现这个提示。这个文本行将被删除。如果它出现的不多那没什么问题,但是如果有很多,那应该是训练文本或渲染出了问题
<undecodable>出在在ALIGNED_TRUTH or OCR TEXT输出早期在训练中。它是字符集进行压缩和CTC训练的结果(参看上面的字符集压缩和训练模式)。这应该是无害的可以忽略。它出现 的频率应该随着训练的进行而越来越少
十、合并输出文件
lstmtraining程序输出两种类型的checkpoint文件:
<model_base>_checkpoint:是最终的模型文件
<model_base><char_error>_<iteration>.lstm文件会定期地被输出,以最好的训练结果。这个lstm的后缀是一个误导,好像文件格式和识别模式文件格式不同。它和checkpoint文件一样是训练的输出 ,但它更小,因为它并没有一个模型备份,如果训练运行到一个分支时将需要这个备份
这些文件都可以转化为一个识别模型:
training/lstmtraining --model_output ~/tesstutorial/eng_from_chi/eng.lstm \
--continue_from ~/tesstutorial/eng_from_chi/base_checkpoint \
--stop_training
最后,将你的新模型文件和语言模型文件合并成一个数据文件:
training/combine_tessdata -o tessdata/eng.traineddata \
~/tesstutorial/eng_from_chi/eng.lstm \
~/tesstutorial/engtrain/eng.lstm-number-dawg \
~/tesstutorial/engtrain/eng.lstm-punc-dawg \
~/tesstutorial/engtrain/eng.lstm-word-dawg
dawg文件是可选的,没有它们也可以正常工作,但它们通常提供了一些精度 上的改进
注意:Tesseract 4.00将和一个包含了lang.lstm文件的traineddata文件工作得很好。lstm-*-dawgs是可选的,如果没有这些文件,则ocr引擎模式要求使用OEM_LSTM_ONLY 模式,不需要bigrams, chichar ambigs或其它的一些文件,有这些文件甚至没有任何影响
当增加到一个已经存在的Tessearcat traineddata文件中,LSTM字符集并不要求必须与Tesseract中的字符集匹配,但是在训练LSTM和构建lstm-*-dawgs文件时则要求必须使用同样的字符集