从RNN讲到LSTM,再讲到Transformer

从RNN讲到Transformer

1990年,RNN雏形与BP网络结合出现,但是由于梯度消失和梯度爆炸的问题,训练比较困难。1997年,LSTM和双向RNN同年被提出来,解决了这个问题,并开始被广泛使用也出现了很多变体。pytorch tutorial的intermediate部分就是复现RNN相关网络,在pytorch框架上实现RNN网络比较简单,跟着教程走就行,但是有必要在这里也记录一下理论学习(理论学习资料:油管StatQuest with Josh Starmer的三个视频:RNNLSTMTransformer,当然也可以读李沐的动手学深度学习然后完成课后练习,这样可以更深入地巩固理论和实践知识,我有时间也要看一下并练习!!!)。

一、RNN(Recurrent Neural Network)

首先,在RNN被提出来之前,我们已经有很多神经网络可以很好地训练图像数据和语言数据等,对于这类数据输入时固定的,比如固定为一张图片,一句话等,如果我们还希望能在时序数据上也训练得比较好,能完美满足我的预测任务。

那为什么我要单独指出时序数据这种类型呢?
因为时间序列信息是连续输入的,不同于其他数据类型的固定状态。比如说,我要预测明天的天气,那我可以用过去五天的天气来进行预测,也可以用过去50天的天气来预测,时序数据预测模型必须满足我可以任意改历史数据数量,只要输出明天的预测值即可,只不过预测值可能更准确或者更模糊。另外,由于时间的连续性,我要预测明天的天气,就必须知道今天的天气,在今天的天气的基础上再继续预测明天的天气。诸如此类的差异性,让我们明显感觉到,我们需要一种新的网络针对性地完成时间序列数据集上的任务,现存的网络已经行不通了!

于是RNN诞生了
故名思意,循环神经网络中有循环结构,但是为了更好地理解,这里将循环结构铺平展开,展开后的网络结构如下:
循环神经网络结构
便于理解,这里就举一个比较简单的例子——用前天的数据预测明天的数据。对上述图像进行概括如下:

  1. 首先,用前天数据预测昨天的数据,放进网络计算 y 1 = w 1 ∗ x 1 + b 1 y_1=w_1*x_1+b_1 y1=w1x1+b1,这时如果我们的预测目标是昨天的预测值,则我们可以直接用 y 1 y_1 y1输出,再把它扔进一个网络 p r e d y e s = w 3 ∗ y 1 + b 2 pred_{yes}=w_3*y_1+b_2 predyes=w3y1+b2,这就是铺平的网络结构中第一行的含义。
  2. 但是,由于我们真实的预测目标是明天的预测值,因此前天数据信息我得接着用来预测今天的值,于是,在预测今天的值时,我的先验知识有 y 1 y_1 y1(前天的信息)和 x 2 x_2 x2(昨天的值),因此我们有 y 2 = w 1 ∗ x 2 + w 2 ∗ y 1 + b 1 y_2=w_1*x_2+w_2*y_1+b_1 y2=w1x2+w2y1+b1。与第一行类似,此时我们可以选择输出今天的预测值,也可以继续往后预测,直到输出我的目标预测值为止。
  3. 以此类推。

为什么会发生梯度消失和梯度爆炸?
看到上面的网络结构,其实这个问题就很清晰了。我们用2天前的数据预测下一天,则权重 w 2 w_2 w2被使用了两次,那么在输出的计算公式中关于 w 2 w_2 w2的部分就是 y 1 ∗ w 2 2 y_1*w_2^2 y1w22。那如果用50天的数据来预测后天的数据呢?则 o u t p u t = y 1 ∗ w 2 50 + . . . output=y_1*w_2^{50}+... output=y1w250+...,而实际数据可不仅仅只有50个数据, w 2 w_2 w2的指数在计算梯度时会严重影响梯度的大小,从而导致梯度消失或爆炸。

二、LSTM(Long Short-Term Memory)

根据上述对RNN的描述,我们可以知道RNN梯度爆炸或消失的根本原因其实就是,预测下一个值时要用到历史记忆太远了,从10000个数据以前开始预测今天的值,那最初那个值我都快忘记了,或者要追溯很久才能找到那个数据的记忆,导致在输出中原始值对应权重的指数太大,严重影响梯度计算,那么为了解决RNN这个问题,我只要解决长期记忆被使用策问题即可,而LSTM尝试选择性遗忘长期记忆。

什么是遗忘门(Forget Gate), 输入门(Input Gate)和输出门(Output Gate)

长短时记忆网络主要内容就标题中三个门,理解了为什么要有这三个门,他们的作用是什么就能完整地理解该网络了。

先来一个总结吧: 把LSTM看成一个小房子,则LSTM有两条更新线路(长期记忆线路和短期记忆线路)要穿过上述三个门(很多次),其中长期记忆线路每次都要保存部分输出数据的信息,另外还得有一个通道用来将输入数据一个一个地输送到这个房子中去。

首先这两条线路要穿过遗忘门, 如下图所示:
Forget Gate
看完上图的结构后就显而易见了,长短记忆两条线路首先有个原始值,短期记忆只与当前步骤的输入有关,而这个短期记忆和输入数据本身经过加权(或者任意网络结构)被sigmoid函数处理后放到长期记忆中,如果该步骤对目标预测值不重要,则放进长期记忆的信息就少,如果对目标预测值很重要,则放进长期记忆线路的信息量就多,这个部分用来保存部分长期记忆,另一部分则选择遗忘,因此叫做遗忘门。这个部分完美解决了长期记忆太久远从而影响目标函数梯度计算的问题。
此部分不更新短期记忆

接着这两条线路继续穿行,马上就到了输入门,如下图所示:
Input Gate
经过遗忘门之后,我们知道有多少长期记忆是需要遗忘的,多少是需要保留的。那么,在我们的输入数据中,还有没有什么潜在的记忆需要留下来的,于是就出现了输入门,再次处理输入数据信息和短期记忆,再分别经过Tanh函数和Sigmoid函数处理后求和,得到最终更新后的长期记忆的值。这一模块,就是输入门。

接着这两条线路继续穿行,终于到了输出门,如下图所示:
Output Gate
遗忘门和输入门都没有改变短期记忆,因为短期记忆只与最近的一次预测值有关。而在RNN中我们知道,短期记忆是假设该时刻的数据值的下一个预测值就是我们的目标预测值,那我们可以把 y 1 y_1 y1处理后直接输出,这个直接输出的部分就是我们短期记忆,因为它直接影响到我们的输出。在LSTM中也是如此,如果我们下一时刻值就是我们的目标预测值,则我们直接更新短期记忆,更新后的短期记忆就是我们的目标预测值。具体更新方法自然需要用到当下时刻的输入数据信息以及长期记忆中保留下来的信息。

如图所示,结合原短期记忆数据和输入数据并作sigmoid处理后,再与经Tanh函数处理后的长期记忆信息结合得到最终的输出,如果预测后的这一时刻就是我们的目标预测时刻,则短期记忆更新后的数据就是我们的目标预测值,反之,则长短期记忆两条线路继续更新前进,直到我们的目标预测时刻为止。

因为经过这一模块输出的短期记忆更新值可能就是我们的最终输出值,因此,该模块被称为输出门。至此,LSTM理论讲完。

三、Transformer

Attention is all you need,当下应该没人不知道transformer的重要性,截至目前几乎所有的网络结构都会结合注意力机制或者它的变体,它是ChatGPT的底层机制,transformer更是占据了许多企业招聘时的面试题库,所以在进入AI领域之前,必须要明白什么是注意力机制和transformer,怎么使用才能改善模型性能,为什么它们可以改善模型性能等。但是为什么我要在循环神经网络这部分继续讲transformer的理论呢? 因为它们是层层递进的关系,理解了RNN-LSTM理论,才能真正意义上地理解transformer。

提到transformer必须先说注意力机制(self-attention)

为什么注意力机制如此重要?
举一个很简单的例子,如果我希望机器翻译这个句子:The pizza came out of the oven and it tastes good! 对于人来讲,我们很容易理解到it 指代的是前文中的pizza 而不是oven,但是机器不行,就是因为机器没有人的自注意力机制。那么这个自注意力机制具体到底是什么?怎么加进模型中呢?

首先,以语言模型为例,明白word-embedding操作
明确目前的任务是:将英文Squach eats pizza 翻译成西班牙语。在翻译之前,我们需要对输入的英文句子进行编码,从而可以被语言模型识别并处理然后才能完成翻译任务。编码过程中我们需要保留原英文句子中的必要信息,比如每个单词块的特定信息以及它们的位置信息。

在这个基础上,我们有了如下图所示的编码方式:
语言编码
具体操作概述如下:

  1. 对特定单词进行编码,比如对单词Squatch 的初始编码为1,0,0,0,该单词对应位置编码为1,其余位置是0,另外 < E O S > <EOS> <EOS>表示end of sentence为句子结束标志。首先将每个编码放进线性操作中输出,正常情况下,到这个步骤编码中已经可以蕴含每个单词的特定信息了(word-embedding)。
  2. 但是除此之外,每个单词的位置信息也是非常重要的,这里用幅度不同的sin和cos函数表示不同单词出现的顺序,得到新的位置编码,最后将原来的特征编码与位置编码相加,得到加入自注意力机制之前最终的编码(position encoding)。

但是此时的编码,不能表示单词之间的关系,于是加入自注意力机制
正如前文所说,The pizza came out of the oven and it tastes good! 对于人来讲,我们很容易理解到it 指代的是前文中的pizza 而不是oven,但是机器不行。就是因为我们没有让机器学习单词之间的关系,而自注意力机制旨在让模型学习到it 分别与pizzaoven 之间的关系分数,如果前者大于后者,则模型便可以像人一样理解it 指代的是前文中的pizza 。单词之间的关系分数计算方式如下图所示:
单词之间的关系
图看起来比较复杂,但实际操作比较简单,这里我就简单概括一下,还是不能理解的同学可以参考原视频。

在每个单词的原编码的基础上生成一个自注意力机制模块(self-attention cell),该模块包括关键信息(Key),质询单元(Query)和值(Value)三个部分,其中Key用来提取该单词的关键信息,Query作用于Key生成的值并进行softmax操作用于询问该单词与自己的关系分数和另一个单词的关系分数,Value用于处理最终的两个关系分数并生成最终的self-attention scores。最后,为了方便计算,结合position encoding和self-attention生成残差连接(Residual Connection),transformer编码部分到此结束。

用自注意力机制表示不同单词之间的关系操作步骤到此就讲完了,值得一提的是,最初提出的transformer中用了8个self-attention cell,我们也不知道为什么是8个,可能是用实验试出来的吧。因此我们得到的最终的编码部分如下图所示:
transformer's encoder

有了encoder,自然也得有decoder
Decoder部分整体上与Encoder操作类似,也包括Word Embedding,Position Encoding,Self-Attention三个部分,但是这里有个小巧思来解决句子中重要部分可能被忽略从而完全逆转整个句子大意的问题,即用一个Encoder-Decoder Self-Attention cell来衡量单词的重要性,如下图所示:
encoder-decoder self-attention cell
上述输出结果表明,第一个单词非常重要,所以我们一定要保留第一个单词,而不是第二个单词。因此Transformer的整个框架就差不多讲完了,整理成下图所示:
transformer
从理论到熟练地实践再到找到问题并改进需要时间和继续不断钻研,希望和大家共勉!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值