接上一篇,我終於把 Unicode 問題修正了。
修正後,我重新訓練出 v5。當時我的重新測試方法其實很簡單粗暴:直接拿模型已經訓練過的資料重新辨識,看看它到底有沒有接近 100%。
現在想想,這其實比較接近訓練集上的辨識結果,不是正式的泛化測試。
但當時的我一無所知。
v5 的辨識結果達到了 95.56%,而且原本一直出現的 [UNK] 問題也消失了。
相較於當時 v4 約 89%~91% 的結果,我很自然地認為:
Unicode normalization 修正成功,模型也變好了!好耶!
所以當時的我決定繼續沿著這個方向處理資料。
因為我拿去辨識的,明明就是模型已經看過的訓練資料。
所以當時我的想法是:
既然這些音檔都訓練過了,為什麼模型還會錯?
我開始懷疑,可能是訓練資料中的變調標記沒有處理乾淨,導致模型即使面對訓練過的資料,仍然無法達到 100%。
於是我重新跑了一次資料處理與訓練流程。
然後,我跑出了 v6。
整體辨識準確率:96.84%。
我當時:
🎉🎉🎉
看起來一切都在往好的方向前進。
既然模型已經來到 96.84%,那剩下的問題是什麼?
我開始對錯誤音檔做細部分析。
| 錯誤類型 | 數量 |
|---|---|
| 韻母/韻尾錯誤 | 130 |
| 入聲 -h 錯誤 | 115 |
| 音段刪除/漏音 | 23 |
| 聲母錯誤 | 22 |
| 聲調錯誤 | 12 |
| 音段增加 | 6 |
| 音節數錯誤 | 5 |
| 其他音素錯誤 | 3 |
其中最醒目的,當然就是:
入聲 -h 錯誤:115 筆。
於是我決定排出優先順序,一個一個解決。
現在看起來,這份 Debug 計畫是不是還滿有模有樣的?
我當時也真的非常認真地照著它往下做。
先從最常出問題的 h 開始。
我找出了 a.wav 和 ah.wav,直接比較它們的聲學特徵。
a.wav

ah.wav

當時我根據這些結果得出的結論是:
h 作為韻尾的訊號在連讀中不容易穩定偵測,所以之後用 CAPT 系統過濾就好。
(我這什麼爛結論。圖表這麼明顯的差別,我是眼瞎嗎?)
除了 h 消失之外,我還發現另一種奇怪的錯誤。
例如:bo̍k → bo̍h
我開始追這個案例,當時推測可能是 CTC 在 k 韻尾的聲學衰減階段產生了 h 的混淆。
甚至還因此設計了一套:
CAPT 韻尾混淆規則 v1
< 0.5 → 不提示0.5~0.7 → 「可能接近 X」≥ 0.7 → 「較接近 X」我當時甚至已經開始想:
好,我的 CAPT 系統之後要怎麼處理這些問題?
事情做到這裡,我還完全不知道後面有一個更大的坑在等我。
接下來我繼續分析第 8 聲 → 第 4 聲,以及 h 韻尾的混淆。
這時候,我第一次真正體驗到 Codex 有多可怕。
我原本只是拿一個普普的 Python 小程式,想讓它分析這些錯誤音檔中第 4 聲與第 8 聲的特徵。
結果它直接:
我整個大開眼界。
Codex 也太神。
當然,跑完這輪之後,額度馬上就沒了。QAQ


實驗做到這裡突然停下來。
不是因為模型。
也不是因為 GPU。
是因為我發現:
我的音檔標籤又有問題。
我的程式在處理 n̄g 時,竟然把聲調符號標到了 g 上。
也就是說,我前面拿來分析的一部分「模型錯誤」,可能根本不是模型的問題。
(終於發現了。)
於是 v6 到這裡正式停止。
我修正音檔與標籤,重新建立資料,產出了 v7。
這裡要補一件我在 Day 8 當時根本不知道的事情。
當時我還沒有建立現在使用的固定 mini 測試集。
早期不同版本的評估資料並沒有完全統一,因此:
這些數字雖然反映了我當時的測試結果,但不能直接視為同一套基準下的模型比較。
後來建立固定 mini 測試集後,我重新把舊模型全部拿出來測了一次:
這時候出現了一個很尷尬的結果:
在現在這份固定 mini 測試集上,v5 並沒有超過 v4。
這不代表 Unicode 修正是錯的。Unicode 問題確實存在,[UNK] 也確實消失了。
真正的問題是:
我當時沒有一套固定的評估基準,可以可靠地比較不同版本到底進步了多少。
所以早期的:89% → 95.56% → 96.84%
和後來固定 mini 測試集上的:62.76% → 60.25% → 80.33%
不能直接拿來比較。
不過我都已經訓練完了,就當作一個慘痛的教訓吧。幸好我的老師不會看到我慘痛的實驗記錄。我自己看到我過去用的方法就很頭痛。
我發現了很多錯誤,卻始終沒發現最終癥結點。以為實驗成功,又又又發現資料沒處理乾淨。做了很多沒意義的實驗。
不過在下一篇,我算是步入正軌了吧。我終於快寫到我目前的進度了。那麼今天就先寫到這裡,我是微微,大家明天見。