RNN模型

时间:2024-07-18 19:10:31

介绍

        循环神经网络(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])