75. Google BERT 预训练技术#
75.1. 介绍#
2018 年,自然语言处理领域最大的新闻之一莫过于 Google BERT 的横空出世。Google BERT 声称是最先进的 NLP 预训练技术,支持中文和更多语言。相关论文中,BERT 展示了包括斯坦福问答数据集(SQUAD v1.1)在内 11 个 NLP 任务的最新结果,均取得了最好的效果。
75.2. 知识点#
Google BERT
NLP 预训练技术
BERT 是 Google 开源的 NLP 预训练技术,它的全称是 Bidirectional Encoder Representations from Transformers。
BERT 建立在最新的预训练与上下文相关的语言表示的工作之上,包括 Semi-supervised Sequence Learning、Generative Pre-Training、ELMo 和 ULMFit。然而,与以前的模型不同,BERT 是第一个深度、双向、无监督的语言表示模型,仅使用无标签的文本语料库(在本例中为维基百科)进行预训练。
由于模型结构复杂,再加上语料庞大,BERT 在目前最强商用 GPU 上都需要训练长达数个月之久。不过好消息是,Google 发布了支持中文以及多语言的预训练基础模型 BERT-Base。借助于预训练模型,我们就可以很轻松地完成多种 NLP 任务。
开放型挑战
挑战:利用 Google BERT 提供的中文预训练语言模型,完成假新闻数据文本分类任务。我们建议你对提供的数据进行 8:2 切分,并最终得到测试集上的准确度。
挑战需使用实验中提供的假新闻数据下载链接。
https://cdn.aibydoing.com/aibydoing/files/wsdm_mini.csv # 假新闻数据
https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip # Google 提供下载链接
75.2.1. 指导说明#
本次挑战不适合于通过线上 Notebook 完成,推荐你在本地完成挑战。由于挑战难度较大,在此提供一些指导说明。请注意,示例代码无法正常执行,请仔细揣摩并灵活变通。
这里使用 BERT 完成文本分类将利用微调的方法,首先需要下载 Google 提供的预训练语言模型。然后,克隆 BERT 官方仓库,以便于直接利用 Google 提供的模型训练源码:
# 克隆 BERT 官方仓库
git clone https://github.com/google-research/bert.git
Google 提供的模型训练源码中,完成文本分类的代码放在
run_classifier.py
中。其中,Google 提供了在 4
个基准数据集上的测试代码,并对应
XnliProcessor,MnliProcessor,MrpcProcessor 和
ColaProcessor
中。那么,要想完成自己的文本分类任务,我们只需要模仿并改写类即可。
改写 Processor
类的过程非常简单,只需要按照自己的需要传入数据即可,建议参考源码中
XnliProcessor
类的实现过程,和本次分类任务比较相似。例如,我们这里把自己的文本分类类定为
WSDMProcessor
,其中包含下面四个函数:
class WSDMProcessor(DataProcessor):
# 传入训练数据
def get_train_examples(self, data_dir):
# 读取训练数据路径
file_path = os.path.join(data_dir, 'train.csv')
# 使用 Pandas 读取数据
df = pd.read_csv(file_path)
# 将训练数据切分为 80% 训练集和 20% 验证集
df_train, self.df_dev = train_test_split(df, test_size=0.2)
examples = []
# 按 BERT 推荐格式处理数据
for index, row in df_train.iterrows():
guid = 'train-%d' % index # 索引
text_a = tokenization.convert_to_unicode(str(row[0])) # 文本 1
text_b = tokenization.convert_to_unicode(str(row[1])) # 文本 2
label = row[2] # 文本标签
examples.append(InputExample(guid=guid, text_a=text_a,
text_b=text_b, label=label))
return examples
# 传入验证数据
def get_dev_examples(self, data_dir):
examples = []
for index, row in self.df_dev.iterrows():
guid = 'dev-%d' % index
text_a = tokenization.convert_to_unicode(str(row[0]))
text_b = tokenization.convert_to_unicode(str(row[1]))
label = row[2]
examples.append(InputExample(guid=guid, text_a=text_a,
text_b=text_b, label=label))
return examples
# 传入测试数据(预测)
def get_test_examples(self, data_dir):
file_path = os.path.join(data_dir, 'test.csv')
df_test = pd.read_csv(file_path)
examples = []
for index, row in df_test.iterrows():
guid = 'test-%d' % index
text_a = tokenization.convert_to_unicode(str(row[0]))
text_b = tokenization.convert_to_unicode(str(row[1]))
label = '0' # 随意指定测试数据标签
examples.append(InputExample(guid=guid, text_a=text_a,
text_b=text_b, label=label))
return examples
def get_labels(self):
return ['A', 'B', 'C'] # 示例三分类任务对应数据标签
你会发现,传入训练、验证和测试数据的函数基本一致,关键在于按 BERT 要求将数据处理成规定。
接下来,我们还需要修改
main()
函数中的 processors,添加刚刚自定义的 WSDMProcessor:
def main(_):
tf.logging.set_verbosity(tf.logging.INFO)
processors = {
"cola": ColaProcessor,
"mnli": MnliProcessor,
"mrpc": MrpcProcessor,
"xnli": XnliProcessor,
"self": WSDMProcessor, # 添加自定义 Processor
}
完成上面的工作,就可以开始执行文本分类任务了。按照 BERT 开源仓库示例的执行代码运行即可,例如:
python run_classifier.py \
--task_name=self \ # 执行 processor
--do_train=true \ # 开启训练模型
--do_eval=true \ # 开启验证模型
--do_predict=true \ # 开启测试模型
--data_dir=./dataset \ # 数据路径
--vocab_file=./chinese_L-12_H-768_A-12/vocab.txt \ # 预训练模型下载文件路径
--bert_config_file=./chinese_L-12_H-768_A-12/bert_config.json \
--init_checkpoint=./chinese_L-12_H-768_A-12/bert_model.ckpt \
--max_seq_length=128 \ # 模型训练参数
--train_batch_size=32 \
--learning_rate=5e-5 \
--num_train_epochs=1.0 \
--output_dir=./dataset/output # 输出文件路径
注意,只有定义了相关的函数,才开启相应的选项。例如,Processor
中未定义验证集函数,那么就把
--do_eval=false
即可。模型训练完成之后,会在输出文件路径下保留相应的模型和测试结果。
现在就自己去试一试吧,仔细阅读官方开源页面的说明和仓库 Issues 页面 已知问题来解决遇到的麻烦。
○ 欢迎分享本文链接到你的社交账号、博客、论坛等。更多的外链会增加搜索引擎对本站收录的权重,从而让更多人看到这些内容。