资料来源
【重温系列】RNN循环神经网络及其梯度消失 手把手公式推导+大白话讲解
带时间序列的任务场景
标准神经网络建模的弊端
RNN循环神经网络
网络结构
多输入,多输出
这里的就是对应识别人名的任务,输入就是这里的x1,x2,输出的自然就是0或1了
这种串联的结构,后面的状态会受到前面状态的影响
单元
输入的部分有一个我们的x还有前一个状态
然后这两个进来之后要分别乘以一个相应的权重,再加上我们的一个偏置项
然后再通过tanh激活函数,由此来生成下一个状态就叫做,然后再继续传给下一个单元
这里我们还有一个输出的,,在这之间还有一个权重矩阵,相乘之后再加上一个偏置项,然后才能输出我们的。这里的要看我们的任务是如何定义的,如果我们是一个多分类就接一个softmax,如果是二分类就接一个sigmoid。
我们的这里是一个多输入,多输出的一个结构我们也完全可以是多输入,然后在最后一个节点进行输出。
比如上面的情感分类,我们输入的是一段话,上面输出的是一个评分的预测。
那么我们如何去理解这个单元呢?
我们可以用人脑来进行比喻,比如是跟男朋友吵架的一个状态,是很恼火的,是你的闺蜜进行了一顿输出,输入到了你的大脑,然后两者结合就产生了一个意识,就生成了一个新的状态,新的状态也就是说要跟男朋友分手,那么这个就是新的状态。然后这个softmax就是将想法落实成真正的一个行动,就是产生的一个结果。这些参数/权重就可以想象成人脑当中的各种神经,各种连接或者是思维习惯。
特点
前向传播
损失函数
损失函数的作用
损失函数在机器学习和深度学习中扮演着至关重要的角色,它是评估模型预测与真实值之间差距的指标。损失函数的选择对于模型的训练和性能至关重要。下面是损失函数的一些用途和常见类型:
-
模型训练: 在模型训练过程中,损失函数被用来度量模型的预测值与真实值之间的差距。通过最小化损失函数,我们可以使得模型的预测值逐渐接近真实值,从而提高模型的准确性。
-
模型评估: 损失函数也可以用来评估模型的性能。在训练过程中,我们通常会在训练集上计算损失函数的值,并在验证集或测试集上进行评估,以了解模型的泛化能力和性能。
-
优化算法: 优化算法(如梯度下降)使用损失函数的梯度来更新模型的参数,以最小化损失函数的值。损失函数的梯度指导着优化算法沿着参数空间中的哪个方向更新参数,从而使损失函数逐渐减小。
常见的损失函数包括:
- 均方误差(Mean Squared Error, MSE): 用于回归任务,计算预测值与真实值之间的平方差的均值。
- 交叉熵损失(Cross-Entropy Loss): 用于分类任务,特别是在多分类任务中,衡量模型对于真实类别的预测与真实情况之间的差距。
- 对数损失(Log Loss): 也称为逻辑损失,是交叉熵损失在二分类任务中的特例,通常用于评估二分类模型的性能。
- Hinge Loss: 用于支持向量机(SVM)中的分类任务,对于正确分类的样本,损失为0,对于错误分类的样本,损失为真实类别与最近边界的距离。
- Huber Loss: 一种鲁棒的回归损失函数,相比于均方误差对异常值更具鲁棒性。
单个时间步的损失函数
如果是多输入,多输出的一个结构,一个输入就对应了一个输出,每个时间步就有一个y的输出,因此我们要对单个时间步进行损失的计算
比如我们这里举的例子,判断是否为人名,这里的输出要么是0,要么是1,那么我们这里的softmax就可以用sigmoid来代替。
如果是二分类任务,我们的损失就可以用交叉熵损失
就像是这个样子
整个序列的损失函数
然后我们整个序列的损失函数就是把所有时间步的损失加起来
这里就有一个求和符号,对应就是把我们的所有损失加起来。
反向传播
有了损失函数我们据需要进行反向传播,更新我们的这些参数。
我们需要更新的参数有哪些呢?
首先就比如说我们的,,,,这三个就是我们要更新的参数
由于需要用到我们的链式法则,对这些参数进行更新的时候,我们需要对,就是对上面的那些参数去进行求梯度,求导的这样的一个过程,所以我们需要把这些求导的公式整理一下
为什么要求梯度?
梯度在反向传播参数更新中起着关键作用,主要原因如下:
-
指示参数更新方向: 梯度告诉我们在参数空间中,损失函数增加最快的方向。在梯度下降优化算法中,我们希望最小化损失函数,因此需要朝着梯度的负方向更新参数,以减小损失函数的值。
-
确定参数更新步长: 梯度的大小表示了损失函数在当前参数值处的斜率,即损失函数变化的速度。因此,梯度的大小也指示了参数更新的步长,通常我们会使用学习率(learning rate)来调节梯度的大小,以控制参数更新的幅度,避免更新步长过大或过小。
-
优化模型参数: 通过梯度下降更新参数,可以不断优化模型,使其逼近或达到最优解。通过反复迭代计算梯度并更新参数,我们可以逐步降低损失函数的值,从而改善模型的性能。
总之,求梯度是反向传播参数更新中至关重要的一步,它为我们提供了更新方向和步长的信息,指导着模型在参数空间中不断优化,以使损失函数达到最小值或接近最小值。
具体应该怎么做
反向传播具体应该怎么做还是应该结合我们具体是使用是什么样的损失函数,故这里无法详细展开
但里面使用的东西是一样的,就是说不管我们是使用的是什么损失函数,这一个部分求梯度都是这样做的
tanh
-1——1范围的一个取值
RNN的梯度消失
缺点
现象
让我们以一个形象的例子来说明RNN序列太长时容易导致梯度消失的问题。
假设你正在阅读一本书,其中的每个段落都描述了一场连续发生的事件,而你需要理解整个故事情节。我们可以将这个阅读过程类比为RNN模型处理长序列的过程。
现在,假设这本书有1000页,每一页都是前一页的延续,而你需要从第一页开始,逐页阅读直到最后一页。每一页对应RNN模型中的一个时间步,而阅读整本书就是处理整个序列的过程。
然而,由于这本书非常长,你需要记住很多之前发生的事件,才能理解后面的情节。这就好比在RNN中,网络需要保持对长期依赖关系的记忆,以便正确地预测后续的输出。
现在,想象一下,你阅读到书的中间部分,已经读了几百页。由于书中的情节非常复杂,你可能会逐渐忘记之前的事件,因为你的记忆容量是有限的。在RNN中,类似的情况发生在梯度传播过程中,由于梯度不断地乘以权重矩阵,长序列中较早的事件对梯度的影响会逐渐减弱,最终导致梯度消失。
因此,就像在阅读长篇小说时,你可能会忘记之前的情节一样,在处理长序列时,RNN模型可能会遗忘较早的信息,导致难以理解整个序列。这就是RNN序列太长时容易导致梯度消失的形象例子。
举例
简化一下序列,但其实还是跟之前一样
S就是这里生成的状态
我们对单个时间求梯度
对我们的网络参数求梯度 参数有,,,,
整理一下
我们可以看到这里面有许多的连乘项,从这里我们可以看出,第三个节点的梯度值的更新会受到第二个时间节点,比如,,当然还有他自己的这些输入的影响,包括他们的一些梯度值等等,前后也是关联的,就是说后面所作的一些决定,是受到前面的一些因素的影响的,因此模型在学习这些参数的时候,也需要把前面的集合起来
然后变成一个累加的形式
中间连乘的方式可以用这种符号进行改写
任意时刻下的梯度公式
任意时刻我们用t来代替,数字3全用t来代替
这个式子就有可能导致我们的梯度爆炸跟梯度消失
梯度爆炸
首先我们看中间的这一项
我们知道其求导之后的范围是0-1之间
故其不会导致梯度爆炸,但是有一定的概率导致梯度消失,但不是主要原因
比方说我们的连乘项比较少的时候并且求得的梯度值比较接近1的时候,那么他的梯度消失并不会特别严重。
主要的就是我们的最后一项,也是一个连乘的一个项,当我们的很小的时候,比如是0.1,0.01等等,比较接近于0.当这个地方进行一系列的连乘之后,就会导致这里非常接近于0.
当是一个比1大的数,2、3、4、5等等就会导致梯度爆炸。
所以导致梯度爆炸跟梯度消失最主要的原因就是
假设t=20的时候
如果这时候我们是一个比1小的一个数的话,他的17次方就近似等于0了,那么前面的东西就厄密什么意义了