调用scipy.optimize.minimize时出现f0维度错误求助
解决scipy.optimize.minimize维度错误及逻辑回归梯度下降代码问题
问题根源
- ValueError:
f0passed has more than 1 dimension:损失函数r返回1维数组(np.array([f/n])),但scipy.optimize.minimize要求目标函数必须返回标量(单个数值)。 - 维度不匹配问题:梯度函数
gradr返回列向量(3x1),和输入的beta(1维数组)运算时会产生维度冲突;exactsearch返回二维数组,导致后续步长更新运算出错。 - TypeError: only size-1 arrays can be converted to Python scalars:
math.exp仅支持标量输入,而代码中np.dot(X[i],beta)会生成数组,必须用np.exp处理数组运算。
具体修改点
- 修正损失函数
r:将返回数组改为返回标量def r(beta): f=0 for i in range(n): f=f+ (1-y[i])* np.dot(X[i],beta) + np.log( 1+np.exp(-np.dot(X[i],beta) )) return f/n # 直接返回标量,而非数组 - 修正梯度函数
gradr:返回1维数组而非列向量def gradr(beta): f=0 for i in range(n): mu= h(np.dot(X[i],beta)) f=f+ (mu-y[i])*X[i] return f/n # 返回(3,)的1维数组,无需reshape成(3,1) - 修正精确搜索函数
exactsearch:返回标量步长而非数组def exactsearch(beta_0,d): phi_aux = lambda alfa : r(beta_0+ alfa*d) alfa_0=np.array([1]) bds=[(0,None)] res = minimize(phi_aux, alfa_0, bounds=bds) alfa = res.x.item() # 提取标量值 return alfa - 修正循环终止条件:避免浮点数直接相等,改用精度阈值判断
while True: if np.abs(r(beta) - r(beta+alfa*p)) < e: break # 用差值小于阈值替代直接相等 if N==10000:break if alfa<=e:break else: N=N+1 beta=beta+alfa*p p=-gradr(beta) alfa=f(beta,p)
修改后的完整代码
import numpy as np import scipy from scipy.optimize import minimize x1=[1,2,1] ; y1=0 x2=[1,1,2] ; y2=0 x3=[2,3,3] ; y3=1 x4=[2,2,1] ; y4=1 x5=[1,2,3] ; y5=0 x6=[1,3,1] ; y6=1 x7=[1,1,1] ; y7=0 x8=[1,2,2] ; y8=0 x9=[1,2,1] ; y9=0 x10=[1,1,1] ; y10=0 x11=[2,2,2] ; y11=1 x12=[1,2,2] ; y12=0 X= np.array([x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12]) y=np.array([y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12]) n=len(y) def h(x): return 1/(1+np.exp(-x)) def r(beta): f=0 for i in range(n): f=f+ (1-y[i])* np.dot(X[i],beta) + np.log( 1+np.exp(-np.dot(X[i],beta) )) return f/n #gradient of r def gradr(beta): f=0 for i in range(n): mu= h(np.dot(X[i],beta)) f=f+ (mu-y[i])*X[i] return f/n def exactsearch(beta_0,d): phi_aux = lambda alfa : r(beta_0+ alfa*d) alfa_0=np.array([1]) bds=[(0,None)] res = minimize(phi_aux, alfa_0, bounds=bds) alfa = res.x.item() return alfa def GradientMethod(beta,f): N=0 e=10**(-5) p=-gradr(beta) alfa=f(beta,p) while True: if np.abs(r(beta) - r(beta+alfa*p)) < e: break if N==10000:break if alfa<=e:break else: N=N+1 beta=beta+alfa*p p=-gradr(beta) alfa=f(beta,p) return [beta,r(beta),N] # 运行测试 result = GradientMethod(np.array([1,1,1]),exactsearch) print("优化后的beta:", result[0]) print("最终损失值:", result[1]) print("迭代次数:", result[2])
内容的提问来源于stack exchange,提问作者Samuel Adip Gonzalez Acharya
相关产品推荐
相关产品推荐

