學(xué)公式識別算法 CAN 實(shí)戰(zhàn)指南:Counting-Aware Network 訓(xùn)練、評估與推理部署)
PaddleOCR 手寫數(shù)學(xué)公式識別算法 CAN 實(shí)戰(zhàn)指南Counting-Aware Network 訓(xùn)練、評估與推理部署【免費(fèi)下載鏈接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100 languages.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR手寫數(shù)學(xué)公式識別HMER是 OCR 領(lǐng)域中極具挑戰(zhàn)性的任務(wù)其難點(diǎn)在于公式的二維空間結(jié)構(gòu)、符號歧義與書寫隨意性。本指南以 PaddleOCR 倉庫中的 CANCounting-Aware Network算法文檔為核心完整講解該算法在 PaddleOCR 中的訓(xùn)練、評估、預(yù)測與推理部署全流程并結(jié)合 rec_d28_can.yml 配置與 rec_can_head.py 等源碼深入剖析其 Counting 模塊與 Attention Decoder 的實(shí)現(xiàn)原理幫助讀者從會跑命令進(jìn)階到理解算法。1. 算法簡介CANCounting-Aware Network由 Bohan Li、Ye Yuan、Dingkang Liang、Xiao Liu、Zhilong Ji、Jinfeng Bai、Wenyu Liu、Xiang Bai 等人提出論文《When Counting Meets HMER: Counting-Aware Network for Handwritten Mathematical Expression Recognition》發(fā)表于 ECCV 2022。其核心思想是在傳統(tǒng)的序列到序列Seq2Seq識別框架之外額外引入一個(gè)計(jì)數(shù)解碼器Counting Decoder顯式地統(tǒng)計(jì)每個(gè)數(shù)學(xué)符號在圖像中出現(xiàn)的次數(shù)以此約束注意力機(jī)制緩解手寫公式中符號密集、空間錯(cuò)位導(dǎo)致的漏識別與錯(cuò)識別問題。PaddleOCR 中 CAN 使用 CROHME 手寫公式數(shù)據(jù)集訓(xùn)練對應(yīng)測試集上的精度如下模型骨干網(wǎng)絡(luò)配置文件ExpRate下載鏈接CANDenseNetrec_d28_can.yml51.72%訓(xùn)練模型說明ExpRateExpression Recognition Rate是公式級識別準(zhǔn)確率即整條公式的符號序列完全正確的比例比字符級準(zhǔn)確率更為嚴(yán)格。2. 網(wǎng)絡(luò)結(jié)構(gòu)與源碼實(shí)現(xiàn)2.1 整體架構(gòu)CAN 在 PaddleOCR 中遵循Backbone Head的模塊化設(shè)計(jì)由 rec_d28_can.yml 中的Architecture字段定義BackboneDenseNet配置growthRate: 24、reduction: 0.5、bottleneck: True、use_dropout: True、input_channel: 1輸入為單通道灰度圖HeadCANHeadin_channel: 684DenseNet 輸出的特征通道數(shù)、out_channel: 111符號類別數(shù)、max_text_length: 36、ratio: 16特征圖相對原圖的下采樣倍數(shù)。2.2 Counting 模塊多尺度計(jì)數(shù)解碼器在 rec_can_head.py 中CANHead內(nèi)部構(gòu)造了兩個(gè)CountingDecoder分別使用卷積核大小為 3 和 5 的trans_layer提取特征并通過ChannelAtt通道注意力自適應(yīng)平均池化 兩層全連接 Sigmoid進(jìn)行通道加權(quán)最后以 1×1 卷積加 Sigmoid 輸出每個(gè)符號的計(jì)數(shù)熱力圖再按空間維度求和得到符號計(jì)數(shù)預(yù)測counting_preds1kernel_size3 的計(jì)數(shù)解碼器輸出counting_preds2kernel_size5 的計(jì)數(shù)解碼器輸出counting_preds (counting_preds1 counting_preds2) / 2兩者取平均作為最終計(jì)數(shù)向量。多尺度卷積核分別關(guān)注局部與更廣感受野的符號分布增強(qiáng)了計(jì)數(shù)模塊對密集小符號如上下標(biāo)、積分號的感知能力。2.3 Attention Decoder帶位置編碼與覆蓋率懲罰的序列解碼AttDecoder使用單層 GRUGRUCell逐符號自回歸解碼其關(guān)鍵設(shè)計(jì)包括PositionEmbeddingSine對編碼器特征疊加正弦位置編碼補(bǔ)償 CNN 缺乏位置先驗(yàn)的問題Coverage 注意力Attention模塊將歷史注意力累積alpha_sum通過卷積kernel_size11與線性層映射與當(dāng)前隱藏狀態(tài)、編碼特征相加計(jì)算注意力分?jǐn)?shù)抑制注意力重復(fù)聚焦同一區(qū)域Counting 約束融合計(jì)數(shù)向量經(jīng)counting_context_weight線性映射后與隱藏狀態(tài)、詞嵌入、上下文向量求和共同決定當(dāng)前符號的輸出分布word_prob使解碼過程知道每個(gè)符號應(yīng)該出現(xiàn)幾次。訓(xùn)練時(shí)解碼器按is_trainTrue使用教師強(qiáng)制teacher forcing逐位取標(biāo)簽labels[:, i]作為下一步輸入推理時(shí)is_trainFalse則取上一步argmax結(jié)果自回歸生成直至max_text_length默認(rèn) 36結(jié)束。2.4 損失函數(shù)與評估指標(biāo)損失函數(shù)CANLoss見 rec_can_loss.py由兩部分組成——符號序列的CrossEntropyLoss詞級損失與三個(gè)計(jì)數(shù)預(yù)測counting_preds1、counting_preds2、取平均后的counting_preds相對真實(shí)計(jì)數(shù)的SmoothL1Loss計(jì)數(shù)損失之和。真實(shí)計(jì)數(shù)標(biāo)簽由gen_counting_label按類別直方圖生成并忽略[0, 1, 107, 108, 109, 110]等特殊 token評估指標(biāo)CANMetric見 rec_metric.py基于SequenceMatcher計(jì)算字符級相似度統(tǒng)計(jì)word_rate符號級與exp_rate公式級兩個(gè)指標(biāo)配置文件中以main_indicator: exp_rate作為主指標(biāo)。3. 環(huán)境配置在開始訓(xùn)練前請先完成 PaddleOCR 運(yùn)行環(huán)境的準(zhǔn)備與項(xiàng)目代碼的克隆運(yùn)行環(huán)境準(zhǔn)備參考《運(yùn)行環(huán)境準(zhǔn)備》項(xiàng)目代碼克隆參考《項(xiàng)目克隆》。CAN 模型的訓(xùn)練數(shù)據(jù)為 CROHME 數(shù)據(jù)集官方以黑底白字手寫公式為白色、背景為黑色的格式提供。訓(xùn)練數(shù)據(jù)目錄結(jié)構(gòu)需與配置文件保持一致即./train_data/CROHME/training/images labels.txt與./train_data/CROHME/evaluation/images labels.txt。4. 模型訓(xùn)練PaddleOCR 對代碼進(jìn)行了模塊化訓(xùn)練 CAN 識別模型時(shí)需要更換配置文件為 rec_d28_can.yml。詳細(xì)訓(xùn)練流程可參考文本識別訓(xùn)練教程。4.1 啟動(dòng)訓(xùn)練完成數(shù)據(jù)準(zhǔn)備后即可啟動(dòng)訓(xùn)練# 單卡訓(xùn)練訓(xùn)練周期長不建議 python3 tools/train.py -c configs/rec/rec_d28_can.yml # 多卡訓(xùn)練通過 --gpus 參數(shù)指定卡號 python3 -m paddle.distributed.launch --gpus 0,1,2,3 tools/train.py -c configs/rec/rec_d28_can.yml4.2 訓(xùn)練參數(shù)與注意事項(xiàng)配置文件 rec_d28_can.yml 中幾個(gè)關(guān)鍵訓(xùn)練參數(shù)配置項(xiàng)默認(rèn)值說明Global.epoch_num240總訓(xùn)練輪數(shù)Global.eval_batch_step[0, 1105]每 1105 次 iteration即 1 個(gè) epochbatch_size8 時(shí)評估一次Global.character_dict_pathppocr/utils/dict/latex_symbol_dict.txtLaTeX 符號字典CAN 專用Global.max_text_length36最大輸出序列長度Optimizer.nameMomentum動(dòng)量優(yōu)化器momentum0.9clip_norm_global100.0Optimizer.lrTwoStepCosinelr0.01warmup_epoch1兩段式余弦學(xué)習(xí)率衰減Train.dataset.transforms含GrayImageChannelFormat: inverse: True黑底白字預(yù)處理灰度圖取反Train.loader.batch_size_per_card8單卡 batch sizeTrain.loader.collate_fnDyMaskCollator動(dòng)態(tài) mask 整理器用于生成圖像 mask 與標(biāo)簽 mask訓(xùn)練時(shí)需要特別注意以下兩點(diǎn)圖像顏色模式官方提供的 CROHME 數(shù)據(jù)集將手寫公式存儲為黑底白字格式因此配置中GrayImageChannelFormat.inverse: True會在灰度化后取反圖像。若您自行準(zhǔn)備的數(shù)據(jù)集為白底黑字請關(guān)閉取反python3 tools/train.py -c configs/rec/rec_d28_can.yml -o Train.dataset.transforms.GrayImageChannelFormat.inverseFalse評估頻率默認(rèn)每訓(xùn)練 1 個(gè) epoch1105 次 iteration評估 1 次該值與batch_size8掛鉤。若您更改 batch_size 或更換數(shù)據(jù)集請按數(shù)據(jù)集長度 // batch_size重新計(jì)算并覆蓋評估步數(shù)python3 tools/train.py -c configs/rec/rec_d28_can.yml -o Global.eval_batch_step[0, {length_of_dataset//batch_size}]此外標(biāo)簽編碼由CANLabelEncode見 label_ops.py完成它將 LaTeX 符號序列按空格分詞逐 token 映射為字典索引并追加結(jié)束符/s字典中不存在的符號會被跳過。因此自備數(shù)據(jù)集時(shí)務(wù)必保證標(biāo)簽序列中的符號全部存在于latext_symbol_dict.txt字典中。5. 模型評估可下載已訓(xùn)練完成的模型文件使用如下命令進(jìn)行評估# 注意將 pretrained_model 的路徑設(shè)置為本地路徑。 # 若使用自行訓(xùn)練保存的模型請注意修改路徑和文件名為 {path/to/weights}/{model_name}。 python3 -m paddle.distributed.launch --gpus 0 tools/eval.py -c configs/rec/rec_d28_can.yml -o Global.pretrained_model./rec_d28_can_train/best_accuracy.pdparams評估過程復(fù)用配置文件中Eval段的數(shù)據(jù)集與預(yù)處理同樣含GrayImageChannelFormat.inverse: True最終輸出word_rate與exp_rate兩項(xiàng)指標(biāo)其中exp_rate即文檔表中所列的 51.72%對應(yīng)官方預(yù)訓(xùn)練模型在 CROHME 測試集上的表現(xiàn)。6. 模型預(yù)測使用如下命令進(jìn)行單張圖片預(yù)測# 注意將 pretrained_model 的路徑設(shè)置為本地路徑。 python3 tools/infer_rec.py -c configs/rec/rec_d28_can.yml -o Architecture.Head.attdecoder.is_trainFalse Global.infer_img./doc/datasets/crohme_demo/hme_00.jpg Global.pretrained_model./rec_d28_can_train/best_accuracy.pdparams # 預(yù)測文件夾下所有圖像時(shí)可修改 infer_img 為文件夾如 Global.infer_img./doc/datasets/crohme_demo/。關(guān)鍵點(diǎn)說明Architecture.Head.attdecoder.is_trainFalse必須顯式指定使解碼器切換為自回歸推理模式訓(xùn)練時(shí)為教師強(qiáng)制模式預(yù)測的輸入圖像要求為黑底白字與訓(xùn)練數(shù)據(jù)一致手寫公式為白色、背景為黑色若自行訓(xùn)練時(shí)修改過字典需同步檢查Global.character_dict_path指向的字典文件是否正確。7. 推理部署7.1 導(dǎo)出 Inference 模型首先將訓(xùn)練得到的最優(yōu)模型轉(zhuǎn)換成靜態(tài)圖 inference model。以官方訓(xùn)練完成的模型為例模型下載地址# 注意將 pretrained_model 的路徑設(shè)置為本地路徑。 python3 tools/export_model.py -c configs/rec/rec_d28_can.yml -o Global.pretrained_model./rec_d28_can_train/best_accuracy.pdparams Global.save_inference_dir./inference/rec_d28_can/ Architecture.Head.attdecoder.is_trainFalse # 目前的靜態(tài)圖模型默認(rèn)的最大輸出長度為 36 # 如果您需要預(yù)測更長的序列請?jiān)趯?dǎo)出模型時(shí)指定合適的輸出長度例如 Architecture.Head.max_text_length72注意如果您是在自己的數(shù)據(jù)集上訓(xùn)練的模型并調(diào)整了字典文件請確認(rèn)配置文件中的character_dict_path指向的是所需字典。轉(zhuǎn)換成功后目錄下會生成三個(gè)文件/inference/rec_d28_can/ ├── inference.pdiparams # 識別 inference 模型的參數(shù)文件 ├── inference.pdiparams.info # 識別 inference 模型的參數(shù)信息可忽略 └── inference.pdmodel # 識別 inference 模型的 program 文件7.2 使用 predict_rec.py 推理執(zhí)行如下命令進(jìn)行模型推理python3 tools/infer/predict_rec.py --image_dir./doc/datasets/crohme_demo/hme_00.jpg --rec_algorithmCAN --rec_batch_num1 --rec_model_dir./inference/rec_d28_can/ --rec_char_dict_path./ppocr/utils/dict/latex_symbol_dict.txt # 預(yù)測文件夾下所有圖像時(shí)可修改 image_dir 為文件夾如 --image_dir./doc/datasets/crohme_demo/。 # 如果您需要在白底黑字的圖片上進(jìn)行預(yù)測請?jiān)O(shè)置 --rec_image_inverseFalse在 predict_rec.py 中當(dāng)rec_algorithm CAN時(shí)后處理選用CANLabelDecode見 rec_postprocess.py它沿時(shí)間維取argmax得到符號索引序列以序列中第一個(gè)結(jié)束符位置截?cái)嘣賹⑺饕痦?xiàng)映射回 LaTeX 符號并以空格連接輸出預(yù)處理調(diào)用norm_img_can先將圖像轉(zhuǎn)為灰度圖若rec_image_inverseTrue默認(rèn)則執(zhí)行255 - img取反再按(1, 32, 320)形狀進(jìn)行等比縮放與填充見 predict_rec.py 中 norm_img_can 實(shí)現(xiàn)推理輸入為[norm_img_batch, norm_img_mask_batch, word_label_list]三元組其中 mask 全 1、標(biāo)簽為全 1 的占位序列與訓(xùn)練階段的多輸入結(jié)構(gòu)保持一致。對上方示例圖片執(zhí)行命令后預(yù)測結(jié)果識別的 LaTeX 符號序列會打印到屏幕上Predicts of ./doc/imgs_hme/hme_00.jpg:[x _ { k } x x _ { k } y _ { k } y x _ { k }, []]推理注意事項(xiàng)預(yù)測圖像必須為黑底白字手寫公式為白色、背景為黑色推理時(shí)需通過rec_char_dict_path指定字典若您修改了字典請同步修改該參數(shù)若您修改了預(yù)處理方法需修改 predict_rec.py 中 CAN 的預(yù)處理為您的預(yù)處理方法。7.3 C / Serving / 更多推理部署由于 C 預(yù)處理與后處理尚未支持 CANC 推理部署暫未支持Serving 服務(wù)化部署與更多推理部署如 Paddle Lite 等當(dāng)前同樣暫不支持。該限制明確記載于 algorithm_rec_can.md 文檔中部署到上述平臺前請留意此約束。8. FAQCROHME 數(shù)據(jù)集從何而來CROHME 數(shù)據(jù)集來自于 CAN 源 repohttps://github.com/LBH1024/CANPaddleOCR 在 rec_can_head.py 與 rec_can_loss.py 的代碼注釋中也明確標(biāo)注了參考來源。為什么 CAN 需要專門的字典CAN 的輸出是 LaTeX 符號 token 序列而非普通文本因此必須使用 latext_symbol_dict.txt111 類含/s等特殊 token不能復(fù)用通用中英文字典。9. 引用misc{https://doi.org/10.48550/arxiv.2207.11463, doi {10.48550/ARXIV.2207.11463}, url {https://arxiv.org/abs/2207.11463}, author {Li, Bohan and Yuan, Ye and Liang, Dingkang and Liu, Xiao and Ji, Zhilong and Bai, Jinfeng and Liu, Wenyu and Bai, Xiang}, keywords {Computer Vision and Pattern Recognition (cs.CV), Artificial Intelligence (cs.AI), FOS: Computer and information sciences, FOS: Computer and information sciences}, title {When Counting Meets HMER: Counting-Aware Network for Handwritten Mathematical Expression Recognition}, publisher {arXiv}, year {2022}, copyright {arXiv.org perpetual, non-exclusive license} }【免費(fèi)下載鏈接】PaddleOCRTurn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between images/PDFs and LLMs. Supports 100 languages.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/pa/PaddleOCR創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考