目录
torch.nn子模块Recurrent Layers
nn.RNNBase
RNNBase 类描述
RNNBase 类的功能和作用
flatten_parameters() 方法
示例代码
nn.RNN
RNN 类描述
RNN 类的功能和作用
RNN 类的参数
输入和输出
注意事项
示例代码
nn.LSTM
LSTM 类描述
LSTM 类的功能和作用
LSTM 类的参数
输入和输出
注意事项
示例代码
nn.GRU
GRU 类描述
GRU 类的功能和作用
GRU 类的参数
输入和输出
注意事项
示例代码
nn.RNNCell
RNNCell 类描述
RNNCell 类的功能和作用
RNNCell 类的参数
输入和输出
形状
变量
注意事项
示例代码
nn.LSTMCell
LSTMCell 类描述
LSTMCell 类的功能和作用
LSTMCell 类的参数
输入和输出
变量
注意事项
示例代码
nn.GRUCell
GRUCell 类描述
GRUCell 类的功能和作用
GRUCell 类的参数
输入和输出
形状
变量
注意事项
示例代码
总结
torch.nn.RNNBase
是 PyTorch 中用于构建循环神经网络的基类。它是 RNN、LSTM 和 GRU 等更具体的循环神经网络类的基础。下面将详细描述这个类和它的一个主要方法 flatten_parameters
。
初始化: RNNBase 类提供了 RNN, LSTM, 和 GRU 这些子类的基本初始化参数。这包括输入大小(input_size
)、隐藏层大小(hidden_size
)、层数(num_layers
)、使用偏置(bias
)、是否以批处理为主(batch_first
)、dropout 比例(dropout
)、是否双向(bidirectional
)等。
参数管理: RNNBase 还提供了一些用于参数管理的实用方法,如参数的存储和重置。
注意: RNNBase 类本身并不实现 forward
方法。这意味着你不能直接使用 RNNBase 来创建一个模型实例;它只是提供了一个共同的基础结构,用于构建各种类型的循环神经网络。
作用: flatten_parameters
方法用于优化 RNN 的内部参数存储结构,从而使得 RNN 可以使用更快的代码路径进行计算。
技巧: 这个方法尤其在使用 GPU 和启用 cuDNN 时非常有效。在这些条件下,它会重新设置参数数据指针,以优化内存访问模式和提高效率。
注意事项: 当模块不在 GPU 上或者没有启用 cuDNN 时,flatten_parameters
将不起作用,也就是说,它在这种情况下是一个无操作(no-op)。
下面是一个示例代码,展示了如何使用 LSTM (继承自 RNNBase)并在其中调用 flatten_parameters
方法。
import torch
import torch.nn as nn
# 定义一个简单的 LSTM 网络
class SimpleLSTM(nn.Module):
def __init__(self, input_size, hidden_size, num_layers):
super(SimpleLSTM, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, num_layers)
def forward(self, x):
self.lstm.flatten_parameters()
output, (hn, cn) = self.lstm(x)
return output, hn, cn
# 参数
input_size = 10
hidden_size = 20
num_layers = 2
# 创建模型实例
model = SimpleLSTM(input_size, hidden_size, num_layers)
# 示例输入
x = torch.randn(5, 3, input_size) # (seq_length, batch, input_size)
# 前向传播
output, hn, cn = model(x)
这段代码展示了如何创建一个简单的 LSTM 网络,它在每次前向传播前调用 flatten_parameters
方法以优化性能。在这里,x
是一个随机生成的输入张量,其维度是序列长度、批大小和输入大小。
torch.nn.RNN
是 PyTorch 中用于构建一个简单的 Elman 循环神经网络(RNN)的类。它可以应用于输入序列,使用 tanh
或 ReLU
作为激活函数。下面将详细描述这个类的功能、参数和注意事项。
Elman RNN: 这个类实现了基本的 Elman RNN 架构。对于输入序列中的每个元素,每层 RNN 都会计算一个新的隐藏状态,该状态取决于当前输入和前一时间点的隐藏状态。
激活函数: 可以选择使用 tanh
或 ReLU
作为非线性激活函数。
num_layers=2
表示两个 RNN 层堆叠在一起。'tanh'
或 'relu'
。False
,则层不使用偏置权重 b_ih
和 b_hh
。True
,则输入和输出张量的格式为 (batch, seq, feature)
;否则为 (seq, batch, feature)
。True
,则变为双向 RNN。输入: input
, h_0
input
: 形状为 (seq_len, batch, input_size)
或 (batch, seq_len, input_size)
(如果 batch_first=True
)的张量,包含输入序列的特征。h_0
: 形状为 (num_layers * num_directions, batch, hidden_size)
的张量,包含初始隐藏状态。如果未提供,默认为零。输出: output
, h_n
output
: 包含最后一层 RNN 的输出特征(h_t
)的张量。h_n
: 形状为 (num_layers * num_directions, batch, hidden_size)
的张量,包含批次中每个元素的最终隐藏状态。U(-k, k)
初始化,其中 k = 1 / hidden_size
。torch.float16
等),cudnn 可以选择持久算法来提升性能。import torch
import torch.nn as nn
# 创建 RNN 实例
rnn = nn.RNN(input_size=10, hidden_size=20, num_layers=2, nonlinearity='tanh')
# 输入数据
input = torch.randn(5, 3, 10) # (seq_len, batch, input_size)
h0 = torch.randn(2, 3, 20) # (num_layers, batch, hidden_size)
# 前向传播
output, hn = rnn(input, h0)
这段代码展示了如何创建一个简单的 RNN 网络并进行前向传播。在这个例子中,input
是一个随机生成的输入张量,其维度是序列长度、批大小和输入大小。h0
是初始隐藏状态。输出 output
包含了每个时间步的隐藏状态,而 hn
是最终的隐藏状态。
torch.nn.LSTM
是 PyTorch 中用于构建长短期记忆(LSTM)网络的类。LSTM 是一种特殊类型的循环神经网络(RNN),特别适合处理和预测时间序列数据中的长期依赖关系。
num_layers=2
表示两个 LSTM 层堆叠在一起。False
,则层不使用偏置权重 b_ih
和 b_hh
。True
,则输入和输出张量的格式为 (batch, seq, feature)
;否则为 (seq, batch, feature)
。True
,则变为双向 LSTM。输入: input
, (h_0, c_0)
input
: 形状为 (seq_len, batch, input_size)
或 (batch, seq_len, input_size)
(如果 batch_first=True
)的张量,包含输入序列的特征。h_0
: 形状为 (num_layers * num_directions, batch, hidden_size)
的张量,包含初始隐藏状态。c_0
: 形状为 (num_layers * num_directions, batch, hidden_size)
的张量,包含初始细胞状态。输出: output
, (h_n, c_n)
output
: 包含最后一层 LSTM 的输出特征(h_t
)的张量。h_n
: 形状为 (num_layers * num_directions, batch, hidden_size)
的张量,包含序列中每个元素的最终隐藏状态。c_n
: 形状为 (num_layers * num_directions, batch, hidden_size)
的张量,包含序列中每个元素的最终细胞状态。U(-k, k)
初始化,其中 k = 1 / hidden_size
。h_n
和 output
的含义有所不同。h_n
包含最终的前向和后向隐藏状态,而 output
包含每个时间步的隐藏状态。proj_size
应小于 hidden_size
。import torch
import torch.nn as nn
# 创建 LSTM 实例
lstm = nn.LSTM(input_size=10, hidden_size=20, num_layers=2)
# 输入数据
input = torch.randn(5, 3, 10) # (seq_len, batch, input_size)
h0 = torch.randn(2, 3, 20) # (num_layers, batch, hidden_size)
c0 = torch.randn(2, 3, 20) # (num_layers, batch, hidden_size)
# 前向传播
output, (hn, cn) = lstm(input, (h0, c0))
这段代码展示了如何创建一个 LSTM 网络并进行前向传播。在这个例子中,input
是一个随机生成的输入张量,其维度是序列长度、批大小和输入大小。h0
和 c0
分别是初始隐藏状态和细胞状态。输出 output
包含了每个时间步的隐藏状态,而 (hn, cn)
是最终的隐藏状态和细胞状态。
torch.nn.GRU
是 PyTorch 中用于构建门控循环单元(GRU)网络的类。GRU 是一种循环神经网络,类似于 LSTM,但结构更为简单,用于处理序列数据。
num_layers=2
表示两个 GRU 层堆叠在一起。False
,则层不使用偏置权重 b_ih
和 b_hh
。True
,则输入和输出张量的格式为 (batch, seq, feature)
;否则为 (seq, batch, feature)
。True
,则变为双向 GRU。输入: input
, h_0
input
: 形状为 (seq_len, batch, input_size)
或 (batch, seq_len, input_size)
(如果 batch_first=True
)的张量,包含输入序列的特征。h_0
: 形状为 (num_layers * num_directions, batch, hidden_size)
的张量,包含初始隐藏状态。输出: output
, h_n
output
: 包含最后一层 GRU 的输出特征(h_t
)的张量。h_n
: 形状为 (num_layers * num_directions, batch, hidden_size)
的张量,包含序列中每个元素的最终隐藏状态。U(-k, k)
初始化,其中 k = 1 / hidden_size
。h_n
和 output
的含义有所不同。h_n
包含最终的前向和后向隐藏状态,而 output
包含每个时间步的隐藏状态。import torch
import torch.nn as nn
# 创建 GRU 实例
gru = nn.GRU(input_size=10, hidden_size=20, num_layers=2)
# 输入数据
input = torch.randn(5, 3, 10) # (seq_len, batch, input_size)
h0 = torch.randn(2, 3, 20) # (num_layers, batch, hidden_size)
# 前向传播
output, hn = gru(input, h0)
这段代码展示了如何创建一个 GRU 网络并进行前向传播。在这个例子中,input
是一个随机生成的输入张量,其维度是序列长度、批大小和输入大小。h0
是初始隐藏状态。输出 output
包含了每个时间步的隐藏状态,而 hn
是最终的隐藏状态。
torch.nn.RNNCell
是 PyTorch 中的一个模块,用于实现单个 Elman RNN 单元。这个类比完整的 RNN
类更为基础,它处理的是序列中的单个时间步,而不是整个序列。
False
,则单元不使用偏置权重 b_ih
和 b_hh
。默认为 True
。'tanh'
或 'relu'
。默认为 'tanh'
。输入: input
, hidden
input
: 包含输入特征的张量。hidden
: 包含初始隐藏状态的张量。如果未提供,默认为零。输出: h'
h'
: 形状为 (batch, hidden_size)
的张量,包含批次中每个元素的下一个隐藏状态。(N, H_in)
或 (H_in)
的张量,其中 H_in = input_size
。(N, H_out)
或 (H_out)
的张量,其中 H_out = hidden_size
。如果未提供,默认为零。(N, H_out)
或 (H_out)
的张量,包含下一个隐藏状态。torch.Tensor
): 学习得到的输入-隐藏权重,形状为 (hidden_size, input_size)
。torch.Tensor
): 学习得到的隐藏-隐藏权重,形状为 (hidden_size, hidden_size)
。(hidden_size)
。(hidden_size)
。U(-k, k)
初始化,其中 k = 1 / hidden_size
。import torch
import torch.nn as nn
# 创建 RNNCell 实例
rnn = nn.RNNCell(10, 20)
# 输入数据
input = torch.randn(6, 3, 10) # (time_steps, batch, input_size)
hx = torch.randn(3, 20) # (batch, hidden_size)
# 模拟时间步循环
output = []
for i in range(6):
hx = rnn(input[i], hx)
output.append(hx)
这段代码展示了如何使用 RNNCell
来处理一个序列。在这个例子中,input
是一个随机生成的输入张量,其维度是时间步、批大小和输入大小。hx
是初始隐藏状态。循环通过逐个时间步调用 RNNCell
来更新 hx
,并将每个时间步的输出收集到 output
列表中。
torch.nn.LSTMCell
是 PyTorch 中用于构建单个长短期记忆(LSTM)单元的类。与 LSTM
类处理整个序列不同,LSTMCell
只处理序列中的单个时间步。
LSTM
类似,LSTMCell 使用输入门、遗忘门、输出门和细胞状态来控制和维持长期依赖关系。False
,则单元不使用偏置权重 b_ih
和 b_hh
。默认为 True
。输入: input
, (h_0, c_0)
input
: 形状为 (batch, input_size)
或 (input_size)
的张量,包含输入特征。h_0
: 形状为 (batch, hidden_size)
或 (hidden_size)
的张量,包含初始隐藏状态。c_0
: 形状为 (batch, hidden_size)
或 (hidden_size)
的张量,包含初始细胞状态。输出: (h_1, c_1)
h_1
: 形状为 (batch, hidden_size)
或 (hidden_size)
的张量,包含下一个隐藏状态。c_1
: 形状为 (batch, hidden_size)
或 (hidden_size)
的张量,包含下一个细胞状态。torch.Tensor
): 学习得到的输入-隐藏权重,形状为 (4*hidden_size, input_size)
。torch.Tensor
): 学习得到的隐藏-隐藏权重,形状为 (4*hidden_size, hidden_size)
。(4*hidden_size)
。(4*hidden_size)
。U(-k, k)
初始化,其中 k = 1 / hidden_size
。import torch
import torch.nn as nn
# 创建 LSTMCell 实例
lstm_cell = nn.LSTMCell(10, 20) # (input_size, hidden_size)
# 输入数据
input = torch.randn(2, 3, 10) # (time_steps, batch, input_size)
hx = torch.randn(3, 20) # (batch, hidden_size)
cx = torch.randn(3, 20) # (batch, hidden_size)
# 模拟时间步循环
output = []
for i in range(input.size()[0]):
hx, cx = lstm_cell(input[i], (hx, cx))
output.append(hx)
# 将输出堆叠起来
output = torch.stack(output, dim=0)
这段代码展示了如何使用 LSTMCell
来处理一个序列。在这个例子中,input
是一个随机生成的输入张量,其维度是时间步、批大小和输入大小。hx
和 cx
分别是初始隐藏状态和细胞状态。循环通过逐个时间步调用 LSTMCell
来更新 hx
和 cx
,并将每个时间步的隐藏状态收集到 output
列表中,最后将这些输出堆叠起来。
torch.nn.GRUCell
是 PyTorch 中用于构建单个门控循环单元(GRU)的类。与完整的 GRU
类不同,GRUCell
专门处理序列中的单个时间步。
GRU
类似,GRUCell 使用更新门(update gate)和重置门(reset gate)来控制信息的流动,有效地捕捉序列数据中的长期依赖关系。False
,则单元不使用偏置权重 b_ih
和 b_hh
。默认为 True
。输入: input
, hidden
input
: 包含输入特征的张量。hidden
: 包含初始隐藏状态的张量。如果未提供,默认为零。输出: h'
h'
: 包含批次中每个元素的下一个隐藏状态的张量。(N, H_in)
或 (H_in)
的张量,其中 H_in = input_size
。(N, H_out)
或 (H_out)
的张量,其中 H_out = hidden_size
。如果未提供,默认为零。(N, H_out)
或 (H_out)
的张量,包含下一个隐藏状态。torch.Tensor
): 学习得到的输入-隐藏权重,形状为 (3*hidden_size, input_size)
。torch.Tensor
): 学习得到的隐藏-隐藏权重,形状为 (3*hidden_size, hidden_size)
。(3*hidden_size)
。(3*hidden_size)
。U(-k, k)
初始化,其中 k = 1 / hidden_size
。import torch
import torch.nn as nn
# 创建 GRUCell 实例
gru_cell = nn.GRUCell(10, 20) # (input_size, hidden_size)
# 输入数据
input = torch.randn(6, 3, 10) # (time_steps, batch, input_size)
hx = torch.randn(3, 20) # (batch, hidden_size)
# 模拟时间步循环
output = []
for i in range(6):
hx = gru_cell(input[i], hx)
output.append(hx)
这段代码展示了如何使用 GRUCell
来处理一个序列。在这个例子中,input
是一个随机生成的输入张量,其维度是时间步、批大小和输入大小。hx
是初始隐藏状态。循环通过逐个时间步调用 GRUCell
来更新 hx
,并将每个时间步的输出收集到 output
列表中。
在这篇博客中,我们深入探索了 PyTorch 中的循环神经网络(RNN)相关的几个关键类:RNNBase
, RNN
, LSTM
, GRU
及其对应的单元格版本 RNNCell
, LSTMCell
, GRUCell
。每个类的功能、作用、参数和使用方法都得到了详细的解释和示例代码的支持。从基础的 RNN 架构到更复杂的 LSTM 和 GRU 结构,本文提供了深入了解这些强大的序列模型工具的机会,同时也展示了如何在实际场景中应用这些模型。这些类不仅对于理解序列数据的基本动态至关重要,而且在许多先进的深度学习应用中发挥着核心作用。