iT邦幫忙

2026 iThome 鐵人賽

DAY 1
1
Software Development

TW-OCR:高準確率繁體中文公文辨識與版面重建系統系列 第 2

Day 2|OCR 到底怎樣才算「準」?99% 準確率可能什麼都沒告訴你

  • 分享至 

  • xImage
  •  

昨天聊完為什麼我要自己做一套繁體中文公文 OCR,今天先不急著講 CRAFT、PaliGemma2 或 LoRA。

因為在開始調模型之前,我遇到一個更基本的問題:

到底怎樣才叫做 OCR 很準?

很多 OCR 產品或研究都會出現類似這樣的描述:

辨識準確率 98%、99%,甚至 99.5%。

乍看之下很好理解。

99% 準確率,不就是 100 個字只錯 1 個嗎?

但真的開始做 OCR Benchmark 後,我才發現:

單獨看到一個「99%」,其實幾乎沒有意義。

你至少還要知道三件事情:

哪個模型、考哪一批文件、用什麼方式計分。

少掉其中一個,兩個百分比很可能根本不能直接比較。


我最後選擇用 CER

這個專案主要處理繁體中文,因此我最主要看的指標是:

CER(Character Error Rate,字元錯誤率)

它的概念其實很直覺。

把 OCR 輸出的文字跟正確答案相比,看看需要修改幾次才能變成正確答案。

公式是:

CER = (S + D + I) / N

其中:

S(Substitution) 是把字認錯。

例如:

正確:環境保護

辨識:環境保謢

「護」被認成「謢」,算一次替換。

D(Deletion) 是漏掉原本應該存在的字。

正確:

環境保護署

辨識:

環境保署

少了一個「護」,算一次刪除。

I(Insertion) 則是多辨識出本來不存在的字。

正確:

環境保護署

辨識:

環境境保護署

多了一個「境」,算一次插入。

最後的 N,就是正確答案原本有多少個字元。

所以如果一份文件總共有 10,000 個字,總共發生 100 次錯誤:

CER = 100 / 10000 = 1%

大致可以理解成:

每 100 個字錯 1 個。

或者:

每 1,000 個字錯 10 個。

這也是我一開始替自己定下來的目標:

CER < 1%


但這時候第一個坑就來了

假設今天有一頁文件,OCR 把每一行的文字都辨識得非常準。

這代表整頁 OCR 就很準嗎?

不一定。

因為昨天有提到,我這套 OCR 並不是:

圖片 → Model → 文字

而是一整條 Pipeline。

前面還有:

文字偵測、版面分析、表格切割、閱讀順序判斷。

所以可能發生一件很有趣的事情:

每一行字都辨識對了,但整頁內容還是錯的。

例如原本閱讀順序是:

第一段 → 第二段 → 第三段

結果版面分析組成:

第二段 → 第一段 → 第三段

如果我只拿「成功切出來的文字行」去算 CER,模型看起來可能超準。

但使用者最後拿到的文件卻是亂的。

所以後來我發現:

OCR 的 Benchmark 不只要決定怎麼算錯字,還要先決定「在哪一層算」。


同一套 OCR,我其實可以算出三種不同的 CER

最單純的是 Crop CER

把一小塊已經裁好的文字圖片直接丟給模型。

例如:

[ 環境部環境管理署 ]

然後只看模型有沒有讀對。

這種方式非常適合評估:

「辨識模型本身會不會認字?」

但是它完全不管前面的 Detection 有沒有漏字,也不管閱讀順序。

第二種是 Matched CER

先讓 OCR 自己找文字,再把成功找到、而且可以跟 Ground Truth 配對的文字行拿出來比較。

這會比 Crop 更接近真實流程。

但它還是存在一個很大的問題:

沒找到的東西可能根本沒進入計分。

例如原本有 100 行文字,OCR 只找到 90 行。

如果只拿那成功配對的 90 行去算,可能會得到一個非常漂亮的 CER。

但另外消失的 10 行呢?

對使用者來說,那才是最大的問題。


所以我最後最在意的是整頁 CER

我現在最主要看的指標叫:

Page CER

做法很直接。

把 Ground Truth 整頁的文字按照正確閱讀順序串起來。

OCR 的輸出也按照系統判斷的閱讀順序串起來。

然後兩邊直接算 CER。

這樣一來:

辨識錯字會被算進去。

漏掉文字會被算進去。

多出文字會被算進去。

連閱讀順序錯誤也會反映在結果裡。

也就是說,Page CER 測的已經不只是 PaliGemma2。

它測的是:

「這整套 OCR Pipeline 最後到底交出了什麼東西給使用者?」

這才是我真正關心的數字。


0.385% 是真的,但這句話只講一半

做到目前,我這套系統有一個看起來非常漂亮的數字:

Page CER = 0.3850%

換算一下,大概就是:

每 1,000 個字錯 4 個左右。

而最初版本的錯誤率是:

5.4164%

一路調到最後的 0.3850%。

降幅超過 90%。

如果我要做一張漂亮的簡報,到這裡其實就可以停了。

但是問題來了。

這個 0.3850% 到底是在哪一份資料上得到的?

答案是:

我的固定回歸測試集

這一組包含 20 份文件、40 頁,共 25,715 個字元。

它最大的用途是:

每次我改模型、改前處理、改後處理,都拿同一批文件重新跑,確認系統沒有被改壞。

這對工程開發非常重要。

但是它有一個致命問題:

我已經看過它很多次了。


測試集看太多次,也會被「用掉」

這是一個我做這個專案之後越來越在意的觀念。

假設我今天改了一個演算法。

跑固定測試集:

CER 下降。

我就保留這個修改。

明天又改一版。

CER 上升。

於是我把修改撤掉。

重複幾十次之後會發生什麼?

雖然我從來沒有直接拿測試集去 Training,

但是:

我的工程決策一直在根據這份測試集做調整。

久而久之,整套系統其實已經間接針對這張考卷最佳化。

所以我後來把它叫做:

固定回歸測試集。

而不是「完全沒看過的測試集」。

它可以回答:

「這一版有沒有比上一版退步?」

但不能完全回答:

「明天隨便丟一份沒看過的政府公文進來,也會有 0.385% CER 嗎?」

這是兩個完全不同的問題。


所以還需要 Holdout

要回答第二個問題,就需要另外準備:

Holdout Set,保留集。

概念很簡單。

這批資料:

模型訓練時不能看。

調參時不能看。

做產品修正時也不要一直拿出來看。

一直到真的想知道:

「現在這個版本遇到陌生文件到底表現怎樣?」

才拿出來考一次。

我實際測到的結果就很有意思。

固定回歸集:

0.3850%

但另外兩批陌生文件的結果分別是:

holdout_v3:1.0396%

holdout_v4:1.2585%

這時候你會發現:

0.385% 沒有錯。

1.04% 也沒有錯。

1.26% 也沒有錯。

它們回答的是不同問題。


所以我現在不會說「我的 OCR 準確率是 99.6%」

比較精確的說法應該是:

目前 v10 在固定回歸測試集上的整頁 CER 為 0.3850%。

而如果問:

「那陌生公文呢?」

目前的證據只能說:

在兩批未參與訓練與先前調整的文件上,Page CER 約為 1.04% 與 1.26%。

所以至少以現在的實驗,我還不能直接宣稱:

「所有陌生政府公文都能做到 CER < 1%。」

這句話看起來沒有「99.6% 準確率!」那麼帥。

但我認為這才是 Benchmark 真正應該呈現的方式。


還有一個很容易忽略的問題:考卷本身長什麼樣子?

後來我還遇到更麻煩的事情。

某一階段,我的開發集成績改善了大約 39%

看起來模型進步非常大。

但真正拿保留集測試時:

改善幅度只有 8.6%

為什麼?

回頭檢查才發現:

當時的開發集主要都是一般橫排文章。

但真正的政府公文裡還有:

密集表格、直書、多欄版面、複雜閱讀順序。

也就是說:

考卷出的題目跟產品真正會遇到的題目不一樣。

這時候模型在 Benchmark 上進步很多,使用者卻不一定會有同樣的感受。

這件事情後來對我的影響很大。

因為它代表:

Benchmark 不只是拿資料來測試,Benchmark 本身也是一個需要被設計的產品。


CER 相同,也不代表錯得一樣

最後還有一個我現在不太敢忽略的問題。

假設兩個版本 CER 都是 1%。

它們真的一樣好嗎?

版本 A:

偶爾把「護」認成「謢」。

版本 B:

偶爾整行文字直接消失。

數學上最後可能都是差不多的錯誤字數。

但是如果今天 OCR 後面要接 RAG 或 AI 審查,

整行消失的破壞性遠比單字 typo 嚴重。

所以我現在每次修改系統,不只是看 CER。

還會一起看錯誤分布:

替換、刪除、插入、漏行。

目的就是避免:

總分沒變,但是我們只是把一種錯誤換成了另一種更嚴重的錯誤。


Day 2 小結

今天如果只記得一句話,我希望是:

不要問「這個 OCR 準確率多少」,先問「在哪份資料、用什麼單位、怎麼算的」。

對我來說,目前最重要的尺度是:

Page CER

因為我不是只想知道模型會不會認字。

我要知道的是:

從找文字、判斷版面、辨識,到最後組回整份文件,使用者真正拿到的東西到底有多準。

而 0.3850% 這個數字也是真的。

只是它代表的是:

固定回歸集上的成果。

不是所有未來文件的保證。

下一篇 Day 3,我就可以正式把整套系統攤開來看:

一張公文進來後,到底經過了哪些模型?

為什麼我最後沒有選擇讓一個 VLM 從頭做到尾,而是拆成文字偵測、版面分析、表格解析與文字辨識四層。

也會開始介紹這套系統裡第一個真正工作的模型:

CRAFT。


上一篇
Day 1|為什麼我想重做一套繁體中文公文 OCR?
下一篇
Day 3|一張公文進來後,到底經過了哪些模型?
系列文
TW-OCR:高準確率繁體中文公文辨識與版面重建系統3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言