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

Logistic Regression中y_data一维与二维输入的结果差异原因探究

Logistic Regression中y_data一维/二维输入导致损失停滞的原因

我是AI专业学生,编写了一段基于PyTorch的Logistic Regression代码:

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

torch.manual_seed(1)

x_data = [[10.0], [20.0], [30.0], [40.0], [50.0], [60.0], [70.0], [80.0], [90.0], [100.0]]
y_data = [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0]
x_train = torch.FloatTensor(x_data)
y_train = torch.FloatTensor(y_data)

W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)

optimizer = optim.SGD([W, b], lr=0.01)

num_epochs = 10000
for epoch in range(num_epochs + 1):

    eps = 1e-7

    hypothesis = 1 / (1 + torch.exp(-(x_train.matmul(W) + b)))
    loss = -(y_train * torch.log(torch.clamp(hypothesis, eps, 1-eps)) + (1 - y_train) * torch.log(torch.clamp(1 - hypothesis, eps, 1-eps))).mean()

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print('Epoch {:4d}/{} Loss: {:.6f}'.format(
            epoch, num_epochs, loss.item()
        ))

hypothesis = torch.sigmoid(x_train.matmul(W) + b)
print(hypothesis)

当y_data是一维数组时代码运行正常,但改成二维数组(y_data = [[0.0], [0.0], [0.0], [0.0], [0.0], [1.0], [1.0], [1.0], [1.0], [1.0]])后,损失值一直停滞在0.693147,无法下降。


问题根源:张量维度不匹配引发的广播错误

核心问题是**y_train和hypothesis的维度不匹配,导致PyTorch广播机制错误地扩展张量,最终让参数更新的梯度被抵消**:

  1. 维度变化拆解:
    • x_train是(10,1)的二维张量,W是(1,)的一维张量,两者做matmul后得到(10,)的一维张量(每个样本的计算结果为标量),加b后hypothesis的维度仍为(10,)。
    • 当y_data为一维时,y_train是(10,),和hypothesis维度完全匹配,元素相乘后得到(10,)的张量,损失计算和梯度更新都正常。
    • 当y_data改为二维时,y_train变成(10,1),和hypothesis的(10,)维度不匹配。PyTorch会触发广播机制:把hypothesis扩展成(1,10),y_train扩展成(10,10),两者相乘后得到(10,10)的张量。
  2. 对损失的影响:
    原本应该是每个样本的标签对应自身预测值计算损失,现在变成每个样本的标签和所有样本的预测值相乘,取平均后得到的损失梯度是这些错误乘积的均值,直接抵消了有效的更新信号,导致W和b一直停留在初始的0值,损失也就固定在初始的log(2)≈0.6931(初始预测全为0.5,交叉熵损失为-(0.5*log0.5 + 0.5*log0.5)=log2)。

两种解决方法

方法1:调整权重W的维度,让hypothesis和y_train维度匹配

把W的定义改为二维张量,这样x_train.matmul(W)会得到(10,1)的结果,和y_train的(10,1)维度一致:

W = torch.zeros((1,1), requires_grad=True)

方法2:将二维的y_train压缩成一维

通过squeeze()方法去掉y_train中多余的维度,保持和hypothesis的(10,)一致:

y_train = torch.FloatTensor(y_data).squeeze()

也可以在损失计算时临时对齐维度,比如把hypothesis扩展成二维:

hypothesis = hypothesis.unsqueeze(1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:47:50