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

Python实现Logistic Regression遇问题:梯度下降异常与scipy.opt报错

Andrew Ng机器学习课程Logistic Regression实现问题解答

一、梯度下降参数更新异常解惑

手动实现梯度下降法更新参数时,不同学习率(alpha)下成本变化表现异常:

  • alpha=0.0001、迭代400000次:成本曲线缓慢下降,最终分类结果可接受
  • alpha=0.01、迭代200000次:成本曲线出现震荡波动,但最终分类结果依然达标

异常原因分析

  1. alpha=0.0001的情况:学习率过小,参数更新步长不足,需要极多次迭代才能逐步收敛到成本函数最小值附近,因此成本曲线下降缓慢,但整体趋势正确,最终能得到合理结果。
  2. alpha=0.01的情况:学习率偏大,每次参数更新步长超过最优下降方向,导致在最小值区域来回震荡。不过梯度下降的特性决定了即使震荡,参数也会在最小值范围内波动,因此最终结果仍可接受。

建议:尝试学习率衰减策略(如每次迭代后alpha乘以0.99),或测试多个alpha值(比如0.001),选择既能快速收敛又无过度震荡的学习率。

二、scipy.opt函数调用维度不匹配问题解决

问题代码

import numpy as np
from scipy import opt

m,n=data.shape 
X=data[:,0:n-1]
y=data[:,-1:]
theta=np.array([[0] for i in range(n)],dtype=np.float64)
print(X.shape,y.shape,theta.shape)

# OUT:(100, 2) (100, 1) (3, 1)

X=np.concatenate((np.array([[1] for i in range(m)]),X),axis=1)

def sigmoid(z):
    return 1/(1+np.exp(-z))
def h(X,theta):
    return sigmoid(X@theta)
def calculate_cost(X,y,theta):
    first=-y.T @ np.log(h(X,theta)+1e-5)  
    second=(1-y).T@np.log(1-h(X,theta)+1e-5)   
    return 1/m*(first-second)[0][0]
def gradient(X,y,theta):
    return  1/m*(X.T@(h(X,theta)-y)).T

result = opt.fmin_tnc(func=calculate_cost, x0=theta, fprime=gradient, args=(X, y))

报错信息

Cell In[5], line 4, in h(X, theta)
      3 def h(X,theta):
----> 4     return sigmoid(X@theta)

ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 100 is different from 3)

问题根源

scipy.optimize.fmin_tnc会将输入的x0(即theta)自动转换为一维数组,但你的代码中theta初始是(3,1)的二维数组。函数调用时theta被转为(3,)的一维数组,此时X((100,3))与theta的矩阵乘法维度不匹配,导致报错。

解决方案

修改函数以兼容一维theta,同时调整维度匹配逻辑:

修正后的代码

import numpy as np
from scipy import optimize as opt

m,n=data.shape 
X=data[:,0:n-1]
y=data[:,-1:]
# 初始theta设为一维数组,或在函数内转换维度
theta=np.zeros(n, dtype=np.float64)
print(X.shape,y.shape,theta.shape)

# OUT:(100, 2) (100, 1) (3,)

X=np.concatenate((np.ones((m,1)),X),axis=1)

def sigmoid(z):
    return 1/(1+np.exp(-z))
def h(X,theta):
    # 将theta转为二维列向量,确保矩阵乘法维度匹配
    theta = theta.reshape(-1,1)
    return sigmoid(X@theta)
def calculate_cost(X,y,theta):
    theta = theta.reshape(-1,1)
    h_val = h(X,theta)
    first=-y.T @ np.log(h_val+1e-5)  
    second=(1-y).T@np.log(1-h_val+1e-5)   
    return 1/m*(first-second)[0][0]
def gradient(X,y,theta):
    theta = theta.reshape(-1,1)
    grad = 1/m*(X.T@(h(X,theta)-y))
    # 将梯度转为一维数组,符合fmin_tnc的输出要求
    return grad.flatten()

result = opt.fmin_tnc(func=calculate_cost, x0=theta, fprime=gradient, args=(X, y))

关键修改点

  1. theta初始形状:将theta初始化为一维数组np.zeros(n, dtype=np.float64),减少后续转换步骤;
  2. 函数内维度兼容:在h、calculate_cost、gradient函数中,先将theta转为二维列向量,确保X@theta的维度匹配(X(100,3) × theta(3,1) = (100,1));
  3. 梯度格式适配:gradient函数返回一维数组,用grad.flatten()将二维梯度转为一维,满足fmin_tnc的输入要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:05:33