微调tesseract-ocr识别IPA(失败)

前言

尝试使用 tesseract OCR 模型识别 IPA 字符,加速录入过程。失败过程记录。

缘起

如果你有看前面的文章那你应该知道我维护了一个方言网站,它的地址在这里。这个网站建设还相当不完整,因为一般的 OCR 软件实在是没法识别这些古古怪怪的 IPA 字符,例如ɕ、ø、ɛ、ə、ɔ、ã……带声调的拉丁字母和希腊字母在中文语境下已经够少见了,IPA 字符却还包括一些反写、倒写的拉丁字母,这就更难指望它们了。所以过去若干篇幅的音标,都是我一个个手动校对录入的。

这样低效率的解决方案可不优雅。实际上音标中涉及的只有 5 个数字+约 30 来个字母,拢共只有十个不到的特殊字符。字符集也不算很大,似乎在别人的现有模型上进行一些微调是可行方案?

安装

简单的搜索之后就找到了一篇文章(参考文献 1)介绍了一个模型:tesseract-OCR。博主介绍到 tesseract-OCR 在字母识别上优于 easyOCR,这和我们的情境一致,再看 GitHub 星星也很多。于是沿着该博主给的方案前进。

开始前先介绍我的环境:

  • Windows 11 24 H 2
  • WSL 2 Ubuntu 22.04
    安装 tesseract OCR 可以直接通过 apt 进行 (参考文献 2)
1
2
sudo apt install tesseract-ocr
sudo apt install libtesseract-dev

目前提供的是 4.0 版本,默认仅安装英语。

要安装其它语言也可以直接通过 apt 搜索,需要注意所有语言都使用三个字母进行缩写(而非常见的两个)。以补充安装中文(简体)为例:

1
sudo apt install tesseract-ocr-chi-sim

这里是第一个错误,熬夜熬傻了,一开始拿的英文做训练,后来才意识到词表里面中文也不少,拿英文模型做训练会把汉字全识别成乱码。

补充素材

要补充训练需要有 TIF 格式的图片,可以下载这个叫 jTessBoxEditor 的工具,需要注意是下方下载列表的第二个(或者第一个也行?🤔)而非最上方的 latest。我们使用的是一个越南语 OCR 的附带小工具。

看它 README 可以知道这个工具本来是针对 tesseract 2. 0 X 和 3.0 X 开发的,只可惜不支持 4.0 X。

简单地在一个文本框中输入我们需要的特殊字符,然后截个图保存。打开 jTessBoxEditor,把 png 格式的图片转化为 tif 格式。

打开→Tools→merge TIFF→选择文件 →选择输出路径和输出名字

然后输入命令导出对应的 .box 文件。.box 文件记录了切分字符的方式。

1
tesseract inputfile.tif outputfile -l chi_sim --psm 7 batch.nochop makebox

其中

  • inputfile.tif 是前面创建的 tif 文件
  • outputfile 是输出的 .box 文件的文件名
  • -l 指定语言(这里是中文简体)
  • --psm 指定模式,这里 7 表示单行

不带任何参数输出往往都能看到解释信息,因此下面就自提紧要部分了。

同样打开 jTessBoxEditor,点击顶栏下一栏的 Box Editor,即可编辑表示的字符、方框坐标长宽等信息,最后保存。

这个编辑器用来最后检查所有的坐标是否对齐确实有用,但是编辑体验相当糟糕。由于 box 文件实际上就是一个空格分隔的表,你可以直接记事本打开后拷贝到 excel 中进行修改。下面是几个要点:

  • 每行的第一列表示对应的字符
  • 接下来的四个字符表示 LDTR
  • 可以使用 Excel 通过 LD 计算 TR 值,保证宽高大体正确

微调的一般流程

tessdata_best 上下载对应的各语言最佳效果模型。

apt 安装的模型进行了其它调整,不能直接用于训练。详见官方文档。

下载下来的 .traineddata 文件事实上整合了包括模型在内的若干文件。其中,模型是以 .lstm 结尾的,这是因为从 4.0 开始 tesseract 基于 lstm 深度学习算法。从中提取模型

1
combine_tessdata -e chi_sim.traineddata chi_sim.lstm

🎯 combine_tessdata -u filename 查看 .traineddata 中的所有文件。

接着将我们的 tif 文件转化为待训练集合 .ltsmf 文件

1
tesseract input.tif outputfile -l chi_sim --psm 7 lstm.train

新键一个文件写入 .lstmf 的路径,命名可以叫 train_listfile

再新键一个文件 .sh 写入运行训练命令(注意替换地址)

1
2
3
4
5
6
7
8
lstmtraining \
--model_output=".../testOcr/output/" \
--continue_from=".../testOcr/chi_sim.lstm" \
--train_listfile=".../testOcr/chi_sim.training_files" \
--traineddata="chi_sim.traineddata" \
--debug_interval -1 \
--max_iterations 2000 \
--target_error_rate 0.01

然后运行命令。

训练顺利结束,再新键一个 .sh 文件写下这串命令(注意替换地址)

1
2
3
4
lstmtraining --stop_training \
--traineddata="/.../testOcr/chi_sim.traineddata" \
--continue_from="/.../testOcr/output/_checkpoint" \
--model_output="/.../testOcr/ipa.traineddata"

其中第一项是我们拿来的基础模型,第二项是训练过程中生成的检查点文件,第三项是输出文件(注意后缀名)。

最后将我们的模型拷贝到 tesseract 放模型的地址即可调用我们的模型了(输入时省略后缀名)。注意这里我和参考文献 1 给出的地址并不一致。我的是 /usr/share/tesseract-ocr/4.00/tessdata/,不确定的话,用 find 查找一下你的安装地址

find / -name eng.traineddata

我遇到的困难和麻烦

整个过程主要是犯了两个错误,第一个就是没看书(没错,网站建设摸了很久了)就直接操刀,结构拿英语模型进行训练,中文直接全部变乱码了。

另一个错误更麻烦一点就是直接在 .box 文件中写对应的特殊字符。倒不是说这样不行,但是要改就得全都改,还得要在 .traindeddata 文件中的 .unicharset 等中添加好对应的字符集信息才行。到这儿就得要去仔细地看看文档和论坛讨论了。随后还有一个就是即使添加好了字符,也得要输入足量的字符进行学习。到这儿问题就不太对了:既然如此,一些本来我就用不到的字符我直接删掉避免出现这个结果不好吗?直接重新训练一个不好吗?于是就此打住。关于一些我觉得有价值的信息,可以看参考文献 3 和参考文献 4。总之,如果直接修改 .box 文件,那么有下面这样的错误

1
2
Encoding of string failed! Failure bytes:......
Can't encode transcription:...... in language ''

(最后让它跑起来的解决方案倒也简单,并不是所有的字符都在拼音中被用到了,使用没有被用到的进行替换即可,如 b, d, z, r……)

然而,成功跑起来之后发现,整体的识别成功率仍然不尽如人意。实际上不仅是字母和标声调的数字很容易识别不准,就连汉字也有若干错误。总之成功率略显感人。只能暂且放弃。

参考文献

  1. 如何训练专属的 OCR 文字识别模型_easyocr 训练自己的模型-CSDN 博客: https://blog.csdn.net/SEU_Calvin/article/details/134517629
  2. Introduction | tessdoc: https://tesseract-ocr.github.io/tessdoc/Installation.html
  3. Can’t encode transcription · Issue #2695 · tesseract-ocr/tesseract: https://github.com/tesseract-ocr/tesseract/issues/2695
  4. Tesseract-OCR LSTM 模型訓練指南 - HackMD: https://hackmd.io/@garyli-wd/rJ619THsO