LSTM神经网络 和 GRU神经网络

本文深入解析了LSTM(长短期记忆网络)的工作原理及其如何克服传统RNN的梯度消失问题,并介绍了GRU(门控循环单元)作为LSTM的一种简化变体,包括其模型结构与训练过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LSTM是什么

LSTM即Long Short Memory Network,长短时记忆网络。它其实是属于RNN的一种变种,可以说它是为了克服RNN无法很好处理远距离依赖而提出的。

我们说RNN不能处理距离较远的序列是因为训练时很有可能会出现梯度消失,即通过下面的公式训练时很可能会发生指数缩小,让RNN失去了对较远时刻的感知能力。

EW=tEtW=tk=0Etnettnettst(tj=k+1stsk)skW

解决思路

RNN梯度消失不应该是由我们学习怎么去避免,而应该通过改良让循环神经网络自己具备避免梯度消失的特性,从而让循环神经网络自身具备处理长期序列依赖的能力。

RNN的状态计算公式为St=f(St1,xt),根据链式求导法则会导致梯度变为连乘的形式,而sigmoid小于1会让连乘小得很快。为了解决这个问题,科学家采用了累加的形式,St=tτ=1ΔSτ,其导数也为累加,从而避免梯度消失。LSTM即是使用了累加形式,但它的实现较复杂,下面进行介绍。

LSTM模型

回顾一下RNN的模型,如下图,展开后多个时刻隐层互相连接,而所有循环神经网络都有一个重复的网络模块,RNN的重复网络模块很简单,如下下图,比如只有一个tanh层。 
这里写图片描述

这里写图片描述

而LSTM的重复网络模块的结构则复杂很多,它实现了三个门计算,即遗忘门、输入门和输出门。每个门负责是事情不一样,遗忘门负责决定保留多少上一时刻的单元状态到当前时刻的单元状态;输入门负责决定保留多少当前时刻的输入到当前时刻的单元状态;输出门负责决定当前时刻的单元状态有多少输出。

这里写图片描述

每个LSTM包含了三个输入,即上时刻的单元状态、上时刻LSTM的输出和当前时刻输入。

LSTM的机制

这里写图片描述

根据上图咱们一步一步来看LSTM神经网络是怎么运作的。

首先看遗忘门,用来计算哪些信息需要忘记,通过sigmoid处理后为0到1的值,1表示全部保留,0表示全部忘记,于是有

ft=σ(Wf[ht1,xt]+bf)

其中中括号表示两个向量相连合并,Wf是遗忘门的权重矩阵,σ为sigmoid函数,bf为遗忘门的偏置项。设输入层维度为dx,隐藏层维度为dh,上面的状态维度为dc,则Wf的维度为dc×(dh+dx)

这里写图片描述

其次看输入门,输入门用来计算哪些信息保存到状态单元中,分两部分,第一部分为

it=σ(Wi[ht1,xt]+bi)

该部分可以看成当前输入有多少是需要保存到单元状态的。第二部分为

c~t=tanh(Wc[ht1,xt]+bc)

该部分可以看成当前输入产生的新信息来添加到单元状态中。结合这两部分来创建一个新记忆。

这里写图片描述

而当前时刻的单元状态由遗忘门输入和上一时刻状态的积加上输入门两部分的积,即

ct=ftct1+itc~t

这里写图片描述

最后看看输出门,通过sigmoid函数计算需要输出哪些信息,再乘以当前单元状态通过tanh函数的值,得到输出。

ot=σ(Wo[ht1,xt]+bo)

ht=ottanh(ct)

这里写图片描述

LSTM的训练

化繁为简,这里只讨论包含一个LSTM层的三层神经网络(如果有多个层则误差项除了沿时间反向传播外,还会向上一层传播),LSTM向前传播时与三个门相关的公式如下,

ft=σ(Wf[ht1,xt]+bf)

it=σ(Wi[ht1,xt]+bi)

c~t=tanh(Wc[ht1,xt]+bc)

ct=ftct1+itc~t

ot=σ(Wo[ht1,xt]+bo)

ht=ottanh(ct)

需要学习的参数挺多的,同时也可以看到LSTM的输出ht有四个输入分量加权影响,即三个门相关的ftitc~tot,而且其中权重W都是拼接的,所以在学习时需要分割出来,即 
Wf=Wfx+Wfh

Wi=Wix+Wih

Wc~=Wc~x+Wc~h

Wo=Wox+Woh

输出层的输入yit=Wyiht,输出为yot=σ(yit)

设某时刻的损失函数为Et=12(ydyot)2,则某样本的损失为

E=Tt=1Et

设当前时刻t的误差项δt=Eht,那么误差沿着时间反向传递则需要计算t-1时刻的误差项δt1,则

δt1=Eht1=Ehththt1=δththt1

LSTM的输出ht可看成是一个复合函数,f[ft(ht1),it(ht1),c~t(ht1),ot(ht1)],由全导数公式有,

htht1=htctctftftnetf,tnetf,tht1+htctctititneti,tneti,tht1+htctctc~tc~tnetc~,tnetc~,tht1+htototneto,tneto,tht1

其中netf,tneti,tnetc~,tneto,t表示对应函数的输入。将上述所有偏导都求出来,

htct=ot(1tanh(ct)2)ctft=ct1ftnetf,t=ft(1ft)netf,tht1=Wfh

同样地,其他也可以求出来,最后得到t时刻和t-1时刻之间的关系。再设 

δf,t=Enetf,tδi,t=Eneti,tδc~,t=Enetc~,tδo,t=Eneto,t

得到, 
δt1=δf,tWfh+δi,tWih+δc~,tWch+δo,tWoh

接着对某时刻t的所有权重进行求偏导, 

EWfh,t=Enetf,tnetf,tWfh,t=δf,tht1

EWih,t=Eneti,tneti,tWih,t=δi,tht1

EWch,t=Enetc~,tnetc~,tWch,t=δc~,tht1

EWoh,t=Eneto,tneto,tWoh,t=δo,tht1

EWfx=Enetf,tnetf,tWfx=δf,txt

EWix=Eneti,tneti,tWix=δi,txt

EWcx=Enetc~,tnetc~,tWcx=δc~,txt

EWox=Eneto,tneto,tWox=δo,txt

Ebo,t=Eneto,tneto,tbo,t=δo,t

Ebf,t=Enetf,tnetf,tbf,t=δf,t

Ebi,t=Eneti,tneti,tbi,t=δi,t

Ebc,t=Enetc~,tnetc~,tbc,t=δc~,t

对于整个样本,它的误差是所有时刻的误差之和,而与上个时刻相关的权重的梯度等于所有时刻的梯度之和,其他权重则不必累加,最终得到

EWfh=j=1tδf,jhj1

EWih=j=1tδi,jhj1

EWch=j=1tδc~,jhj1

EWoh=j=1tδo,jhj1

Ebf=j=1tδf,j

Ebi=j=1tδi,j

Ebc=j=1tδc~,j

Ebo=j=1tδo,j

EWfx=Enetf,tnetf,tWfx=δf,txt

EWix=Eneti,tneti,tWix=δi,txt

EWcx=Enetc~,tnetc~,tWcx=δc~,txt

EWox=Eneto,tneto,tWox=δo,txt

================================================================================================================================


GRU神经网络


前面已经详细讲了LSTM神经网络(文末有链接回去),接着往下讲讲LSTM的一个很流行的变体。

GRU是什么

GRU即Gated Recurrent Unit。前面说到为了克服RNN无法很好处理远距离依赖而提出了LSTM,而GRU则是LSTM的一个变体,当然LSTM还有有很多其他的变体。GRU保持了LSTM的效果同时又使结构更加简单,所以它也非常流行。

GRU模型

回顾一下LSTM的模型,LSTM的重复网络模块的结构很复杂,它实现了三个门计算,即遗忘门、输入门和输出门。

这里写图片描述

而GRU模型如下,它只有两个门了,分别为更新门和重置门,即图中的ztrt。更新门用于控制前一时刻的状态信息被带入到当前状态中的程度,更新门的值越大说明前一时刻的状态信息带入越多。重置门用于控制忽略前一时刻的状态信息的程度,重置门的值越小说明忽略得越多。

这里写图片描述

GRU向前传播

根据前面GRU模型图来一步步看他是怎么向前传播的,根据图不难得到以下式子: 

rt=σ(Wr[ht1,xt])

zt=σ(Wz[ht1,xt])

h~t=tanh(Wh~[rtht1,xt])

ht=(1zt)ht1+zth~t

yt=σ(Woht)

其中[]表示两个向量相连接,*表示矩阵元素相乘。

GRU的训练

从前面的公式中可以看到需要学习的参数就是WrWzWhWo那些权重参数,其中前三个权重都是拼接的,所以在学习时需要分割出来,即

Wr=Wrx+Wrh

Wz=Wzx+Wzh

Wh~=Wh~x+Wh~h

输出层的输入yit=Woh,输出为yot=σ(yit)

设某时刻的损失函数为Et=12(ydyot)2,则某样本的损失为

E=Tt=1Et

与前面LSTM网络类似,最终可以推出

EWo=δy,tht

EWzx=δz,txt

EWzh=δz,tht1

EWh~x=δtxt

EWh~h=δt(rtht1)

EWrx=δr,txt

EWrh=δr,tht1

δy,t=(ydyot)σ

δh,t=δy,tWo+δz,t+1Wzh+δt+1Wh~hrt+1+δh,t+1Wrh+δh,t+1(1zt+1)

δz,t=δt,h(h~tht1)σ

δt=δh,tztϕ

δr,t=ht1[(δh,tztϕ)Wh~h]σ


原文地址: http://blog.youkuaiyun.com/wangyangzhizhou/article/details/76651116

http://blog.youkuaiyun.com/wangyangzhizhou/article/details/77332582


### GRU 模块代码实现 下面是一个基于 PyTorch 的 GRU 模型的具体实现示例。此模型定义了一个简单的循环神经网络,其中包含了两层 GRU 单元: ```python import torch import torch.nn as nn class SimpleGRUNet(nn.Module): def __init__(self, input_size, hidden_size, num_layers, output_size): super(SimpleGRUNet, self).__init__() self.gru = nn.GRU( input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, batch_first=True ) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): out, _ = self.gru(x) out = self.fc(out[:, -1, :]) return out model = SimpleGRUNet(input_size=3, hidden_size=10, num_layers=2, output_size=1) x = torch.randn(32, 5, 3) # (batch_size, sequence_length, input_size) output = model(x) print(output.shape) ``` 上述代码创建了一个名为 `SimpleGRUNet` 的类来封装 GRU 层及其全连接输出层。构造函数接收四个参数:输入维度大小 (`input_size`)、隐藏状态向量尺寸 (`hidden_size`)、堆叠 GRU 层的数量 (`num_layers`) 最终线性变换后的输出特征数 (`output_size`). 在前馈过程中,数据通过 GRU 层处理后仅取最后一个时间步的结果作为后续分类或其他任务的基础[^3]. #### 初始化与训练过程中的注意事项 当构建并初始化 GRU 或其他 RNN 类型的模型时,需要注意以下几点以确保良好的性能表现: - **权重初始化**: 使用合适的初始方法可以帮助加速收敛速度以及提高泛化能力. - **序列长度选择**: 序列过长可能导致梯度消失/爆炸问题; 过短则可能丢失重要上下文信息. - **批量标准化(batch normalization)**: 对于某些应用来说,在每一步之后加入批范式有助于稳定学习过程. 此外,对于防止过拟合的问题,可以通过调整超参数如正则化系数或者采用早停策略等方式加以缓解[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值