當前位置:
首頁 > 知識 > 使用Bert預訓練模型文本分類

使用Bert預訓練模型文本分類

作者:GjZero

標籤:Bert, 中文分類, 句子向量

本文約1500字,建議閱讀8分鐘

本文從實踐入手,帶領大家進行Bert的中文文本分類和作為句子向量進行使用的教程。

Bert介紹

Bert模型是Google在2018年10月發布的語言表示模型,Bert在NLP領域橫掃了11項任務的最優結果,可以說是現今最近NLP中最重要的突破。Bert模型的全稱是Bidirectional Encoder Representations from Transformers,是通過訓練Masked Language Model和預測下一句任務得到的模型。關於Bert具體訓練的細節和更多的原理,有興趣的讀者可以去看在[arXiv](https://arxiv.org/abs/1810.04805)上的原文。本篇文章從實踐入手,帶領大家進行Bert的中文文本分類和作為句子向量進行使用的教程。

對於文本分類任務,一個句子中的N個字元對應了E_1,…,E_N,這N個embedding。文本分類實際上是將BERT得到的T_1這一層連接上一個全連接層進行多分類。

準備工作

1. 下載bert

在命令行中輸入

git clone

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

2. 下載bert預訓練模型

3.(可選項)

安裝bert-as-service,這是一個可以利用bert模型將句子映射到固定長度向量的服務。

在命令行中輸入

pip install bert-serving-server # server

pip install bert-serving-client # client, independent of "bert-serving-server"

該服務要求tensorflow的最低版本為1.10。

準備數據

數據格式

作為中文文本分類問題,需要先將數據集整理成可用的形式。不同的格式對應了不同的DataProcessor類。可以將數據保存成如下格式:

gameAPEX是個新出的吃雞遊戲。

technology Google將要推出tensorflow2.0。

一行代表一個文本,由標籤加上一個tab加上正文組成。

將文本分割為三個文件,train.tsv(訓練集),dev.tsv(驗證集),test.tsv(測試集);然後放置在同一個data_dir文件夾下。

編寫DataProcessor類

在bert文件夾下的「run_classifier.py**中的」def main(_):」函數中將processors的內容增加為

python

processors = {

"cola": ColaProcessor,

"mnli": MnliProcessor,

"mrpc": MrpcProcessor,

"xnli": XnliProcessor,

"mytask": MyTaskProcessor,

}

實現如下的「MyTaskProcessor

(DataProcessor)」類,並將這一段代碼放置在「run_classifier.py」和其他Processor並列的位置。

「\_\_init\_\_(self)」中的self.labels含有所有的分類label,在這個例子中我們將文本可能分為3類:game, fashion, houseliving。

python

class MyTaskProcessor(DataProcessor):

"""Processor for the News data set (GLUE version)."""

def __init__(self):

self.labels = ["game", "fashion", "houseliving"]

def get_train_examples(self, data_dir):

return self._create_examples(

def get_dev_examples(self, data_dir):

return self._create_examples(

def get_test_examples(self, data_dir):

return self._create_examples(

def get_labels(self):

return self.labels

def _create_examples(self, lines, set_type):

"""Creates examples for the training and dev sets."""

examples = []

for (i, line) in enumerate(lines):

guid = "%s-%s" % (set_type, i)

text_a = tokenization.convert_to_unicode(line[1])

label = tokenization.convert_to_unicode(line[0])

examples.append(

InputExample(guid=guid, text_a=text_a, text_b=None, label=label))

return examples

如果數據格式並不是一個label,一個tab,一段文本;則需要更改「_create_examples()」的實現。

編寫運行腳本

新建一個運行腳本文件名為「run.sh」,將文件內容編輯為:

bash

export DATA_DIR=/media/ganjinzero/Code/bert/data/

export BERT_BASE_DIR=/media/ganjinzero/Code/bert/chinese_L-12_H-768_A-12

python run_classifier.py

--task_name=mytask

--do_train=true

--do_eval=true

--data_dir=$DATA_DIR/

--vocab_file=$BERT_BASE_DIR/vocab.txt

--bert_config_file=$BERT_BASE_DIR/bert_config.json

--init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt

--max_seq_length=128

--train_batch_size=32

--learning_rate=2e-5

--num_train_epochs=3.0

--output_dir=/mytask_output

其中DATA_DIR是你的要訓練的文本的數據所在的文件夾,BERT_BASE_DIR是你的bert預訓練模型存放的地址。task_name要求和你的DataProcessor類中的名稱一致。下面的幾個參數,do_train代表是否進行fine tune,do_eval代表是否進行evaluation,還有未出現的參數do_predict代表是否進行預測。如果不需要進行fine tune,或者顯卡配置太低的話,可以將do_trian去掉。max_seq_length代表了句子的最長長度,當顯存不足時,可以適當降低max_seq_length。

進行預測

運行腳本

bash

./run.sh

可以得到類似如下樣式的結果

***** Eval results *****

eval_accuracy = 0.845588

eval_loss = 0.505248

global_step = 343

loss = 0.505248

如果出現了這樣的輸出,就是運行成功了。在「run.sh」里指定的output_dir文件夾下可以看到模型的evaluation結果和fine-tune(微調)之後的模型文件。

以句子向量的形式使用Bert

如果想要將bert模型的編碼和其他模型一起使用,將bert模型作為句子向量使用很有意義(也就是所謂的句子級別的編碼)。我們可以使用bert-as-service來完成這個目標。

安裝完bert-as-service以後,就可以利用bert模型將句子映射到固定長度的向量上。在終端中用一下命令啟動服務:

bash

bert-serving-start -model_dir /media/ganjinzero/Code/bert/chinese_L-12_H-768_A-12 -num_worker=4

model_dir後面的參數是bert預訓練模型所在的文件夾。num_worker的數量應該取決於你的CPU/GPU數量。

這時就可以在Python中調用如下的命令:

python

from bert_serving.client import BertClient

bc = BertClient()

bc.encode(["一二三四五六七八", "今天您吃了嗎?"])

最好以列表的形式,而非單個字元串傳給」bc.encode()」參數,這樣程序運行的效率較高。

參考文檔

[Github:bert]

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

[arXiv:bert](https://arxiv.org/pdf/1810.04805.pdf)

[Github:bert-as-service](https://github.com/hanxiao/bert-as-service)

【作者簡介】

GjZero,清華大學統計中心博士二年級在讀。研究方向是醫學信息學中的自然語言處理。興趣是撲克、麻將等和博弈論有關的運動。

github:

https://github.com/GanjinZero

個人主頁:

https://ganjinzero.github.io/

編輯:文婧

校對:林亦霖


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 數據派THU 的精彩文章:

如何在數據科學領域從起步到就業
10本好書帶你從Python爬蟲小白進階數據分析大神

TAG:數據派THU |