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

PyTorch时间序列建模报错:AssertionError: 张量尺寸不匹配

问题:PyTorch时间序列建模中TensorDataset尺寸不匹配错误

问题背景

我是PyTorch新手,正在尝试用它建模时间序列数据。我有两个列表x和y:x中的每个元素包含29个时间步与4个特征,对应的y元素是第30个时间步的4列数据。创建Tensor数据集时出现以下错误:

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Input In [35], in <cell line: 2>()
      1 # Step 2: Concatenate 'x' and 'y' tensors properly
----> 2 train_dataset = TensorDataset(*x_train_tensors, *y_train_tensors)
      3 valid_dataset = TensorDataset(*x_valid_tensors, *y_valid_tensors)
      5 # Step 3: Create DataLoader for training and validation sets

File ~\anaconda3\lib\site-packages\torch\utils\data\dataset.py:192, in TensorDataset.__init__(self, *tensors)
    191 def __init__(self, *tensors: Tensor) -> None:
--> 192     assert all(tensors[0].size(0) == tensor.size(0) for tensor in tensors), "Size mismatch between tensors"
    193     self.tensors = tensors

AssertionError: Size mismatch between tensors

参考代码(报错区域已标记)

import pickle
import numpy as np
import pandas as pd

with open('lists_data.pkl', 'rb') as file:
    x, y = pickle.load(file)

from sklearn.preprocessing import MinMaxScaler
# 创建空列表存储归一化后的数据
norm_x = []
norm_y = []

scaler = MinMaxScaler()

# 使用zip遍历x和y中对应的DataFrame
for temp_x, temp_y in zip(x, y):
    temp = pd.concat([temp_x, temp_y])
    norm_temp = pd.DataFrame(scaler.fit_transform(temp), columns=temp.columns)
    norm_x.append(norm_temp.iloc[:-1])  # 将除最后一行外的所有行添加到norm_x
    norm_y.append(norm_temp.iloc[[-1]])  # 将最后一行添加到norm_y

from sklearn.model_selection import train_test_split
# 将x和y转换为numpy数组以便操作
x_array = np.array(norm_x)
y_array = np.array(norm_y)

# 设置随机种子以保证可复现性
random_seed = 42

# 将x和y划分为训练集(70%)、验证集(15%)和测试集(15%)
x_train, x_temp, y_train, y_temp = train_test_split(x_array, y_array, test_size=0.3, random_state=random_seed)
x_valid, x_test, y_valid, y_test = train_test_split(x_temp, y_temp, test_size=0.5, random_state=random_seed)

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

x_train_tensors = [torch.tensor(x, dtype=torch.float32) for x in x_train]
x_valid_tensors = [torch.tensor(x, dtype=torch.float32) for x in x_valid]
x_test_tensors = [torch.tensor(x, dtype=torch.float32) for x in x_test]

y_train_tensors = [torch.tensor(y, dtype=torch.float32) for y in y_train]
y_valid_tensors = [torch.tensor(y, dtype=torch.float32) for y in y_valid]
y_test_tensors = [torch.tensor(y, dtype=torch.float32) for y in y_test]

class RNNModel(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(RNNModel, self).__init__()
        self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        out, _ = self.rnn(x)
        out = self.fc(out[:, -1, :])
        return out

# Error block
batch_size = 64
train_dataset = TensorDataset(*x_train_tensors, *y_train_tensors)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

valid_dataset = TensorDataset(*x_valid_tensors, *y_valid_tensors)
valid_loader = DataLoader(valid_dataset, batch_size=batch_size)

问题原因

你错误地将每个样本的张量单独传入TensorDataset,而TensorDataset的设计逻辑是:传入的每个张量代表一个数据维度(比如特征、标签),且所有张量的第一维度(样本数)必须一致。你把所有样本张量展开传入,导致第一个张量的第一维度是29(时间步),后续张量的第一维度却是1(单个标签样本),自然触发尺寸不匹配的断言错误。

修复方案

1. 合并样本张量

将每个样本的小张量合并成一个大张量,维度符合模型输入要求:

  • 特征张量:形状为 [样本数, 时间步数, 特征数],即(N,29,4)
  • 标签张量:形状为 [样本数, 特征数],即(N,4)(需要去掉y中多余的(1,4)维度)

2. 修正数据集创建代码

把合并后的特征张量和标签张量传入TensorDataset,而不是展开单个样本。

修改后的报错区域代码如下:

# 合并训练集张量
x_train_tensor = torch.stack(x_train_tensors)  # 形状: [N, 29, 4]
y_train_tensor = torch.cat(y_train_tensors).squeeze(1)  # 形状: [N, 4]

# 合并验证集张量
x_valid_tensor = torch.stack(x_valid_tensors)
y_valid_tensor = torch.cat(y_valid_tensors).squeeze(1)

# 创建数据集和DataLoader
batch_size = 64
train_dataset = TensorDataset(x_train_tensor, y_train_tensor)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

valid_dataset = TensorDataset(x_valid_tensor, y_valid_tensor)
valid_loader = DataLoader(valid_dataset, batch_size=batch_size)

额外优化建议

其实你可以直接从numpy数组转换为张量,跳过逐个转换再合并的步骤,更高效:

# 直接从numpy数组转张量,无需逐个转换列表
x_train_tensor = torch.tensor(x_train, dtype=torch.float32)  # x_train是numpy数组,形状[N,29,4]
y_train_tensor = torch.tensor(y_train, dtype=torch.float32).squeeze(1)  # y_train形状[N,1,4],squeeze后变为[N,4]

x_valid_tensor = torch.tensor(x_valid, dtype=torch.float32)
y_valid_tensor = torch.tensor(y_valid, dtype=torch.float32).squeeze(1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:04:59