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

梯度下降代码中列表append重复插入同一元素的原因排查

问题分析与解决思路

你遇到的问题本质是可变对象的引用传递导致的——当你把x追加到X列表时,并没有保存x当前的数值副本,而是保存了指向x这个对象的引用。之后每次循环里修改x的值时,列表X里所有指向x的引用都会同步更新,最终导致所有元素都变成最后一次迭代的x值。

具体原因拆解

你的代码里,初始x = [1,1]是一个列表,后续循环中x -= alpha * J会直接原地修改这个列表(如果J是numpy数组,执行减法后x会被隐式转换为numpy数组,但依然是可变对象)。X.append(x)只是把这个可变对象的"地址"存在了列表里,而非当前的数值快照。

解决办法:保存x的副本而非引用

只需要在追加到X时,创建x的副本即可,具体有两种方式:

方式1:如果x是列表,使用list.copy()方法

X.append(x.copy())

方式2:如果x被转换为numpy数组,使用np.copy()或.copy()方法

X.append(np.copy(x))
# 或者
X.append(x.copy())

修改后的完整代码示例

import numpy as np

C = np.array([10 ** ((i-1)/(2-1)) for i in range(2)])
C = C * np.identity(2)
x = np.array([1, 1])  # 建议直接初始化为numpy数组,避免隐式转换
J = (C.T + C) @ x
theta = 1e-5
alpha = 0.1
X = []

while np.linalg.norm(alpha * J, ord=2) >= theta:  # 这里sum可以去掉,norm本身就是标量
    J = (C.T + C) @ x
    x -= alpha * J
    X.append(x.copy())  # 关键:保存副本
    print("x = ", x)
    print("X[i] = ", np.array(X))

验证效果

修改后,X里的每个元素都会是对应迭代步骤的x值,不会再全部同步为最新值。比如第一次迭代后X是[[0.98 0.8 ]],第二次迭代后会变成[[0.98 0.8 ], [0.9604 0.64 ]],以此类推。

另外提个小优化:你的循环条件里np.sum(np.linalg.norm(...))是多余的,因为np.linalg.norm返回的已经是标量,直接用np.linalg.norm(alpha * J, ord=2) >= theta即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 00:07:43