[ML]关于RNN的笔记总结:关于RNN输出信息维度,隐藏状态在不同epoch和batch间的处理,和gpt的连续问答,记录在此,_nn

  1. 首先:rnn的是一种网络结构而seq2seq是一种架构,(在学习seq2seq时候我混淆了,导致认为例如pytorch的rnn函数输入和输出也可以不同序列长度,这一点错误(即问题2))
    在这里插入图片描述
  2. 单层纯的RNN单元的输入和输出的sequence的length 一定是相同的 正确吗? 正确
    例子 out (16,5,32) hidden(1,16,32), out[:, -1, :] 和 hidden.squeeze(0) 维度都是(16,32)
  3. 怎么样让输入和输出序列的序列维度的长度不一样长呢,用pytorch举一个具体的例子说明,是因为输出只取了输出向量的最后一个值吗?

在某些情况下,RNN的输入序列和输出序列的长度可以不同,这通常发生在序列到序列(Seq2Seq)模型中,其中输入序列和输出序列的长度可以是不同的。一个典型的例子是机器翻译,其中输入是一种语言的句子,输出是另一种语言的句子,而这两个句子的长度通常不同。
下面是一个用PyTorch示例说明这个情况的简单示例:

import torch
import torch.nn as nn

# 假设输入序列长度为3,每个时间步有3个特征
input_sequence = torch.randn(1, 3, 3)

# 创建一个简单的RNN模型
rnn = nn.RNN(input_size=3, hidden_size=2, num_layers=1, batch_first=True)

# 将输入序列传递给RNN
output_sequence, hidden_state = rnn(input_sequence)

# 输出序列的形状
print("Output Sequence Shape:", output_sequence.shape)

在这个示例中,我们创建了一个RNN模型,输入序列的长度是3(3个时间步),每个时间步有3个特征。输出序列的形状将是(1,3,2),因为RNN的输出是隐藏状态序列,每个时间步都生成一个隐藏状态向量。这个输出序列的长度与输入序列的长度相同。
如果您希望输出序列的长度与输入序列的长度不同,通常需要将RNN的输出进行进一步的处理。例如,可以只选择输出序列中的最后一个时间步的隐藏状态,然后将其传递给一个全连接层以生成最终的输出。以下是一个示例:

# 仅选择输出序列中的最后一个时间步
last_hidden_state = output_sequence[:, -1, :]

# 通过全连接层生成最终输出
fc = nn.Linear(2, 1)  # 2是隐藏状态的维度,1是输出的维度
final_output = fc(last_hidden_state)

print("Final Output Shape:", final_output.shape)


  1. 对于以上的第一个例子我有两个问题:1 output_sequence, hidden_state = rnn(input_sequence) 中的hiddenstate是什么 形状是什么 2 他和output之间不同点是什么,因为你这个rnn没有加入激活函数也没有线型层,他和输出是不是同一个东西?(ps: 看了这个大佬的回答和例子我彻底悟了彻底悟了
  2. 在这里插入图片描述

很好的问题!让我为您解释一下。

  • hidden_state 的形状和定义: hidden_state 是RNN在最后一个时间步的隐藏状态。对于一个基本的RNN,hidden_state 的形状是 (num_layers, batch_size, hidden_size)。在上面的例子中,num_layers 为1,batch_size 为1,hidden_size 为2,所以 hidden_state 的形状是 (1, 1, 2)。 hidden_state
    可以被视为RNN的内部记忆。它捕获了之前时间步的信息,并被用于下一个时间步的计算。
  • outputsequence 和 hiddenstate 的区别: output_sequence 是一个包含每个时间步的隐藏状态的序列。对于每个输入时间步,RNN都会计算一个新的隐藏状态,并将其添加到 output_sequence 中。
    而 hidden_state 只是最后一个时间步的隐藏状态。在基本的RNN中(不考虑LSTM和GRU的情况),hidden_state 和 output_sequence 的最后一个时间步实际上是相同的。 使用以下代码,您可以验证这一点:
print(torch.equal(output_sequence[:, -1, :], hidden_state.squeeze(0))) 

输出应该是 True,这意味着 output_sequence 的最后一个隐藏状态和 hidden_state 是相同的。
确实,简单的RNN层并不包括激活函数和线性层(在PyTorch的nn.RNN中,内部默认使用tanh作为激活函数)。所以,输出序列的每个隐藏状态和 hidden_state(对于最后一个时间步)基本上是通过应用线性变换和激活函数(例如tanh)得到的。如果您想获得更复杂的输出,您可以在RNN的输出上附加额外的层,例如线性层或其他网络结构。

  1. 你以上例子的rnn模型没有传递hidden state的接口是内部自己传递了吗

我之前提供的示例中确实没有显式传递 hidden_state,但这是因为 PyTorch 的 RNN 模块默认会在内部处理隐藏状态。RNN
模块在每个时间步都会更新隐藏状态,并在内部维护这个状态。您可以访问隐藏状态,但通常不需要手动传递它,除非您有特定的需求。
在我的先前示例中,hidden_state 是 output_sequence 的最后一个时间步的隐藏状态。 PyTorch 的 RNN
模块将隐藏状态存储在内部,并且当您传递新的时间步数据时,它会自动更新这个隐藏状态。 如果您需要显式地传递 hidden_state,可以使用
initial_hidden 参数来提供一个初始的隐藏状态,或者使用 .forward 方法的 hidden
参数,来手动传递隐藏状态。但在大多数情况下,不需要手动传递隐藏状态,因为 RNN 模块会自动管理它。 以下是手动传递隐藏状态的示例:


import torch import torch.nn as nn

# 假设输入序列长度为3,每个时间步有3个特征 
input_sequence = torch.randn(1, 3, 3)

# 创建一个简单的RNN模型 
rnn = nn.RNN(input_size=3, hidden_size=2, num_layers=1, batch_first=True)

# 初始隐藏状态
 initial_hidden = torch.zeros(1, 1, 2)  # 形状是(1, 1, 2)

# 将输入序列传递给RNN,并显式传递隐藏状态 
output_sequence, hidden_state = rnn(input_sequence, initial_hidden)

print("Output Sequence Shape:", output_sequence.shape) print("Hidden State Shape:", hidden_state.shape) 

  1. 一个关于维度的附加问题:有一个tensor [[[1,2],[1,2]],[[1,2],[1,2]]] 他的dim 0 ,1,2 分别是什么方向?
    这个tensor有三个维度,我们可以按照以下方式理解它们:

1.dim=0: 最外层的方括号。在这个例子中,它有2个元素。我们可以将其视为“批次”维度或“列表”维度,每个元素是一个列表。
2.dim=1: 第二层的方括号。在此例子中,每个“列表”都包含2个元素。我们可以将其视为“序列”维度或“行”维度,每个元素是一个向量。
3.dim=2: 最内层的方括号。在此例子中,每个“向量”都包含2个元素。我们可以将其视为“特征”维度或“列”维度。

在许多深度学习上下文中,如处理序列数据时:

4.dim=0 通常表示批次(batch)的大小
5.dim=1 通常表示序列长度(sequence length)
6.dim=2 通常表示特征数或输入维度(input size or feature size)

对于给出的tensor: [
[
[1,2],
[1,2]
],
[
[1,2],
[1,2]
] ]

7.dim=0 有2个元素
8.dim=1 有2个元素
9.dim=2 有2个元素

所以,tensor的形状(shape)是 [2, 2, 2]

  1. rnn 的维度记录:
    x = torch.randn(batch_size, seq_len, input_size) # 输入数据
    h0 = torch.zeros(num_layers,batch_size, hidden_size) # 修改后的输入数据
    out 是RNN层的输出,它的形状通常是 [batch_size, sequence_length, hidden_size]

8.out.view(-1, hidden_size) 的作用是什么

def forward(self, x, hidden_prev):
   out, hidden_prev = self.rnn(x, hidden_prev)


### 最后

除了简历做到位,面试题也必不可少,整理了些题目,前面有117道汇总的面试到的题目,后面包括了HTML、CSS、JS、ES6、vue、微信小程序、项目类问题、笔试编程类题等专题。

* **[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

  ![](https://img-blog.csdnimg.cn/img_convert/64ce8432d0f753e43f93972ad19fcd72.png)


![](https://img-blog.csdnimg.cn/img_convert/d508b1ae6a5e7d5e7d5daf668e9eccea.png)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值