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

PyTorch多层Simple RNN序列预测遇输入维度错误求助

问题排查:Simple RNN输入维度不匹配错误

错误核心原因

报错RuntimeError: input.size(-1) must be equal to input_size. Expected 8, got 1的本质是RNN输入维度参数设置混淆:

  • 你的数据是单特征时序,每个时间步的特征数为1,窗口长度(序列长度)为8。但你初始化模型时将input_sz设为8,把序列长度当成了每个时间步的特征维度,导致输入张量最后一维(特征数1)和RNN期望的输入维度8不匹配。

其他需修正的问题

  • Forward函数返回值错误:当前返回所有时间步的RNN输出和隐藏状态,但我们只需要最后一个时间步的输出用于预测下一个值,多余的返回值会导致训练时维度不匹配。
  • 隐藏状态设备不匹配:初始化的hidden张量未同步到输入所在设备(CPU/GPU),会引发设备不一致错误。
  • Eval代码缩进错误:continue语句会跳过后续评估逻辑,需调整缩进确保代码执行。
  • 目标张量维度冗余:Y无需额外添加维度,保持(batch_size, 1)即可匹配预测值维度。

修正后的完整代码

import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as data
import numpy as np

# 滑动窗口构建的训练集
X = np.array( [ [0.40, 0.82, 0.14, 0.01, 0.98, 0.53, 2.5, 0.49], 
                [0.82, 0.14, 0.01, 0.98, 0.53, 2.5, 0.49, 0.53], 
                [0.14, 0.01, 0.98, 0.53, 2.5, 0.49, 0.53, 3.37] ], dtype=np.float32)
Y = np.array([[0.53], [3.37], [0.49]], dtype=np.float32)

class RNNModel(nn.Module):
    def __init__(self, input_sz, n_layers):
        super(RNNModel, self).__init__()
        self.hidden_dim = 3 * input_sz
        self.n_layers = n_layers
        self.output_sz = 1
        # input_sz为每个时间步的特征数(单特征设为1),batch_first=True对应输入形状(batch_size, seq_len, input_sz)
        self.rnn = nn.RNN(input_sz, self.hidden_dim, num_layers=n_layers, batch_first=True)
        self.linear = nn.Linear(self.hidden_dim, self.output_sz)

    def forward(self, x):
        batch_sz = x.size(0)
        # 初始化隐藏状态并同步到输入所在设备
        hidden = torch.zeros(self.n_layers, batch_sz, self.hidden_dim).to(x.device)
        out, hidden = self.rnn(x, hidden)
        # 取最后一个时间步的输出用于预测
        out = out[:, -1, :]
        # 全连接层输出预测值
        out = self.linear(out)
        return out

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# input_sz改为1,对应单特征时序
model = RNNModel(1, 2).to(device)
# X添加特征维度,形状变为(batch_size, seq_len, input_sz)=(3,8,1)
X = torch.tensor(X[:, :, np.newaxis]).to(device)
# Y保持(batch_size, 1)维度即可
Y = torch.tensor(Y).to(device)

optimizer = optim.Adam(model.parameters())
loss_fn = nn.MSELoss()

loader = data.DataLoader(data.TensorDataset(X, Y), shuffle=False, batch_size=3)

n_epoch = 10
for epoch in range(n_epoch):
    model.train()
    total_loss = 0.0
    for X_batch, Y_batch in loader:
        Y_pred = model(X_batch)
        loss = loss_fn(Y_pred, Y_batch)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        total_loss += loss.item()

    # 调整条件与缩进,确保评估代码正常执行
    if epoch % 10 == 0:
        model.eval()
        with torch.no_grad():
            Y_pred = model(X)
            train_rmse = np.sqrt(loss_fn(Y_pred, Y).item())
        print(f"Epoch {epoch}: train RMSE {train_rmse:.4f}")

关键修正点说明

  1. RNN输入维度修正:将RNNModel(8,2)改为RNNModel(1,2),匹配单特征时序的每个时间步特征数。
  2. Forward函数优化:
    • 隐藏状态初始化时添加.to(x.device),确保与输入设备一致。
    • 提取最后一个时间步的输出out[:, -1, :],用于预测下一个时序值。
    • 移除多余的隐藏状态返回,直接输出预测值。
  3. Eval逻辑修复:调整条件判断与缩进,让评估代码能正常触发执行。
  4. 目标张量简化:Y不再添加冗余维度,保证与预测值维度匹配。

内容的提问来源于stack exchange,提问作者Shew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:05:34