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,而非通过参数传入。这种写法会导致循环训练不同任务时,模型和优化器的状态混乱,一旦某次输入维度异常,就会报错。
修复建议
动态设置模型输入维度
修改模型定义,用参数接收输入特征数,避免硬编码: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)每次训练前重新初始化模型和优化器
在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) # ... 评估代码 ...修改训练循环,避免使用全局变量
更新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检查数据形状
在数据处理部分添加打印,确认每次循环中exo_spectra、X_train的形状是否符合预期:print(f"exo_spectra形状: {exo_spectra.shape}") print(f"X_train形状: {X_train.shape}")
内容的提问来源于stack exchange,提问作者Tessa
相关产品推荐
相关产品推荐

