Matlab梯度下降代码正常运行,Python循环段报错求排查
Python梯度下降循环段Bug排查与修正
错误点分析
- 矩阵运算顺序与运算符错误:
- Matlab中
A*xk - b是先做矩阵乘法再减b,Python代码错误写成np.matmul(A,xk - b),颠倒了运算顺序,正确应为np.matmul(A, xk) - b。 - 计算梯度时误用
*元素级乘法,而非矩阵乘法,需替换为np.matmul或@运算符。
- Matlab中
- 列表赋值错误:
gradErr是空列表,直接通过gradErr[k]索引赋值会触发IndexError,需用append()方法添加元素。 - 数组索引语法错误:Python中numpy数组索引用
[]而非Matlab的(),比如x_old(1)应改为x_old[0,0](取第一个元素)、x_old[1,0](取第二个元素)。 - 浅拷贝问题:
x_old = xk是引用赋值,修改xk时x_old会同步变化,需用x_old = xk.copy()做深拷贝。 - 绘图上下文问题:原代码未关联到之前的等高线画布,导致迭代路径无法叠加显示,需在同一个figure对象上绘制。
修正后的完整Python代码
等高线绘图(保留画布对象)
import numpy as np import matplotlib.pyplot as plt # 生成网格数据 x1, x2 = np.meshgrid(np.arange(-30, 30.5, 0.5), np.arange(-30, 30.5, 0.5)) F = (x1 - 2) ** 2 + 2 * (x2 - 3) ** 2 # 绘制等高线并保留画布,开启交互模式 fig, ax = plt.subplots() ax.contour(x1, x2, F, 20) plt.ion() plt.show()
矩阵与向量初始化
A = np.array([[1, 0], [0, 2]]) AT = np.transpose(A) b = np.array([[4], [12]]) Nit = 100 tol = 1e-05 lr = 0.2 xk = np.array([[-10], [-10]]) noIterations = 1 gradErr = []
修正后的梯度下降循环
for k in range(Nit): x_old = xk.copy() # 深拷贝保存当前迭代值 # 修正矩阵运算逻辑,与Matlab保持一致 gradient = np.matmul(AT, np.matmul(A, xk) - b) xk = xk - lr * gradient # 计算梯度误差并添加到列表 current_err = np.linalg.norm(np.matmul(AT, np.matmul(A, xk) - b), 'fro') gradErr.append(current_err) if current_err < tol: break # 绘制迭代路径,正确使用numpy数组索引 ax.plot([x_old[0, 0], xk[0, 0]], [x_old[1, 0], xk[1, 0]], 'ko-') plt.pause(0.1) # 暂停观察路径绘制 noIterations += 1 plt.ioff() plt.show()
关键修正说明
- 矩阵运算:调整运算顺序为
np.matmul(A, xk) - b,确保和Matlab逻辑完全对齐,矩阵乘法统一使用np.matmul保证运算正确性。 - 列表操作:用
append()替代索引赋值,避免空列表索引错误。 - 数组索引:针对形状为(2,1)的列向量,使用
[行索引, 列索引]的方式取值,符合Python语法规范。 - 深拷贝:通过
copy()方法避免引用传递导致的x_old值被篡改。 - 绘图优化:开启交互模式,在同一个等高线画布上叠加绘制迭代路径,实现动态展示效果。
内容的提问来源于stack exchange,提问作者Elfs
相关产品推荐
相关产品推荐

