DateWhale零基础入门NLP之新闻文本分类学习打卡task06--kk

费曼说:学习一件事情最好的方式是做它的老师,这也是写这篇博文的目的,写这篇博文,即便有其他原因,但更多的还是写给自己,话不多说,让我们开始进入NLP吧

  本次的内容主要还是对赛题进行对于BERT的实践过程,BERT相较于先前学习的几个模型,它的架构复杂度有了质的变化,同时,也由于版本兼容性,这也给实践带来了许多问题

  任务说明:任务task6

  基座课程:基座课程
 

1.方法解释

  1.Transformer原理

  对于Transformer,最先发表的论文是Attention is All you need中提出的,模型的编码是一组编码器的堆叠,模型的解码部分是由相同数量的解码器的堆叠。

   让我们退回到2017 年,Google 提出了 Transformer 模型,用全Self Attention 的结构,取代了以往 NLP 任务中的 RNN 网络结构,在 WMT 2014 Englishto-German 和 WMT 2014 English-to-French两个机器翻译任务上都取得了当时 SOTA 的效果。

  但是,这个模型更加重要的贡献是:使得模型训练过程能够并行计算。在 RNN 中,每一个 time step 的计算都依赖于上一个 time step 的输出,这就使得所有的 time step 必须串行化,无法并行计算,如下图所示。这就是Transformer相对于RNN具有的重要的优势,并行运算

  Transformer 使用了 Seq2Seq任务中常用的结构——包括两个部分:Encoder 和 Decoder。一般的结构图,都是像下面这样。两个框内,分别是编码器和解码器。

 让我们先从编码器开始

1.Encoder:

  Transformer 的论文中使用了 6 层编码器,这里的层数 6 并不是固定的,你也可以根据实验效果来修改层数)。同理,解码部分也是由多层的解码器(decoder)组成(论文里也使用了 6 层的解码器)。

每一个编码器 在结构上都是一样的,但它们的权重参数是不同的。每一个编码器里面,可以分为 2 层

  • Self-Attention Layer
  • Feed Forward Neural Network(前馈神经网络,缩写为 FFNN)

  让我们把目光放的再小一些,来到FC层与self-attention层的结构:

上面的注意力机制的缩写与下面向量的缩写是一一对应的:

而以上这些Query、keys、values向量的产生,是由对应的权重矩阵W_{_{}}与输入向量相乘所得到的:

因此,它们的工作机制如下:

  同时,Encoder与Decoder也存在注意力机制:如图所示,即我们需要多个权重矩阵来对于输入词向量进行处理:

Decoder和Encoder的注意力机制:

2.Decoder:

  Decoder的输入分为两类:
一种是训练时的输入,一种是预测时的输入。训练时的输入就是已经对准备好对应的target数据。例如翻译任务,Encoder输入"Tom chase Jerry",Decoder输入"汤姆追逐杰瑞"。
预测时的输入,一开始输入的是起始符,然后每次输入是上一时刻Transformer的输出。例如,输入"",输出"汤姆",输入"汤姆",输出"汤姆追逐",输入"汤姆追逐",输出"汤姆追逐杰瑞",输入"汤姆追逐杰瑞",输出"汤姆追逐杰瑞"结束。

3.除此之外:

  1.为了使模型保持单词的语序,模型中添加了位置编码向量。如下图所示,每行对应一个向量的位置编码。因此,第一行将是我们要添加到输入序列中第一个单词的嵌入的向量。每行包含512个值—每个值都在1到-1之间。因为左侧是用sine函数生成,右侧是用cosine生成,所以可以观察到中间显著的分隔。

  位置向量原理图:

  编码器结构中值得提出注意的一个细节是,在每个子层中(Self-attention, FFNN),都有残差连接,并且紧跟着layer-normalization。如果我们可视化向量和LayerNorm操作,将如下所示:

  2.残差网络就是一种防止模型层数过大,梯度下降机制失效的结构:一句话总结就是,在输出前面加上输入,但是不限制跨越的层数:

4.输出:
 

  Output如图中所示,首先经过一次线性变换,然后Softmax得到输出的概率分布,然后通过词典,输出概率最大的对应的单词作为我们的预测输出。

2.代码实践:

1.种子的设置:方便代码复现,即在不同的硬件环境下复现相同的结果

2.训练数据集的十折划分,即把数据集随机划分为十份,其中通常有一份作为验证集用以获取超参数的取值,(按十四种分类进行均分):

  其中 all_data2fold 的作用把每个类别的数据平均分为 10 份,返回的数据是 fold_data,是一个 list,有 10 个元素,每个元素是 dict,包括 label 和 text 的 list。

  然后分别写入到 10 个文件中:train_0train_1train_9。每篇文章之间添加一个空行作为文章之间的分隔符

3.划分验证集,导入测试集:可以看到,测试集的id为9

4.导包

5.创建数据字典:我们创建字典,保存训练集中所有的单词,并添加 [PAD][UNK], [CLS][SEP], [MASK] 等 token。

6.attention代码:存在线性模型,同时对于全零向量置零

7.编码器:Encoder 

8. WhitespaceTokenizer:对于非全零向量,导入wordvocab.txt文件进行编码

9.SentEncoder(句子编码器):LSTM机制的应用

10.建立模型:观察到模型有7.72M的parameter

11.优化器

参数如下:learning_rate = 2e-4(学习率)
bert_lr = 5e-5(bert学习率)
decay = .75(decay_rate:衰减系数  (学习率的衰减系数))
decay_step = 1000(衰减速度 (相当于iteration ,总样本/batch-size))

12.建立数据集

13.数据集加载器

14.得分统计函数

15.训练

16.训练

17.遇到的问题

 由于版本不兼容所导致的问题

一些问题:

由于BERT的代码较长,参考的课程案例的代码为三年前的代码,许多环境配置都与现在的线上平台及线下的python环境存在着不兼容的问题,我进行了许多次尝试:

kaggle:出现未知报错(未来得及截图)

colab:中存在着对于TensorFlow1及之前的版本不兼容的问题,据查阅资料,在2020年前,我们只需要一段代码就可以完成TensorFlow版本切换,而在今天,我们需要使用更加复杂的方式:

但colab与国内存在着网络连接的问题,这种方式没有经过实践。

本地:存在着python3.9与对应的TensorFlow、keras等包存在版本冲突的问题,这也同时将我引入到了python包管理这样的一个问题中来,不过由于前面的探索消耗了很多的时间,到ddl前,我还没有对于环境管理有一个明确的实践经验,这也是我需要再深入的地方,同时,在查阅许多代码的同时,在readme中(通常需要标明执行环境),大多数作者,甚至是非常熟练的代码人都没有给出环境甚至没有这种意识,这也是需要补齐的短板。代码的效率固然是重要的,但作为一段好的代码,它的适用性也是需要关注到的,这也是我需要注意的。

3.总结

  本次对于BERT和模型的架构通体都有了一定的认识,对于自注意力机制有了更加明确的理解,总体来说还是很有收获的,但在时间的投入上海有待进一步地实践

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值