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

Python实现梯度下降函数:损失函数与权重更新异常排查

梯度下降函数实现错误排查

错误根因

两处核心逻辑错误直接对应两条报错:

  • 损失函数实现错误:你写的损失公式既不是逻辑回归要求的交叉熵损失,计算全程没有用到sigmoid输出的预测值h,属于公式套用错误,自然输出不对。
  • 权重更新逻辑错误:误差项误用了线性输出z和标签y的差值,逻辑回归的梯度计算需要用sigmoid激活后的预测值h和标签y的差值作为误差项,误差项错了梯度计算结果完全不对,theta自然无法收敛到正确值。

你看到的cost持续下降是假象:错误的损失计算刚好和真实损失的大趋势一致,数值会持续走低,但根本不是练习要求统计的损失值,永远达不到收敛阈值。

修正点说明

  1. 把误差项从z - y改成h - y,匹配逻辑回归的梯度计算要求
  2. 替换交叉熵损失公式为逻辑回归标准形式:J = (-1/m) * np.sum(y * np.log(h) + (1-y)*np.log(1-h))
  3. 注意梯度计算的维度匹配:x.T和误差项点乘后除以样本数m得到平均梯度,更新theta时直接乘学习率alpha即可,不要重复除以m
  4. 取样本数m推荐用x.shape[0],比len(x)对numpy矩阵的兼容性更好

修正后可运行代码

import numpy as np

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def gradientDescent(x, y, theta, alpha, num_iters):
    """
    Input:
        x: 特征矩阵,维度(m,n+1)
        y: 对应标签,维度(m,1)
        theta: 权重向量,维度(n+1,1)
        alpha: 学习率
        num_iters: 训练迭代次数
    Output:
        J: 最终损失值
        theta: 训练完成的权重向量
    """
    m = x.shape[0]
    J = 0

    for i in range(num_iters):
        z = np.dot(x, theta)
        h = sigmoid(z)
        # 计算预测误差
        loss = h - y
        
        # 计算交叉熵损失
        J = (-1/m) * np.sum(y * np.log(h) + (1 - y) * np.log(1 - h))
        print(f"Iteration {i} | Cost: {J:.6f}")
        
        # 计算平均梯度
        gradient = np.dot(x.T, loss) / m
        # 更新权重
        theta = theta - alpha * gradient

    J = float(J)
    return J, theta

额外提示

如果跑的时候出现log计算的nan警告,可以在算log的时候给h加一个极小值epsilon,比如np.log(h + 1e-8)、np.log(1 - h + 1e-8),避免预测值完全为0或1时对数计算无意义,练习场景下不加也能跑通。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:51:18