介绍
循环神经网络(RNN)是一种深度学习模型,专门用于处理序列数据。它通过内部的循环结构,能够有效地捕捉序列数据中的时间关系和上下文信息。
RNN模型在短序列任务上性能和效果都表现优异,但在过长的序列导致梯度的计算异常, 发生梯度消失或爆炸。
手动构建RNN模型
import torch
import torch.nn as nn
class RNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
"""
初始化RNN模型。
Args:
input_size (int): 输入张量的最后一个维度大小。
hidden_size (int): 隐藏层张量的最后一个维度大小。
output_size (int): 输出层张量的最后一个维度大小。
"""
super(RNN, self).__init__()
self.hidden_size = hidden_size
# 第一个线性层:输入到隐藏层
self.input_to_hidden = nn.Linear(input_size + hidden_size, hidden_size)
# Tanh 激活函数
self.tanh = nn.Tanh()
# 第二个线性层:隐藏层到输出层
self.input_to_output = nn.Linear(hidden_size, output_size)
# LogSoftmax 层用于输出
self.softmax = nn.LogSoftmax(dim=-1)
def forward(self, current_input, prev_hidden_state):
"""
RNN 模型的前向传播逻辑。
Args:
current_input (torch.Tensor): 当前时间步的输入张量。
形状应为 (1, input_size)。
prev_hidden_state (torch.Tensor): 上一个时间步的隐藏状态张量。
形状应为 (1, hidden_size)。
Returns:
torch.Tensor: 经过 softmax 处理后的输出张量。
torch.Tensor: 更新后的隐藏状态张量。
"""
# 将当前输入张量和上一个时间步的隐藏状态张量拼接起来
concatenated = torch.cat((current_input, prev_hidden_state), dim=1)
# 进入第一个线性层:输入到隐藏层
hidden = self.input_to_hidden(concatenated)
# 应用 Tanh 激活函数
hidden = self.tanh(hidden)
# 进入第二个线性层:隐藏层到输出层
output = self.input_to_output(hidden)
# 应用 LogSoftmax 函数
output = self.softmax(output)
return output, hidden
def init_hidden(self):
"""
初始化隐藏状态张量。
Returns:
torch.Tensor: 初始化的隐藏状态张量,全为0。
形状为 (1, hidden_size)。
"""
return torch.zeros(1, self.hidden_size)
if __name__ == '__main__':
# Define parameters
input_size = 768
hidden_size = 128
output_size = 2
# 初始化模型
rnn_model = RNN(input_size, hidden_size, output_size)
# 随机生成输入张量和隐藏状态张量
input_tensor = torch.rand(1, input_size)
hidden_tensor = rnn_model.init_hidden()
# 前向传播
outputs, hiddens = rnn_model(input_tensor, hidden_tensor)
print("outputs size:", outputs.size())
print("hidden state size:", hiddens.size())
outputs size: torch.Size([1, 2])
hidden state size: torch.Size([1, 128])
使用Pytorch的API构建RNN模型
import torch
import torch.nn as nn
class RNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size, num_layers=1):
"""
初始化RNN模型
Args:
input_size (int): 输入张量的最后一个维度大小。
hidden_size (int): 隐藏层张量的最后一个维度大小。
output_size (int): 输出层张量的最后一个维度大小。
num_layers (int, optional): RNN的层数。默认为1。
"""
super(RNN, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
# RNN层
self.rnn_layer = nn.RNN(input_size, hidden_size, num_layers)
# 输出线性层
self.output_layer = nn.Linear(hidden_size, output_size)
# LogSoftmax层用于输出
self.softmax = nn.LogSoftmax(dim=-1)
def forward(self, current_input, prev_hidden_state):
"""
RNN前向传播逻辑
Args:
current_input (torch.Tensor): 当前时间步的输入张量。
形状应为 (1, input_size)。
prev_hidden_state (torch.Tensor): 上一个时间步的隐藏状态张量。
形状应为 (num_layers, 1, hidden_size)。
Returns:
torch.Tensor: 经过LoSoftmax处理后的输出张量。
torch.Tensor: 更新后的隐藏状态张量。
"""
current_input = current_input.unsqueeze(0) # 添加批次维度
rnn_output, new_hidden_state = self.rnn_layer(current_input, prev_hidden_state)
output = self.output_layer(rnn_output)
output = self.softmax(output)
return output, new_hidden_state
def init_hidden(self):
"""
初始化隐藏状态张量
Returns:
torch.Tensor: 初始化的隐藏状态张量。
形状为 (num_layers, 1, hidden_size)。
"""
return torch.zeros(self.num_layers, 1, self.hidden_size)
if __name__ == '__main__':
# 定义参数
input_size = 768
hidden_size = 128
output_size = 2
num_layers = 1
# 实例化RNN模型
rnn = RNN(input_size, hidden_size, output_size, num_layers)
# 随机生成输入张量和隐藏状态张量
input_tensor = torch.rand(1, input_size)
hidden_tensor = rnn.init_hidden()
# 前向传播
outputs, hiddens = rnn(input_tensor, hidden_tensor)
# 打印输出结果和隐藏状态
print("outputs size:", outputs.size())
print("hidden state size:", hiddens.size())
outputs size: torch.Size([1, 1, 2])
hidden state size: torch.Size([1, 1, 128])