数值梯度计算结果异常:为何输出[25000 35000]而非预期值?
数值梯度计算结果异常的原因与修复方案
你得到[25000 35000]这种异常结果的核心原因是输入的numpy数组为整数类型,导致在执行微小扰动计算时,浮点数被自动截断为整数,完全偏离了数值微分的预期逻辑。
具体分析
当你传入np.array([3,4])时,这个数组的默认类型是int64(整数类型):
- 执行
x[idx] = tmp_val + h时,3 + 1e-4 = 3.0001会被截断为整数3 - 执行
x[idx] = tmp_val - h时,3 - 1e-4 = 2.9999会被截断为整数2
此时计算fxh1 - fxh2的结果是(3²+4²) - (2²+4²) = 25 - 20 = 5,再除以2*h(即0.0002)就得到5/0.0002 = 25000,这正是你看到的异常输出。
修复方案
有两种简单的修复方式:
方案1:调用时传入浮点类型数组
直接在创建数组时指定浮点类型:
grd1 = numerical_gradient(function_2, np.array([3,4], dtype=np.float64)) print(grd1) # 输出 [6.00000001 8.00000001]
方案2:函数内部强制转换为浮点类型
在numerical_gradient函数开头添加类型转换,确保计算过程中使用浮点数:
def numerical_gradient(f, x): x = x.astype(np.float64) # 强制转换为浮点类型,避免截断 h = 1e-4 grad = np.zeros_like(x) for idx in range(x.size): tmp_val = x[idx] # f(x + h) x[idx] = tmp_val + h fxh1 = f(x) # f(x - h) x[idx] = tmp_val - h fxh2 = f(x) grad[idx] = (fxh1 - fxh2) / (2 * h) x[idx] = tmp_val return grad
验证结果
修改后重新运行代码,会得到符合预期的结果:[6.00000001 8.00000001],和理论梯度[6,8]几乎一致。
内容的提问来源于stack exchange,提问作者열두시
相关产品推荐
相关产品推荐

