用PaddleOCR的PPOCRLabel來微調醫療診斷書和收據 (WSL 2跑Ubuntu 22.04)

https://github.com/Deep-Learning-101

基於機器閱讀理解和指令微調的統一信息抽取框架之診斷書醫囑資訊擷取分析

https://huggingface.co/spaces/DeepLearning101/OCR101TW

WSL 安裝 PaddleOCR、Windows 10 安裝 PaddleOCR、PalldeOCR v3 微調

一切都是從這個神奇的需求開始的,因為要識別醫療診斷書中的醫囑內容,所以前期處理的OCR識別就非常重要,雖然 PaddleOCR (https://github.com/PaddlePaddle/PaddleOCR) 已經很強,但是卡在很多格式內容或者簡體和繁體字的問題,所以常常OCR識別後的內容就出包,然後導致醫囑的分析也就容易跟著翻車啦 (但BU端才不管你這些呢 >"<);所以只能再次抱著壯士斷腕的決心,再自己標註一次數據了 ! 那麼,值得一提的是,標註NLP的工具可以用標文字蠻不錯的 Doccano (https://github.com/doccano/doccano) 或者是可以標圖像和文字的 Label Studio (https://labelstud.io/),但是要標給OCR用,感覺上還是得用 PPOCRLabelv2但是因為平常不太可能開著 Ubuntu 來處理這個工作,所以只能先想辦法從 WINDOWS 10 上安裝 WSL (1或2),然後再幫它啟用桌面,然後採遠端桌面登入,接著再來安裝中文輸入法等等;總計有這幾個動作:

  • WINDOWS 10 啟用 WSL
  • WSL 啟動 Ubuntu 再啟用桌面
  • WINDOWS 10 遠端桌面至 WSL 的 Ubuntu
  • 安裝 PaddleOCR、PPOCRLabelv2 
  • 幫 WSL 的 Ubuntu 安裝繁體中文輸入法
搞很久後,才 ~~~ 啊 ! 它有WINDOWS 版啊 XD ~ 往下滑看 " Paddle OCR 應用場景開發微調 "

但還是加減把相關 PaddleOCR 的應用場景開發過程還有參考的文件都記錄下來吧 !  WINDOWS 10 安裝 PaddleOCR、PPOCRLabelv2 的一堆奇怪的問題記錄

WINDOWS 10 啟用 WSL

那接著就是先啟用 WSL 1 或 2,目前已知就是差在要怎樣直接遠端桌面,或者是透過 XLaunch來連線;我目前是啟用 WSL 2 啦 ! 所以裝好後就是到 Microsoft 商店取得 Ubuntu 22.04.2 LTS (在上面的連結) 啦 ! 照官網所寫,其實安裝跟啟動非常簡單,然後就是設定帳號跟密碼,主要是給你能使用 sudo 這樣 ! 網上有的教學說要再另外裝 terminal,但我裝好是直接有個 Ubuntu 22.04.2 的終端機可以啟動啦 ! 

$ sudo apt update && sudo apt upgrade
$ sudo apt install -y xfce4 xrdp xfce4-goodies

再來就是要更新還有安裝遠端桌面和繁體中文輸入法所需套件,安裝xfce4過程中會出現選擇顯示管理DM選擇的提示,建議用lightdm。
$ sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak
$ sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini
$ sudo sed -i 's/max_bpp=32/#max_bpp=32\nmax_bpp=128/g' /etc/xrdp/xrdp.ini
$ sudo sed -i 's/xserverbpp=24/#xserverbpp=24\nxserverbpp=128/g' /etc/xrdp/xrdp.ini
$ echo xfce4-session > ~/.xsession
修改 xrdp 設定,並註解掉 X11 那兩行
$ sudo vi /etc/xrdp/startwm.sh
# test -x /etc/X11/Xsession && exec /etc/X11/Xsession
# exec /bin/sh /etc/X11/Xsession
然後新增 xfce 這兩行
# xfce
startxfce4
接著就是啟動 RDP 然後看狀態
$ sudo /etc/init.d/xrdp start
$ sudo /etc/init.d/xrdp status
* xrdp-sesman is running
* xrdp is running
接著就是安裝Fctix5設定新酷音輸入法;其中,別忘了要到設定裡的地區和語言設定語言支援,不過不知為啥,我的是沒辦法設定,但是卻有直接一個 Fctix5 的選項,點一點就這樣意外搞定?

$ sudo apt install fcitx5 fcitx5-chinese-addons fcitx5-config-qt fcitx5-chewing
以上就是在Windows 10 跑 WSL 2,然後設定遠端桌面跟注音輸入法(繁體),陸續參考了以下文章

接著就是安裝 PaddleOCR 還有 PPOCRLabelv2,每次在做這些工作時,總會想到為何那麼多人在抗中保台,結果放眼望去,台灣都沒相關的數據或者工具套件開源出來?XD

https://github.com/PaddlePaddle/PaddleOCR
https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.6/PPOCRLabel/README_ch.md

https://zhuanlan.zhihu.com/p/523972865
PPv3-OCR自定義數據從訓練到部署

然後這時發現其實可以省掉上面的 WSL,直接裝 WINDOWS 版就可以了 XD
所以最後就補充一些碰到的問題,然後分別參考了那些連結解決的吧
最後 ! 附上一個PPOCRLabelv2標註的擷圖

還有 PaddleOCR 的 識別(REC) 訓練擷圖吧 ! 2023/07/15訓練集有100萬張,驗證集有1萬張。
這邊要加減補充一下 !!! 整個 PaddleOCR 就是分為 Detection (偵測,ch_PP-OCRv3_det) 跟 Recognition (識別,ch_PP-OCRv3_rec),其中,偵測又有所謂的表格,但一般做就是要先處理識別,因為都只有簡體字 ! 經過一番實測,用 ch_PP-OCRv3_rec 並且將字典檔轉成繁體,且要注意因為字典檔內有些許繁體字,直接簡轉繁會造成重複,所以替換時要小心



Paddle OCR 應用場景開發微調 (官方github FAQ)

目前現有 PP-OCR系列模型列表:推理、訓練、預訓練,然後包括檢測跟識別;官方文件如下:

首先就是識別,說明一下字典檔相關數據的生成,為了輸出的效果更符合目前優先的醫療收據應用場景,所以根據已搜集的7萬筆醫囑還有台灣常用字典檔做為語料庫,藉此產生大量的數據資料,來微調 ppocr-v3;這邊要怎樣生成呢 ? 可以參考 文字資料集產生(text_renderer)  或者是你前面有用 PPOCRLabelv2 標了一些數據,那麼就可以把標好的文字拿來再做數據集生成的組合


最後在V100*8的機器上費時51hr跑了100epoch,訓練acc: 0.84133,驗證acc:0.92796,wer 的結果如下

Training_0804_latest
------------------------- Overall Results -------------------------
SENT: %Correct=75.51 [H=589, S=191, N=780]
WORD: %Corr=92.91, Acc=90.52, WER: 9.48 [Sub=5.36, Del=1.73, Ins=2.39]

Training_0721_epoch18
------------------------- Overall Results -------------------------
SENT: %Correct=70.77 [H=552, S=228, N=780]
WORD: %Corr=91.30, Acc=89.53, WER: 10.47 [Sub=6.65, Del=2.05, Ins=1.78]

no mark
Training_0804_latest_nomark
------------------------- Overall Results -------------------------
SENT: %Correct=87.63 [H=928, S=131, N=1059]
WORD: %Corr=97.04, Acc=95.96, WER: 4.04 [Sub=2.27, Del=0.69, Ins=1.08]

Training_0721_epoch18_nomark
------------------------- Overall Results -------------------------
SENT: %Correct=83.57 [H=885, S=174, N=1059]
WORD: %Corr=96.27, Acc=95.64, WER: 4.36 [Sub=2.72, Del=1.00, Ins=0.63]


識別的效果做得差不多之後,就是要優化偵測的效果了;在官方文件中有講到,可以微調模型讓其達到 end to end 只認定特定的目標偵測區的效果,再透過 kie 來處理,使用Semantic Entity Recognition,SER模型和Relationship Extraction,RE模型將欄位做關聯連線。這邊要注意的是與識別不同,簡體中文和繁體中文的外觀是雷同的,所以在做繁體中文的ocr任務時,det模型是可以直接使用簡體中文的權重。此外,det模型會把所有中文字都偵測出來,但實務上並不完全都是必要的文字,官方說可以透過微調來處理,但是卻碰到了如果是多家醫院,其整張收據表單的格式都不雷同,你就很難去個別特定的偵測;在這邊我們就改換用 yolo 來優先處理整張表單在圖片中的那個位置,然後再偵測出需要的文字在那裡,最後再透過所謂的表格偵測模型來處理。

另外,還是需要opencv前處理圖片,因為原先部份照片的陰影以及皺摺可能造成偵測和辨識模型的準確度下降;另外,也是嘗試了 kie 的效果,標記好的資料,訓練出來的kie模型還滿準的,但問題在於偵測模型需要準確的辨識出目標偵測框,那麼提高偵測模型的準確度是當前目標啦;值得注意的是,如果你的目標,裡面是有表格的話,那就是要再用另外的方法來做了 !


最後就是到了把整個模型佈到 HuggingFace Hub 上了,像是

想用 python 直接調用自定義數據的訓練模型,但是看log最後都會變為使用官方預訓練模型 (會出現如 det=True, rec=True, type=ocr 等等,並另外本地端執行自定義數據訓練和官方預訓練模型確認是官方預訓練模型結果)。使用自訂模型

ocr = PaddleOCR(det_model_dir='{your_det_model_dir}', rec_model_dir='{your_rec_model_dir}', rec_char_dict_path='{your_rec_char_dict_path}', cls_model_dir='{your_cls_model_dir}', use_angle_cls=True)
result = ocr.ocr(img, cls=True, det=False, rec=False)