循环神经网络RNN原理与优化

目录

前言

RNN背景

RNN原理

上半部分:RNN结构及按时间线展开图

下半部分:RNN在不同时刻的网络连接和计算过程

LSTM

RNN存在的问题

LSTM的结构与原理

数学表达层面

与RNN对比优势

应用场景拓展

从简易但严谨的代码来看RNN和LSTM

RNN

LSTM


前言

绕循环神经网络(RNN)、注意力机制(Attention)以及相关模型(如 LSTM、Transformer、BERT、GPT 等)在深度学习中的应用展开,介绍了其原理、结构、算法流程和实际应用场景。

RNN背景

RNN 产生的原因:深度神经网络(DNN)在处理输入时,每个输入之间相互独立,无法处理序列信息。然而在自然语言处理(NLP)和视频处理等任务中,需要考虑输入元素之间的关联性,因此引入 RNN。以 NLP 中的词性标注任务为例,需处理单词序列才能准确标注词性,仅单独理解每个单词是不够的。

RNN 的结构与公式:RNN 在结构上引入了循环层,其隐藏层状态St不仅取决于当前输入Xt,还与上一时刻的隐藏层状态相关。具体公式为

输出

这样的结构使RNN网络能够对序列信息进行处理

RNN原理

上半部分:RNN结构及按时间线展开图

RNN结构:

输入层(Input Layer):标记为"x",接收输入数据。

隐藏层(Hidden Layer):标记为"s",是RNN的核心部分,包含循环连接。图中显示了权重矩阵"U"(连接输入层和隐藏层)和"W"(隐藏层的循环连接)(输入层的)。

输出层(Output Layer):标记为"o",通过权重矩阵"V"与隐藏层相连(输出层的),产生最终输出。

按时间线展开:

将RNN在时间维度上展开,展示了不同时刻(t-1, t, t+1)的网络状态。每个时刻都有输入x_t、隐藏层状态s_t和输出o_t。权重矩阵"U"、"W"和"V"在不同时刻保持不变,体现了RNN在时间上共享参数的特性。

下半部分:RNN在不同时刻的网络连接和计算过程

t-1时刻:

展示了隐藏层状态s的向量形式,s=[s1, s2, ..., sn],其中每个元素代表隐藏层的一个神经元状态。权重矩阵"W"连接了t-1时刻的隐藏层神经元。

t时刻:

输入层:输入向量X=[x1, x2, ..., xm],其中m是输入维度。

隐藏层:通过权重矩阵"U"接收输入层的信息,并通过权重矩阵"W"接收t-1时刻的隐藏层状态信息。图中显示了隐藏层的计算过程,即

其中f是激活函数。

输出层:根据隐藏层状态S_t,通过权重矩阵"V"计算输出

其中g是输出层的激活函数。

LSTM

LSTM(Long - Short - Term Memory,长短期记忆网络)是为解决传统循环神经网络(RNN)存在的问题而设计的。

RNN存在的问题

RNN有两个主要问题。一是短期记忆问题,当处理足够长的序列时,它难以将早期时间步的信息传递到后期。比如处理一段文本进行预测时,可能会遗漏开头的重要信息。二是梯度消失问题,在反向传播过程中,梯度随着时间反向传播而缩小。当梯度值变得极小,对神经网络权重更新的贡献就很小,导致早期的层停止学习,这也使得RNN在处理长序列时容易遗忘之前的信息。

LSTM的结构与原理

输入:

门:

当前时刻的输出及保存当前细胞状态(传递给下一个'细胞'):

LSTM通过引入"细胞状态(cell state)"和"门(gate)"机制来解决上述问题:

细胞状态:就像一条传送带,在整个网络中运行,它可以在序列的不同时间步之间传递信息,使得LSTM能够处理长序列而不容易丢失早期信息。

门:

遗忘门(forget gate):决定从细胞状态中丢弃哪些信息。它读取当前输入和上一时刻隐藏状态,输出一个0 - 1之间的值,1表示"完全保留",0表示"完全丢弃"。

输入门(input gate):确定要在细胞状态中存储哪些新信息。它包含一个sigmoid层来决定更新哪些值,以及一个tanh层来创建新的候选值向量,这些候选值可能会被添加到细胞状态中。

输出门(output gate):确定LSTM的输出。它首先通过sigmoid层决定细胞状态的哪些部分将被输出,然后将细胞状态通过tanh层(将值映射到 - 1到1之间),并将其与sigmoid层的输出相乘,得到最终的输出。

通过这些机制,LSTM能够更好地处理长序列数据,有选择性地记忆和遗忘信息,有效克服了RNN的短期记忆和梯度消失问题,这也是LSTM在后续的一些自然语言处理、语音识别等领域得到广泛应用的主要原因。

数学表达层面

遗忘门计算:

,其中W_f是权重矩阵,[h_{t - 1},x_t]是上一时刻隐藏状态和当前输入的拼接('细胞'传递),b_f是偏置项(截距),sigma是sigmoid激活函数,输出值在0 - 1之间,决定从细胞状态中遗忘的信息比例。

输入门计算:

确定更新值比例,

生成候选值向量,二者后续用于更新细胞状态。

细胞状态更新:

是逐元素相乘,即结合遗忘门输出、上一时刻细胞状态、输入门输出和候选值向量来更新细胞状态。

输出门计算:

决定输出比例,

得到最终隐藏状态输出。

与RNN对比优势

长期依赖处理:RNN受限于梯度消失难以保持长期依赖,LSTM通过门控机制控制细胞状态信息流,能有效保存和传递长距离信息,比如在处理长篇小说文本时,可记住开头人物关系等信息用于后续情节理解和生成。

学习效率:RNN因梯度问题早期层学习困难,LSTM通过门控灵活控制信息流动,更高效学习,在训练时间和收敛速度上表现更好,在语音识别任务中,可更快学习到语音序列中的特征模式。

应用场景拓展

自然语言处理:除常见的文本生成、机器翻译、情感分析,在文本摘要提取中,能抓住长文本关键信息;在命名实体识别中,准确识别不同类型实体。

时间序列预测:在金融领域,预测股票价格、汇率等波动;在能源领域,预测电力负荷、能源消耗等,利用其对时间序列中长短期信息的捕捉能力提高预测准确性。

视频处理:分析视频帧序列,用于动作识别、视频内容理解与生成,如判断视频中人物动作类别,生成符合逻辑的视频字幕等。

从简易但严谨的代码来看RNN和LSTM

通过pytorch框架来定义只有一个'细胞'的RNN和LSTM,进一步理解这两个网络的架构的应用

RNN
复制代码
import torch`
`import torch.nn as nn`

`# 定义RNN模型`
`class` `SimpleRNN(nn.Module):`
    `def` `__init__(self, input_size, hidden_size, num_layers, output_size):`
        `super(SimpleRNN, self).__init__()`
`        self.hidden_size = hidden_size`
`        self.num_layers = num_layers`
`        self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)`
`        self.fc = nn.Linear(hidden_size, output_size)`

    `def` `forward(self, x):`
`        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)`
`        out, _ = self.rnn(x, h0)`
`        out = self.fc(out[:,` `-1,` `:])`
        `return out`
        
`# 示例参数`
`input_size =` `10`
`hidden_size =` `20`
`num_layers =` `1`
`output_size =` `5`
`batch_size =` `3`
`seq_length =` `8`

`# 创建输入数据`
`x = torch.randn(batch_size, seq_length, input_size)`

`# 实例化RNN模型`
`model = SimpleRNN(input_size, hidden_size, num_layers, output_size)`

`# 前向传播`
`output = model(x)`
`print(output.shape)`
`

说明:

定义了一个简单的SimpleRNN类继承自nn.Module。在构造函数中,初始化了 RNN 层和全连接层。nn.RNN指定了输入维度input_size、隐藏层维度hidden_size、层数num_layers,并设置batch_first=True表示输入数据的形状为(batch_size, seq_length, input_size)。

forward方法中,首先初始化隐藏状态h0,然后将输入数据x和初始隐藏状态传入 RNN 层,获取输出out。最后将 RNN 最后一个时间步的输出传入全连接层得到最终输出。

LSTM
复制代码
import torch`
`import torch.nn as nn`

`# 定义LSTM模型`
`class` `SimpleLSTM(nn.Module):`
    `def` `__init__(self, input_size, hidden_size, num_layers, output_size):`
        `super(SimpleLSTM, self).__init__()`
`        self.hidden_size = hidden_size`
`        self.num_layers = num_layers`
`        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)`
`        self.fc = nn.Linear(hidden_size, output_size)`

    `def` `forward(self, x):`
`        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)`
`        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)`
`        out, _ = self.lstm(x,` `(h0, c0))`
`        out = self.fc(out[:,` `-1,` `:])`
        `return out`
        
`# 示例参数`
`input_size =` `10`
`hidden_size =` `20`
`num_layers =` `1`
`output_size =` `5`
`batch_size =` `3`
`seq_length =` `8`

`# 创建输入数据`
`x = torch.randn(batch_size, seq_length, input_size)`

`# 实例化LSTM模型`
`model = SimpleLSTM(input_size, hidden_size, num_layers, output_size)`

`# 前向传播`
`output = model(x)`
`print(output.shape)`
`

说明:

1.定义了SimpleLSTM类,同样继承自nn.Module。构造函数中初始化了 LSTM 层和全连接层,nn.LSTM的参数设置与 RNN 类似。

2.forward方法里,除了初始化隐藏状态h0,还初始化了细胞状态c0,然后将输入x、h0和c0传入 LSTM 层,获取输出out,最后经全连接层得到最终结果。

相关推荐
Acrelhuang6 分钟前
8.3MW屋顶光伏+光储协同:上海汽车变速器低碳工厂的能源革命-安科瑞黄安南
大数据·数据库·人工智能·物联网·数据库开发
区块链蓝海6 分钟前
沉浸式体验测评|AI Ville:我在Web3小镇“生活”了一周
人工智能·web3·生活
whaosoft-14321 分钟前
51c自动驾驶~合集15
人工智能
花楸树22 分钟前
前端搭建 MCP Client(Web版)+ Server + Agent 实践
前端·人工智能
用户876128290737431 分钟前
前端ai对话框架semi-design-vue
前端·人工智能
量子位32 分钟前
稚晖君刚挖来的 90 后机器人大牛:逆袭履历堪比爽文男主
人工智能·llm
量子位38 分钟前
200 亿机器人独角兽被曝爆雷,官方回应来了
人工智能·llm
机器之心41 分钟前
细节厘米级还原、实时渲染,MTGS方法突破自动驾驶场景重建瓶颈
人工智能
arbboter1 小时前
【AI插件开发】Notepad++ AI插件开发实践:从Dock窗口集成到功能菜单实现
人工智能·notepad++·动态菜单·notepad++插件开发·dock窗口集成·ai代码辅助工具·ai对话窗口
jndingxin1 小时前
OpenCV 图形API(或称G-API)(1)
人工智能·opencv·计算机视觉