You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从零实现多层RNN:输入逻辑困惑与PyTorch反向传播原地修改错误

问题解决:堆叠RNN输入逻辑与反向传播原地修改错误

一、堆叠RNN的输入逻辑澄清

你对堆叠RNN的理解是正确的:每个时间步中,第一层的输出作为同时间步第二层的输入,后续层以此类推。

PyTorch官方文档中给出的RNN代码是简化的示意版本,目的是展示RNN的基础循环逻辑,并非真实的堆叠RNN实现。实际PyTorch内部的nn.RNN当num_layers>1时,严格遵循层间传递输入的逻辑——上层的输出作为下层的输入,而非所有层都使用原始输入x[t]。

二、反向传播原地修改错误的解决

错误原因

你的代码中h_t = h_0是直接赋值,导致h_t与h_0共享同一块内存空间。后续的h_t[layer] = ...属于原地修改张量,这会破坏PyTorch自动微分系统对张量版本的跟踪,从而引发梯度计算错误。

修复方案

每次时间步循环时,创建新的h_t张量来存储当前层的隐藏状态,避免复用之前的张量内存。同时修正层间输入传递的语法错误。

修改后的完整代码:

def forward(self, x, h_0=None):
    batch_size, seq_len, _ = x.size()
    x = x.transpose(0, 1)  # 切换为(seq_len, batch_size, input_dim)格式
    if h_0 is None:
        h_0 = torch.zeros(self.num_layers, batch_size, self.hidden_dim, device=x.device)
    h_t_minus_1 = h_0
    output_list = []
    
    for t in range(seq_len):
        # 为当前时间步创建新的隐藏状态张量,避免原地修改
        h_t = torch.zeros_like(h_t_minus_1)
        for layer in range(self.num_layers):
            if layer == 0:
                current_input = x[t]
            else:
                # 上层输出作为当前层输入,做线性变换匹配维度
                current_input = F.linear(h_t[layer-1], self.w_hh2.T)
            
            # 计算当前层的隐藏状态
            h_t[layer] = torch.tanh(
                current_input @ self.w_ih[layer].T +
                h_t_minus_1[layer] @ self.w_hh[layer].T +
                self.b_hh[layer]
            )
        
        # 输出层计算
        output = F.linear(h_t[-1], self.w_oh, self.b_oh)
        output_list.append(output)
        h_t_minus_1 = h_t  # 更新隐藏状态
    
    # 转换回(batch_size, seq_len, output_dim)格式
    output_list = torch.stack(output_list).transpose(0, 1)
    return output_list

关键改动点

  1. 移除h_t = h_0的直接赋值,改为在每个时间步创建全新的h_t = torch.zeros_like(h_t_minus_1),避免内存共享。
  2. 修正了current_input赋值的语法错误(原代码if-else结构不完整)。
  3. 增加device=x.device参数,确保张量在同一设备上运行,避免潜在的设备不匹配问题。

内容的提问来源于stack exchange,提问作者Tuhin Subhra De

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 06:25:57