Tesseract 4.00 训练及OCR中文识别

本文原文在[https://github.com/tesseract-ocr/tesseract/wiki/TrainingTesseract-4.00](https://github.com/tesseract-ocr/tesseract/wiki/TrainingTesseract-4.00)

翻译工具: google翻译。

介绍

Tesseract 4.00包括一个新的基于神经网络的识别引擎,与以前的版本相比,它提供了更高的准确度(在文档图像上),以换取所需计算能力的显着提高。 然而,在复杂语言上,它实际上可能比基础Tesseract更快。

神经网络需要更多的训练数据,训练速度比基础Tesseract慢很多。 对于基于拉丁语的语言,提供的现有模型数据已经过大约400种字体的训练,大约有400种字体。 对于其他脚本,没有那么多字体可用,但它们仍然在相似数量的文本行上进行过培训。 Tesseract 4.00不需要花几分钟到几个小时来训练,而是需要几天到几周。 即使有了所有这些新的训练数据,您可能会发现它不适合您的特定问题,因此您在这里想要重新训练它。

训练有多种选择:

   微调。 从现有的训练有素的语言开始,训练您的特定附加数据。 这可能适用于接近现有训练数据的问题,但在某种微妙的方式上有所不同,例如特别不寻常的字体。 即使是少量的培训数据也可以使用。

 从网络中切掉顶层(或一些任意数量的层),并使用新数据重新训练新的顶层。 如果微调不起作用,这很可能是下一个最佳选择。 如果您从最相似的外观脚本开始,切断顶层仍然可以用于训练全新的语言或脚本。

 从头开始。 这是一项艰巨的任务,除非您有一个非常有代表性且足够大的训练集来解决您的问题。 如果没有,您很可能会得到一个过度拟合的网络,该网络在训练数据方面做得很好,但在实际数据方面则不然。

虽然上述选项可能听起来不同,但除了命令行之外,训练步骤实际上几乎相同,因此考虑到并行运行它们的时间或硬件,所有方法都相对容易。

至少对于4.00,旧的识别引擎仍然存在,并且也可以被训练,但是被弃用,并且除非有充分理由保留它,否则可能在将来的版本中被删除。

在你开始之前

您不需要任何神经网络背景来训练Tesseract 4.00,但它可能有助于理解训练选项之间的差异。 在深入研究培训过程之前,请阅读实施简介,与培训Tesseract 3.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,则需要使用单独的make命令制作和安装培训工具。 安装上述附加库后,从Tesseract源目录运行以下命令:

./configure

默认情况下,如果缺少仅用于培训的依赖关系,则Tesseract配置将继续进行,但是对于培训,您必须确保安装所有这些可选依赖项,并且Tesseract的构建环境可以找到它们。 在./configure的输出中查找这些行:

checking for pkg-config... [some valid path]

checking for lept >= 1.74... yes

checking for libarchive... yes

checking for icu-uc >= 52.1... yes

checking for icu-i18n >= 52.1... yes

checking for pango >= 1.22.0... yes

checking for cairo... yes

[...]

Training tools can be built and installed with:

(当然,版本号可能会随时间而变化。 我们要找的是“是”,所有可选的依赖项都可用。)

如果configure没有说可以构建训练工具,您仍然需要添加库或确保pkg-config可以找到它们。

配置完成后,您可以尝试构建培训工具:

make

make training

sudo make training-install

构建ScrollView.jar也很有用,但不是必需的:

make ScrollView.jar

export SCROLLVIEW_PATH=$PWD/java

在带有Homebrew的macOS Mojave上

Homebrew有一种不寻常的方式来设置pkgconfig,因此您必须选择加入某些文件。 通常运行brew info包并确保将提到的PKG_CONFIG_PATH附加到此环境变量。

brew install cairo pango icu4c autoconf libffi libarchive

exportPKG_CONFIG_PATH=\

$(brew --prefix)/lib/pkgconfig:\

$(brew --prefix)/opt/libarchive/lib/pkgconfig:\

$(brew --prefix)/opt/icu4c/lib/pkgconfig:\

$(brew --prefix)/opt/libffi/lib/pkgconfig

./configure

软硬件需求

在撰写本文时,培训仅适用于Linux。 (macOS几乎可以工作;它需要对shell脚本进行轻微的修改,以解释它提供的旧版本bash以及mktemp的差异。)Windows未知,但需要msys或Cygwin。

至于运行Tesseract 4.0.0,它是有用的,但不是必需的,有一个多核(4是好)的机器,OpenMP和Intel Intrinsics支持SSE / AVX扩展。 基本上它仍会在具有足够内存的任何东西上运行,但处理器越高,它的速度就越快。 不需要GPU。 (不支持。)可以通过--max_image_MB命令行选项控制内存使用,但是您可能需要至少1GB的内存,而不是您的操作系统所占用的内存。

训练文本需求

对于基于拉丁语的语言,提供的现有模型数据已经过大约400种字体的训练,大约有400种字体。 对于其他脚本,没有那么多字体可用,但它们仍然在相似数量的文本行上进行过培训。

请注意,拥有更多的训练文本并创建更多页面是有益的,因为神经网络也不会概括,需要训练类似于它们将要运行的内容。 如果目标域严重受限,那么关于需要大量训练数据的所有可怕警告可能不适用,但可能需要更改网络规范。

训练过程概述

整体培训过程类似于培训3.04。

概念上相同:

1 准备培训文本。

2 将文本渲染为图像+框文件。 (或者为现有图像数据创建手工制作的盒子文件。)

3 制作unicharset文件。 (可以部分指定,即手动创建)。

4 从unicharset和可选字典数据中制作入门训练数据。

5 运行tesseract处理图像+框文件以制作训练数据集。

6 运行培训数据集培训。

7 合并数据文件。

关键的区别是:

 这些框只需要在文本行级别。 因此,从现有图像数据制作训练数据要容易得多。

 .tr文件由.lstmf数据文件替换。

 字体可以而且应该自由混合而不是分开。

 聚集步骤(mtraraining,cntraining,shapeclustering)用单个慢速训练步骤代替。

由于以下几个原因,培训不能像3.04培训那样自动化:

 慢速训练步骤不适合从脚本中间运行,因为如果停止可以重新启动,并且很难在完成时自动判断。

 如何训练网络有多种选择(见上文)。

 允许语言模型和unicharset与基础Tesseract使用的语言模型和unicharset不同,但不一定如此。

 没有必要使用与神经网络Tesseract相同语言的基础Tesseract。

了解训练期间使用的各种文件

与基础Tesseract一样,完成的LSTM模型及其所需的所有其他内容都会在trainingdata文件中收集。 与基础Tesseract不同,在训练期间会提供入门训练的数据文件,并且必须提前设置。 它可以包含:

 配置文件提供控制参数。

 Unicharset定义字符集。

 Unicharcompress,又名重新编码器,它将unicharset进一步映射到神经网络识别器实际使用的代码。

 标点符号模式dawg,允许在单词周围使用标点符号。

 Word dawg。 系统单词列表语言模型。

 数字dawg,具有允许的数字模式。

必须提供粗体的元素。 其他是可选的,但如果提供任何dawgs,还必须提供标点符号dawg。 一个新工具:combine_lang_model用于从unicharset和可选单词列表中制作入门训练数据。

在训练期间,训练器会编写检查点文件,这是神经网络训练器的标准行为。 如果需要,这允许停止训练并在以后再次继续训练。 可以使用--stop_training命令行标志将任何检查点转换为完整的训练数据以进行识别。

训练器还会定期将检查点文件写入培训期间实现的新的最佳状态。

通过告诉训练器从现有检查点文件或裸LSTM模型文件中继续_continue_,可以修改网络并重新训练其中的一部分,或者对特定训练数据进行微调(即使使用修改后的unicharset!) 已使用combine_tessdata从现有的训练数据文件中提取,但尚未转换为整数。

如果在--traineddata标志中更改了unicharset,与通过--continue_from提供的模型中使用的那个相比,则必须为--old_traineddata标志提供相应的训练数据文件,该文件保存单播和重新编码。 这使训练器能够计算字符集之间的映射。

训练数据通过.lstmf文件提供,这些文件是序列化的DocumentData它们包含一个图像和相应的UTF8文本转录,并且可以使用Tesseract从tif / box文件对生成,其方式与为旧引擎.tr文件创建的方式类似。

LSTM训练命令行

lstmtrainning程序是一种用于训练神经网络的多功能工具。 下表描述了其命令行选项:

标记                类型            缺省值              说明

traineddata      string            none                入门训练数据文件的路径,包含单字符,重新编码器和可选语言模型。

net_spec          string              none                指定网络的拓扑。

model_output    string            none            model files/checkpoints.输出目录

max_image_MB    int            6000            用于缓存图像的最大内存量。

sequential_training bool        false            设置为true以进行序列培训。 默认是以循环方式处理所有训练数据。

net_mode            int                192            来自NetworkFlags in network.h的标志。 可能的值:128为Adam优化而不是动量; 64允许不同的层具有自己的学习速率,自动发现。

perfect_sample_delay    int    0                    当网络变得良好时,自从允许最后一个完美的样本以来,在看到许多不完美的样本之后,只能提供完美的样本。

debug_interval        int            0                    如果非零,则每隔多次迭代显示可视调试。

weight_range          double    0.1                权重初始化值范围

momentum                double    0.5              α平滑渐变的动量。

adam_beta            double        0.999            ADAM算法中的平滑因子平方梯度。

max_iterations        int            0                    停止训练前迭代次数

target_error_rate     double      0.01              如果平均百分比错误率低于此值,停止训练。

continue_from        string        none            上一个检查点的路径,可以从中继续训练或微调。

stop_training        bool            false            将--continue_from中的训练检查点转换为识别模型。

convert_to_int        bool          false            使用stop_training,转换为8位整数以获得更高的速度,精度稍差。

append_index        int            -1                在给定索引处切断网络的头部并附加--net_spec网络代替切断部分。

train_listfile            string        none            列出培训数据文件的文件的文件名。

eval_listfile            string        none            列出评估数据文件的文件的文件名,该评估数据文件用于独立于训练数据评估模型。

大多数标志都使用默认值,有些只是下面列出的特定操作所必需的,但首先是对更复杂标志的一些详细注释:

Unicharset Compression-recoding

LSTM非常适合学习序列,但是当状态数量太大时,LSTM会减慢很多。有实证结果表明,要求LSTM学习长序列而不是许多类的短序列是更好的,因此对于复杂的脚本(Han,Hangul和印度语脚本),最好将每个符号重新编码为来自少数类的短代码序列,而不是具有大量类的代码。 combine_lang_model命令默认启用此功能。它将每个汉字字符编码为1-5个代码的可变长度序列,Hangul使用Jamo编码作为3个代码的序列,以及其他脚本作为其unicode组件的序列。对于使用virama字符生成合取辅音的脚本(所有印度语脚本加缅甸和高棉语),函数NormalizeCleanAndSegmentUTF8将virama与适当的邻居配对,以在unicharset中生成更加面向字形的编码。要充分利用此改进,应为combine_lang_model脚本设置--pass_through_recoder标志。

随机化训练数据和序列训练

为了使随机梯度下降能够正常工作,训练数据应该在所有样本文件中随机混合,因此训练者可以依次读取每个文件的路径并在到达结束时返回第一个文件。

如果使用渲染代码(通过tesstrain.sh),那么它将随机播放每个文件中的示例文本行,但是您将获得一组文件,每个文件包含来自单个字体的训练样本。 要添加更均匀的混合,默认设置是依次处理每个文件中的一个样本,即“循环”样式。 如果您以其他方式生成了训练数据,或者它们都来自相同的样式(例如手写的手稿),那么您可以使用--sequential_training标志进行lstmtraining。 这样的内存效率更高,因为它一次只从两个文件加载数据,并按顺序处理它们。 (第二个文件是预读的,因此在需要时就可以使用了。)

模型输出

训练器使用--model_output作为基本名称定期保存检查点。 因此,可以在任何时候停止训练,并使用相同的命令行重新启动它,它将继续。 要强制重新启动,请使用其他--model_output或删除所有文件。

网络模型和优化

128标志打开Adam优化,这似乎比普通动量好很多。

64标志启用自动层特定学习速率。 当进度停滞时,训练员调查哪些层应该独立地降低他们的学习率,并且可以降低一个或多个学习率以继续学习。

net_mode的默认值为192,可启用Adam和特定于图层的学习速率。

完美的样品延迟

对“简单”样本进行培训不一定是个好主意,因为这是浪费时间,但不应该让网络忘记如何处理它们,因此如果它们即将到来就可以丢弃一些简单的样本 过于频繁。 如果自上次完美样本以来没有看到那么多不完美的样本,则--perfect_sample_delay参数会丢弃完美样本。 当前默认值为零使用所有样本。 在实践中,该值似乎没有产生巨大影响,并且如果允许训练运行足够长时间,则零产生最佳结果。

调试间隔和可视化调试

使用零(默认)--debug_interval,训练器每100次迭代输出一次进度报告,类似于以下示例。

At iteration 61239/65000/65015, Mean rms=1.62%, delta=8.587%, char train=16.786%, word train=36.633%, skip ratio=0.1%, wrote checkpoint.

At iteration 61332/65100/65115, Mean rms=1.601%, delta=8.347%, char train=16.497%, word train=36.24%, skip ratio=0.1%,  wrote checkpoint.

2 Percent improvement time=44606, best error was 17.77 @ 16817

Warning: LSTMTrainer deserialized an LSTMRecognizer!

At iteration 61423/65200/65215, Mean rms=1.559%, delta=7.841%, char train=15.7%, word train=35.68%, skip ratio=0.1%,  New best char error = 15.7At iteration 45481, stage 0, Eval Char error rate=6.9447893, Word error rate=27.039255 wrote best model:./SANLAYER/LAYER15.7_61423.checkpoint wrote checkpoint.

使用--debug_interval -1,培训师为每次训练迭代输出详细的调试文本。 文本调试信息包括真实文本,识别文本,迭代次数,训练样本id(lstmf文件和行)以及几个错误度量的平均值。 在所有情况下都会显示该行的GROUND TRUTH。 仅当与GROUND TRUTH不同时,才会显示ALIGNED TRUTH和BEST OCR TEXT。

Iteration 455038: GROUND TRUTH : उप॑ त्वाग्ने दि॒वेदि॑वे॒ दोषा॑वस्तर्धि॒या व॒यम् ।

File /tmp/san-2019-03-28.jsY/san.Mangal.exp0.lstmf line 451 (Perfect):

Mean rms=1.267%, delta=4.155%, train=11.308%(32.421%), skip ratio=0%

Iteration 455039: GROUND  TRUTH : मे अपराध और बैठे दुकानों नाम सकते अधिवक्ता, दोबारा साधन विषैले लगाने पर प्रयोगकर्ताओं भागे

File /tmp/san-2019-04-04.H4m/san.FreeSerif.exp0.lstmf line 28 (Perfect):

Mean rms=1.267%, delta=4.153%, train=11.3%(32.396%), skip ratio=0%

Iteration 1526: GROUND TRUTH :

Iteration 1526: ALIGNED TRUTH :

Iteration 1526: BEST OCR TEXT :   

File /tmp/eng-2019-04-06.Ieb/eng.CuneiformComposite.exp0.lstmf line 19587 :

Mean rms=0.941%, delta=12.319%, train=56.134%(99.965%), skip ratio=0.6%

Iteration 1527: GROUND  TRUTH :

Iteration 1527: BEST OCR TEXT :

File /tmp/eng-2019-04-06.Ieb/eng.CuneiformOB.exp0.lstmf line 7771 :

Mean rms=0.941%, delta=12.329%, train=56.116%(99.965%), skip ratio=0.6%

使用--debug_interval> 0,训练器在网络层上显示几个调试信息窗口。 在--debug_interval 1的特殊情况下,它会在继续下一次迭代之前等待LSTMForward窗口中的单击,但对于所有其他窗口,它只是继续并以请求的频率绘制信息。

请注意,要使用--debug_interval> 0,您必须构建ScrollView.jar以及其他培训工具。 请参阅构建培训工具。

可视化调试信息包括:

每个网络层的前向和后向窗口。 大多数只是随机噪声,但输出/输出返回和ConvNL窗口值得一看。 输出显示最终Softmax的输出,该输出以空字符的黄线开始,并在其认为存在字符的每个点处逐渐形成黄色标记。 (x轴是图像x坐标,y轴是字符类。)输出后窗口使用相同的布局显示实际输出和目标之间的差异,但是黄色表示“给我更多” 这个“和蓝色为”给我少了这个“。 随着网络的学习,ConvNL窗口开发出您期望从底层获得的典型边缘检测器结果。

LSTMForward显示训练图像上整个网络的输出。 LSTMTraining显示训练图像上的训练目标。 在两者中,绘制绿线以显示每个字符的峰值输出,并且字符本身被绘制在该行的右侧。

值得关注的另外两个窗口是CTC输出和CTC目标。 这些显示网络的当前输出和目标作为输出强度与图像x坐标的线图。 而不是热图,如输出窗口,为每个字符类绘制不同的彩色线,y轴是输出强度。

TessTutorial

下面记录了创建训练数据的过程,然后是lstmtraining的教程指南,其中介绍了主要的训练过程,命令行已经过实际测试。 至少在Linux上,您应该能够将命令行复制粘贴到终端中。

要使tesstrain.sh脚本正常工作,需要将PATH设置为包含本地培训和api目录,或使用make install。

TessTutorial的一次性安装

为了成功运行TessTutorial,您需要安装tesseract和培训工具,并在某些目录中包含培训脚本和必需的训练数据文件。 这些说明仅涵盖从字体渲染的情况,因此必须首先安装所需的字体。 请注意,您的字体位置可能有所不同。

sudo apt update

sudo apt install ttf-mscorefonts-installer

sudo apt install fonts-dejavu

fc-cache -vf

按照以下说明进行TessTutorial的首次设置。

mkdir ~/tesstutorial

cd ~/tesstutorial

mkdir langdata

cd langdata

wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/radical-stroke.txt

wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/common.punc

wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/font_properties

wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/Latin.unicharset

wget https://raw.githubusercontent.com/tesseract-ocr/langdata_lstm/master/Latin.xheights

mkdir eng

cd eng

wget https://raw.githubusercontent.com/tesseract-ocr/langdata/master/eng/eng.training_text

wget https://raw.githubusercontent.com/tesseract-ocr/langdata/master/eng/eng.punc

wget https://raw.githubusercontent.com/tesseract-ocr/langdata/master/eng/eng.numbers

wget https://raw.githubusercontent.com/tesseract-ocr/langdata/master/eng/eng.wordlist

cd ~/tesstutorial

git clone --depth 1 https://github.com/tesseract-ocr/tesseract.git

cd tesseract/tessdata

mkdir best

cd best

wget https://github.com/tesseract-ocr/tessdata_best/raw/master/eng.traineddata

wget https://github.com/tesseract-ocr/tessdata_best/raw/master/heb.traineddata

wget https://github.com/tesseract-ocr/tessdata_best/raw/master/chi_sim.traineddata

创建训练数据

与基础Tesseract一样,可以选择从字体渲染合成训练数据,或标记一些预先存在的图像(例如古代手稿)。

在任何一种情况下,所需的格式仍然是tiff / box文件对,其中框只需要覆盖文本行而不是单个字符。

制作box文件

Tesseract 4接受多种格式的盒子文件用于LSTM培训,尽管它们与Tesseract 3使用的不同(详情)。

框文件中的每一行都匹配tiff图像中的“字符”(字形)。

其中 可以是单个字形或整个文本行的边界框坐标(例子)

要标记文本行尾,必须在一系列行后插入一个特殊行。

Using tesstrain.sh

运行tesstrain.sh的设置与基础Tesseract的设置相同。 使用--linedata_only选项进行LSTM培训。 请注意,拥有更多的训练文本并创建更多页面是有益的,因为神经网络也不会泛化,需要训练类似于它们将要运行的内容。 如果目标域严重受限,那么关于需要大量训练数据的所有可怕警告可能不适用,但可能需要更改网络规范。

使用tesstrain.sh创建训练数据,如下所示:

src/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引擎来说,这是非常不合适的,但它是一个很好的教程演示。

现在尝试这个来制作'Impact'字体的eval数据:

src/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教程指南

创建Starter Traineddata

lstmtraining在其命令行上获取训练有素的数据文件,以获取所需语言的所有信息。 受训数据必须至少包含一个lstm-unicharset和lstm-recoder组件,并且还可能包含三个dawg文件:lstm-punc-dawg lstm-word-dawg lstm-number-dawg配置文件也是可选的。 其他组件(如果存在)将被忽略和未使用。

没有工具可以直接创建lstm-recoder。 而是有一个工具combine_lang_model,它将input_unicharset和script_dir(script_dir指向langdata目录)和lang(lang是正在使用的语言)和可选的单词列表文件作为输入。 它从input_unicharset创建lstm-recoder并创建所有dawgs,如果提供了单词列表,则将所有内容放在一起训练的数据文件中。

从头开始训练

以下示例显示了从头开始进行培训的命令行。 使用上面命令行创建的默认训练数据尝试使用它。

mkdir -p ~/tesstutorial/engoutput

training/lstmtraining --debug_interval 100 \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --net_spec '[1,36,0,1 Ct3,3,16 Mp3,3 Lfys48 Lfx96 Lrx96 Lfx256 O1c111]' \

  --model_output ~/tesstutorial/engoutput/base --learning_rate 20e-4 \

  --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

您应该观察到,通过600次迭代,空间(白色)开始显示在CTC输出窗口上,并且通过1300次迭代,绿色线出现在LSTMForward窗口上,其中图像中有空格。

通过1300次迭代,CTC输出中存在明显的非空间凸起。请注意,由于空间的确定输出和其他字符的临时输出,因此在相同高度处开始的CTC目标现在的高度不同。同时,LSTMTraining窗口中绿线的字符和位置不像最初那样准确,因为网络的部分输出会混淆CTC算法。 (CTC假设不同x坐标之间存在统计独立性,但它们显然不是独立的。)

通过2000次迭代,应该在“输出”窗口中清楚地看到一些微弱的黄色标记出现,表示非空和非空格有一些增长的输出,并且字符开始出现在LSTMForward窗口中。

在3700次迭代之后,字符错误率降至50%以下,并且在将终止的情况下降至5000%至约13%。 (在目前使用AVX的高端机器上大约20分钟。)

请注意,此引擎是使用与传统Tesseract引擎使用的相同数量的训练数据进行训练的,但其对其他字体的准确性可能非常差。 对'Impact'字体运行独立测试:

training/lstmeval --model ~/tesstutorial/engoutput/base_checkpoint \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

85%的字符错误率? 不太好!

现在基础Tesseract在'Impact'上做得不是很好,但它包含在用于训练新LSTM版本的4500左右的字体中,所以如果你可以运行它来进行比较:

training/lstmeval --model tessdata/best/eng.traineddata \

  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

2.45%的字符错误率? 好多了!

作为下一节的参考,还要对我们一直使用的训练集运行完整模型的测试:

training/lstmeval --model tessdata/best/eng.traineddata \

  --eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt

字符错误率= 0.25047642,字错误率= 0.63389585

你可以训练另外5000次迭代,并使训练集的错误率低很多,但它对Impact字体没有多大帮助:

mkdir -p ~/tesstutorial/engoutput

training/lstmtraining \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --net_spec '[1,36,0,1 Ct3,3,16 Mp3,3 Lfys48 Lfx96 Lrx96 Lfx256 O1c111]' \

  --model_output ~/tesstutorial/engoutput/base --learning_rate 20e-4 \

  --train_listfile ~/tesstutorial/engtrain/eng.training_files.txt \

  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt \

  --max_iterations 10000 &>>~/tesstutorial/engoutput/basetrain.log

Impact的字符错误率现在> 100%,即使训练集上的错误率已降至2.68%字符/ 10.01%字:

training/lstmeval --model ~/tesstutorial/engoutput/base_checkpoint \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

这表明该模型完全过度适应所提供的训练集! 它很好地说明了当训练集未覆盖目标数据中所需的变化时会发生什么。

总之,从头开始的培训需要一个非常有限的问题,大量的培训数据,或者您需要通过减少上面的--net_spec中的某些层的大小来缩小网络。 或者,您可以尝试微调......

细微调整影响

微调是在不更改网络的任何部分的情况下在新数据上训练现有模型的过程,尽管您现在可以在字符集中添加字符。

training/lstmtraining --model_output /path/to/output [--max_image_MB 6000] \

  --continue_from /path/to/existing/model \

  --traineddata /path/to/original/traineddata \

  [--perfect_sample_delay 0] [--debug_interval 0] \

  [--max_iterations 0] [--target_error_rate 0.01] \

  --train_listfile /path/to/list/of/filenames.txt

请注意,即使文件格式不同, - continue_from arg也可以指向训练检查点或识别模型。 训练检查点是以--model_output开头并以检查点结束的文件。 可以使用combine_tessdata从现有的训练数据文件中提取识别模型。 请注意,还需要提供原始的训练数据文件,因为它包含unicharset和重新编码器。 让我们首先微调我们之前构建的模型,看看我们是否可以使它适用于'Impact':

mkdir -p ~/tesstutorial/impact_from_small

training/lstmtraining --model_output ~/tesstutorial/impact_from_small/impact \

  --continue_from ~/tesstutorial/engoutput/base_checkpoint \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --train_listfile ~/tesstutorial/engeval/eng.training_files.txt \

  --max_iterations 1200

在100次迭代后,它的字符/字错误为22.36%/ 50.0%,在1200时降至0.3%/ 1.2%。现在是一个独立的测试:

training/lstmeval --model ~/tesstutorial/impact_from_small/impact_checkpoint \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

这显示了0.0086%/ 0.057%的更好结果,因为培训师平均超过1000次迭代,并且一直在改进。 这不是Impact字体的代表性结果,因为我们正在测试训练数据!

这是一个玩具的例子。 微调的想法实际上是应用于一个完全训练的现有模型:

mkdir -p ~/tesstutorial/impact_from_full

training/combine_tessdata -e tessdata/best/eng.traineddata \

  ~/tesstutorial/impact_from_full/eng.lstm

training/lstmtraining --model_output ~/tesstutorial/impact_from_full/impact \

  --continue_from ~/tesstutorial/impact_from_full/eng.lstm \

  --traineddata tessdata/best/eng.traineddata \

  --train_listfile ~/tesstutorial/engeval/eng.training_files.txt \

  --max_iterations 400

在100次迭代之后,它具有1.35%/ 4.56%的字符/字错误,并且在400处下降到0.533%/ 1.633%。再次,独立测试给出了更好的结果:

training/lstmeval --model ~/tesstutorial/impact_from_full/impact_checkpoint \

  --traineddata tessdata/best/eng.traineddata \

  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

字符错误0.017%,单词0.120%然而,更有趣的是对其他字体的影响,因此对我们一直使用的基本训练集运行测试:

training/lstmeval --model ~/tesstutorial/impact_from_full/impact_checkpoint \

  --traineddata tessdata/best/eng.traineddata \

  --eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt

字符错误率= 0.25548592,字错误率= 0.82523491

尽管在训练集上达到了接近于零的误差,并且仅在400次迭代中实现了它,但情况稍微差一些。 请注意,超过400次迭代的进一步训练会使基本集上的错误更高。

总之,预训练模型可以微调或适应小数据集,而不会对其一般精度造成很大损害。 但是,避免过度配合仍然非常重要。

精细调整±几个字符

新功能可以在字符集中添加一些新字符,并通过微调对其进行训练,而无需大量的训练数据。

培训需要一个新的unicharset /重新编码器,可选的语言模型,以及包含旧的unicharset / rewder的旧的训练数据文件。

training/lstmtraining --model_output /path/to/output [--max_image_MB 6000] \

  --continue_from /path/to/existing/model \

  --traineddata /path/to/traineddata/with/new/unicharset \

  --old_traineddata /path/to/existing/traineddata \

  [--perfect_sample_delay 0] [--debug_interval 0] \

  [--max_iterations 0] [--target_error_rate 0.01] \

  --train_listfile /path/to/list/of/filenames.txt

让我们尝试将加号 - 减号(±)添加到现有的英语模型中。 修改langdata / eng / eng.training_text以包含一些±的样本。 我插入了14个,如下图所示:

grep ± ../langdata/eng/eng.training_text

alkoxy of LEAVES ±1.84% by Buying curved RESISTANCE MARKED Your (Vol. SPANIEL

TRAVELED ±85¢ , reliable Events THOUSANDS TRADITIONS. ANTI-US Bedroom Leadership

Inc. with DESIGNS self; ball changed. MANHATTAN Harvey's ±1.31 POPSET Os—C(11)

VOLVO abdomen, ±65°C, AEROMEXICO SUMMONER = (1961) About WASHING Missouri

PATENTSCOPE® # © HOME SECOND HAI Business most COLETTI, ±14¢ Flujo Gilbert

Dresdner Yesterday's Dilated SYSTEMS Your FOUR ±90° Gogol PARTIALLY BOARDS firm

Email ACTUAL QUEENSLAND Carl's Unruly ±8.4 DESTRUCTION customers DataVac® DAY

Kollman, for ‘planked’ key max) View «LINK» PRIVACY BY ±2.96% Ask! WELL

Lambert own Company View mg \ (±7) SENSOR STUDYING Feb EVENTUALLY [It Yahoo! Tv

United by #DEFINE Rebel PERFORMED ±500Gb Oliver Forums Many | ©2003-2008 Used OF

Avoidance Moosejaw pm* ±18 note: PROBE Jailbroken RAISE Fountains Write Goods (±6)

Oberflachen source.” CULTURED CUTTING Home 06-13-2008, § ±44.01189673355 €

netting Bookmark of WE MORE) STRENGTH IDENTICAL ±2? activity PROPERTY MAINTAINED

现在生成新的培训和评估数据:

src/training/tesstrain.sh --fonts_dir /usr/share/fonts --lang eng --linedata_only \

  --noextract_font_properties --langdata_dir ../langdata \

  --tessdata_dir ./tessdata --output_dir ~/tesstutorial/trainplusminus

src/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/evalplusminus

对新的训练数据进行微调。 这需要更多迭代,因为它只有一些新目标字符的样本:

training/combine_tessdata -e tessdata/best/eng.traineddata \

  ~/tesstutorial/trainplusminus/eng.lstm

training/lstmtraining --model_output ~/tesstutorial/trainplusminus/plusminus \

  --continue_from ~/tesstutorial/trainplusminus/eng.lstm \

  --traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \

  --old_traineddata tessdata/best/eng.traineddata \

  --train_listfile ~/tesstutorial/trainplusminus/eng.training_files.txt \

  --max_iterations 3600

在100次迭代之后,它具有1.26%/ 3.98%的字符/字错误并且在3600处下降到0.041%/ 0.185%。再次,独立测试给出了更好的结果:

training/lstmeval --model ~/tesstutorial/trainplusminus/plusminus_checkpoint \

  --traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \

  --eval_listfile ~/tesstutorial/trainplusminus/eng.training_files.txt

字符错误0.0326%,字0.128%。 更有趣的是,是否可以在“Impact”字体中识别新字符,因此对影响评估集运行测试:

training/lstmeval --model ~/tesstutorial/trainplusminus/plusminus_checkpoint \

  --traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \

  --eval_listfile ~/tesstutorial/evalplusminus/eng.training_files.txt

字符错误率= 2.3767074,字错误率= 8.3829474

这与影响数据集上原始模型的原始测试相比非常好。 此外,如果您检查错误:

training/lstmeval --model ~/tesstutorial/trainplusminus/plusminus_checkpoint \

  --traineddata ~/tesstutorial/trainplusminus/eng/eng.traineddata \

  --eval_listfile ~/tesstutorial/evalplusminus/eng.training_files.txt 2>&1 |

  grep ±

你应该看到它的所有±符号都是正确的! (包含±的每个真值行也在相应的OCR行上包含±,并且在grep输出中没有真正行没有匹配的OCR行。)

这是个好消息! 这意味着可以添加一个或多个新字符而不会影响现有的准确性,并且识别新字符的能力在某种程度上至少会推广到其他字体!

注意:进行微调时,重要的是要尝试迭代次数,因为对小数据集的过度训练会导致过度拟合。 ADAM非常适合找到使稀有类正确的必要特征组合,但它似乎比简单的优化器更适合。

只训练几层

如果您只想添加新的字体样式或需要几个新字符,那么微调就可以了,但是如果你想为克林贡语训练怎么办?你不太可能有太多的训练数据而且不像其他任何东西,所以你做什么?您可以尝试删除现有网络模型的一些顶层,用新的随机层替换其中一些,然后训练您的数据。命令行与从头开始训练大致相同,但另外您必须为--continue_from和--append_index提供模型。

--append_index参数告诉它删除具有给定索引的图层上方的所有图层(从零开始,在最外面的系列中),然后将给定的--net_spec参数附加到剩余的内容。虽然这种索引系统不是引用网络层的完美方式,但它是大大简化的网络规范语言的结果。构建器将输出与其生成的网络对应的字符串,从而可以非常轻松地检查索引是否指向了预期的层。

4.00 alpha的一个新功能是combine_tessdata可以列出训练的数据文件及其版本字符串的内容。 在大多数情况下,版本字符串包含用于训练的net_spec:

training/combine_tessdata -d tessdata/best/heb.traineddata

对chi_sim:

training/combine_tessdata -d tessdata/best/chi_sim.traineddata

请注意,层数相同,但只有大小不同。 因此,在这些模型中, - append_index的以下值将保留关联的最后一层,并附加在上面:

Index        layer

0                Input

1                Ct3,3,16

2                Mp3,3

3                Lfys48/64

4                Lfx96

5                Lrx96

6                Lfx192/512

现有模型的剩余部分中的权重最初未更改,但允许通过新的训练数据进行修改。

举个例子,让我们尝试将现有的chi_sim模型转换为eng。 我们将切断最后一个LSTM层(对于chi_sim比用于训练eng模型的层更大)和softmax,取而代之的是更小的LSTM层和新的softmax:

mkdir -p ~/tesstutorial/eng_from_chi

training/combine_tessdata -e tessdata/best/chi_sim.traineddata \

  ~/tesstutorial/eng_from_chi/eng.lstm

training/lstmtraining --debug_interval 100 \

  --continue_from ~/tesstutorial/eng_from_chi/eng.lstm \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --append_index 5 --net_spec '[Lfx256 O1c111]' \

  --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 3000 &>~/tesstutorial/eng_from_chi/basetrain.log

由于较低层已经过训练,因此这比从头开始训练要快一些。 在600次迭代中,它突然开始产生输出,到800时,它已经使大多数字符正确。 当它停止在3000次迭代时,它应该是6.00%字符/ 22.42%字。

尝试完整训练集的常规测试:

training/lstmeval --model ~/tesstutorial/eng_from_chi/base_checkpoint \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --eval_listfile ~/tesstutorial/engtrain/eng.training_files.txt

和Impact字体的独立测试:

training/lstmeval --model ~/tesstutorial/eng_from_chi/base_checkpoint \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --eval_listfile ~/tesstutorial/engeval/eng.training_files.txt

在完整的训练组中,我们得到5.557%/ 20.43%和冲击36.67%/ 83.23%,这比从刮伤训练好得多,但仍然严重过度拟合。

总之,可以从头开始切断现有网络和火车的顶层,但仍需要相当大量的训练数据以避免过度拟合。

来自训练的错误信息

运行培训时可能会出现各种错误消息,其中一些可能很重要,而另一些则不是很重要:

字符串编码失败! 无法使用给定的unicharset编码训练图像的文本字符串时的结果。 可能的原因是:

1 文中有一个没有代表性的角色,比如一个不在你的unicharset中的英镑符号。

2 文本中的杂散不可打印字符(如制表符或控制字符)。

3 文中没有代表性的印度语字素/ aksara。

无论如何,它将导致训练者忽略训练图像。 如果错误很少发生,则无害,但可能表明您的unicharset不足以代表您正在训练的语言。

Unichar xxx太长了无法编码!! (最有可能只有印度语)。 可以在重新编码器中使用的unicode字符的长度有一个上限,这简化了LSTM引擎的unicharset。 它会继续并让Aksara离开可识别的组合,但如果有很多,那么你就麻烦了。

boxfile字符串中的坏框坐标! LSTM训练器仅需要完整文本行的边界框信息,而不是字符级别,但如果在框字符串中放置空格,则如下所示:

解析器会混淆并给你错误信息。

当训练输入不是LSTM格式或文件不可读时,会发生反序列化标题失败。 检查文件列表文件以查看它是否包含有效的文件名。

没有块重叠文本行:当布局分析无法正确分割作为训练数据给出的图像时发生。 文本行被删除。 没有太多问题,但如果有很多问题,培训文本或渲染过程可能出现问题。

可以在训练早期的ALIGNED_TRUTH或OCR TEXT输出中出现。 这是unicharset压缩和CTC训练的结果。 (参见上面的Unicharset Compression和train_mode)。 这应该是无害的,可以安全地忽略。 随着训练的进行,它的频率应该下降。

组合输出文件

lstmtraining程序输出两种检查点文件:

1 _checkpoint是最新的模型文件。

2 _ .checkpoint定期写为具有最佳训练错误的模型。 它就像检查点一样是一个训练转储,但是更小,因为如果训练发生分歧,它就没有备用模型可供使用。

这些文件中的任何一个都可以转换为标准的训练数据文件,如下所示:

training/lstmtraining --stop_training \

  --continue_from ~/tesstutorial/eng_from_chi/base_checkpoint \

  --traineddata ~/tesstutorial/engtrain/eng/eng.traineddata \

  --model_output ~/tesstutorial/eng_from_chi/eng.traineddata

这将从训练转储中提取识别模型,并将其插入到--traineddata参数中,以及unicharset,rewder和训练期间提供的任何dawgs。

注意Tesseract 4.00现在可以使用训练有素的数据文件快乐地运行,该文件只包含lang.lstm,lang.lstm-unicharset和lang.lstm-recoder。lstm  -  *  -  dawgs是可选的,并且OEM_LSTM_ONLY不需要或使用其他任何组件作为OCR引擎模式。不需要bigrams,unichar ambigs或任何其他组件,如果存在,甚至没有任何影响。执行任何操作的唯一其他组件是lang.config,它可以影响布局分析和子语言。

如果添加到现有的Tesseract训练数据文件,则lstm-unicharset不必与Tesseract unicharset匹配,但必须使用相同的unicharset来训练LSTM并构建lstm  -  *  -  dawgs文件。

OCR中文识别

下面用tesseract预训练的lstm模型来识别图片中的中文。原始图片未作去噪处理,手机拍后直接提交给tesseract识别。

从这里下载中文预训练模型chi_sim.traineddata文件,复制到tesseract安装目录下的tessdata目录下,然后在命令行执行:

tesseract imgfile result -l chi_sim

imgfile是要识别的图片文件名,识别结果放在当前目录的result.txt中。 -l chi_sim表示用刚才下载的模型进行识别。


tesseract 识别结果:



序言

在 人 工 智能 界 有 一 种 说 法 , 认为 机 器 学 习 是 人 工 智能 领域 中 最 能 够 体现 智能 的 一 个 分 支 从 历 更

来 看 , 机 器 学 习 似乎 也 是 人 工 智能 中 发 展 最 快 的 分 支 之 一 . 在 三 十 世纪 从 二 年 代 的 时 候 , 符号 学 习 可

能 还 是 机 器 学 习 的 主流 , 而 自从 三 十 世纪 九 十 年 代 以 来 , 就 三 直 是 统计 机 器 学 习 的 天 下 了 不 知道 是

否 可 以 这 样 认为 : 从 主流 为 符号 机 器 学 习 发 展 到 主流 为 统计 机 器 学 习 , 反映 了 机 器 学 习 从 纯粹 的 理论

研究 和 模型 研究 发 展 到 以 解决 现实 生活 中 实际 问题 为 目的 的 应 用 研究 这 是 科学 研究 的 三 种 进步 有

关机 器 学 习 的 专著 国内 出 版 的 不 是 很 多 . 前 两 年 有 李 航 教授 的 《统计 学 习 方法 丸 出 版 ,以 衔 要 的 方式

介绍 了 一 批 重要 和 常用 的 机 器 学 习 方法 . 此 次 周志 华 教授 的 鸿 篇 巨著 《机 器 学 习 丸 则 休 面 而 详细 炖 汞

绍 了 机 器 学 习 的 各 个 分 支 , 既 可 作为 教材 , 又 可 作为 自学 用 书 和 科研 参考 书



几个大写的数字和》以及倒数第二行的“介”识别错误,错误率2%左右。

你可能感兴趣的:(Tesseract 4.00 训练及OCR中文识别)