PyTorch线性回归预测值为25而非预期32,是什么原因导致的?
问题原因分析
核心是你的模型结构和拟合目标不匹配,具体包含三个问题:
- 你期望拟合的是两个输入特征的乘法关系(x₁*x₂),但你使用的
nn.Linear(2,1)是纯线性变换,计算逻辑为w₁*x₁ + w₂*x₂ + bias,只有加法和缩放运算,天然不具备拟合乘法规则的能力。 - 你的输入样本存在完全共线性:所有训练样本的第二个特征都是第一个特征的2倍(x₂=2x₁),这会导致线性层的两个权重参数无法独立收敛,模型实际等价于在拟合单变量线性关系
y = k*x₁ + b。 - 你的标签Y本质是二次函数:结合x₂=2x₁的共线性特征,你期望的输出
y=x₁*x₂=2x₁²是关于x₁的二次函数,用线性模型拟合二次数据只能得到全局最优的线性近似,不可能完全拟合所有样本点,这也是你的损失最后卡在0.88左右无法继续下降的原因。
输出为25左右的原因
对你的三个训练样本做最优线性拟合,计算可得:
线性函数为y = 8x₁ - 6.6667,当x₁=4(对应你测试输入的[4,8])时,预测结果为8*4 - 6.6667≈25.33,和你代码输出的25.3124几乎完全吻合,属于线性模型拟合二次数据的正常结果。
修复方案
如果需要实现乘法拟合,可选择以下任意一种方案修改:
- 手动构造乘法特征:给输入增加x₁*x₂的特征维度,直接用线性层即可完美拟合
# 训练输入增加乘法特征 X = torch.FloatTensor([[1., 2., 1.*2.], [2., 4., 2.*4.], [3., 6., 3.*6.]]) # 测试输入同步增加乘法特征 XX = torch.FloatTensor([[4., 8., 4.*8.]]) # 线性层输入维度修改为3 self.l1 = nn.Linear(3, 1)
- 给模型增加非线性能力:加入隐藏层和非线性激活函数,让模型可以学习乘法规则
class TEST(nn.Module): def __init__(self): super(TEST,self).__init__() self.l1 = nn.Linear(2, 8) self.relu = nn.ReLU() self.l2 = nn.Linear(8, 1) def forward(self, input): x = self.relu(self.l1(input)) x = self.l2(x) return x
修改后可适当调大学习率(如改成0.01)、增加训练轮数,即可得到接近32的预测结果。
内容的提问来源于stack exchange,提问作者user1537041
相关产品推荐
相关产品推荐

