前言
雖然早就知道Transformer、BERT、paddlepaddle,也知道它們很好用,但覺(jué)得很復(fù)雜就一直拖著沒(méi)去嘗試,在看完了ACL2018和NER相關(guān)的論文后(項(xiàng)目地址),我終于決定嘗試新模型了,網(wǎng)上現(xiàn)在做NER的模型大多是BiLSTM+CRF,區(qū)別就在于對(duì)字/詞向量的提取、處理等。ACL這篇論文是將字向量與詞向量融合起來(lái)當(dāng)作網(wǎng)絡(luò)的輸入,但和BERT比起來(lái),它對(duì)向量的處理還是略顯幼稚,雖然BERT是基于字符的,并沒(méi)有融入詞語(yǔ)信息,但我覺(jué)得BERT中的自注意力機(jī)制讓它可以捕獲上下文意思,但還沒(méi)經(jīng)過(guò)實(shí)驗(yàn),我也不知道哪個(gè)比較好用,但BERT已經(jīng)在眾多數(shù)據(jù)集上達(dá)到了sota水準(zhǔn),所以我要開(kāi)始深入BERT了。
先驗(yàn)知識(shí)
博客
從Word Embedding到Bert模型—自然語(yǔ)言處理中的預(yù)訓(xùn)練技術(shù)發(fā)展史BERT發(fā)展史
The Illustrated Transformer【譯】詳細(xì)解釋了Transformer
論文
Attention Is All You Need解釋了Transformer中的注意力機(jī)制
FAQ(frequently asked questions)
Q:到底是直接用BERT做NER還是BERT只用來(lái)生成字向量,再將字向量置于其它模型中?
A: 我傾向于后者,BERT是用來(lái)捕捉字/句子之間深度關(guān)系的,然后輸出是向量,這大概就是BERT的作用了,之后再將字/句子向量輸入到其它模型中。但是想得到字向量,得先把輸入改造成BERT需要的樣子。
Q:對(duì)于NER而言,如何預(yù)處理數(shù)據(jù)呢?
A: unknown for now
Q:BERT源碼解讀
A:
- modeling.py
-
tokenization.py
tokenization是對(duì)原始句子內(nèi)容的解析,分為BasicTokenizer和WordpieceTokenizer兩個(gè)。- BasicTokenizer的主要是進(jìn)行unicode轉(zhuǎn)換、標(biāo)點(diǎn)符號(hào)分割、小寫(xiě)轉(zhuǎn)換、中文字符分割、去除重音符號(hào)等操作,最后返回的是關(guān)于詞的數(shù)組(中文是字的數(shù)組)。
- WordpieceTokenizer的目的是將合成詞分解成類似詞根一樣的詞片。例如將"unwanted"分解成["un", "##want", "##ed"]這么做的目的是防止因?yàn)樵~的過(guò)于生僻沒(méi)有被收錄進(jìn)詞典最后只能以[UNK]代替的局面,因?yàn)橛⒄Z(yǔ)當(dāng)中這樣的合成詞非常多,詞典不可能全部收錄。
- FullTokenizer的作用就很顯而易見(jiàn)了,對(duì)一個(gè)文本段進(jìn)行以上兩種解析,最后返回詞(字)的數(shù)組,同時(shí)還提供token到id的索引以及id到token的索引。這里的token可以理解為文本段處理過(guò)后的最小單元。
-
create_pretraining_data.py
對(duì)原始數(shù)據(jù)進(jìn)行轉(zhuǎn)換,原始數(shù)據(jù)本是無(wú)標(biāo)簽的數(shù)據(jù),通過(guò)句子的拼接可以產(chǎn)生句子關(guān)系的標(biāo)簽,通過(guò)MASK可以產(chǎn)生標(biāo)注的標(biāo)簽,其本質(zhì)是語(yǔ)言模型的應(yīng)用 -
run_pretraining.py
在執(zhí)行預(yù)訓(xùn)練的時(shí)候針對(duì)以上兩種標(biāo)簽分別利用bert模型的不同輸出部件,計(jì)算loss,然后進(jìn)行梯度下降優(yōu)化。 - run_squad.py(run_squad.py和run_classifier.py是bert中fine-tune的例子)
- run_classifier.py(講的很好,還涉及了如何把代碼改造成自己需要的樣子)
代碼
- bert-as-service 可以生成字/詞/句子向量,但維度相同,不知道這有何意義,但字向量至少是可以用的,而且極其簡(jiǎn)單。
- 另一個(gè)基于Keras的代碼,也可以用,用起來(lái)也很簡(jiǎn)單。 作者還寫(xiě)了一個(gè)實(shí)例
- 使用預(yù)訓(xùn)練語(yǔ)言模型BERT做中文NER(bert-chinese-ner-master),這個(gè)代碼沒(méi)有加入BiLSTM和CRF,但是它是最基礎(chǔ)的,之后的都在這上面改。 (代碼解讀見(jiàn)另一篇博客)
- BERT-BiLSTM-CRF-NER,這個(gè)代碼加入了BiLSTM和CRF,路徑:F:\google下載\BERT相關(guān)\Name-Entity-Recognition-master\BERT-BiLSTM-CRF-NER。
-
BERT-BiLSTM-CRF-NER-master,這個(gè)代碼也加入了BiLSTM和CRF,但是和上面的相比功能好像更全,作者還生成了軟件包,里面集成了bert-as-service。(用不起來(lái),已放棄)
注意事項(xiàng):
這里面的代碼一般都不能直接用,都需要按照README.md中進(jìn)行配置,就是加個(gè)文件夾之類的。
我的理解
參考BERT中自帶的fine-tune的實(shí)例(run_squad.py和run_classifier.py)可以發(fā)現(xiàn),想把BERT用于NER,首先得把自己的輸入改造成BERT所需的格式,然后寫(xiě)一個(gè)Processor類,這個(gè)類就和run_classifier.py中的Processor結(jié)構(gòu)相同,但是里面的方法要重寫(xiě)。除此之外,還可以加上自己的損失函數(shù)(在create_model中),還可以加入CRF層等。
參考博客
http://www.itdecent.cn/p/22e462f01d8c
https://blog.csdn.net/u014108004/article/details/84142035#commentBox