赞
踩
BERT(Bidirectional Encoder Representations from Transformers)是谷歌在2018年10月推出的深度语言表示模型。
一经推出便席卷整个NLP领域,带来了革命性的进步。
从此,无数英雄好汉竞相投身于这场追剧(芝麻街)运动。
只听得这边G家110亿,那边M家又1750亿,真是好不热闹!
然而大家真的了解BERT的具体构造,以及使用细节吗?
本文就带大家来细品一下。
前言
本系列文章分成三篇介绍BERT,本文主要介绍BERT主模型(BertModel)的结构及其组件相关知识,另有两篇分别介绍BERT预训练相关和如何将BERT应用到不同的下游任务。
文章中的一些缩写:NLP(natural language processing)自然语言处理;CV(computer vision)计算机视觉;DL(deep learning)深度学习;NLP&DL 自然语言处理和深度学习的交叉领域;CV&DL 计算机视觉和深度学习的交叉领域。
文章公式中的向量均为行向量,矩阵或张量的形状均按照PyTorch的方式描述。
向量、矩阵或张量后的括号表示其形状。
本系列文章的代码均是基于transformers库(v2.11.0)的代码(基于Python语言、PyTorch框架)。
为便于理解,简化了原代码中不必要的部分,并保持主要功能等价。
在代码最开始的地方,需要导入以下包:
代码
阅读本系列文章需要一些背景知识,包括Word2Vec、LSTM、Transformer-Base、ELMo、GPT等,由于本文不想过于冗长(其实是懒),以及相信来看本文的读者们也都是冲着BERT来的,所以这部分内容还请读者们自行学习。
本文假设读者们均已有相关背景知识。
目录
1、主模型 1.1、输入 1.2、嵌入层 1.2.1、嵌入变换 1.2.2、层标准化 1.2.3、随机失活 1.3、编码器 1.3.1、隐藏层 1.3.1.1、线性变换 1.3.1.2、激活函数 1.3.1.2.1、tanh 1.3.1.2.2、softmax 1.3.1.2.3、GELU 1.3.1.3、多头自注意力 1.3.1.4、跳跃连接 1.4、池化层 1.5、输出
1、主模型
BERT的主模型是BERT中最重要组件,BERT通过预训练(pre-training),具体来说,就是在主模型后再接个专门的模块计算预训练的损失(loss),预训练后就得到了主模型的参数(parameter),当应用到下游任务时,就在主模型后接个跟下游任务配套的模块,然后主模型赋上预训练的参数,下游任务模块随机初始化,然后微调(fine-tuning)就可以了(注意:微调的时候,主模型和下游任务模块两部分的参数一般都要调整,也可以冻结一部分,调整另一部分)。
主模型由三部分构成:嵌入层、编码器、池化层。
如图:
其中
输入:一个个小批(mini-batch),小批里是batch_size个序列(句子或句子对),每个序列由若干个离散编码向量组成。
嵌入层:将输入的序列转换成连续分布式表示(distributed representation),即词嵌入(word embedding)或词向量(word vector)。
编码器:对每个序列进行非线性表示。
池化层:取出[CLS]标记(token)的表示(representation)作为整个序列的表示。
输出:编码器最后一层输出的表示(序列中每个标记的表示)和池化层输出的表示(序列整体的表示)。
下面具体介绍这些部分。
1.1、输入
一般来说,输入BERT的可以是一句话:
I’m repairing immortals.
也可以是两句话:
I’m repairing immortals. ||| Me too.
其中|||是分隔两个句子的分隔符。
BERT先用专门的标记器(tokenizer)来标记(tokenize)序列,双句标记后如下(单句类似):
I ’ m repair ##ing immortal ##s . ||| Me too .
标记器其实就是先对句子进行基于规则的标记化(tokenization),这一步可以把’m以及句号.等分割开,再进行子词分割(subword segmentation),示例中带##的就是被子词分割开的部分
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。