大數據:機器學習專家帶你實踐LSTM語言模型
背景
給定一串文字,它是否代表一個地址? 一般地址里有xx路,xx街之類的,這些字符都是地址串的很強的特征。
但是如果僅靠這樣,還是不夠,比如:延安路發生重大交通事故,很明顯不是地址串。 這類問題直覺上是更適合用語言模型來捕獲地址的常用說法。借助tensorflow,我們可以很容易訓練一個這樣的模型。
訓練數據
本模型中,使用了100w+個地址串,加上全國省市區縣的組合(特別規整的xx省xx市xx縣). 覆蓋了大部分地址串的樣例
-
北京朝陽區朝陽北路101號朝陽大悅城6樓(近星河灣)
-
汕頭金平區汕樟立交橋底金華街口(近金華小學)
-
綏化肇東市利民南路
-
長春經濟開發區臨河街天地十二坊C29棟(近肯德基)
-
六盤水鐘山區人民中路220號
-
寧波河頭路83、87、91號
-
上海楊浦區殷行路752號(城達集貿市場大門口)
-
衢州江山市鹿溪南路鹿溪廣場北側鹿溪大廈2幢11—16號
模型輸入
語言模型可以是基于字的,也也可以是基于詞的,基于字的,對中文而已,也有幾千個不同的字。 基于詞就更大了。
基于詞的則還另外需要借助分詞器,分好詞,而且分詞也可能損失精度。 基于字的相對模型簡單點,容錯也更強。
我們訓練的采用基于字的語言模型。這樣我們對輸入的地址串先按Unicode分割,然后只保留出現頻率超過1的作為字典。另外,我們地址串中假設最長50個字符,要不然每段(50個)單獨處理。 考慮到我們訓練時采用的字符不一定能覆蓋所有在線測試時的字符,如果不在字典中,字典會把它映射到id為0。 但是字符串末尾還需要特殊表示下,以區分這種不在字典里的情況,我們對每個串末尾加上來表示結尾
Label & Loss
字語言模型的本質就是給定上下文, 計算下一個位置出現的字符的概率分布,訓練的時候,我們給出的地址串,隱含的給出了每個timestep的標注輸出值。
一般語言模型的損失函數是困惑度,這里采用的是類似的,把每一步的交叉熵加總起來,由于timestep是固定的,這樣相當于把困惑度近似放大了timestep*batch_size倍.
訓練代碼
這樣整個訓練代碼其實很短,如下:
在線使用
線上代碼使用c++調用的,而python訓練出來的模型變量和計算圖是分開存儲的,我們使用tensorflow自帶的工具tensorflow/python/tools/freeze_graph.py來把這些合并在一個模型文件中,然后我們C++代碼中載入模型。 計算某個句子的困惑度時先把句子按Unicode字符切分,填充好input以及target對應的tensor,然后運行指定的計算節點,獲取loss,計算困惑度,這里我們對困惑度做了簡單歸一化,困惑度越低分值越接近1,反之越接近0。