bert cnn知识抽取模型_预训练BERT,官方代码发布前他们是这样用TensorFlow解决的...

参与:思源、王淑婷

这个月谷歌提出的 BERT 受到了很多关注,该研究凭借预训练模型刷新了 11 项 NLP 任务的当前最优性能记录。论文表示这个月月末会放出代码与预训练模型,但目前还没有发布。因此很多研究者尝试使用中等数据集降低计算力,或使用 OpenAI 的 Transformer 预训练模型作为初始化条件。

本文介绍的两个 BERT 实现项目分别基于 TensorFlow 和 Keras,其中基于 TensorFlow 的项目会使用中等数据集与其它技巧降低计算力,并发现使用 TextCNN 代替 Transformer 主干网络,且保留 BERT 预训练任务也能得到非常好的效果。而基于 Keras 的项目尝试使用预训练的 OpenAI Transformer 作为初始化权重,并以较小的计算力重新训练 BERT 预训练模型,再将该预训练的 BERT 应用到不同任务。

这两个项目都在尝试使用 BERT 核心思想,并以较小的计算成本应用于其它 NLP 任务。当然如果读者希望使用大型 BERT 预训练模型,还需要等谷歌发布代码与模型。

BERT 简介

BERT 的全称是基于 Transformer 的双向编码器表征,其中双向表示模型在处理某个词时,它能同时利用前面的词和后面的词两部分信息。这种双向的在于 BERT 与传统语言模型不同,它不是在给定所有前面词的条件下预测最可能的当前词,而是随机遮掩些词,并利用所有没被遮掩的词进行预测。下图展示了三种预训练模型,其中 BERT 和 ELMo 都使用双向信息,OpenAI GPT 使用单向信息。

如上所示为不同预训练模型的架构,BERT 可以视为结合了 OpenAI GPT 和 ELMo 优势的新模型。其中 ELMo 使用两条独立训练的 LSTM 获取双向信息,而 OpenAI GPT 使用新型的 Transformer 和经典语言模型只能获取单向信息。BERT 的主要目标即在 OpenAI GPT 的基础上对预训练任务做些改进,以同时利用 Transformer 深度模型与双向信息的优势。

BERT 的核心过程非常简洁,它会先从数据集抽取两个句子,其中第二句是第句的下句概率是 50%,这样就能学习句子之间的关系。其次随机去除两个句子中的些词,并要求模型预测这些词是什么,这样就能学习句子内部的关系。最后再将经处理的句子传入大型 Transformer 模型,并通过两个损失函数同时学习上面两个目标就能完成训练。

TensorFlow 实现项目简介

BERT 最近在 10 几项 NLP 任务上取得了新进展,这个项目是和这两篇论文的 tensorflow 实现。

这个项目了预训练方法与代码,并做了些调整以加快收敛速度。这份 TensorFlow 实现在使用中等数据集下计算力并不是太大,所以感兴趣的读者也可以尝试使用。当然,希望使用大型预训练 BERT 模型的读者可以等谷歌发布模型。

预训练和微调实验

项目把 Transfprmer 换成 TextCNN,替换了 BERT 的主干网络,结果发现使用大量原始数据用遮蔽语言模型预训练的模型可以显著提高性能,因此他们认为预训练和微调策略是独立于模型和预训练任务的。因此,可以修正主干网络添加更多的预训练任务或者定义些新的预训练任务,预训练不限于遮蔽语言模型或预测下句的任务。让人惊讶的是,对于中等规模的数据集(比如说百万条数据)来说,即使不使用外部数据,只要借助于预训练任务(如带掩码的语言模型),性能也可以大幅提升,而且模型可以更快地收敛。有时在微调阶段,训练仅需几个 epoch。

目的

性能

下图是在中等规模数据集(cail2018,45 万)上文本分类任务的效果,其中采用 BERT 预训练思想的 TextCNN 要显著优于其它模型:

下图是在小规模数据集(private,10 万)上的效果:

TensorFlow 实现项目细节

使用方法

如果想在 Masked 语言模型上预训练 BERT 模型,并在新 NLP 任务上使用它,那么使用方法主要可以分为两步骤。值得注意的是,该项目并没有预训练模型,所以需要大量计算力的预训练过程仍然需要自行执行。

1. 通过 BERT 预训练语言模型

python train_bert_lm.py [DONE]

2. 在新任务微调模型

python train_bert_fine_tuning.py [Done]

在项目的试验中,即使在微调的起点,刚刚从预训练模型恢复参数也能获得比从头训练更低的损失。预训练模型的 F1 值同样要比从头训练的高,且从头训练的 F1 值还需要从零开始增长。

此外为了快速新想法与模型,可以将超参数 test_mode 设置为 True,在这种模式下模型只会加载少量的数据进行,因此训练非常迅速。

在基本步骤中,还可以通过 Transform 解决文本分类问题:

预训练和微调过程还有其它些可选超参数,它们控制了模型的大小与训练过程:

d_model:模型维度,默认为 [512]。

num_layer:层级数,默认为 [6]。

num_header:自注意力机制的 Head 数,默认为 [8]。

d_k:Key(K)和 Query(Q)的维度,默认为 [64]。

d_v:Value(V)的维度,默认为 [64]。default hyperparameter

isd_model=

512,h=

8,d_k=d_v=

64(big).

ifyou have want to train the model fast,

orhas a small data set

orwant to train a small model, use d_model= 128,h= 8,d_k=d_v= 16(small), ord_model= 64,h= 8,d_k=d_v= 8(tiny).

实现细节

首先,TensorFlow 的实现环境比较简单:python 3+ tensorflow 1.10。其次,实现时要注意以下问题:

1. 预训练和微调阶段之间有哪些能够共享和无法共享的参数?

基本来说,预训练和微调阶段的主干网络使用的所有参数都能共享。

既然可以共享很多参数,那微调阶段只需学习很少的参数,此外这两个阶段的词嵌入也可以共享。

因此,在微调的初始阶段已经学习了大部分参数。

2. 如何实现带 Mask 的语言模型?

为了让事情变得简单点,可以根据文件生成很多句子。把每个句子截断并填充到相同的长度,随机选择个单词,用 [MASK]、单词本身或个随机单词替换它。

3. 如何使微调阶段变得更高效并同时不影响在预训练阶段学到的结果和知识?

在微调阶段使用较小的学习率,因此只需在很小的范围内进行调整。

Keras 实现

基于 TensorFlow 的实现同样没有预训练语言模型,这样的模型在预训练阶段会需要大量的计算力,这样的计算力需求对于很多研究者与者都是接受不了的。但是现在的实现与预训练模型仍然没有放出来,因此有者利用 OpenAI 预训练的 Transformer 作为初始化参数,并训练新的 BERT 预训练模型,这种方式大大降低了计算力需求。

在这个 Keras 实现项目中,用预训练的 OpenAI Transformer 作为初始化条件,并训练新的 BERT,项目表示这样可以不使用 TPU 而实现预训练。以下展示了 Keras 实现的主要语句,包括加载 OpenAI Transformer 预训练模型、加载 BERT 模型和保存新的预训练权重等。

# this is a pseudo code you can read an actual working example in tutorial.ipynb

text_encoder = MyTextEncoder(**my_text_encoder_params) # you create a text encoder (sentence piece and openai"s bpe are included)

lm_generator = lm_generator(text_encoder, **lm_generator_params) # this is essentially your data reader (single sentence and double sentence reader with masking and is_next label are included)

task_meta_datas = [lm_task, classification_task, pos_task] # these are your tasks (the lm_generator must generate the labels for these tasks too)

encoder_model = create_transformer(**encoder_params) # or you could simply load_openai

trained_model = train_model(encoder_model, task_meta_datas, lm_generator, **training_params) # it does both pretraing and finetuning

trained_model.save_weights( "my_awesome_model") # save it

model = load_model( "my_awesome_model", encoder_model) # load it later and use it!

表示这个项目有些很重要说明,针对不同的任务与需求,可以根据这些说明修改模型结构和预训练过程。

这个库的核心观点是使用 OpenAI 的预训练模型作为训练新模型的初始状态,因此通过 GPU 就能训练 BERT。

通过 Keras 加载 OpenAI 模型已经在 TensorFlow 后端和 Theano 后端得到。

对于大多数 NLP 模型,能使用这个项目定义的数据生成器和任务元数据,即使在其它框架中也是。

数据集和 Transformer 都会执行些单元,如果你不太了解代码可以阅读这些。

还可以使用其它编码器进行训练,例如 LSTM 或 BiQRNN 等。

当代码发布后会发生什么?数据读取器仍然会保持稳定,甚至可以导入发布的权重到这个库中(认为他会完成这过程,因为实际的 Transformer 还是比较容易实现的)

强烈建议阅读项目中的 tutorial.ipynb 文件,它展示了整个项目的使用过程。

重要的代码概念

任务:有两个般任务,句子级任务(如下句预测和情感分析)和 token 级任务(如词性标注和命名实体识别)。

句子:句子表示段带有和所有内容的实例,它为每个任务了个目标(句子级任务的单个标注值,token 级任务的每个 token )和个掩码;对于 token 级任务,除了忽略 padding 外,还要使用第个符号向量预测类别(BERT 中的 [CLS] 符号)。

TaskWeightScheduler:项目希望从语言模型开始训练,迁移到到分类任务,我们可以用这个类快速实现。

special_tokens:pad, start, end, delimiter, mask

本文相关词条概念解析:

模型

模型是所研究的系统、过程、事物或概念的一种表达形式,也可指根据实验、图样放大或缩小而制作的样品,模型一般用于展览或实验或铸造机器零件等用的模子。对于现实世界的事物、现象、过程或系统的简化描述,或其部分属性的模仿。在一般的意义下是指模仿实物或设计中的构造物的形状制成的雏型,其大小可以分为缩小型、实物型和放大型。

使用

使人员、器物、资金等为某种目的服务。元陈以仁《存孝打虎》楔子:“大人呼唤小官,那厢使用?”《古今小说·临安里钱婆留发迹》:“两日正没生意,且去淘摸几贯钱钞使用。”胡采《序》:“他善于使用一种火辣辣的艺术语言,来赞颂人类最美好的心灵。”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值