编写数值梯度函数时,Python for循环无法更新NumPy数组值
数值梯度函数中Numpy数组修改未生效的问题
你写的数值梯度函数里,循环内修改theta_upper和theta_lower后数组始终没变化,核心原因是Numpy数组的赋值是引用传递,不是创建副本。
问题根源
当你执行theta_upper = theta时,并没有生成新数组,只是让theta_upper指向原数组theta的内存地址。后续修改theta_upper[i]时,实际是直接修改了原数组theta;紧接着执行theta_lower[i] = theta[i] - e时,theta[i]已经被前一步改成了theta[i]+e,这一步相当于把值改回了初始值((theta[i]+e) - e = theta[i])。循环结束后原数组theta回到初始状态,返回的theta_upper和theta_lower自然和原数组一致。
解决方法
必须创建原数组的独立副本,才能在不修改原数组的前提下操作。可以用Numpy数组的.copy()方法,或者np.copy()函数:
修改后的测试代码
import numpy as np def target_gradient(theta): e = 10 for i in range(theta.shape[0]): # 创建副本,而非引用原数组 theta_upper = theta.copy() theta_lower = theta.copy() theta_upper[i] = theta[i] + e theta_lower[i] = theta[i] - e print(f"theta_upper {theta_upper}") print(f"theta_lower {theta_lower}") return theta_upper, theta_lower u, l = target_gradient(np.array([1, 1, 1, 1, 1]))
修改后的完整梯度函数
def target_gradient(theta, x, y): e = 0.01 gradient = np.zeros(theta.shape[0]) for i in range(theta.shape[0]): # 创建独立副本,避免修改原theta theta_upper = theta.copy() theta_lower = theta.copy() theta_upper[i] = theta[i] + e theta_lower[i] = theta[i] - e gradient[i] = ( foo(theta=theta_upper, x=x, y=y) - foo(theta=theta_lower, x=x, y=y) ) / (2 * e) return gradient
这样每次循环都会基于原数组theta的副本修改,不会相互干扰,也不会改变原数组的值,就能正确计算每个维度的数值偏导数了。
内容的提问来源于stack exchange,提问作者cc88
相关产品推荐
相关产品推荐

