文章目錄
一、簡單說明
常用的N-gram訓練工具有SRILM、IRSTLM、BerkeleyLM和KenLM等。這幾種工具所 用的算法思想基本一致,只是在實現細節上有所不同,所以我們只需理解其中一個訓 練工具即可。
本文以KenLM(號稱速度最快,佔用內存最少)作爲訓練工具,對基於N-gram的過程進行詳細介紹,所用的平滑技術是Modified Kneser-ney smoothing,因爲它是當 前一個標準的、廣泛採用的、效果最好的平滑算法。
Modified Kneser-ney smoothing 論文,點我
二、執行過程
以2-gram爲例
1.拿到文本
我
我是
他
2.分詞處理 text
我
我 是
他
cd language_model/srilm
3.生成n-gram統計文件
sudo ngram-count -text 輸入文本 -order 2 -write 輸出的統計文本 -unk
例如
sudo ngram-count -text language_model_demo/text -order 2 -write language_model_demo/2gram.count -unk
4.生成語言模型
sudo ngram-count -read 輸入統計文本 -order 2 -lm 輸出語言模型文件 -interpolate -unk
例如:
sudo ngram-count -read language_model_demo/2gram.count -order 2 -lm language_model_demo/2gram.count.klm -interpolate -unk
5.轉爲二進制文件
進入kenLm目錄:cd ../kenlm
sudo build/bin/build_binary 輸入語言模型文件 輸出二進制語音模型文件
例如:
sudo build/bin/build_binary language_model_demo/2gram.count.klm language_model_demo/2gram.binary
6.生成trie文件
cd mozilla_deepspeech/native_client
./generate_trie 字母表文件 二進制語言模型文件 trie文件
例如
./generate_trie ../data/alphabet_zh.txt language_model_demo/2gram.binary language_model_demo/2gram_trie
7.結果分析
vim 2gram.count
這一步分別對1-gram和2-gram做原始計數
vim 2gram.count.klm
生成兩張表,1-gram表比2-gram表多一列,多出來的一列表示回退概率。
三、生成原理
1.增加<s>
和</s>
標記符,表示句子的開頭和結尾。
<s> 我 </s>
<s> 我 是 </s>
<s> 他 </s>
2.映射ID
把每個詞映射到唯一的數字id,爲了更直觀地描述下面的關鍵步驟,我們這裏就不把單詞映射爲數字id。
3.Counting
(原始計數)。也就是把相同的字合併,然後排序(假設編碼順序爲<s>
、我、是、他、<\s>
) 。根據步驟一的文本,我們可以得到1-gram和2-gram的原始計數:
1-gram | 原始計數 |
---|---|
<s> |
3 |
我 | 2 |
是 | 1 |
他 | 1 |
<\s> |
3 |
2-gram | 原始計數 |
---|---|
<s> 我 |
2 |
我</s> |
1 |
我 是 | 1 |
是 </s> |
1 |
<s> 他 |
1 |
他 </s> |
1 |
4.Adjusting
(調整計數)。其基本思想是對於那些lower-gram,我們不care其出現的次數,而是關心其作爲novel continuation的可能性。比如“York”,其在語料中出現的次數一般會比較多,因爲“New York”是很高頻的詞。但“York”作爲continuation(中文意思:別的詞把“york”作爲接續詞)的可能性就較低,也就是說它前面的詞只有“new”等少數幾類詞,所以應該給它較低的計數。
1-gram | 中間計算過程 | adjust計數 |
---|---|---|
<s> |
w1=<s> ,計數保持 |
3 |
我 | “我”的前面只出現了"<s> "一種情況 |
1 |
是 | “是”的前面只出現了"我"一種情況 | 1 |
他 | “他”的前面只出現了"<s> "一種情況 |
1 |
<\s> |
“</s> ”的前面出現了"我"、“是”、“他”三種情況 |
3 |
2-gram表的計數保持不變
5.Discounting。
其基本思想是把經常出現的一些N-Gram的概率分一些出來給沒有出 現的N-gram,也就等同於將經常出現的N-Gram次數減去(discount)一部分,這樣做的道理就在於,對於出現次數比較多的計數我們其實已經得到了一個相對比較好的估計,那麼當我們從這個計數值中減去一個較小的數值d後應該影響不大。那 到底該discount取多少呢?其中比較有代表性的有Church & Gale於1991年通過留存 法實驗從而得到的Absolute Discounting;另一個是Chen and Goodman於1998年提出 的方法。
6.Normalization
(1)計算n-gram的概率,該概率稱之爲pseudo probability,也就是說它不是最終的概率,但對於計算最終概率是有用的
(2)計算回退權重,也稱爲back-off weight, 它衡量的是某個詞後面能接不同詞的能力。
舉個例子,考慮 spite 和 constant 的 bigram,在 Europarl corpus 中,兩個 bigram 都出現了 993 次,以 spite 開始的 bigram 只有 9 種,大多數情況下 spite 後面跟着 of(979 次),因爲 in spite of 是常見的表達,而跟在 constant 後的單詞有 415 種,所以我們更有可能見到一個跟在 constant 後面的bigram,因此back-off(constant)>back-off(spite)
對上述兩個概率取以10爲底的log,就能得到最終的結果
7.Interpolation
我們先看一個例子:如果c(多的)和c(多斂) 都爲0,也就是說在某個語料中都沒出現,那麼在傳統的n-gram中,p(的∣多)=p(斂∣ 多)。而這個概率我們直觀上來看是錯誤的,p(的∣多)應該比p(斂∣多)高很多。要實 現這個,我們就希望把 bigram 和 unigram 結合起來,因爲“的”比“斂”常見的多,就能保證p(的∣多)>p(斂∣多)。interpolate 就是這樣一種方法。