固定步长梯度下降优化三峰驼函数时循环停止条件报错求助
固定步长梯度下降法停止条件错误修复
错误原因
你遇到的TypeError是因为代码里写了e.all<tolerance:
e.all是numpy数组的内置方法(不是属性),直接拿方法对象和浮点数比较,Python自然不支持这种操作。- 同时这个逻辑也不符合停止条件的需求——我们需要判断新旧点的差值是否足够小,而不是检查方法对象。
正确的停止条件写法
通常有两种合理的停止判断方式,选其一即可:
- 计算新旧点的欧氏距离:用
np.linalg.norm(e)计算差值向量的L2范数,判断是否小于容差 - 检查所有分量的绝对值:用
np.all(np.abs(e) < tolerance)判断每个维度的差值绝对值都小于容差
额外的代码优化点
- 原代码中
k=kp1是列表直接赋值,会导致后续迭代中k和kp1指向同一内存地址,建议改成k = kp1.copy()或者全程用numpy数组处理 - 原函数最后返回空列表,建议返回最终优化得到的点,方便后续使用
修正后的完整代码
import numdifftools as nd import numpy as np # 固定步长梯度下降法 def gradient(k): def eq(x): # 三峰驼函数 return 2*(x[0]**2) - 1.05*(x[0]**4) + (x[0]**6)/6 + x[0]*x[1] + x[1]**2 grad = nd.Gradient(eq)(k) return grad def gdcss(initial_value, step_size, iterations): k = np.array(initial_value) # 直接转numpy数组,避免列表引用问题 tolerance = 1e-6 # 容差提前定义,不用每次循环重复创建 for i in range(iterations): grad = gradient(k) kp1 = k - step_size * grad # 直接用numpy数组运算,更简洁 print("迭代次数: ", i+1) print("当前点梯度: ", grad) print("新点坐标: ", kp1) e = kp1 - k # 方式1:判断欧氏距离小于容差 if np.linalg.norm(e) < tolerance: print(f"达到容差要求,提前停止迭代,共迭代{i+1}次") break # 方式2:判断所有分量差值绝对值小于容差(二选一即可) # if np.all(np.abs(e) < tolerance): # print(f"达到容差要求,提前停止迭代,共迭代{i+1}次") # break k = kp1 return k # 返回最终优化点 # 调用函数 result = gdcss([-1, 2], 0.1, 70) print("最终优化结果:", result)
代码说明
- 全程用numpy数组处理坐标和梯度,运算更简洁,也避免了列表引用的问题
- 容
tolerance提前定义,减少循环内的重复操作 - 增加了停止时的提示信息,方便查看迭代情况
- 返回最终的优化点,让函数更实用
内容的提问来源于stack exchange,提问作者Roha Gul
相关产品推荐
相关产品推荐

