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