为什么numpy的keepdims参数会导致np.linalg.norm平方输出结果不同
问题解答
结论
该现象不属于bug,是IEEE754浮点数计算的固有特性,搭配NumPy内部性能优化的路径差异,产生的正常精度误差。
具体原因
浮点数累加的固有精度限制
示例代码用的float32类型只能保留约6~7位十进制有效数字,对100万个元素做累加操作时,累加顺序、中间结果的截断策略都会带来累积的舍入误差,当前观测到的误差远低于float32的精度上限,属于正常范围。keepdims参数触发了不同的底层计算分支
np.linalg.norm和它依赖的底层求和运算,会根据keepdims的取值切换不同的性能优化路径:keepdims=1时输出是带维度的数组,整个计算全程用float32类型做分块向量累加,每一步的中间结果都会截断到float32精度,最终得到的范数结果是float32类型,平方后也会保留float32的截断特性。keepdims=0时输出是0维标量,NumPy内部会优先用更高精度的CPU寄存器(比如64位浮点寄存器)存储累加中间结果,不会每一步都做float32截断,部分场景下还会隐式把中间结果提升为float64计算,最终得到的结果精度更高,和keepdims=1的结果存在微小差异。
移除
开平方运算会压缩数值的误差范围,两个路径产生的微小误差刚好落在**2后结果匹配的原因float32的最小精度台阶以内,所以观测不到差异;平方运算会把误差重新放大到可观测的量级,就会出现结果不一致的情况。本地与Colab结果差异的原因
不同CPU架构支持的向量指令集不同(比如AVX2、AVX512等),NumPy底层的分块求和策略会根据指令集调整块大小与累加顺序,由此带来的微小浮点误差属于正常现象,原理和keepdims导致的差异一致。
内容的提问来源于stack exchange,提问作者OverLordGoldDragon
相关产品推荐
相关产品推荐

