(四)序列標(biāo)注——實(shí)體識(shí)別BERT-BLSTM-CRF(下)

????????前面說(shuō)的是ner的經(jīng)典算法以及今年的一些比較好的工作,最近bert模型刷新了NLP的絕大部分任務(wù),可謂是一夜之間火爆了整個(gè)NLP界,這里我簡(jiǎn)單記錄下bert在NER上的使用,至于原理部分我后續(xù)的博客會(huì)做詳細(xì)的說(shuō)明。這里先暫時(shí)理解成bert同樣也是產(chǎn)生embedding的工具就可以,只不過(guò)這個(gè)embedding比Word2vec的embedding要厲害。

? ? ? ? ok 我們先設(shè)定下框架。

? ? ? ? 框架很簡(jiǎn)單,就是bert+Bilstm-CRF,前面講了bert就是用來(lái)產(chǎn)生詞向量的,所以如果拋開(kāi)這個(gè)原理,這個(gè)升級(jí)版本的NER模型就很簡(jiǎn)單了。

這里先給出代碼鏈接。BERT是Google提出的基于tensorflow1.11.0的代碼,里面用了高級(jí)API,所以這篇博客我主要在代碼層面講一下bert的應(yīng)用。原理部分我也做了詳細(xì)的介紹,請(qǐng)戳

bert的官方版本tensorflowpytorch版本。

bert官方版本的代碼寫(xiě)的非常好(雖然很難懂哈),這里借NER這個(gè)應(yīng)用簡(jiǎn)單學(xué)習(xí)下:

1.數(shù)據(jù)準(zhǔn)備

這里還是以中文數(shù)據(jù)為例,數(shù)據(jù)的格式還是和之前一樣:

我們最終需要把數(shù)據(jù)轉(zhuǎn)換成bert論文中的形式:

代碼中的數(shù)據(jù)就是轉(zhuǎn)成這樣,這部分是純工程問(wèn)題,就不詳細(xì)介紹????:

接下來(lái)就講一下這個(gè)高級(jí)API的用法:

1.代碼中將所有數(shù)據(jù)封裝成record的形式:

注意這里是對(duì)每一組數(shù)據(jù)進(jìn)行逐條封裝

2.讀取record 數(shù)據(jù),組成batch

這里主要也是通過(guò)回調(diào)函數(shù)完成

input_file就是保存的record文件,然后用d = tf.data.TFRecordDataset(input_file)讀數(shù)據(jù),這樣就得到了一個(gè)batch的數(shù)據(jù)。

然后定義estimator封裝器

有了這個(gè)封裝器訓(xùn)練、驗(yàn)證測(cè)試都比較方便(難得讀懂喲),這里的model_fn就是模型定義的的回調(diào)函數(shù)。

3.定義模型

????????大致思路:這個(gè)model_fn_builder是為了構(gòu)造代碼中默認(rèn)調(diào)用的model_fn函數(shù)服務(wù)的,為了使用其他的參數(shù),只不過(guò)model_fn函數(shù)的默認(rèn)參數(shù)只有features, labels, mode, params,這四個(gè),所以在model_fn包裹了一層model_fn_builder


注意這個(gè)init_checkpoint就是下載的模型,接下來(lái)我們看一下模型的構(gòu)造即model_fn函數(shù),以及他是如何使用init_checkpoint:

? ? - 在這個(gè)回調(diào)函數(shù)中,第一步就是創(chuàng)建模型,這一步其實(shí)和之前的tensorflow的寫(xiě)法思路一樣,都是在完成“圖”這個(gè)部分,

那么creat_model里有啥呢,不看也知道,第一步就是拿到bert的輸出了,也就是embedding = model.get_sequence_output(),后面就是在創(chuàng)造blstm_crf這塊就不再講了,到這兒是不是完了呢,顯然不是,因?yàn)槲覀冎皇前褕D建完了,bert的預(yù)訓(xùn)練的參數(shù)還沒(méi)有喂給模型呢,接下來(lái)就是create_model后面一部分,加載模型預(yù)訓(xùn)練參數(shù):

首先讀取在create_model中的所有需要訓(xùn)練的參數(shù),因?yàn)閕nit_checkpoint中的參數(shù)對(duì)應(yīng)的是bert的,所以要把訓(xùn)練參數(shù)分開(kāi),只能初始化bert的部分,同時(shí)bert論文中也提到了fine-tune,是不是這樣,我們把參數(shù)打印出來(lái)看看就知道了:


bert模型的部分參數(shù)
lstm-crf模型參數(shù)

assignment_map是一個(gè)字典,里面存的就是需要create_model中需要初始化的變量,也就是bert的部分,然后調(diào)用tf.train.init_from_checkpoint(init_checkpoint, assignment_map)來(lái)加載模型,看看恢復(fù)出來(lái)的參數(shù):

最后就是優(yōu)化器的定義了:

實(shí)驗(yàn)結(jié)果:紅框是總的實(shí)驗(yàn)精度,黃框是每個(gè)類(lèi)別的結(jié)果

梳理完了代碼,現(xiàn)在來(lái)總結(jié)下這個(gè)estimator API是怎么用的(看一堆基礎(chǔ)教程,真不如看大牛寫(xiě)的代碼來(lái)的快哈?。?/p>

1.首先把數(shù)據(jù)存成record

2.創(chuàng)建estimator 對(duì)象,對(duì)象里要傳入創(chuàng)建model的回調(diào)函數(shù)model_fn

? ? ? ? model_fn的用法:

? ? ? ? ? ? - 參數(shù)model_fn(features, labels, mode, params) 這個(gè)是固定的,如果需要額外參數(shù)就在外面在包一層回調(diào)函數(shù)

? ? ? ? ? ? ????????-?features就是record解析后的結(jié)果

? ? ? ? ? ? - 調(diào)用數(shù)據(jù)并送入創(chuàng)建的模型

3.創(chuàng)建優(yōu)化器并使用tf.contrib.tpu.TPUEstimatorSpec封裝優(yōu)化器和loss

4.創(chuàng)建讀取record并生成batch的回調(diào)函數(shù)

? ?5.訓(xùn)練模型

上述僅僅只是一個(gè)代碼的分析,詳細(xì)使用請(qǐng)看我的github吧?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容