当前位置: 首页 > news >正文

第一章、RNN(循环神经网络)

1 循环神经网络(RNN)

展开表示该模型可以表示为:
在这里插入图片描述注意其中的RNN中的参数共用同一套参数。 那直观的理解这个网络的作用实际上就是结合当前的信息和历史中有用的信息综合输出相应的结果,及结合当前信息后的总历史信息。

那么这个网络能干嘛呢?跟CNN或者全连接神经网络有什么不同呢?
例1:假设我们现在有一个时间序列的预测问题,以股票为例(不考虑环境政策等问题,仅从数据出发为理解RNN),我们想从过去的数据中估计下一天股票会涨还是跌。
该问题可以用数学描述为,已知某股票过去 t t t天的交易量为 [ x 1 , x 2 , x 3 , x 4 , ⋯ , x t ] [x_1,x_2,x_3,x_4,\cdots ,x_t] [x1,x2,x3,x4,,xt],及对应的涨跌情况为 [ y 1 , y 2 , y 3 , y 4 , ⋯ , y t ] [y_1,y_2,y_3,y_4,\cdots,y_t] [y1,y2,y3,y4,,yt]那么已知第 t + 1 t+1 t+1天的股票交易量为 x t + 1 x_{t+1} xt+1则该天股票会涨还是跌?
假设你已经有前连接神经网络的知识,那你就会这样解决问题:模型输入为 t t t天的交易量,输出为 t t t天的涨跌情况。根据收集的数据训练一个全连接网络(代估计参数为 w w w),则 t + 1 t+1 t+1天的涨跌情况为 y ^ t + 1 = f ( w ∗ x t + 1 + b ) \hat{y}_{t+1}=f(w*x_{t+1}+b) y^t+1=f(wxt+1+b)
在这里插入图片描述
在这个问题中我们利用 x t + 1 x_{t+1} xt+1估计 y t + 1 y_{t+1} yt+1。但是有一个问题就产生了,股票不仅仅跟当天的交易量相关它实际上与之前的交易量也相关,上面的估计实际上没有充分利用已知信息,那么怎么利用这些已知信息呢?重新整里我们的问题

当前信息历史信息目标
x 1 x_1 x1- y 1 y_1 y1
x 2 x_2 x2 [ x 1 ] [x_1] [x1] y 2 y_2 y2
x 3 x_3 x3 [ x 1 , x 2 ] [x_1,x_2] [x1,x2] y 3 y_3 y3
x 4 x_4 x4 [ x 1 , x 2 , x 3 ] [x_1,x_2,x_3] [x1,x2,x3] y 4 y_4 y4
⋯ \cdots ⋯ \cdots ⋯ \cdots
x t x_t xt [ x 1 , x 2 , x 3 , ⋯ , x t − 1 ] [x_1,x_2,x_3,\cdots,x_{t-1}] [x1,x2,x3,,xt1] y t y_t yt

所以问题变成 t t t时刻的输入是 [ x 1 , x 2 , x 3 , ⋯ , x t − 1 , x t ] [x_1,x_2,x_3,\cdots,x_{t-1},x_t] [x1,x2,x3,,xt1,xt]输出是 y t y_t yt。那这么一个问题能不能用全连接解决答案是不行,因为 t t t时刻的输入是 [ x 1 , x 2 , x 3 , ⋯ , x t − 1 , x t ] [x_1,x_2,x_3,\cdots,x_{t-1},x_t] [x1,x2,x3,,xt1,xt]的长度在不停的变化,而我们之前学习的卷积也好全连接也好都是固定输入维度的,那怎么解决。

现在的问题是历史信息的维度在变化,如果我们能综合历史信息把它提取成一个长度不变的向量就好了,RNN本质上就是在做这样的事情。上述问题变成:

当前信息历史信息RNN处理后的历史信息目标
x 1 x_1 x1- h 0 h_0 h0 y 1 y_1 y1
x 2 x_2 x2 [ x 1 ] [x_1] [x1] h 1 h_1 h1 y 2 y_2 y2
x 3 x_3 x3 [ x 1 , x 2 ] [x_1,x_2] [x1,x2] h 2 h_2 h2 y 3 y_3 y3
x 4 x_4 x4 [ x 1 , x 2 , x 3 ] [x_1,x_2,x_3] [x1,x2,x3] h 3 h_3 h3 y 4 y_4 y4
⋯ \cdots ⋯ \cdots ⋯ \cdots ⋯ \cdots
x t x_t xt [ x 1 , x 2 , x 3 , ⋯ , x t − 1 ] [x_1,x_2,x_3,\cdots,x_{t-1}] [x1,x2,x3,,xt1] h t − 1 h_{t-1} ht1 y t y_t yt

所以RNN适用与结果跟一序列变量有关且序列长度不等的情况。例如:一段句子是正面的还是负面的,一段语句是高兴还是悲伤,甚至与文字翻译都可以用到RNN。

用折叠的RNN模型可以表示为如下图所示的形式:
在这里插入图片描述
显而易见对于 t t t 时刻而言,网络的输入是 x t , h t − 1 x_t,h_{t-1} xt,ht1;输出是 o t , h t o_t,h_{t} ot,ht。需要注意的是 h t − 1 h_{t-1} ht1实际上结合了前 t − 1 t-1 t1时刻的信息。

2 RNN参数学习

结合之前的内容,我们可以用以下数学表达式来表示RNN:
h t = f ( w 1 x t + w 2 h t − 1 + b ) h_t=f(w_1x_t+w_2h_{t-1}+b) ht=f(w1xt+w2ht1+b)
o t = g ( w 3 h t ) o_t=g(w_3h_t) ot=g(w3ht)
误差: L t = l ( o t − y t ) L_t=l(o_t-y_t) Lt=l(otyt)其中 y t y_t yt是真实值。
待学习的参数即 w 1 , w 2 , w 3 w_1,w_2,w_3 w1,w2,w3
梯度: δ L δ w 1 \frac{\delta L}{\delta w_1} δw1δL δ L δ w 2 \frac{\delta L}{\delta w_2} δw2δL δ L δ w 3 \frac{\delta L}{\delta w_3} δw3δL
具体计算过程不再叙述,可以通过梯度下降优化参数。
唯一需要强调的是RNN 是在整个序列完成后更新参数。

3 pytorch实现

官方网址:https://docs.pytorch.org/docs/stable/generated/torch.nn.RNN.html#torch.nn.RNN
在这里插入图片描述

# 高效实现等效于双向=False的RNN前向传播
def forward(x, hx=None):# 如果输入格式是批次优先(batch_first=True),需要转置为序列优先# PyTorch内部处理使用序列优先格式 (seq_len, batch_size, features)if batch_first:x = x.transpose(0, 1)  # 从(batch, seq, features)转为(seq, batch, features)# 获取输入张量的维度信息seq_len, batch_size, _ = x.size()  # 序列长度, 批次大小, 输入特征维度# 如果没有提供初始隐藏状态,初始化为全零if hx is None:hx = torch.zeros(num_layers, batch_size, hidden_size)  # 形状(层数, 批次大小, 隐藏大小)# 初始化隐藏状态变量h_t_minus_1 = hx  # 上一时间步的隐藏状态 (t-1时刻)h_t = hx         # 当前时间步的隐藏状态 (t时刻)# 存储每个时间步的输出output = []# 遍历序列中的每个时间步for t in range(seq_len):# 遍历每个RNN层for layer in range(num_layers):# 计算当前层在当前时间步的隐藏状态# 公式: h_t = tanh(W_ih * x_t + b_ih + W_hh * h_{t-1} + b_hh)h_t[layer] = torch.tanh(# 输入到隐藏的变换:x[t] @ weight_ih[layer].T + bias_ih[layer]  # 当前时间步的输入# 隐藏到隐藏的变换:+ h_t_minus_1[layer] @ weight_hh[layer].T + bias_hh[layer]  # 上一时间步的隐藏状态)# 只保存最后一层的输出作为该时间步的输出# 注意: 在多层RNN中,通常只使用最后一层的输出output.append(h_t[-1])  # 形状(batch_size, hidden_size)# 为下一个时间步准备隐藏状态h_t_minus_1 = h_t  # 当前状态变为下一个时间步的"上一个状态"# 将所有时间步的输出堆叠成张量output = torch.stack(output)  # 形状(seq_len, batch_size, hidden_size)# 如果原始输入是批次优先,将输出转回相同格式if batch_first:output = output.transpose(0, 1)  # 从(seq, batch, hidden)转回(batch, seq, hidden)# 返回:#   output: 所有时间步最后一层的输出 (根据batch_first决定形状)#   h_t: 最后一个时间步所有层的隐藏状态 (num_layers, batch_size, hidden_size)return output, h_t

应用只需要4行

# 创建RNN模型,指定模型的输入维度是10,隐藏维度是20,层数为2
rnn = nn.RNN(10, 20, 2)
# 输入【序列长度,batch_size,输入维度】
input = torch.randn(5, 3, 10)
# 隐藏输入(实际上就是前面说的历史信息,初始时候全为0)【层数,batch_size,隐藏维度】
h0 = torch.randn(2, 3, 20)
# forward向前推理
output, hn = rnn(input, h0)
http://www.dtcms.com/a/270034.html

相关文章:

  • 怪物机制分析(有限状态机、编辑器可视化、巡逻机制)
  • Android UI 组件系列(四):EditText 使用详解与输入限制
  • 后台设计指南:系统架构、交互规范与工具实战全流程解析
  • 布隆过滤器+缓存穿透
  • 智能推荐社交分享小程序(websocket即时通讯、协同过滤算法、时间衰减因子模型、热度得分算法)
  • 【论文阅读】Improving the Diffusability of Autoencoders
  • Word2Vec模型详解:CBOW与Skip-gram
  • 结构化数据格式解析:JSON 与 XML 的技术应用与实践
  • Serverless 数据库来了?无服务器数据库 vs 传统数据库有何不同?
  • MySQL索引面试问题梳理
  • 华为eNSP防火墙实验(包含详细步骤)
  • Spring AI:检索增强生成(RAG)
  • SystemVerilog 断言重复操作符和序列操作符
  • 用 Spring Boot + Redis 实现哔哩哔哩弹幕系统(上篇博客改进版)
  • 2025年INS SCI2区,灵活交叉变异灰狼算法GWO_C/M+集群任务调度,深度解析+性能实测
  • 短视频电商APP源码开发技术栈解析:音视频、商品链路与互动设计
  • Web前端:not(否定伪类选择器)
  • 高效学习之一篇搞定分布式管理系统Git !
  • 编译安装Python 3.9(Linux Centos 7)
  • 淘宝直播与开源链动2+1模式AI智能名片S2B2C商城小程序的融合发展研究
  • Spring中Bean的实例化(xml)
  • 【docker】linux CentOS docker 安装流程
  • CSS知识复习5
  • CKS认证 | Day5 供应链安全 Trivy、kubesec、Webhook
  • 【Linux】基础开发工具(3)
  • 云归子批量混剪软件批量剪辑软件批量分割视频更新记录
  • 关于 scrapy框架 详解
  • Spring AI 基本组件详解 —— ChatClient、Prompt、Memory
  • 装修水电改造需要注意什么?水电改造有哪些注意事项?
  • C++ 的 copy and swap 惯用法