使用BFGS方法实现逻辑回归时的维度错误问题
解决BFGS实现逻辑回归的维度错误问题
嘿,我之前在吴恩达机器学习课程的数据集上用BFGS做逻辑回归时,也碰到过一模一样的维度错误问题!TNC能正常跑是因为它对输入维度的兼容度更高,而BFGS对参数、梯度的维度一致性要求特别严格,大概率是以下几个地方出了问题:
1. 参数θ的形状不匹配(一维 vs 二维)
scipy的minimize函数里,BFGS算法默认要求输入的初始参数θ是一维数组(比如形状为(n,)),而不是我们在吴恩达课程里习惯用的二维列向量(n,1)。如果你的θ是二维的,就算梯度计算正确,BFGS也会抛出维度错误。
举个正确的初始化和目标函数写法:
import numpy as np from scipy.optimize import minimize # 假设X已经添加了偏置项,形状为(m, n),y形状为(m, 1) m, n = X.shape initial_θ = np.zeros(n) # 一维数组,长度为特征数(含偏置) def sigmoid(z): return 1 / (1 + np.exp(-z)) def cost_and_grad(θ): # 先把一维θ转成列向量用于矩阵计算 θ = θ.reshape(n, 1) h = sigmoid(X @ θ) # 计算损失(转成标量返回) cost = -1/m * (y.T @ np.log(h) + (1 - y).T @ np.log(1 - h)) # 计算梯度,最后转成一维数组返回 grad = (1/m) * X.T @ (h - y) return cost.flatten()[0], grad.flatten() # 调用BFGS result = minimize(cost_and_grad, initial_θ, method='BFGS', jac=True)
2. 梯度输出的维度不符合要求
如果你设置了jac=True(手动提供梯度),BFGS要求梯度的形状必须和初始θ完全一致——也就是一维数组。很多人会犯的错误是:梯度计算出来是二维列向量,直接返回给BFGS,这就会触发维度错误。
像上面的代码里,我把计算好的二维梯度用grad.flatten()转成了一维数组,这一步是关键。而TNC可能会自动处理这种维度转换,所以不会报错。
3. 数据集的偏置项遗漏
检查你的特征矩阵X有没有添加偏置项(第一列全为1)。如果没加,θ的维度会比X的特征数少1,导致X @ θ的矩阵乘法维度不匹配。BFGS对这种错误会直接报错,而TNC可能有一定的容错机制。
添加偏置项的正确代码:
# 给X添加偏置项(假设原X形状为(m, n-1)) X = np.hstack((np.ones((m, 1)), X))
快速排查步骤
- 打印初始θ的形状:确认是
(n,)而不是(n,1) - 打印梯度函数返回的梯度形状:确认和初始θ形状一致
- 验证
X @ θ和y的维度是否匹配:确保两者都是(m,1)(当θ转成列向量时)
我当时就是因为把θ初始成了二维列向量,梯度也没转成一维,导致BFGS报错,调整后就和TNC一样正常运行了。
内容的提问来源于stack exchange,提问作者Dima Zhavoronkov
相关产品推荐
相关产品推荐

