深度学习实战(基于pytroch)系列(四十三)深度循环神经网络pytorch实现

深度循环神经网络pytorch实现

架构概述

前述的循环神经网络仅包含单向单隐藏层,在实际深度学习应用中,我们通常使用含多个隐藏层的循环神经网络,称为深度循环神经网络。图6.11展示了一个具有L个隐藏层的深度循环神经网络架构,其中每个隐藏状态同时向两个方向传递:

  • 当前层的下一时间步(时间维度)
  • 当前时间步的下一层(深度维度)

数学定义

输入与输出定义

在时间步 t t t 中,设小批量输入为 X t ∈ R n × d \boldsymbol{X}_t \in \mathbb{R}^{n \times d} Xt∈Rn×d(样本数为 n n n,输入维度为 d d d),第 l l l 隐藏层( l = 1 , 2 , ... , L l = 1, 2, \ldots, L l=1,2,...,L)的隐藏状态为 H t ( l ) ∈ R n × h \boldsymbol{H}_t^{(l)} \in \mathbb{R}^{n \times h} Ht(l)∈Rn×h(隐藏单元个数为 h h h),输出层变量为 O t ∈ R n × q \boldsymbol{O}_t \in \mathbb{R}^{n \times q} Ot∈Rn×q(输出个数为 q q q),隐藏层激活函数为 ϕ \phi ϕ。

第1隐藏层计算

第1隐藏层的隐藏状态计算与传统循环神经网络一致:

H t ( 1 ) = ϕ ( X t W x h ( 1 ) + H t − 1 ( 1 ) W h h ( 1 ) + b h ( 1 ) ) \boldsymbol{H}t^{(1)} = \phi(\boldsymbol{X}t \boldsymbol{W}{xh}^{(1)} + \boldsymbol{H}{t-1}^{(1)} \boldsymbol{W}_{hh}^{(1)} + \boldsymbol{b}_h^{(1)}) Ht(1)=ϕ(XtWxh(1)+Ht−1(1)Whh(1)+bh(1))

其中模型参数包括:

  • W x h ( 1 ) ∈ R d × h \boldsymbol{W}_{xh}^{(1)} \in \mathbb{R}^{d \times h} Wxh(1)∈Rd×h:输入到第1隐藏层的权重矩阵
  • W h h ( 1 ) ∈ R h × h \boldsymbol{W}_{hh}^{(1)} \in \mathbb{R}^{h \times h} Whh(1)∈Rh×h:第1隐藏层循环权重矩阵
  • b h ( 1 ) ∈ R 1 × h \boldsymbol{b}_h^{(1)} \in \mathbb{R}^{1 \times h} bh(1)∈R1×h:第1隐藏层偏置向量

第 l l l隐藏层计算( l ≥ 2 l \geq 2 l≥2)

对于第 l l l 隐藏层( l ≥ 2 l \geq 2 l≥2),隐藏状态计算基于前一层的输出:

H t ( l ) = ϕ ( H t ( l − 1 ) W x h ( l ) + H t − 1 ( l ) W h h ( l ) + b h ( l ) ) \boldsymbol{H}t^{(l)} = \phi(\boldsymbol{H}t^{(l-1)} \boldsymbol{W}{xh}^{(l)} + \boldsymbol{H}{t-1}^{(l)} \boldsymbol{W}_{hh}^{(l)} + \boldsymbol{b}_h^{(l)}) Ht(l)=ϕ(Ht(l−1)Wxh(l)+Ht−1(l)Whh(l)+bh(l))

其中模型参数包括:

  • W x h ( l ) ∈ R h × h \boldsymbol{W}_{xh}^{(l)} \in \mathbb{R}^{h \times h} Wxh(l)∈Rh×h:第 l − 1 l-1 l−1层到第 l l l层的权重矩阵
  • W h h ( l ) ∈ R h × h \boldsymbol{W}_{hh}^{(l)} \in \mathbb{R}^{h \times h} Whh(l)∈Rh×h:第 l l l层循环权重矩阵
  • b h ( l ) ∈ R 1 × h \boldsymbol{b}_h^{(l)} \in \mathbb{R}^{1 \times h} bh(l)∈R1×h:第 l l l层偏置向量

输出层计算

最终输出基于最后一层隐藏层的隐藏状态:

O t = H t ( L ) W h q + b q \boldsymbol{O}_t = \boldsymbol{H}t^{(L)} \boldsymbol{W}{hq} + \boldsymbol{b}_q Ot=Ht(L)Whq+bq

其中输出层参数包括:

  • W h q ∈ R h × q \boldsymbol{W}_{hq} \in \mathbb{R}^{h \times q} Whq∈Rh×q:隐藏层到输出层的权重矩阵
  • b q ∈ R 1 × q \boldsymbol{b}_q \in \mathbb{R}^{1 \times q} bq∈R1×q:输出层偏置向量

扩展说明

  1. 超参数选择 :隐藏层个数 L L L 和隐藏单元个数 h h h 是需要调节的超参数
  2. 门控机制扩展:将基础循环单元替换为门控循环单元(GRU)或长短期记忆(LSTM)单元,即可构建深度门控循环神经网络
  3. 初始化策略 :各层初始隐藏状态 H 0 ( l ) \boldsymbol{H}_0^{(l)} H0(l) 通常初始化为零向量

PyTorch实现

python 复制代码
import torch
import torch.nn as nn

class DeepRNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, num_layers, 
                 rnn_type='rnn', activation='tanh', dropout=0.0):
        """
        深度循环神经网络
        
        Args:
            input_size: 输入特征维度 d
            hidden_size: 隐藏单元个数 h
            output_size: 输出维度 q
            num_layers: 隐藏层数量 L
            rnn_type: RNN类型 ('rnn', 'gru', 'lstm')
            activation: 激活函数 ('tanh', 'relu'),仅对RNN有效
            dropout: 层间dropout概率
        """
        super(DeepRNN, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        
        # 选择RNN类型
        if rnn_type.lower() == 'rnn':
            self.rnn = nn.RNN(
                input_size=input_size,
                hidden_size=hidden_size,
                num_layers=num_layers,
                batch_first=False,  # (seq_len, batch, input_size)
                nonlinearity=activation,
                dropout=dropout
            )
        elif rnn_type.lower() == 'gru':
            self.rnn = nn.GRU(
                input_size=input_size,
                hidden_size=hidden_size,
                num_layers=num_layers,
                batch_first=False,
                dropout=dropout
            )
        elif rnn_type.lower() == 'lstm':
            self.rnn = nn.LSTM(
                input_size=input_size,
                hidden_size=hidden_size,
                num_layers=num_layers,
                batch_first=False,
                dropout=dropout
            )
        else:
            raise ValueError("rnn_type must be 'rnn', 'gru', or 'lstm'")
        
        # 输出层
        self.fc = nn.Linear(hidden_size, output_size)
    
    def forward(self, x, hidden=None):
        """
        前向传播
        
        Args:
            x: 输入序列, shape: (seq_len, batch_size, input_size)
            hidden: 初始隐藏状态,如果为None则自动初始化
            
        Returns:
            output: 输出序列, shape: (seq_len, batch_size, output_size)
            hidden: 最终隐藏状态
        """
        # RNN前向传播
        rnn_output, hidden = self.rnn(x, hidden)  # (seq_len, batch_size, hidden_size)
        
        # 全连接层
        output = self.fc(rnn_output)  # (seq_len, batch_size, output_size)
        
        return output, hidden
    
    def init_hidden(self, batch_size, device=None):
        """初始化隐藏状态"""
        if device is None:
            device = next(self.parameters()).device
            
        if isinstance(self.rnn, nn.LSTM):
            # LSTM需要隐藏状态和细胞状态
            h0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(device)
            c0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(device)
            return (h0, c0)
        else:
            # RNN和GRU只需要隐藏状态
            return torch.zeros(self.num_layers, batch_size, self.hidden_size).to(device)


# 手动实现版本(更贴近数学公式)
class ManualDeepRNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, num_layers, activation='tanh'):
        """
        手动实现的深度循环神经网络
        
        Args:
            input_size: 输入特征维度 d
            hidden_size: 隐藏单元个数 h
            output_size: 输出维度 q
            num_layers: 隐藏层数量 L
            activation: 激活函数
        """
        super(ManualDeepRNN, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        
        # 选择激活函数
        if activation == 'tanh':
            self.phi = torch.tanh
        elif activation == 'relu':
            self.phi = torch.relu
        else:
            raise ValueError("激活函数支持 'tanh' 或 'relu'")
        
        # 创建各层参数
        self.layers = nn.ModuleList()
        
        # 第1层(输入到隐藏)
        self.layers.append(nn.RNNCell(input_size, hidden_size, nonlinearity=activation))
        
        # 中间层(隐藏到隐藏)
        for _ in range(1, num_layers):
            self.layers.append(nn.RNNCell(hidden_size, hidden_size, nonlinearity=activation))
        
        # 输出层
        self.fc = nn.Linear(hidden_size, output_size)
    
    def forward(self, x):
        """
        前向传播
        
        Args:
            x: 输入序列, shape: (seq_len, batch_size, input_size)
            
        Returns:
            outputs: 输出序列, shape: (seq_len, batch_size, output_size)
        """
        seq_len, batch_size, _ = x.shape
        
        # 初始化各层隐藏状态
        hidden_states = [torch.zeros(batch_size, self.hidden_size).to(x.device) 
                        for _ in range(self.num_layers)]
        
        outputs = []
        
        for t in range(seq_len):
            # 第1层处理
            hidden_states[0] = self.layers[0](x[t], hidden_states[0])
            
            # 后续层处理
            for layer in range(1, self.num_layers):
                hidden_states[layer] = self.layers[layer](
                    hidden_states[layer-1], hidden_states[layer]
                )
            
            # 输出层
            output_t = self.fc(hidden_states[-1])
            outputs.append(output_t)
        
        return torch.stack(outputs)


# 测试代码
def test_deep_rnn():
    # 参数设置
    input_size = 10
    hidden_size = 32
    output_size = 5
    num_layers = 3
    batch_size = 4
    seq_len = 8
    
    # 创建模型
    model = DeepRNN(input_size, hidden_size, output_size, num_layers, rnn_type='rnn')
    
    # 创建测试数据
    x = torch.randn(seq_len, batch_size, input_size)
    
    # 前向传播
    output, hidden = model(x)
    
    print(f"输入形状: {x.shape}")
    print(f"输出形状: {output.shape}")
    print(f"隐藏状态形状: {hidden.shape if not isinstance(hidden, tuple) else hidden[0].shape}")
    
    # 验证输出形状
    assert output.shape == (seq_len, batch_size, output_size)
    print("测试通过!")


if __name__ == "__main__":
    test_deep_rnn()

小结

  • 深度循环神经网络通过堆叠多个隐藏层来增强模型的表达能力
  • 每个隐藏状态同时向时间维度(下一时间步)和深度维度(下一层)传递信息
  • 可通过替换基础循环单元为GRU或LSTM来构建更强大的深度门控循环神经网络
  • 隐藏层数量L和隐藏单元数量h是需要精心调节的重要超参数

本系列目录链接

深度学习实战(基于pytroch)系列(一)环境准备
深度学习实战(基于pytroch)系列(二)数学基础
深度学习实战(基于pytroch)系列(三)数据操作
深度学习实战(基于pytroch)系列(四)线性回归原理及实现
深度学习实战(基于pytroch)系列(五)线性回归的pytorch实现
深度学习实战(基于pytroch)系列(六)softmax回归原理
深度学习实战(基于pytroch)系列(七)softmax回归从零开始使用python代码实现
深度学习实战(基于pytroch)系列(八)softmax回归基于pytorch的代码实现
深度学习实战(基于pytroch)系列(九)多层感知机原理
深度学习实战(基于pytroch)系列(十)多层感知机实现
深度学习实战(基于pytroch)系列(十一)模型选择、欠拟合和过拟合
深度学习实战(基于pytroch)系列(十二)dropout
深度学习实战(基于pytroch)系列(十三)权重衰减
深度学习实战(基于pytroch)系列(十四)正向传播、反向传播
深度学习实战(基于pytroch)系列(十五)模型构造
深度学习实战(基于pytroch)系列(十六)模型参数
深度学习实战(基于pytroch)系列(十七)自定义层
深度学习实战(基于pytroch)系列(十八) PyTorch中的模型读取和存储
深度学习实战(基于pytroch)系列(十九) PyTorch的GPU计算
深度学习实战(基于pytroch)系列(二十)二维卷积层
深度学习实战(基于pytroch)系列(二十一)卷积操作中的填充和步幅
深度学习实战(基于pytroch)系列(二十二)多通道输入输出
深度学习实战(基于pytroch)系列(二十三)池化层
深度学习实战(基于pytroch)系列(二十四)卷积神经网络(LeNet)
深度学习实战(基于pytroch)系列(二十五)深度卷积神经网络(AlexNet)
深度学习实战(基于pytroch)系列(二十六)VGG
深度学习实战(基于pytroch)系列(二十七)网络中的网络(NiN)
深度学习实战(基于pytroch)系列(二十八)含并行连结的网络(GoogLeNet)
深度学习实战(基于pytroch)系列(二十九)批量归一化(batch normalization)
深度学习实战(基于pytroch)系列(三十) 残差网络(ResNet)
深度学习实战(基于pytroch)系列(三十一) 稠密连接网络(DenseNet)
深度学习实战(基于pytroch)系列(三十二) 语言模型
深度学习实战(基于pytroch)系列(三十三)循环神经网络RNN
深度学习实战(基于pytroch)系列(三十四)语言模型数据集(周杰伦专辑歌词)
深度学习实战(基于pytroch)系列(三十五)循环神经网络的从零开始实现
深度学习实战(基于pytroch)系列(三十六)循环神经网络的pytorch简洁实现
深度学习实战(基于pytroch)系列(三十七)通过时间反向传播
深度学习实战(基于pytroch)系列(三十八)门控循环单元(GRU)从零开始实现
深度学习实战(基于pytroch)系列(三十九)门控循环单元(GRU)pytorch简洁实现
深度学习实战(基于pytroch)系列(四十)长短期记忆(LSTM)从零开始实现
深度学习实战(基于pytroch)系列(四十一)长短期记忆(LSTM)pytorch简洁实现
深度学习实战(基于pytroch)系列(四十二)双向循环神经网络pytorch实现
深度学习实战(基于pytroch)系列(四十三)深度循环神经网络pytorch实现
深度学习实战(基于pytroch)系列(四十四) 优化与深度学习

相关推荐
前端摸鱼匠2 分钟前
面试题2:Transformer的Encoder、Decoder结构分别包含哪些核心组件?
人工智能·深度学习·ai·面试·职场和发展·transformer
罗罗攀21 分钟前
PyTorch学习笔记|张量的线性代数运算
人工智能·pytorch·笔记·学习·线性代数
sin°θ_陈21 分钟前
行业调研——XGRIDS (其域创新):空间数据生产、资产化与工业工作流的真正价值
经验分享·笔记·深度学习·3d·金融·3dgs·空间智能
油泼辣子多加24 分钟前
【DL】Transformer算法应用
人工智能·深度学习·算法·机器学习·transformer
剑穗挂着新流苏31230 分钟前
108_深度学习中的“瘦身术”:最大池化层(MaxPool2d)原理与实战
pytorch·深度学习·计算机视觉
qq_5710993531 分钟前
学习周报三十七
人工智能·深度学习·学习
智算菩萨33 分钟前
与AI一起记忆:从分布式记忆到AI策划记忆与人机共忆——文献精读
论文阅读·人工智能·分布式·深度学习·ai·文献
此方ls38 分钟前
机器学习深度学习二——GAN网络
深度学习·机器学习·生成对抗网络
grant-ADAS9 小时前
记录paddlepaddleOCR从环境到使用默认模型,再训练自己的数据微调模型再推理
人工智能·深度学习
云和数据.ChenGuang10 小时前
魔搭社区 测试AI案例故障
人工智能·深度学习·机器学习·ai·mindstudio