{"id":21023957,"url":"https://github.com/linxueyuanstdio/latex_ocr","last_synced_at":"2025-04-05T04:11:37.286Z","repository":{"id":37601937,"uuid":"169225673","full_name":"LinXueyuanStdio/LaTeX_OCR","owner":"LinXueyuanStdio","description":":gem: 数学公式识别 Math Formula OCR","archived":false,"fork":false,"pushed_at":"2023-03-24T22:42:10.000Z","size":513489,"stargazers_count":526,"open_issues_count":5,"forks_count":104,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-29T03:06:42.782Z","etag":null,"topics":["deep-learning","latex","ocr"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LinXueyuanStdio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-02-05T10:49:13.000Z","updated_at":"2025-03-24T02:58:34.000Z","dependencies_parsed_at":"2024-01-17T00:35:07.534Z","dependency_job_id":null,"html_url":"https://github.com/LinXueyuanStdio/LaTeX_OCR","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LinXueyuanStdio%2FLaTeX_OCR","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LinXueyuanStdio%2FLaTeX_OCR/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LinXueyuanStdio%2FLaTeX_OCR/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LinXueyuanStdio%2FLaTeX_OCR/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LinXueyuanStdio","download_url":"https://codeload.github.com/LinXueyuanStdio/LaTeX_OCR/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284949,"owners_count":20913704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","latex","ocr"],"created_at":"2024-11-19T11:21:34.631Z","updated_at":"2025-04-05T04:11:37.246Z","avatar_url":"https://github.com/LinXueyuanStdio.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LaTeX OCR\r\n\u003e 本项目增强版：[LaTeX_OCR_PRO](https://github.com/LinXueyuanStdio/LaTeX_OCR_PRO)\r\n* [1. 搭建环境](#1-搭建环境)\r\n    * [Linux](#linux)\r\n    * [Mac](#mac)\r\n* [2. 开始训练](#2-开始训练)\r\n    * [生成小数据集、训练、评价](#生成小数据集训练评价)\r\n    * [生成完整数据集、训练、评价](#生成完整数据集训练评价)\r\n* [3. 可视化](#3-可视化)\r\n    * [可视化训练过程](#可视化训练过程)\r\n    * [可视化预测过程](#可视化预测过程)\r\n* [4. 评价](#4-评价)\r\n* [5. 模型的具体实现细节](#5-模型的具体实现细节)\r\n    * [总述](#总述)\r\n    * [数据获取和数据处理](#数据获取和数据处理)\r\n    * [模型构建](#模型构建)\r\n* [6. 踩坑记录](#6-踩坑记录)\r\n    * [win10 用 GPU 加速训练](#win10-用-gpu-加速训练)\r\n    * [如何可视化Attention层](#如何可视化attention层)\r\n* [致谢](#致谢)\r\n\r\nSeq2Seq + Attention + Beam Search。\r\n\r\n![](./art/6.png)\r\n![](./art/visualization_6_short.gif)\r\n![](./art/12.png)\r\n![](./art/visualization_12_short.gif)\r\n![](./art/14.png)\r\n![](./art/visualization_14_short.gif)\r\n\r\n结构\r\n\r\n![](./art/architecture.jpg)\r\n\r\n## 1. 搭建环境\r\n\r\n1. python3.5 + tensorflow1.12.2\r\n2. latex (latex 转 pdf)\r\n3. ghostscript (图片处理)\r\n4. magick (pdf 转 png)\r\n\r\n### Linux\r\n\r\n一键安装\r\n```shell\r\nmake install-linux\r\n```\r\n或\r\n1. 安装本项目依赖\r\n```shell\r\nvirtualenv env35 --python=python3.5\r\nsource env35/bin/activate\r\npip install -r requirements.txt\r\n```\r\n2. 安装 latex (latex 转 pdf)\r\n```shell\r\nsudo apt-get install texlive-latex-base\r\nsudo apt-get install texlive-latex-extra\r\n```\r\n3. 安装 ghostscript\r\n```shell\r\nsudo apt-get update\r\nsudo apt-get install ghostscript\r\nsudo apt-get install libgs-dev\r\n```\r\n4. 安装[magick](https://www.imagemagick.org/script/install-source.php) (pdf 转 png)\r\n```shell\r\nwget http://www.imagemagick.org/download/ImageMagick.tar.gz\r\ntar -xvf ImageMagick.tar.gz\r\ncd ImageMagick-7.*; \\\r\n./configure --with-gslib=yes; \\\r\nmake; \\\r\nsudo make install; \\\r\nsudo ldconfig /usr/local/lib\r\nrm ImageMagick.tar.gz\r\nrm -r ImageMagick-7.*\r\n```\r\n\r\n### Mac\r\n\r\n一键安装\r\n\r\n```shell\r\nmake install-mac\r\n```\r\n\r\n或\r\n1. 安装本项目依赖\r\n```shell\r\nsudo pip install -r requirements.txt\r\n```\r\n2. LaTeX 请自行安装\r\n\r\n3. 安装[magick](https://www.imagemagick.org/script/install-source.php) (pdf 转 png)\r\n\r\n```shell\r\nwget http://www.imagemagick.org/download/ImageMagick.tar.gz\r\ntar -xvf ImageMagick.tar.gz\r\ncd ImageMagick-7.*; \\\r\n./configure --with-gslib=yes; \\\r\nmake;\\\r\nsudo make install; \\\r\nrm ImageMagick.tar.gz\r\nrm -r ImageMagick-7.*\r\n```\r\n## 2. 开始训练\r\n\r\n### 生成小数据集、训练、评价\r\n\r\n提供了样本量为 100 的小数据集，方便测试。只需 2 分钟就可以根据 `./data/small.formulas/` 下的公式生成用于训练的图片。\r\n\r\n一步训练\r\n\r\n```\r\nmake small\r\n```\r\n或\r\n\r\n1. 生成数据集\r\n\r\n   用 LaTeX 公式生成图片，同时保存公式-图片映射文件，生成字典 __只用运行一次__\r\n\r\n    ```shell\r\n    # 默认\r\n    python build.py\r\n    # 或者\r\n    python build.py --data=configs/data_small.json --vocab=configs/vocab_small.json\r\n    ```\r\n\r\n2. 训练\r\n    ```\r\n    # 默认\r\n    python train.py\r\n    # 或者\r\n    python train.py --data=configs/data_small.json --vocab=configs/vocab_small.json --training=configs/training_small.json --model=configs/model.json --output=results/small/\r\n    ```\r\n\r\n3. 评价预测的公式\r\n    ```\r\n    # 默认\r\n    python evaluate_txt.py\r\n    # 或者\r\n    python evaluate_txt.py --results=results/small/\r\n    ```\r\n\r\n4. 评价数学公式图片\r\n\r\n    ```\r\n    # 默认\r\n    python evaluate_img.py\r\n    # 或者\r\n    python evaluate_img.py --results=results/small/\r\n    ```\r\n\r\n\r\n### 生成完整数据集、训练、评价\r\n\r\n根据公式生成 70,000+ 数学公式图片需要 `2`-`3` 个小时\r\n\r\n一步训练\r\n\r\n```\r\nmake full\r\n```\r\n或\r\n\r\n1. 生成数据集\r\n\r\n   用 LaTeX 公式生成图片，同时保存公式-图片映射文件，生成字典 __只用运行一次__\r\n    ```\r\n    python build.py --data=configs/data.json --vocab=configs/vocab.json\r\n    ```\r\n\r\n2. 训练\r\n    ```\r\n    python train.py --data=configs/data.json --vocab=configs/vocab.json --training=configs/training.json --model=configs/model.json --output=results/full/\r\n    ```\r\n\r\n3. 评价预测的公式\r\n    ```\r\n    python evaluate_txt.py --results=results/full/\r\n    ```\r\n\r\n4. 评价数学公式图片\r\n    ```\r\n    python evaluate_img.py --results=results/full/\r\n    ```\r\n## 3. 可视化\r\n\r\n### 可视化训练过程\r\n\r\n用 tensorboard 可视化训练过程\r\n\r\n小数据集\r\n\r\n```\r\ncd results/small\r\ntensorboard --logdir ./\r\n```\r\n\r\n完整数据集\r\n\r\n```\r\ncd results/full\r\ntensorboard --logdir ./\r\n```\r\n### 可视化预测过程\r\n\r\n打开 `visualize_attention.ipynb`，一步步观察模型是如何预测 LaTeX 公式的。\r\n\r\n或者运行\r\n\r\n```shell\r\n# 默认\r\npython visualize_attention.py\r\n# 或者\r\npython visualize_attention.py --image=data/images_test/6.png --vocab=configs/vocab.json --model=configs/model.json --output=results/full/\r\n```\r\n\r\n可在 `--output` 下生成预测过程的注意力图。\r\n\r\n## 4. 评价\r\n\r\n|      指标       | 训练分数 | 测试分数 |\r\n| :-------------: | :------: | :------: |\r\n|   perplexity    |   1.39   |   1.44   |\r\n|  EditDistance   |  81.68   |  80.45   |\r\n|     BLEU-4      |  78.21   |  75.42   |\r\n| ExactMatchScore |  13.93   |  12.44   |\r\n\r\nperplexity 是越接近1越好，其余3个指标是越大越好。ExactMatchScore 比较低，继续训练应该可以到 70 以上。机器不太好，训练太费时间了。\r\n\r\n\r\n## 5. 模型的具体实现细节\r\n\r\n### 总述\r\n\r\n首先我们获取到足够的公式，对公式进行规范化处理，方便划分出字典。然后通过规范化的公式使用脚本生成图片，具体用到了latex和ghostscript和magick，同时保存哪个公式生成哪个图片，保存为公式-图片映射文件。这样我们得到了3个数据集：规范化的公式集，图片集，公式-图片映射集，还有个附赠品：latex字典。这个字典决定了模型的上限，也就是说，模型预测出的公式只能由字典里的字符组成，不会出现字典以外的字符。\r\n\r\n然后构建模型。\r\n\r\n模型分为3部分，数据生成器，神经网络模型，使用脚本。\r\n\r\n数据生成器读取公式-图片映射文件，为模型提供(公式, 图片)的矩阵元组。\r\n\r\n神经网络模型是 Seq2Seq + Attention + Beam Search。Seq2Seq的Encoder是CNN，Decoder是LSTM。Encoder和Decoder之间插入Attention层，具体操作是这样：Encoder到Decoder有个扁平化的过程，Attention就是在这里插入的。随Attention插入的还有我们自定义的一个op，用来导出Attention的数据，做Attention的可视化。\r\n\r\n使用脚本包括构建脚本、训练脚本、测试脚本、预测脚本、评估脚本、可视化脚本。使用说明看上面的命令行就行。\r\n\r\n训练过程根据epoch动态调整LearningRate。decoder可以选择用`lstm`或`gru`，在`configs/model.json`里改就行。最后输出结果可以选择用 `beam_search` 或 `greedy`，也是在`configs/model.json`里改。\r\n\r\n### 数据获取和数据处理\r\n\r\n我们只要获取到正确的latex公式就行。因为我们可以使用脚本将latex渲染出图片，所以就不用图片数据了。\r\n\r\n原来我们想使用爬虫爬取[arXiv](https://arxiv.org/)的论文，然后通过正则表达式提取论文里的latex公式。\r\n\r\n但是最后我们发现已经有人做了这个工作，所以就用了他们的公式数据。[im2latex-100k , arXiv:1609.04938](https://zenodo.org/record/56198#.XKMMU5gzZBB)\r\n\r\n现在我们获取到latex公式数据，下面进行规范化。\r\n\r\n\u003e 为什么要规范化：如果不规范化，我们构建字典时就只能是char wise，而latex中有很多是有特定排列的指令，比如`\\lim`，这样模型需要花费额外的神经元来记住这些pattern，会使模型效果变差，也导致训练费时间。（有时根本不收敛...别问我怎么知道的...）\r\n\r\n我们先手动在代码编辑器里对数据进行规范化，很玄学地用了一些正则表达式，一步一步进行规范化。\r\n\r\n最后总结了一下，明确要构建的字典大概是什么样的，然后写了脚本来处理。\r\n\r\n然后是通过公式生成图片，保存公式-图片映射文件，构建字典。\r\n\r\n构建字典很简单，遍历公式文件的每一行，然后以空格符` `为分隔符分割成若干latex块，去掉每一块首尾空格，若非空则加入字典集，保证不重复。\r\n\r\n保存公式-图片映射文件也很简单，就是在渲染出图片后，保存`当前的公式在公式文件里的行号`和`图片路径`，写入映射文件里，也就是`.matching.txt`文件。图片文件名是直接用公式行号来命名的，比如`1234.png 1234`表示第1234行公式的公式图片是1234.png。所以知道了行号，就知道了公式图片路径。\r\n\r\n通过公式生成图片稍微复杂一点，需要用到几个库：latex、ghostscript和magick。事实上用Katex也是可以的，katex是一个渲染latex公式的js库，体积小速度快。原来我们也是打算用这个库处理，后来因为环境问题放弃了。\r\n\r\nlatex原先我的环境里有了，这是用来生成pdf文件的。执行脚本后会得到A4纸大小的一页pdf。\r\n\r\nghostscript和magick绑定在一起，用来把pdf转化为png格式的图片。\r\n\r\n转化为图片后，选定公式 padding 8个像素的方框，crop框外的空白，然后灰度化。\r\n\r\n### 模型构建\r\n\r\n让我鸽一段时间。。。有空再写！\r\n\r\n\r\n## 6. 踩坑记录\r\n\r\n### win10 用 GPU 加速训练\r\n\r\n装驱动后就行了。运行下面代码进行训练：\r\n\r\n```\r\nC:/Users/dlink/AppData/Local/Programs/Python/Python35/python.exe train.py --data=configs/data.json --vocab=configs/vocab.json --training=configs/training.json --model=configs/model.json --output=results/full/\r\n```\r\n\r\n我的环境比较奇葩，是win10+ubuntu wsl，也就是windows+linux子系统。我的GPU驱动装在win里面了，linux里没装，不过文件系统是共用的，所以用win的GPU驱动来训练模型。（嗯，python也有两套版本哈哈哈，都是python3.5）\r\n\r\n### 如何可视化Attention层\r\n\r\n在Attention层内自定义一个op，通过这个op把Attention传递到一个全局变量里。其他程序在模型预测完公式后，就可以在这个全局变量里获取到Attention。\r\n\r\n## 致谢\r\n\r\n十分感谢 Harvard 和 Guillaume Genthial 、Kelvin Xu 等人提供巨人的肩膀。\r\n\r\n论文：\r\n1. [Show, Attend and Tell(Kelvin Xu...)](https://arxiv.org/abs/1502.03044)\r\n2. [Harvard's paper and dataset](http://lstm.seas.harvard.edu/latex/)\r\n1. [Seq2Seq for LaTeX generation](https://guillaumegenthial.github.io/image-to-latex.html).\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinxueyuanstdio%2Flatex_ocr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinxueyuanstdio%2Flatex_ocr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinxueyuanstdio%2Flatex_ocr/lists"}