在構(gòu)建了基于n-gram的糾錯(cuò)檢錯(cuò)模型之后固蛾,我們自然不能放過如今大紅大紫的神經(jīng)網(wǎng)絡(luò)改化,鑒于神經(jīng)網(wǎng)絡(luò)的靈活性和訓(xùn)練的耗時(shí)性逆趋,我們?cè)诜椒▏L試和模型訓(xùn)練上花了很多時(shí)間潜沦,期間走過不少彎路萄涯,也因工業(yè)界大佬進(jìn)行交流走了捷徑,總得來說唆鸡,神經(jīng)網(wǎng)絡(luò)的表現(xiàn)雖然沒有我預(yù)想的那么神奇涝影,但也還是可以的。
本文介紹使用LSTM進(jìn)行檢錯(cuò)糾錯(cuò)的幾個(gè)方案争占,需要注意的點(diǎn)以及和n-gram模型進(jìn)行最終融合的嘗試燃逻。
整體分為四個(gè)部分:
- 備選詞生成(詞級(jí)語言模型)
- 句子檢錯(cuò)模型:
- 序列標(biāo)注模型
- 字級(jí)語言模型
- tricks和坑
- 模型融合
需要提醒的是,鑒于神經(jīng)網(wǎng)絡(luò)的不穩(wěn)定性以及數(shù)據(jù)分布的多樣性臂痕,因此在本文提出的方法不一定適用于讀者的數(shù)據(jù)伯襟,僅供參考。此外握童,為對(duì)項(xiàng)目進(jìn)行保密姆怪,文中不會(huì)給出具體的準(zhǔn)確率、F1數(shù)值舆瘪,只會(huì)以好片效、差等程度詞表明模型結(jié)果。
備選詞生成(詞級(jí)語言模型):
Part 0 : 介紹
我們首先使用LSTM構(gòu)造的是詞級(jí)語言模型英古,目的是為了取代從一對(duì)詞語搭配中獲取備選詞的方法淀衣,而檢錯(cuò)方法還是使用n-gram。 LSTM構(gòu)造的語言模型和n-gram語言模型本源是一樣的召调,都是通過前面的文本獲取下一字或詞的概率膨桥,只不過n-gram是基于統(tǒng)計(jì)的,只能人為設(shè)定有限的n唠叛,而LSTM能夠綜合一個(gè)詞前面所有詞的信息給出概率只嚣。
經(jīng)過在項(xiàng)目通過各種角度使用語言模型,我總結(jié)出語言模型使用的三種思路:
- 檢測(cè)句子流暢度
- 檢測(cè)錯(cuò)誤詞語
- 生成備選詞(句子)
這三個(gè)思路使用的語言模型的原理是一樣的艺沼,只是使用的角度不同册舞。檢測(cè)句子流暢度是掃描整個(gè)句子,計(jì)算每個(gè)字/詞的概率而后乘起來(鑒于字詞概率都會(huì)遠(yuǎn)小于1障般,導(dǎo)致乘起來后值過小调鲸,一般語言模型都會(huì)采用log概率盛杰,即計(jì)算出概率后再取log),將乘出來的數(shù)成為句子流暢度藐石。檢測(cè)錯(cuò)誤詞語就是通過處理前面的文本即供,計(jì)算下一個(gè)已知的詞的概率,若是概率低于閾值(閾值一般是人工設(shè)定)于微,那么就可以標(biāo)記成錯(cuò)誤詞逗嫡。而只要將下一個(gè)詞擴(kuò)展成詞表,對(duì)詞表里每個(gè)詞都求一個(gè)概率株依,然后取出概率最大的詞驱证,那么我們就可以做到備選詞生成了,若是不斷把概率最大的備選詞填入原本句子中再輸入語言模型恋腕,就可以做到句子生成了雷滚。
例如,對(duì)于一句話 "STA 我 今天 吃 蘋果 了 END":
- 檢測(cè)句子流暢度的話吗坚,就是計(jì)算 "STA"后是"我"的概率,【"STA", "我"】后面是"今天"的概率呆万。商源。到 【"STA", "我", "今天", "吃", "蘋果", "了"】后面是"END"的概率,而后將所有概率取log乘起來谋减,得到句子流暢度分?jǐn)?shù)牡彻。
- 檢測(cè)錯(cuò)誤詞語,同樣也是計(jì)算一遍所有詞語的概率出爹,而后將他們放到一起庄吼,根據(jù)認(rèn)為設(shè)定的閾值篩出概率較低的詞。
- 生成備選詞严就,則是首先掃描到例如 "STA 我 今天 吃"总寻,而后計(jì)算詞表中每個(gè)詞的概率,即 若是將一個(gè)詞接到前面掃描的部分的后面梢为,那個(gè)詞的概率渐行,若詞表有【"STA", "我", "今天", "吃", "蘋果", "了", "END"】這么些詞,那就是計(jì)算【"STA 我 今天 吃" + "STA"】的概率铸董,【"STA 我 今天 吃" + "我"】的概率祟印。。粟害。蕴忆,【"STA 我 今天 吃" + "END"】概率,每個(gè)加進(jìn)去的詞都會(huì)得到一個(gè)概率悲幅,若是取概率最大的詞出來即可作為備選詞了套鹅。
Part 1 : 模型模塊詳述
在這個(gè)部分站蝠,我梳理一下常用的用神經(jīng)網(wǎng)絡(luò)處理文本問題的流程,下圖是在lstm后接入詞表大小的全連接層的整體流程圖:
整個(gè)過程分為以下五個(gè)部分(省略預(yù)處理過程):
- tokenizing
- indexing
- embedding
- lstm
- 下游任務(wù)
接下來我將對(duì)每個(gè)部分進(jìn)行介紹芋哭。
1. tokenizing
tokenizing沉衣,從詞義和上圖中就可以知道,就是分詞减牺,而為什么單獨(dú)將它拿出來豌习,則是因?yàn)樗哂歇?dú)特的意義:
一:統(tǒng)計(jì)詞數(shù)、詞頻拔疚。通過分詞之后肥隆,我們能夠清楚地了解語料中總共有多少詞以及每個(gè)詞的頻率,那么我們就可以根據(jù)詞頻進(jìn)行刪減稚失,例如刪掉大量只出現(xiàn)幾次的自造詞栋艳、語氣詞或罕見詞,以此節(jié)省計(jì)算內(nèi)存并減少需要計(jì)算的參數(shù)句各;或者將頻率過高的停用詞替換成統(tǒng)一的標(biāo)簽吸占,防止停用詞對(duì)模型造成影響。
二:構(gòu)造 "詞"-> "索引"表凿宾。在分詞的過程中工具還會(huì)構(gòu)造 "詞"-> "索引"表矾屯,這個(gè)表是做什么用的呢?要知道模型內(nèi)部是不認(rèn)字符的初厚,只認(rèn)數(shù)據(jù)件蚕,為了將詞轉(zhuǎn)換成模型可以處理的向量,就需要先將它們轉(zhuǎn)成索引产禾,而后通過 "索引"->"向量"矩陣直接查到對(duì)應(yīng)的embedding向量排作,就可以成功地把詞轉(zhuǎn)換成向量了。而我們也可以構(gòu)造反轉(zhuǎn)表: "索引"->"詞"亚情,就可以在最后得到概率最大的詞的索引時(shí)查表得到詞的字符表示妄痪。
三:選擇粒度。在英文中势似,詞之間以空格分離拌夏,所以英文處理就沒有分詞方面的困惑(應(yīng)該很少有人會(huì)把句子按字母粒度分開吧?)履因。而中文因?yàn)闆]有空格區(qū)分障簿,因此可能需要進(jìn)行分詞的操作,然而因?yàn)橹形牡亩嗔x性栅迄,分詞的結(jié)果不一定能讓人滿意站故,有可能引入額外的錯(cuò)誤使得模型跑偏,而字級(jí)粒度就可以很好地防止分詞錯(cuò)誤的問題了。但詞級(jí)也同樣有其優(yōu)點(diǎn)西篓,鑒于錯(cuò)誤很可能產(chǎn)生散串愈腾,詞級(jí)在檢測(cè)散串上更有優(yōu)勢(shì)。選擇哪種粒度就見仁見智了岂津,不過選擇的階段就是在tokenizing部分進(jìn)行的虱黄。
2. indexing
indexing要做的事情很簡(jiǎn)單,就是利用tokenizing階段產(chǎn)生的 詞-索引 表吮成,把句子中的詞替換成索引橱乱,而這個(gè)階段也同樣有其額外的功能,那就是padding粱甫。
padding這個(gè)技巧在文本處理中十分常見泳叠,含義就是填充,將句子通過填充達(dá)到一定長度茶宵。原因很簡(jiǎn)單:句子一般是不等長的危纫,而矩陣要求每行元素等長,這個(gè)矛盾的解決那就是通過引入padding乌庶,通過在不等長的句子后面補(bǔ)數(shù)據(jù)(一般補(bǔ)0)种蝶,從而把indexing后的句子補(bǔ)到統(tǒng)一的長度(稱為max length),這就可以以batch進(jìn)行訓(xùn)練了瞒大。當(dāng)然蛤吓,如果你每次只用一個(gè)句子訓(xùn)練,那就不用padding了糠赦,不過速度就可想而知了。那么有人可能會(huì)說:padding最起碼會(huì)加長計(jì)算時(shí)間吧锅棕,如果是雙向LSTM拙泽,還應(yīng)該會(huì)影響訓(xùn)練效果吧,可以盡可能消除padding的影響嗎裸燎?答案是可以的顾瞻,起碼在tensorflow中,就可以用dynamic rnn德绿,通過sequence length參數(shù)將batch里每個(gè)句子的長度傳進(jìn)去荷荤,就可以實(shí)現(xiàn)每個(gè)句子不等長訓(xùn)練了(不過句子在傳進(jìn)去之前還是要padding成同一長度的)。
3. embedding
前面提到移稳,模型不認(rèn)字符蕴纳,只認(rèn)數(shù)字,那么我們就需要將字詞轉(zhuǎn)換成向量(至于為什么不是數(shù)字个粱,那是因?yàn)閱蝹€(gè)數(shù)字所能保存的信息量太少古毛,遠(yuǎn)不如多維向量能表示的信息多)。而這個(gè)向量,可以通過隨機(jī)初始化而后自己訓(xùn)練稻薇,也可以借用其他人訓(xùn)練好的embedding再進(jìn)行磨合(不過慎用嫂冻,tricks和坑部分會(huì)談到)。常用的embedding自然是word2vec了塞椎,不過近來不斷有新的out-performing的embedding出現(xiàn)桨仿,如ELMO、Google的大殺器BERT案狠。
4. lstm
這個(gè)階段就是進(jìn)行語言模型的建模了服傍,LSTM每階段有兩個(gè)向量:hidden state和output,因hidden state中包含從開始到最后語言模型的記憶莺戒,所以我們選擇使用final hidden state作為該階段的輸出物伴嗡,使用hidden state實(shí)際上就是將前面所有詞的信息(但有些信息會(huì)被模型遺忘)用一個(gè)向量表示(就是seq2seq的Encode階段),而后就可以用這個(gè)濃縮的向量進(jìn)行各種下游任務(wù)了从铲。
5. 下游任務(wù)
下游任務(wù)的定義其實(shí)頗為靈活瘪校,若是對(duì)于訓(xùn)練embedding為主的模型,那么下游任務(wù)就是在embedding后的模型層名段,而對(duì)于我們的這個(gè)語言模型阱扬,下游模型層自然是lstm后的網(wǎng)絡(luò)層,具體就是詞表大小的全連接層伸辟。
雖然我們?cè)谇拔闹v到語言模型的三種用法的時(shí)候是先提到計(jì)算單個(gè)詞語概率以此檢測(cè)錯(cuò)誤詞語麻惶,再擴(kuò)展到計(jì)算整個(gè)詞表概率以此生成備選詞,但三種用法的模型層都是一樣的信夫,都是詞表大小的全連接層窃蹋。對(duì)于檢測(cè)錯(cuò)誤詞語的用法,只需要在詞表所有的概率中取出要檢測(cè)的詞的概率即可静稻。
Part 2 : 文本獲取與處理
在這個(gè)模型中警没,我們使用的語料和上一篇文章(基于n-gram的糾錯(cuò)檢錯(cuò)模型)一樣:
- 網(wǎng)上獲取的搜狗通用語料
- 金融新聞?wù)Z料
- 人工糾正語句
語料處理過程的一部分也如前一篇文章那樣,分詞-數(shù)字轉(zhuǎn)星號(hào)-長句切短句-加入STA振湾、END標(biāo)簽杀迹。
而后我們統(tǒng)計(jì)了語料中的詞頻并將過低的詞以UNK替換,并刪去過高的詞押搪。
Part 3 : 模型構(gòu)建及評(píng)價(jià)
模型訓(xùn)練工具包上树酪,鑒于筆者當(dāng)時(shí)是首次用神經(jīng)網(wǎng)絡(luò)處理實(shí)際項(xiàng)目問題,先前都是用tensorflow跟著教程或?qū)憣懶emo大州,因此為了效率和準(zhǔn)確使用了封裝較好的keras续语,而keras當(dāng)時(shí)的版本沒有dynamic rnn,因此padding后的整個(gè)句子都會(huì)被lstm處理厦画。
將模型在語料上滿懷期待地進(jìn)行訓(xùn)練過后绵载,因?yàn)閭溥x詞生成沒有標(biāo)準(zhǔn)答案,只能人工判斷是否正確,于是我開始輸入不完整的句子讓模型給出備選詞來檢測(cè)模型結(jié)果娃豹,然而遺憾的是模型生成的基本都是牛頭不對(duì)馬嘴的詞焚虱,或者是為了通用性用了很常見的詞。嘗試了數(shù)套參數(shù)和配置之后結(jié)果都差不多懂版,我開始感覺到實(shí)際工業(yè)界和學(xué)術(shù)界似乎有些不同鹃栽,但又不確定是否是我本身實(shí)現(xiàn)的問題,因此暫定備選詞仍然采用依存句法提取的詞語搭配躯畴,開始轉(zhuǎn)為使用神經(jīng)網(wǎng)絡(luò)做句子檢錯(cuò)民鼓。
Part 4:模型轉(zhuǎn)移,從備選詞生成到詞級(jí)檢錯(cuò)
上文提到蓬抄,備選詞生成和錯(cuò)誤檢測(cè)使用的模型是一樣的丰嘉,只是使用模型的方法不同。將詞級(jí)模型從備選詞生成轉(zhuǎn)換成錯(cuò)誤檢測(cè)并沒有花太大的功夫嚷缭,在LSTM中從只取final hidden state變成每個(gè)time step的hidden step都要取饮亏,在原本給出的整個(gè)詞表中根據(jù)概率取概率最大的詞變成根據(jù)索引取特定詞的概率。然而模型在檢錯(cuò)方面的準(zhǔn)確率阅爽,F(xiàn)1等指標(biāo)表現(xiàn)很差路幸,遠(yuǎn)不如n-gram的分?jǐn)?shù)。鑒于經(jīng)驗(yàn)不足付翁,筆者在嘗試了幾套參數(shù)和配置之后開始嘗試下一個(gè)模型简肴,至于可能的表現(xiàn)不足的原因,筆者在后面會(huì)給出說明百侧。
序列標(biāo)注模型
Part 0 : 介紹
先前的使用詞級(jí)語言模型的思路是師兄給出的砰识,在嘗試詞級(jí)語言模型效果不理想之后,筆者提出可以將檢錯(cuò)問題視作序列標(biāo)注問題佣渴,正確的標(biāo)0仍翰,錯(cuò)誤的標(biāo)1,將句子詞或字序列輸入模型后根據(jù)預(yù)測(cè)值得到錯(cuò)誤字詞观话。在閱讀論文之后,筆者得知這也是文本檢錯(cuò)的一個(gè)常規(guī)思路越平,也是很符合直覺的频蛔。
序列標(biāo)注模型實(shí)際上就是個(gè)多分類模型,當(dāng)問題是檢錯(cuò)的時(shí)候就是個(gè)二分類模型秦叛,它和其它數(shù)據(jù)型分類模型的區(qū)別在于構(gòu)建特征的時(shí)候需要考慮時(shí)序特性晦溪,就是利用LSTM將文本序列信息嵌入到特征向量中。
Part 1 : 模型模塊簡(jiǎn)述
將序列模型的模塊和語言模型的對(duì)比我們可以發(fā)現(xiàn)挣跋,兩個(gè)模型還是有些區(qū)別的三圆,區(qū)別在embedding后面的兩個(gè)模塊。
在lstm上序列標(biāo)注模型使用了雙向LSTM,在取hidden state的時(shí)候并不是僅取最后的hidden state舟肉,而是將每個(gè)階段的hidden state均取出修噪,至于forward和backward的hidden state是sum還是concat就見仁見智了。
最后的全連接層使用的是兩個(gè)神經(jīng)元路媚,將每個(gè)time Step的hidden state作為特征預(yù)測(cè)這個(gè)詞是否有錯(cuò)黄琼。
Part 2 : 訓(xùn)練集處理與構(gòu)造
使用序列標(biāo)注模型,訓(xùn)練集就不能像使用語言模型那樣直接把整個(gè)句子丟進(jìn)去就行整慎,需要獲取標(biāo)注好的語料或者人為構(gòu)造標(biāo)注好的訓(xùn)練語料脏款。至于該模型的訓(xùn)練集獲取和構(gòu)造,詳見拼音型簡(jiǎn)單錯(cuò)誤語料獲取與處理一文裤园。
Part 3 : 模型效果評(píng)價(jià)
模型訓(xùn)練既然不必多言撤师,在實(shí)際跑出來之后進(jìn)行測(cè)試,效果仍是慘不忍睹拧揽。而后筆者再搜羅各種檢錯(cuò)糾錯(cuò)的論文閱讀剃盾,從其中挖掘了使用序列標(biāo)注模型時(shí)可以改進(jìn)的方向和常用的方法,在正欲嘗試改進(jìn)時(shí)發(fā)生了一些事情(見"字級(jí)語言模型"Part 0)强法,使得筆者留下序列標(biāo)注改進(jìn)這么個(gè)坑万俗,構(gòu)建新的模型去了。
Part 4:可擴(kuò)展方向
bilstm-crf模型
經(jīng)過閱讀論文筆者發(fā)現(xiàn)饮怯,序列標(biāo)注模型闰歪,尤其檢錯(cuò)糾錯(cuò)的序列標(biāo)注,最常用的是bi lstm-crf模型蓖墅,通過lstm對(duì)每個(gè)字的每個(gè)類給出分?jǐn)?shù)库倘,將所有分?jǐn)?shù)輸入crf模型中,求解概率最大的標(biāo)注序列论矾。
加入詞性特征和拼音特征
拼音特征的引入是為了更好地識(shí)別同音字錯(cuò)誤教翩,而詞性特征的引入和語法正確性相關(guān),筆者認(rèn)為還跟錯(cuò)誤產(chǎn)生的散串有關(guān)贪壳。散串理論認(rèn)為當(dāng)句子中有錯(cuò)誤字饱亿、詞時(shí),分詞后的句子會(huì)產(chǎn)生不協(xié)調(diào)的散串闰靴,這些散串以單字分開彪笼,它們和前后無法構(gòu)成詞因此獨(dú)自成詞,而它們本身單獨(dú)成詞很少見或者無法單獨(dú)成詞蚂且。根據(jù)這個(gè)理論配猫,當(dāng)句子中產(chǎn)生散串時(shí),它們的詞性序列就會(huì)很異常杏死,從而被模型捕捉并識(shí)別泵肄。
字級(jí)語言模型
<span id="jump">Part 0 : 介紹</span>
在評(píng)估完一號(hào)版本的序列標(biāo)注模型后捆交,我有幸參加了MSRA-SCUT機(jī)器學(xué)習(xí)夏令營,并在夏令營最后一日前往CVTE參觀腐巢。在參觀途中品追,我有幸和CVTE的自然語言部門的技術(shù)負(fù)責(zé)人就語音識(shí)別后文本糾錯(cuò)領(lǐng)域進(jìn)行一對(duì)一交流,在交流過程中他告訴我系忙,經(jīng)過他們?cè)诠I(yè)界的實(shí)驗(yàn)诵盼,效果最好的是使用雙向LSTM的字級(jí)語言模型,而生成式模型也僅限于在學(xué)術(shù)論文中好看了银还,在實(shí)際工業(yè)界的效果并不好风宁。
經(jīng)過大佬的指點(diǎn),我們又重回語言模型檢錯(cuò)方案蛹疯,只是這次使用字級(jí)粒度戒财,在實(shí)驗(yàn)過程中,盡管在大方向上有了大佬的指導(dǎo)捺弦,但還是踩了不少坑饮寞,在后面的"tricks和坑"部分會(huì)詳述。
Part 1:模型模塊簡(jiǎn)述
字級(jí)語言模型的模塊有些像前面兩個(gè)模型模塊的組合列吼,在LSTM方面使用雙向LSTM幽崩,取每個(gè)階段的hidden state,然后把hidden state作為特征進(jìn)行詞表大小的概率預(yù)測(cè)寞钥,根據(jù)索引查找對(duì)應(yīng)詞的概率慌申,并和閾值比較判定是否認(rèn)為出錯(cuò)。
Part 2:訓(xùn)練集構(gòu)造
訓(xùn)練集和詞級(jí)類似理郑,但為了嘗試不同語料對(duì)模型的作用蹄溉,筆者又獲取了金融領(lǐng)域的保險(xiǎn)推銷對(duì)話、電商平臺(tái)客服對(duì)話您炉,并分別構(gòu)造訓(xùn)練集用于構(gòu)造不同的模型柒爵。
語料的處理方式也和前文詞級(jí)語言模型提到的一樣,區(qū)別在于不需要進(jìn)行分詞處理赚爵,直接一字一斷棉胀,不過要注意不要把STA、END冀膝、UNK標(biāo)簽截?cái)嗔恕?/p>
Part 3:模型構(gòu)建及評(píng)價(jià)
經(jīng)過前兩個(gè)模型實(shí)現(xiàn)的訓(xùn)練唁奢,筆者對(duì)神經(jīng)網(wǎng)絡(luò)實(shí)際應(yīng)用開發(fā)有了進(jìn)一步了解,這次字級(jí)語言模型就使用tensorflow1.2開發(fā)了畸写,經(jīng)過艱苦的debug以及嘗試各種配置的過程,最終模型跑出來結(jié)果還不錯(cuò)氓扛,算是有了份可以見人的成果了枯芬,起碼在檢錯(cuò)效果上將網(wǎng)上大廠公布的語言模型和檢錯(cuò)模型能比下去论笔。
Tricks 和 坑
在這個(gè)部分,我將總結(jié)前面幾個(gè)模型構(gòu)建和訓(xùn)練過程中使用的一些tricks和踩過并意識(shí)到的坑(可能還有沒意識(shí)到的)千所。
tricks
tensorflow使用方面的tricks 見文章 tensorflow 文本序列檢錯(cuò)的tricks (0)
數(shù)據(jù)盡可能保存成文件
神經(jīng)網(wǎng)絡(luò)的訓(xùn)練本身就已經(jīng)很耗時(shí)間了狂魔,我們不希望前期的數(shù)據(jù)處理再占用大量的時(shí)間,如果不保存成文件淫痰,那么模型每次在訓(xùn)練前都需要對(duì)語料進(jìn)行處理最楷,想想就耗時(shí)。
鑒于筆者采用的是tensorflow1.2待错,還不支持各種高級(jí)的DatasetAPI籽孙,因此各種數(shù)據(jù)以文本形式保存下來,其中涉及到的數(shù)據(jù)以及形式有:
- 詞-索引表火俄。保存了這個(gè)表犯建,那么模型就不需要再將整個(gè)語料過一遍以獲取完整詞表,此外我們還可以根據(jù)詞表大小進(jìn)行詞刪減等操作瓜客。
- embedding适瓦。這個(gè)不必說,必定要保存的谱仪。
- padding后的句子索引序列户侥。 在前期處理階段就將語料轉(zhuǎn)換成序列(此時(shí)最好保存成一份文件)罩缴,而后對(duì)不等長序列進(jìn)行padding,補(bǔ)到最大長度,保存補(bǔ)后的索引序列弓熏,那么模型之后就能夠直接讀入并構(gòu)造矩陣了。而前面小括號(hào)內(nèi)推薦額外保存不等長序列是為了之后想要修改最大長度或padding使用的數(shù)據(jù)會(huì)更方便好乐。
大佬指點(diǎn)
在與CVTE的大佬交流后始苇,筆者還獲取了一些tricks,不論用沒用到筷转,在此分享出來:
- 神經(jīng)網(wǎng)絡(luò)和n-gram同樣也僅能捕獲句子的簡(jiǎn)單詞語錯(cuò)誤姑原,因?yàn)槎叹渥由杂行╁e(cuò)就很難還原原本的意思。
- 句子是長是短沒什么影響呜舒,按逗號(hào)句號(hào)把一個(gè)長句子劃分成短句子的方向沒問題锭汛。
- 用雙向lstm,候選集詞語挑選用搜索引擎的ranking技術(shù)袭蝗。
- 加速訓(xùn)練方面:
- 富采樣
- batch normalization
- 多顯卡下用顯卡并行加速訓(xùn)練
- 提高模型準(zhǔn)確率的方法(比賽中常用的技巧):
- 先設(shè)置embedding不動(dòng)而后訓(xùn)練模型參數(shù)唤殴,然后設(shè)置參數(shù)不變訓(xùn)練embedding,只進(jìn)行一輪
坑
訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)同分布
訓(xùn)練數(shù)據(jù)的測(cè)試數(shù)據(jù)盡可能同分布到腥,在文本中就是指詞語的組合方式朵逝、用詞、錯(cuò)誤類型都差不多乡范,例如都是電話中的對(duì)話配名,都是拼音類型為主的錯(cuò)誤等等啤咽。
這在學(xué)術(shù)界看來再正常不過,畢竟數(shù)據(jù)集都是純粹的渠脉,直接隨機(jī)劃分訓(xùn)練集驗(yàn)證集測(cè)試集即可宇整。在工業(yè)界也簡(jiǎn)單,直接雇傭大量人手從要檢測(cè)的大量語料中先糾一部分作為訓(xùn)練語料就行芋膘。然而苦的是夾在學(xué)術(shù)界和工業(yè)界之間的我們鳞青,既沒有學(xué)術(shù)界那種那么純粹而大量的數(shù)據(jù),又沒有工業(yè)界的財(cái)力可以先"人工"再"智能"为朋,于是只能人工糾正一小部分臂拓,再靠網(wǎng)絡(luò)搜集盡可能相似分布的數(shù)據(jù)。然而經(jīng)過實(shí)驗(yàn)表明潜腻,哪怕最好的相似數(shù)據(jù)埃儿,效果也不如人工糾正的那小部分?jǐn)?shù)據(jù)。
embedding不要亂用
筆者之前很大一段時(shí)間都是直接使用其他人發(fā)布的已經(jīng)預(yù)訓(xùn)練過的embedding融涣,認(rèn)為只需要在他們訓(xùn)練好的基礎(chǔ)上針對(duì)我們的語料進(jìn)行更新即可童番,然而現(xiàn)實(shí)給了我個(gè)下馬威,在將預(yù)訓(xùn)練embedding換成隨機(jī)初始化embedding之后威鹿,模型的準(zhǔn)確率和F1瞬間上了一個(gè)臺(tái)階剃斧。在擁有足夠數(shù)據(jù)的情況下,或者哪怕數(shù)據(jù)量不是那么夠忽你,也盡可能自己訓(xùn)練embedding吧幼东,領(lǐng)域不匹配的話,其他人預(yù)訓(xùn)練好的embedding對(duì)你的模型來說就是毒藥科雳。
檢錯(cuò)模型評(píng)價(jià)
在檢錯(cuò)模型評(píng)價(jià)環(huán)節(jié)根蟹,筆者將對(duì)前面提到的三個(gè)模型進(jìn)行對(duì)比,分析優(yōu)劣并給出評(píng)價(jià)糟秘。
比較分為兩個(gè)部分:
- n-gram VS lstm
- 序列標(biāo)注模型 VS 語言模型
- 詞級(jí)粒度 VS 字級(jí)粒度
n-gram VS lstm
在實(shí)際進(jìn)行項(xiàng)目之前简逮,筆者一直受到神經(jīng)網(wǎng)絡(luò)鼓吹者的影響,感覺神經(jīng)網(wǎng)絡(luò)仿佛已經(jīng)萬能了尿赚,傳統(tǒng)機(jī)器學(xué)習(xí)方法都很過時(shí)散庶,效果都遠(yuǎn)不如神經(jīng)網(wǎng)絡(luò)。然而凌净,現(xiàn)實(shí)告訴我悲龟,方法在準(zhǔn)確率上是和冷門熱門無關(guān)的。現(xiàn)在轉(zhuǎn)頭一看冰寻,n-gram和lstm實(shí)際上各有優(yōu)劣须教。
我們來看看n-gram和lstm相比的優(yōu)勢(shì):
- n-gram在訓(xùn)練測(cè)試同分布的要求較低。使用搜狗通用大規(guī)模語料訓(xùn)練出來的n-gram語言模型表現(xiàn)已經(jīng)不錯(cuò)了斩芭,而同樣的大規(guī)模語料在lstm上卻是慘不忍睹轻腺,因其和測(cè)試語料的分布不同羹奉,導(dǎo)致模型無法學(xué)習(xí)到需要學(xué)習(xí)的特征。
- n-gram在散串上的識(shí)別很強(qiáng)约计。同樣是詞級(jí)粒度,當(dāng)文本中出現(xiàn)錯(cuò)誤導(dǎo)致產(chǎn)生若干散串之后迁筛,n-gram能夠很敏捷地察覺出來煤蚌,然而LSTM較難做到。
- n-gram解釋性強(qiáng)细卧,原理清晰尉桩。這個(gè)自然不必多言,從理論到實(shí)際使用上經(jīng)歷許多年許多人的磨礪贪庙,這個(gè)語言模型早已身經(jīng)百戰(zhàn)蜘犁。
然而LSTM也有其優(yōu)勢(shì)的,不然也無法紅火到今日:
- 人工參與較n-gram少止邮,畢竟神經(jīng)網(wǎng)絡(luò)最大的優(yōu)勢(shì)就在于特征自動(dòng)學(xué)習(xí)这橙,再加上如今各種高度抽象的深度學(xué)習(xí)工具包,只需要寥寥數(shù)行代碼就可以構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò)导披。
- 語料數(shù)目要求不高屈扎。寫到這里筆者內(nèi)心其實(shí)也有些猶豫,畢竟神經(jīng)網(wǎng)絡(luò)本身要求數(shù)據(jù)量要足夠大才能玩得轉(zhuǎn)撩匕,然而經(jīng)過實(shí)驗(yàn)鹰晨,層數(shù)較少的神經(jīng)網(wǎng)絡(luò)在語料較少而分布接近的情況下也同樣表現(xiàn)很好,而基于統(tǒng)計(jì)的n-gram若想要得到同樣表現(xiàn)止毕,就需要數(shù)倍數(shù)十倍于LSTM的語料用于訓(xùn)練了模蜡。
序列標(biāo)注模型 VS 語言模型
首先用訓(xùn)練集進(jìn)行對(duì)比:
- 序列標(biāo)注模型語料需要使用標(biāo)注好的數(shù)據(jù)
- 語言模型需要使用正確的數(shù)據(jù)
高下立判。序列標(biāo)注模型需要標(biāo)注好的數(shù)據(jù)才可以訓(xùn)練扁凛,對(duì)學(xué)術(shù)界而言自然不是問題忍疾,但對(duì)于工業(yè)界和夾在工業(yè)學(xué)術(shù)之間的我們顯然不希望在構(gòu)建數(shù)據(jù)上花費(fèi)大量時(shí)間和精力。而語言模型只需要使用正確的句子就可以令漂,而正確的句子在網(wǎng)絡(luò)上到處都是膝昆,Wikipedia、百度百科叠必、知乎什么的荚孵,一爬一大堆,雖然還是要注意分布相似性問題纬朝,但序列標(biāo)注模型也同樣需要考慮收叶。因此語言模型在訓(xùn)練數(shù)據(jù)準(zhǔn)備上無疑優(yōu)于序列標(biāo)注模型很多。
而后根據(jù)模型復(fù)雜度進(jìn)行比較:
- 序列標(biāo)注模型最后的全連接層只需要和類別數(shù)目相同的神經(jīng)元共苛,在本文中即兩個(gè)神經(jīng)元判没,分別代表正確和錯(cuò)誤蜓萄。
- 語言模型最后的全連接層需要詞表大小的神經(jīng)元。
在模型復(fù)雜度方面序列標(biāo)注模型要占優(yōu)勢(shì)澄峰,畢竟詞表少說也有上千上萬個(gè)嫉沽,需要更新的參數(shù)數(shù)目瞬間就多了幾個(gè)量級(jí)。
最后將模型用途進(jìn)行比較:
- 序列標(biāo)注模型僅能用于標(biāo)注俏竞。
- 語言模型可以用于檢測(cè)句子流暢度绸硕、檢測(cè)錯(cuò)誤詞、生成備選詞魂毁。
用途一比玻佩,語言模型又大勝,序列標(biāo)注模型僅專注于標(biāo)注席楚,而語言模型可以一模型多用咬崔,最后全連接層使用詞表大小的神經(jīng)元大大增加了語言模型的能力。
如此對(duì)比一看烦秩,序列標(biāo)注模型或許更適合在學(xué)術(shù)界使用垮斯,畢竟他們擁有大量純粹的數(shù)據(jù),而語言模型更適合工業(yè)界使用超大量語料訓(xùn)練只祠,得到一個(gè)核彈級(jí)多功能通用模型甚脉。
字級(jí) VS 詞級(jí)
在大佬的指點(diǎn)下我們從詞級(jí)語言模型到字級(jí)語言模型,使用發(fā)現(xiàn)效果很不錯(cuò)之后铆农,我們回頭開始比較詞級(jí)和字級(jí)的區(qū)別牺氨,分析為什么字級(jí)模型優(yōu)于詞級(jí)。
- 字級(jí)詞表較詞級(jí)小墩剖。顯然猴凹,中文常用字就那么幾千個(gè),因此字級(jí)若再壓縮的話可以將詞表控制在兩三千的規(guī)模岭皂。而詞級(jí)因組合方式多樣郊霎,再加上專有名詞、成語等因素存在爷绘,導(dǎo)致常用詞的詞表都可以輕松達(dá)到上萬規(guī)模书劝。詞表越大,需要更新和計(jì)算的參數(shù)越多土至,消耗的內(nèi)存空間也越大购对,而詞級(jí)的詞表因規(guī)模大,更可能稀疏陶因,致使效果不好骡苞。
- 詞級(jí)需要分詞,分詞不總是完美的。在使用詞級(jí)模型時(shí)解幽,我們需要對(duì)語料進(jìn)行分詞處理贴见,在分詞工具上使用較為廣泛使用的jieba分詞,但分詞工具總會(huì)有不完美的地方躲株,尤其是作用在對(duì)話的文本中片部,其中包含大量重復(fù)和倒裝的結(jié)構(gòu),導(dǎo)致模型在訓(xùn)練階段就受到不少干擾霜定。
然而吞琐,詞級(jí)模型還是有它的優(yōu)勢(shì)的,在備選詞生成上然爆,字級(jí)模型生成備選詞的效果就不如詞級(jí)。
檢錯(cuò)模型融合
在獲取了n-gram詞級(jí)語言模型和LSTM字級(jí)語言模型后黍图,我們思考能否將它們?nèi)诤掀饋硪垣@取更好的效果曾雕。經(jīng)過實(shí)驗(yàn),我們將句子分別輸入兩個(gè)模型助被,將詞語的分?jǐn)?shù)標(biāo)記給詞中每個(gè)字剖张,而后取兩個(gè)模型給出分?jǐn)?shù)的最高值,再和閾值比較高低判定是否可能出錯(cuò)揩环。
句子糾錯(cuò)
在檢錯(cuò)方面得到一定成果之后搔弄,我們開始結(jié)合檢錯(cuò)和備選詞生成進(jìn)行句子糾錯(cuò),其核心思想用一句話來描述就是:
用語言模型檢錯(cuò) -> 備選詞替換 -> 語言模型檢測(cè)句子流暢度丰滑,挑選流暢度最高的句子顾犹。
雖說一句話就能將核心思想描述了,但內(nèi)部還是有不少細(xì)節(jié)的褒墨。
在語言模型方面采用的是融合之后的n-gram + 字級(jí)LSTM炫刷,備選詞生成采用依存句法提取的詞語搭配對(duì),流暢度檢驗(yàn)使用了百度訓(xùn)練的語言模型郁妈。
在使用語言模型檢錯(cuò)之后浑玛,我們還需要將句子分詞,獲取檢錯(cuò)模型認(rèn)為錯(cuò)誤的詞語的前置詞噩咪,而后用前置詞根據(jù)詞語搭配得到若干備選詞顾彰,將備選詞替換錯(cuò)誤詞后得到若干句子,包括原始句子和幾個(gè)不同備選詞替換后的句子胃碾,將這幾個(gè)句子輸入語言模型中獲取句子流暢度涨享,選擇流暢度最高的句子作為最后輸出。
最后使用語言模型檢測(cè)句子流暢度這一操作仆百,能夠非常有效地把在檢錯(cuò)階段對(duì)全對(duì)的句子的誤判消除灰伟,挑選備選詞替換后的句子流暢度都不如原始的句子。這種召回機(jī)制能夠有效防止正確句子經(jīng)過模型之后反而變成錯(cuò)誤的了。
感悟
這是我進(jìn)入大學(xué)后歷時(shí)最久也是最大的項(xiàng)目栏账,在這個(gè)項(xiàng)目進(jìn)行的幾個(gè)月中帖族,我從一個(gè)對(duì)機(jī)器學(xué)習(xí)只了解皮毛的大二半新生,變成對(duì)機(jī)器學(xué)習(xí)稍有了解的大三老油條挡爵。這個(gè)項(xiàng)目使我離實(shí)際工業(yè)界進(jìn)了一步竖般,使我明白了不能只看最新最火技術(shù),傳統(tǒng)技術(shù)同樣有可取之處的道理茶鹃,也使我對(duì)自然語言處理這個(gè)領(lǐng)域有進(jìn)一步了解和興趣涣雕,或許還要沿著這條路繼續(xù)向下走。
更多實(shí)戰(zhàn)文章歡迎關(guān)注微信公眾號(hào)【AI實(shí)戰(zhàn)派】
我的個(gè)人博客:Zedom1.top