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

PyTorch回归训练报错:矩阵形状不匹配且输入维度异常

问题描述

我用PyTorch对5个形状均为10×3361的数据集训练回归模型,运行时返回错误:

RuntimeError: mat1 and mat2 shapes cannot be multiplied (10x[some multiple of 1499, varying from dataset to dataset] and 3361x64)

我知道这是神经网络第一层维度不匹配导致的,但疑惑为什么数据集维度会变成1499的倍数且随数据集变化,明明所有数据集形状应该一致。

以下是相关代码:

神经网络模型定义

# define neural network model for regression
class Regression(nn.Module): 

  def __init__(self):
    super().__init__()
    self.layers = nn.Sequential(
      nn.Linear(3361, 64), 
      nn.ReLU(),
      nn.Linear(64, 32),
      nn.ReLU(),
      nn.Linear(32, 1)
    )

  def forward(self, x):
    '''
      Forward pass
    '''
    return self.layers(x)

训练循环

def training_loop(n_epochs, train_loader):
# training loop

    for epoch in range(n_epochs):

        # Set current loss value
        current_loss = 0.0
        # Iterate over the DataLoader for training data
        for i, data in enumerate(train_loader, 0):
          # Get and prepare inputs
          inputs, targets = data
          inputs, targets = inputs.float(), targets.float()
          targets = targets.reshape((targets.shape[0],1))
            # Zero the gradients
          optimizer.zero_grad()
          # Perform forward pass
          outputs = model(inputs)
          
          # Compute loss
          loss = loss_function(outputs, targets)
      
          # Perform backward pass
          loss.backward()
      
          # Perform optimization
          optimizer.step()
    return model

调用上下文

exo_file="exo_data_rp2500_set.csv"
exo_data=pd.read_csv(exo_file)
    
input_size = exo_data.shape[1]
batch_size = 10
model=Regression()
n_epochs=100
# loss function and optimizer
loss_function =nn.MSELoss()
# mean square error
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)

...
metrics=[#list of the nine categories of features I'm investigating]

for metric in metrics:
#split and format data
    exo_target=exo_metrics[metric]
    X_train, X_test, y_train, y_test = train_test_split(exo_spectra,exo_target, test_size=0.2, random_state=23) 
    X_train_tensor = torch.from_numpy(X_train)
    X_train_tensor = torch.tensor(X_train_tensor,dtype=torch.float32)
    y_train_tensor = torch.from_numpy(y_train.values)
    y_train_tensor = torch.tensor(y_train_tensor,dtype=torch.float32)
    X_test_tensor = torch.from_numpy(X_test)
    X_test_tensor = torch.tensor(X_test_tensor,dtype=torch.float32)
    y_test_tensor= torch.from_numpy(y_test.values)
    y_test_tensor = torch.tensor(y_test_tensor,dtype=torch.float32)
    # load data
    train_dataset = TensorDataset(X_train_tensor, y_train_tensor)
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) 
    # train data and assess accuracy
    model=training_loop(n_epochs,train_loader)
    y_pred = model(X_test_tensor)
    model_score=r2_score(y_test_tensor.detach().numpy(),y_pred.detach().numpy())
    scores.append(model_score)
错误原因分析

1. 模型输入维度硬编码,未匹配实际数据特征数

你的模型第一层nn.Linear(3361, 64)直接写死了输入特征数为3361,但实际训练时输入数据的特征数是1499的倍数,和模型期望的3361不匹配。你声称所有数据集都是10×3361,但实际可能存在以下问题:

  • 读取CSV时误读了额外列(比如索引列、冗余特征列),导致特征数变成1499的倍数;
  • 在代码省略的...部分处理exo_spectra时,错误修改了特征维度(比如合并特征、转置矩阵、误删列),使得特征数偏离3361。

2. 模型未在每次训练任务前重新初始化

你在metrics循环外只初始化了一次模型,后续训练不同metric时直接复用旧模型。如果某次循环中exo_spectra的特征数意外变化,就会触发维度不匹配的错误。即使所有数据集形状一致,这种复用模型的方式也会埋下隐患。

3. 全局变量滥用导致的逻辑混乱

训练循环training_loop直接使用了全局的model、optimizer和loss_function,而非通过参数传入。这种写法会导致循环训练不同任务时,模型和优化器的状态混乱,一旦某次输入维度异常,就会报错。

修复建议
  1. 动态设置模型输入维度
    修改模型定义,用参数接收输入特征数,避免硬编码:

    class Regression(nn.Module): 
      def __init__(self, input_size):
        super().__init__()
        self.layers = nn.Sequential(
          nn.Linear(input_size, 64), 
          nn.ReLU(),
          nn.Linear(64, 32),
          nn.ReLU(),
          nn.Linear(32, 1)
        )
      def forward(self, x):
        return self.layers(x)
    
  2. 每次训练前重新初始化模型和优化器
    在metrics循环内,根据当前数据的实际特征数初始化模型,并重新创建优化器:

    for metric in metrics:
        # ... 数据处理代码 ...
        # 获取当前训练数据的实际特征数
        current_input_size = X_train.shape[1]
        # 重新初始化模型
        model = Regression(current_input_size)
        # 重新初始化优化器
        optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
        # 训练模型(需修改training_loop接收参数)
        model = training_loop(n_epochs, train_loader, model, optimizer, loss_function)
        # ... 评估代码 ...
    
  3. 修改训练循环,避免使用全局变量
    更新training_loop函数,让它接收模型、优化器和损失函数作为参数:

    def training_loop(n_epochs, train_loader, model, optimizer, loss_function):
        for epoch in range(n_epochs):
            current_loss = 0.0
            for i, data in enumerate(train_loader, 0):
                inputs, targets = data
                inputs, targets = inputs.float(), targets.float()
                targets = targets.reshape((targets.shape[0],1))
                optimizer.zero_grad()
                outputs = model(inputs)
                loss = loss_function(outputs, targets)
                loss.backward()
                optimizer.step()
        return model
    
  4. 检查数据形状
    在数据处理部分添加打印,确认每次循环中exo_spectra、X_train的形状是否符合预期:

    print(f"exo_spectra形状: {exo_spectra.shape}")
    print(f"X_train形状: {X_train.shape}")
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 15:24:53