PyTorch训练回归模型时矩阵形状不匹配异常问题求助
首先,咱们直接抓核心:这个RuntimeError本质是输入模型的特征张量维度和第一层全连接层的输入维度不匹配,而你看到的“1499的倍数”其实是你实际传入模型的特征数,和你以为的3361对不上。具体来说,有几个大概率的原因:
1. 模型输入维度硬编码,没适配实际数据集
你定义Regression类时,第一层nn.Linear(3361, 64)是写死的3361,但你明明计算了input_size = exo_data.shape[1]却没用到它!这就导致:
- 如果
exo_data包含了目标列(target),那exo_spectra作为特征矩阵的列数应该是input_size - 1,自然和3361不匹配; - 更可能的是,你构建
exo_spectra时误选了特征,实际特征数是1499的倍数(比如选了多组1499维的特征类别),和硬编码的3361完全对不上。
2. 数据集的维度顺序搞反了
标准的机器学习数据集格式是(样本数, 特征数),如果你的exo_spectra是反过来的(特征数, 样本数),那train_test_split拆分后得到的X_train形状会是(特征数, 训练样本数)。此时DataLoader取batch_size=10时,会得到形状为(10, 特征数)的张量——这里的“特征数”其实是原数据的样本数,刚好是1499的倍数,就会触发错误。
3. 循环训练时模型没重新初始化(次要但添乱)
你在for metric in metrics外面只初始化了一次模型,之后每次训练都复用旧模型的参数状态。虽然这不会直接导致形状错误,但如果某次训练出问题导致模型参数异常,后续循环会继承这个状态,让问题更难排查。
针对性解决方案
方案1:让模型动态适配输入维度
把Regression类改成可接收输入维度参数的形式,别再硬编码3361:
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): ''' Forward pass ''' return self.layers(x)
然后在每个metric循环里重新初始化模型和优化器(很重要,不然会污染训练):
for metric in metrics: # ... 你的数据拆分代码 ... # 获取实际特征数 input_size = X_train.shape[1] # 重新初始化模型和优化器 model = Regression(input_size) optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) # ... 后续训练代码 ...
方案2:确认数据集维度正确
在数据拆分前加几行打印,检查核心形状:
print(f"exo_spectra shape: {exo_spectra.shape}") print(f"X_train shape: {X_train.shape}")
如果exo_spectra的形状是(特征数, 样本数),用转置修正:
exo_spectra = exo_spectra.T
方案3:检查特征选择逻辑
确认你构建exo_spectra时,确实只选了3361个特征列,没有误选多组1499维的特征(比如重复选择了某些特征类别)。
内容的提问来源于stack exchange,提问作者Tessa

