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

手动用For循环实现逻辑回归SGD是否正确?附绘图疑问

逻辑回归SGD实现问题解答

问题1:lambda_min是否为损失值?

你的lambda_min设计意图是记录迭代过程中最小的损失值,但代码存在两处错误导致它无法正确反映真实损失:

  1. 变量名lambda是Python关键字,不能用作变量名,建议改为loss;
  2. 损失函数计算错误:公式中(1+yy)应为(1-yy),否则逻辑完全颠倒,且你用了全局张量x而非当前batch的xx,导致维度不匹配、计算结果错误。

修正后,lambda_min(建议重命名为min_loss)可以作为迭代过程中出现的最小损失值,但它不是当前batch的实时损失,只是一个记录用的变量。

问题2:参数更新方式是否正确?

完全错误,核心问题如下:

  • 没有计算损失对参数的梯度:SGD需要的是损失的梯度∇λ,而非损失值本身;
  • 参数更新时直接赋值w2 = w1 - ...会破坏PyTorch的梯度追踪机制,导致后续无法计算梯度;
  • 未清空梯度:每次反向传播后梯度会累积,必须手动清空;
  • 损失函数符号错误:负对数似然损失需要取负才能作为最小化目标(原公式的求和结果为负数,取负后转为正数,符合损失越小越好的直观逻辑)。

修正后的核心代码片段

import torch

# 数据准备(修正split后的变量名,保留原始数据用于后续绘图)
some_data = torch.rand(1000, 2)
x = some_data[:, 0]
y = (x + 0.4 * some_data[:, 1] > 0.5).to(torch.int)
x_batches = torch.split(x, 3)
y_batches = torch.split(y, 3)

# 初始化参数,保留梯度追踪
w1 = torch.autograd.Variable(torch.tensor([0.1]), requires_grad=True)
w2 = torch.autograd.Variable(torch.tensor([0.1]), requires_grad=True)
alpha = 0.01  # 学习率
min_loss = float('inf')  # 初始化为无穷大,记录最小损失

for epoch in range(10):
    total_loss = 0.0
    for xx, yy in zip(x_batches, y_batches):
        # 使用当前batch的xx计算预测概率
        p_x = 1 / (1 + torch.exp(-w1 - w2 * xx))
        # 修正负对数似然损失计算
        loss = -torch.sum(yy.float() * torch.log(p_x) + (1 - yy.float()) * torch.log(1 - p_x))
        
        # 反向传播计算梯度
        loss.backward()
        
        # 在无梯度上下文更新参数,避免破坏梯度追踪
        with torch.no_grad():
            w1 -= alpha * w1.grad
            w2 -= alpha * w2.grad
            # 清空梯度,避免累积
            w1.grad.zero_()
            w2.grad.zero_()
        
        total_loss += loss.item()
        # 更新最小损失记录
        if loss.item() < min_loss:
            min_loss = loss.item()
    
    print(f"Epoch {epoch+1}, Average Loss: {total_loss/len(x_batches):.4f}, Min Loss: {min_loss:.4f}")

问题3:绘制包含0/1样本点的逻辑回归曲线

使用matplotlib即可实现,需要将PyTorch张量转换为NumPy数组,步骤如下:

import matplotlib.pyplot as plt

# 获取原始数据的NumPy格式
x_np = x.numpy()
y_np = y.numpy()

# 生成用于绘制曲线的x值范围(覆盖数据分布区间)
x_plot = torch.linspace(0, 1, 100)
# 用训练好的参数计算对应的预测概率
with torch.no_grad():
    p_plot = 1 / (1 + torch.exp(-w1 - w2 * x_plot))

# 转换为NumPy数组用于绘图
x_plot_np = x_plot.numpy()
p_plot_np = p_plot.numpy()

# 绘制样本点(区分0/1类)
plt.scatter(x_np[y_np == 0], y_np[y_np == 0], label='类别0', alpha=0.5, s=10)
plt.scatter(x_np[y_np == 1], y_np[y_np == 1], label='类别1', alpha=0.5, s=10)
# 绘制逻辑回归拟合曲线
plt.plot(x_plot_np, p_plot_np, 'r-', label='逻辑回归拟合')

plt.xlabel('x')
plt.ylabel('预测概率p(x)')
plt.legend()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:42:54