Pytroch实现bert网络文本分类
本实验主要是用来指导用户如何使用pytorch来搭建经典的Bert网络,并在此基础上使用昇腾Npu硬件对Bert网络实现文本分类训练的代码实战过程。
实验介绍目录如下:
- Bert网络的主要创新点介绍
- Bert及网络搭建过程介绍
- input embeddings层
- Self-Attention
- MutiHeadAttention
- Encoder-Transformer模块
- Bert网络模型及架构分析
- Bert网络进行文本分类
- Bert分词器
- 训练任务构建
- 基于昇腾Npu训练Bert模型
- 参考文献
Bert网络的主要创新点介绍
- 提出预训练加微调的思想,其中预训练的思想来源于图像领域中预训练。
- 借鉴了Word2Vec中CBOW的思想(完形填空)双向编码。
- 采用了transform架构作为双向结构的基础模块,使用Attentio机制作为特征提取器将任意位置的两个单词的相关性转换成数字,有效的解决了NLP中长期依赖问题,能更彻底的捕捉语句中的双向关系。
- 在CBOW的基础之上,添加了语言掩码模型(Mask Language Model),减少了训练和推理阶段的不匹配问题,避免了过拟合现象。
- 使用下句预测(NSP)作为无监督预训练的一部分,用于捕捉句子之间的语义关系。
Bert及网络搭建过程介绍

BERT(Bidirectional Encoder Representations from Transformers)是一种基于多层Transformer-Encoder的预训练语言模型。
它通过预训练+微调并与Tokenization、多种Embeddings和特定任务的输出层相结合,能够捕捉文本的双向上下文信息,泛化能力强,在各种自然语言处理任务中表现出色。
BERT的架构主要包括输入层 、编码层 和输出层。
其中输入层负责处理原始文本,编码层由多个Transformer-Encoder模块组成,每个Transformer块包含多头自注意力层(MLA)和前馈神经网络层(FFN),输出层则根据具体任务进行微调。
下面将会对Bert中这三个主要模块的主要原理结合代码一起进行介绍。
input embeddings层

跟大多数NLP深度学习模型一样,BERT将输入文本中的每一个词(token)送入token embedding层从而将每一个词转换成向量形式,但不同于其他模型的是,BERT又多了两个嵌入层,即segment embeddings 和 position embeddings。
下面是输入Bert中Embedding层代码实现,定义了一个Embedding类继承了torch的Module模块,含'init'与'forward'两个功能函数,其中'init'用于遍历初始化,'forward'用于定义网络前向连接结构顺序。
下面详细介绍了上述Token embedding、Position Embeddings与Segment Embeddings原理及过程。
Token embedding
例如现有输入文本是:"strawberries is my favorite",输入文本在送入token embeddings 层之前要先进行tokenization处理,具体的处理方式是:将两个特殊的token会被插入到tokenization的结果的开头 (\[CLS\])和结尾 (\[SEP\]) 因此,输入文本变为"\[CLS\] strawberries is my favorite \[SEP\]"。
Bert中tokenization使用的方法是WordPiece tokenization. 这是一个数据驱动式的tokenization方法,旨在权衡词典大小和oov词的个数,这种方法可以把"strawberries"切分成"straw" 和"berries",将favorite切分为"favo"与"rite"。
因此,输入文本变为"\[CLS\] straw berries is my favo rite \[SEP\]"。
最后,Token Embeddings 层会将每一个wordpiece token转换成768维的向量。这样,例子中的8个token就被转换成了一个(8, 768) 的矩阵或者是(1, 8, 768)的张量(如果考虑batch_size的话)。
Position Embeddings
对于一个nlp任务而言,词与词之间的顺序关系通常会影响着整个句子含义甚至情感的走向,例"武松打虎"与"虎打武松"意义就完全不一样。
Bert中的Attention模块虽然能够有效的解决长距离依赖问题,但是其在计算的过程中未考虑到序列中词语的语序信息,从而导致会出现"武松打虎"与"虎打武松"这两句话通过Attention以后计算的结果完全一样。
这明显是不符合语义常识的,Transform架构中引入了位置编码这一思想,用来解决句子语序问题带来的语义不一致的现象。
Segment Embeddings
在bert预训练的数据集中会有对话场景,问答场景等数据集,像这类场景的话上下文关联对于情感及问答的走向非常重要。
segment embeddings在Bert中主要用来区分一个句子对中的两个句子,来识别上下文子句,标识方式是给第一句赋0,第二句赋1,表示先后关系。
Self-Attention
自注意力机制的其特点是Query、Key和Value都来自同一个输入序列,可以使模型能够迅速的学习到输入序列中的内在关系和依赖性。
自注意力机制中,对于输入序列中的每个位置,模型都会计算它与所有其他位置之间的关系,并得到一个权重分布。
然后,根据这个权重分布对输入序列进行加权求和,以得到每个位置的输出。这个过程也被称为"内部注意"或"自关注"。

整个模块包含三个输入 Q、K、V,其中Q、K、V 来自输入句子 X 的词向量x的线性转化,即对于词向量x,给定三个可学习的矩阵参数
这也是Self-Attention 名字的来源:Q、K、V 三个矩阵由同一个词向量线性转化而得。
模型训练的过程中数据都是以Batch的形式输入到模型,一个Batch中每个句子的长度是不一样的,需要PADDING将所有的句子都补全到最长的长度,PADDING数值可以是0(也可以是其他较大的数)。
由于我们不希望该填充的位置参与到后期的反向传播过程,从而提出了在训练时将补全的位置给Mask掉的做法,也就是图中的MASK模块,当PADDING值为较大的负数时,通过softmax操作以后该位置的预测概率值接近于0。
整个Self-Attention模块具体代码实现如下:

最低0.47元/天 解锁文章
1018

被折叠的 条评论
为什么被折叠?



