PyTorch训练遇RuntimeError:张量维度不匹配问题求助
PyTorch回归模型训练报错排查
问题描述
我是PyTorch新手,无法找出代码中的问题。以下是我的代码:
x_np, y_np = datasets.make_regression(n_samples=100,n_features=1,noise=20,random_state=0) x = torch.from_numpy(x_np.astype(np.float32)) y = torch.from_numpy(y_np.astype(np.float32)) y = y.view(y.shape[0],1) n_samples, n_features = x.shape class Regression(nn.Module): def __init__(self, inputsize, outputsize, hiddensize): super(Regression, self).__init__() self.hidden_size = hiddensize self.input_size = inputsize self.output_size = outputsize self.i2h = nn.Linear(self.input_size+self.hidden_size, self.hidden_size) self.h2o = nn.Linear(self.input_size+self.hidden_size, self.output_size) def forward(self, x): hidden = torch.zeros(1, self.hidden_size) print(x.shape) print(hidden.shape) combined = torch.cat((x,hidden), 1) hidden = self.i2h(combined) output = self.h2o(combined) return output model = Regression(n_features, n_features, 16) lr = 0.01 loss = nn.MSELoss() opt = torch.optim.SGD(model.parameters(), lr = lr) for epoch in range(1000): ypred = model(x) l = loss(y, ypred) l.backward() opt.step() opt.zero_grad() if epoch % 100 == 0: [w, b] = model.parameters() print(f'epoch {epoch+1}: w = {w[0][0].item():.3f}, loss = {l:.8f}')
训练过程中出现如下错误:
RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 100 but got size 1 for tensor number 1 in the list
错误原因及修正
核心错误:张量维度不匹配
报错出现在torch.cat((x,hidden), 1)这一行:
- 输入
x的维度是(100, 1)(100个样本,每个样本1个特征) - 初始化的
hidden维度是(1, 16)(仅1个样本的隐藏层状态) - 拼接时要求除了拼接维度(这里是dim=1)外,其他维度的大小必须一致,但两者的第0维(样本数)一个是100,一个是1,完全不匹配,导致报错。
修正方案1:让隐藏层状态匹配输入的样本数
将forward方法中的hidden初始化代码改成:
hidden = torch.zeros(x.shape[0], self.hidden_size)
这样hidden的维度变为(100,16),和x的(100,1)在dim=1拼接后得到(100,17),可以正常输入到后续的线性层中。
更合理的修正方案:改用标准全连接回归结构
从代码来看,你可能想实现一个带隐藏层的全连接回归模型,但当前的输入+隐藏拼接的结构并不合理(且每次都重置隐藏层为0,没有利用序列信息,不像循环网络)。推荐改用标准的两层全连接结构:
class Regression(nn.Module): def __init__(self, inputsize, outputsize, hiddensize): super(Regression, self).__init__() self.fc1 = nn.Linear(inputsize, hiddensize) # 输入到隐藏层 self.fc2 = nn.Linear(hiddensize, outputsize) # 隐藏层到输出层 def forward(self, x): hidden = torch.relu(self.fc1(x)) # 加入激活函数增强模型表达能力 output = self.fc2(hidden) return output
这个结构既不会有维度问题,也符合常规回归模型的设计,训练效果会更稳定。
额外注意点
- 模型初始化时,第二个参数是输出维度,你的
y是(100,1),所以应该传入1,当前代码中Regression(n_features, n_features, 16)因为n_features=1,所以是对的,但建议显式传入1更清晰:model = Regression(n_features, 1, 16) - 提取参数时
[w, b] = model.parameters()在标准全连接结构中会报错(因为有4个参数:fc1的w和b,fc2的w和b),可以改成遍历打印或者只打印关键参数。
内容的提问来源于stack exchange,提问作者catch_fish99
相关产品推荐
相关产品推荐

