使用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/
編輯:文婧
校對:林亦霖
![](https://pic.pimg.tw/zzuyanan/1488615166-1259157397.png)
![](https://pic.pimg.tw/zzuyanan/1482887990-2595557020.jpg)
※如何在數據科學領域從起步到就業
※10本好書帶你從Python爬蟲小白進階數據分析大神
TAG:數據派THU |