日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

基于BERT预训练的中文命名实体识别TensorFlow实现

發(fā)布時間:2023/11/28 生活经验 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于BERT预训练的中文命名实体识别TensorFlow实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

BERT-BiLSMT-CRF-NER
Tensorflow solution of NER task Using BiLSTM-CRF model with Google BERT Fine-tuning
GitHub: https://github.com/macanv/BERT-BiLSTM-CRF-NER
本文目錄機構(gòu):

自己訓(xùn)練模型
說明
結(jié)果
使用自己的數(shù)據(jù)
2019.1.31更新,支持pip install package
現(xiàn)在可以使用下面的命令下載軟件包了:

pip install bert-base==0.0.7 -i https://pypi.python.org/simple
1
或者使用基于源代碼的安裝:

git clone https://github.com/macanv/BERT-BiLSTM-CRF-NER
cd BERT-BiLSTM-CRF-NER/
python3 setup.py install
1
2
3
如果沒啥問題,你將會看到這個:

筆者在windows10/ Linux/ Mac OSX上都測試過,安裝沒有問題。

軟件包現(xiàn)在支持的功能
命名實體識別的訓(xùn)練
命名實體識別的服務(wù)C/S
繼承優(yōu)秀開源軟件:bert_as_service(hanxiao)的BERT所有服務(wù)
4. 文本分類服務(wù) (2019.2.19)
內(nèi)容還會繼續(xù)補充,同時歡迎大神們分享訓(xùn)練的模型或者新的方法或者數(shù)據(jù)(弱雞的我并不會用在商業(yè)上,畢竟還是一個畢業(yè)即失業(yè)的渣渣~~)。

基于命名行訓(xùn)練命名實體識別模型:
安裝完bert-base后,會生成兩個基于命名行的工具,其中bert-base-ner-train支持命名實體識別模型的訓(xùn)練,你只需要指定訓(xùn)練數(shù)據(jù)的目錄,BERT相關(guān)參數(shù)的目錄即可。可以使用下面的命令查看幫助

bert-base-ner-train -help
1

訓(xùn)練的事例命名如下:

bert-base-ner-train \
-data_dir {your dataset dir}\
-output_dir {training output dir}\
-init_checkpoint {Google BERT model dir}\
-bert_config_file {bert_config.json under the Google BERT model dir} \
-vocab_file {vocab.txt under the Google BERT model dir}
1
2
3
4
5
6
參數(shù)說明
其中data_dir是你的數(shù)據(jù)所在的目錄,訓(xùn)練數(shù)據(jù),驗證數(shù)據(jù)和測試數(shù)據(jù)命名格式為:train.txt, dev.txt,test.txt,請按照這個格式命名文件,否則會報錯。
訓(xùn)練數(shù)據(jù)的格式如下:
海 O
釣 O
比 O
賽 O
地 O
點 O
在 O
廈 B-LOC
門 I-LOC
與 O
金 B-LOC
門 I-LOC
之 O
間 O
的 O
海 O
域 O
。 O
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
每行得第一個是字,第二個是它的標(biāo)簽,使用空格’ '分隔,請一定要使用空格。句與句之間使用空行劃分。程序會自動讀取你的數(shù)據(jù)。

output_dir: 訓(xùn)練模型輸出的文件路徑,模型的checkpoint以及一些標(biāo)簽映射表都會存儲在這里,這個路徑在作為服務(wù)的時候,可以指定為-ner_model_dir
init_checkpoint: 下載的谷歌BERT模型
bert_config_file : 谷歌BERT模型下面的bert_config.json
vocab_file: 谷歌BERT模型下面的vocab.txt
訓(xùn)練完成后,你可以在你指定的output_dir中查看訓(xùn)練結(jié)果。

將命名實體識別任務(wù)進行服務(wù)部署
作為服務(wù)的很多代碼都來自優(yōu)秀的開源項目: bert as service of hanxiao 但是我不知道這樣改動是不是違反了某些許可規(guī)定,如果有違反,請馬上告訴我,我將第一時間進行修改.而且服務(wù)端的代碼很解耦,修改為另外一種任務(wù)的服務(wù)也是很簡單的,例如文本分類,我將會不就提供這一功能,也歡迎愿意分享的童鞋分享模型或者代碼。

作為服務(wù)的命名是:bert-base-serving-start,同樣的,你可以先使用-help查看相關(guān)幫助

bert-base-serving-start -help
1

作為命名實體識別任務(wù)的服務(wù),這兩個目錄是你必須指定的:ner_model_dir, bert_model_dir
然后你就可以使用下面的命令啟動了:

bert-base-serving-start \
-model_dir C:\workspace\python\BERT_Base\output\ner2 \
-bert_model_dir F:\chinese_L-12_H-768_A-12
-mode NER
1
2
3
4
參數(shù)解釋
bert_model_dir: 谷歌BERT模型的解壓路徑,可以在這里下載 https://github.com/google-research/bert
model_dir: 訓(xùn)練好的NER模型或者文本分類模型的路徑,對于上面的output_dir
model_pd_dir: 運行模型優(yōu)化代碼后, 經(jīng)過模型壓縮后的存儲路徑,例如運行上面的命令后改路徑下會產(chǎn)生 ner_model.pb 這個二進制文件
mode:NER 或者是BERT這兩個模式,類型是字符串,如果是NER,那么就會啟動NER的服務(wù),如果是BERT,那么具體參數(shù)將和[bert as service] 項目中得一樣。

我提供了命名實體識別pb模型下載:https://pan.baidu.com/s/1m9VcueQ5gF-TJc00sFD88w, 提取碼: guqq
文本分類模型:https://pan.baidu.com/s/1oFPsOUh1n5AM2HjDIo2XCw, 提取碼: bbu8
文本分類使用的是bert中的demo:run_classxxx.py,在運行的時候使用Pickle序列化了label_list和id2label折兩個變量。
將 ner_mode.pb/classification_model.pb 文件放到 model_pd_dir目錄下,將命名識別的label_list.pkl和id2map.pkl不同的模型不同的文件夾,因為他們同名,但是內(nèi)容不一樣,需要區(qū)分開來
命名實體識別模型只支持人名,地名,住址機構(gòu)名的識別,在我的測試數(shù)據(jù)上有95.6%的F1值(實體級別的得分)
文本分類模型數(shù)據(jù)來自清華大學(xué)的文本分類數(shù)據(jù):http://thuctc.thunlp.org/ , 在測試數(shù)據(jù)上準(zhǔn)確率為98%~99%的準(zhǔn)確率
肥腸歡迎大家分享你們訓(xùn)練的更好的模型。

如果使用的下載的模型,你可以使用下面的命令啟動,替換你自己的路徑即可:

bert-base-serving-start -model_pd_dir /home/macan/ml/workspace/BERT_Base/output/predict_optimizer \
-bert_model_dir /home/macan/ml/data/chinese_L-12_H-768_A-12/ \
-ner_model_dir /home/macan/ml/data/bert_ner \
-num_worker 8
-mode NER
1
2
3
4
5
你將會看到下面的啟動信息(啟動log有點多,分兩張圖截):

?

在本地連接服務(wù)端進行命名實體識別的測試
你可以使用下面的代碼進行服務(wù)的連接,在本地進行NER測試,客戶端代碼如下:

import time
from bert_base.client import BertClient
# 指定服務(wù)器的IP
with BertClient(ip='XXX,XXX,XXX,XXX', ner_model_dir=ner_model_dir, show_server_config=False, check_version=False, check_length=False, mode='NER') as bc:
start_t = time.perf_counter()
str = '1月24日,新華社對外發(fā)布了中央對雄安新區(qū)的指導(dǎo)意見,洋洋灑灑1.2萬多字,17次提到北京,4次提到天津,信息量很大,其實也回答了人們關(guān)心的很多問題。'
rst = bc.encode([str, str]) #測試同時輸入兩個句子,多個輸入同理
print('rst:', rst)
print(time.perf_counter() - start_t)
1
2
3
4
5
6
7
8
9
運行后,會輸出下面的信息:


結(jié)果說明:
返回的結(jié)果就是序列標(biāo)注的結(jié)果,再往后的工作就不準(zhǔn)備再寫了,因為后面的操作會涉及到一些策略問題,寫的太多,影響代碼的靈活,例如有童鞋在terminal_predict.py的代碼上提了issue,無法應(yīng)用到自己的數(shù)據(jù)中。這樣看起來,也比較直觀吧~~

到此,基于命令行的用法已經(jīng)講完,不明白的地方請評論或者在GitHub上提交issue,覺得有用,麻煩在GitHub上點個star吧~~

###########################################################################################

以下是基于源代碼的訓(xùn)練和啟動服務(wù)的教程
###########################################################################################

自己訓(xùn)練命名實體識別模型
使用谷歌的BERT模型在BLSTM-CRF模型上進行預(yù)訓(xùn)練用于中文命名實體識別的Tensorflow代碼’

代碼已經(jīng)托管到GitHub 代碼傳送門 大家可以去clone 下來親自體驗一下!

git clone https://github.com/macanv/BERT-BiLSTM-CRF-NER
1
關(guān)于BERT的相關(guān)理論文章不是本文的主要目的,而且網(wǎng)上簡介該部分的文章多如牛毛,大家自行去查看吧,本文著重講解基于BERT用于中文命名實體的fine-tuning 過程。

1. 下載Google BERT 預(yù)訓(xùn)練模型:
下載
wget https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip
解壓
unzip chinese_L-12_H-768_A-12.zip
1
2
3
4
2. 訓(xùn)練模型
下載了Google的BERT模型和我的GitHub代碼后,就可以開始訓(xùn)練啦
訓(xùn)練之前先在項目目錄中新建一個output文件夾,模型的輸出,和結(jié)構(gòu)都會保存在這個目錄中

mkdir output
1
訓(xùn)練的時候需要一些參數(shù),你可以使用命名行的形式進行模型參數(shù)指定,例如下面的方法:

python3 bert_lstm_ner.py \
--task_name="NER" \
--do_train=True \
--do_eval=True \
--do_predict=True
--data_dir=NERdata \
--vocab_file=checkpoint/vocab.txt \
--bert_config_file=checkpoint/bert_config.json \
--init_checkpoint=checkpoint/bert_model.ckpt \
--max_seq_length=128 \
--train_batch_size=32 \
--learning_rate=2e-5 \
--num_train_epochs=3.0 \
--output_dir=./output/result_dir/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
筆者比較菜,選擇的是將默認(rèn)參數(shù)寫在代碼中,開始訓(xùn)練的之前,只需要修改下面的代碼即可,代碼在bert_lstm_ner.py文件中

if os.name == 'nt': #windows path config
bert_path = '{your BERT model path}'
root_path = '{project path}'
else: # linux path config
bert_path = '{your BERT model path}'
root_path = '{project path}'
1
2
3
4
5
6
os.name=='nt’是表示識別到的系統(tǒng)是windows,其余的是Linux,這里只需要修改一個,如果你是windows訓(xùn)練修改os.name='nt’下面的路徑就好了,Linux或者Mac修改else下面的兩個路徑。
兩個路徑說明:
bert_path: 就是在步驟1中下載解壓的BERT模型的路徑,復(fù)制絕對路徑替換即可,例如我項目中所寫的路徑
root_path: 這個是項目的路徑,也是一個絕對路徑,即BERT-BiLSTM-CRF-NER的路徑

修改好兩個路徑后,就可以開始訓(xùn)練了:

python3 bert_lstm_ner.py
1
說明:
模型代碼主要在bert_lstm_ner.py中的create_model函數(shù)中
下面對該函數(shù)邏輯進行講解:

1使用bert模型對我們的輸入進行represent
#使我們的input_ids數(shù)據(jù)通過bert 網(wǎng)絡(luò)結(jié)構(gòu)
model = modeling.BertModel(
config=bert_config,
is_training=is_training,
input_ids=input_ids,
input_mask=input_mask,
token_type_ids=segment_ids,
use_one_hot_embeddings=use_one_hot_embeddings
)
# 獲取bert 模型最后一層
embedding = model.get_sequence_output()
1
2
3
4
5
6
7
8
9
10
11
bert 的最后一層是所有transformer結(jié)果的最后一維,其是一個三維向量維度是:[batch_size, seq_length, embedding_size],可以類比的理解為我們使用tf.nn.embedding_lookup獲取的結(jié)果。

2 將embedding 作為LSTM結(jié)構(gòu)的輸入:
# 加載BLSTM-CRF模型對象
blstm_crf = BLSTM_CRF(embedded_chars=embedding, hidden_unit=FLAGS.lstm_size, cell_type=FLAGS.cell, num_layers=FLAGS.num_layers,
dropout_rate=FLAGS.droupout_rate, initializers=initializers, num_labels=num_labels,
seq_length=max_seq_length, labels=labels, lengths=lengths, is_training=is_training)
# 獲取添加我們自己網(wǎng)絡(luò)結(jié)構(gòu)后的結(jié)果,這些結(jié)果包括loss, logits, trans, pred_ids
rst = blstm_crf.add_blstm_crf_layer(crf_only=True)
1
2
3
4
5
6
這里有幾點需要說明:

因為BERT里面已經(jīng)存在雙向編碼,所以LSTM并不是必須的,可以將BERT最后一層的結(jié)構(gòu)直接扔給CRF進行解碼。所以在代碼中通過在add_blstm_crf_layer函數(shù)中的crf_only參數(shù)進行控制我們訓(xùn)練的時候使用的是那種網(wǎng)絡(luò)結(jié)構(gòu)用于最后的fine-tuning.通過兩種結(jié)構(gòu)的訓(xùn)練結(jié)果對比,其實他們的最后結(jié)果相差不大,可以說基本是一樣的,足見transformer的強大。
crf_only=True 是我們fine-tuning 只使用CRF進行解碼,不再使用傳統(tǒng)經(jīng)典的BLSTM-CRF,False表示使用blstm-crf這樣的網(wǎng)絡(luò)結(jié)構(gòu)。
但是我在試驗中發(fā)現(xiàn),只使用CRF的訓(xùn)練時間要比BLSTM-CRF結(jié)構(gòu)的時間要長,這一點我百思不得其解,按理加了BLSTM網(wǎng)絡(luò)的參數(shù)會更多,如果有大佬發(fā)現(xiàn)這是個錯的觀察或者有合理的解釋,麻煩不吝賜教。
實驗結(jié)果
1 基于label計算出來的指標(biāo):
In dev data set:


In test data set


2 在很多地方命名實體的結(jié)果使用基于實體級別的評測更為合理,下面是實體級別的評測結(jié)果。

評測腳本使用的是conlleval.pl, conlleval.py

提供我訓(xùn)練的模型下載:

my model can download from baidu cloud:
鏈接:https://pan.baidu.com/s/1GfDFleCcTv5393ufBYdgqQ 提取碼:4cus

3 在線預(yù)測
當(dāng)你的模型訓(xùn)練完后,可以使用下面的腳本加載模型,進行在線預(yù)測
python3 terminal_predict.py
1


使用自己的數(shù)據(jù):
BERT的大腿簡直太粗了,效果很好有木有,看到這樣的效果,是不是很想再自己的數(shù)據(jù)上進行測試一番呢? 其實改的地方很少,只需要修改bert_lstm_ner.py文件中的幾行代碼就好啦:

get_labels 函數(shù)
def get_labels(self):
return ["O", "B-PER", "I-PER", "B-ORG", "I-ORG", "B-LOC", "I-LOC", "X", "[CLS]", "[SEP]"]
1
2
這里是我數(shù)據(jù)中所有的標(biāo)簽,其中"X", “[CLS]”, “[SEP]” 是附加的, “[CLS]”, "[SEP]"是句子的開始和結(jié)束標(biāo)志,X是wordpice產(chǎn)生的東西,中文中目前還沒有遇到過,可以不用管,大家要改的話,就改前面的標(biāo)簽就好啦。
例如你想加一個時間類型的實體,就加 “B-TIME”, “I-TIME”
如果你想應(yīng)用于分詞中,那就沒有-XXX了。就是B,I這些,簡而言之,就是你的序列標(biāo)注數(shù)據(jù)中的第二列的標(biāo)簽的set集合。
你也可以把get_labels函數(shù)寫成這樣一勞永逸,但是要注意在測試集或者驗證機中出現(xiàn)的OOLabel哦:

def get_labels(self):
# 通過讀取train文件獲取標(biāo)簽的方法會出現(xiàn)一定的風(fēng)險。
if os.path.exists(os.path.join(FLAGS.output_dir, 'label_list.pkl')):
with codecs.open(os.path.join(FLAGS.output_dir, 'label_list.pkl'), 'rb') as rf:
self.labels = pickle.load(rf)
else:
if len(self.labels) > 0:
self.labels = self.labels.union(set(["X", "[CLS]", "[SEP]"]))
with codecs.open(os.path.join(FLAGS.output_dir, 'label_list.pkl'), 'wb') as rf:
pickle.dump(self.labels, rf)
else:
self.labels = ["O", 'B-TIM', 'I-TIM', "B-PER", "I-PER", "B-ORG", "I-ORG", "B-LOC", "I-LOC", "X", "[CLS]", "[SEP]"]
return self.labels
1
2
3
4
5
6
7
8
9
10
11
12
13
參考:
The evaluation codes come from:https://github.com/guillaumegenthial/tf_metrics/blob/master/tf_metrics/init.py

https://github.com/google-research/bert

https://github.com/kyzhouhzau/BERT-NER

https://github.com/zjy-ucas/ChineseNER

https://github.com/hanxiao/bert-as-service
---------------------
作者:Macanv
來源:CSDN
原文:https://blog.csdn.net/macanv/article/details/85684284
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!

總結(jié)

以上是生活随笔為你收集整理的基于BERT预训练的中文命名实体识别TensorFlow实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。