为什么这两个numpy运算不等效?如何修正实现等效向量化计算?
问题解答
差异产生的原因
问题核心是求和维度不匹配,加上exp是非线性函数,运算顺序直接决定最终结果:
- 首先看数组运算的基础:
W是长度为3的一维数组,X是2行3列的二维数组,W * X触发广播后得到2行3列的结果数组。 - 无
exp的场景下,不管是先按行求和再相加,还是直接对整个数组求和,加法的交换律和结合律保证了结果一致,所以两个写法等效。 - 加
exp的场景下:- 循环版本
sum_a的运算逻辑是:对X的每一行先计算和W的乘积和,得到两个独立的标量,分别对这两个标量求exp,最后把两个exp的结果相加,也就是exp(第一行乘积和) + exp(第二行乘积和)。 - 你原来写的
sum_b的运算逻辑是:先对W * X的所有6个元素求和得到总标量,再对这个总标量求exp,也就是exp(所有元素的总和)。
因为exp是非线性函数,不满足exp(a + b) = exp(a) + exp(b),所以两个结果差异极大。
- 循环版本
等效向量化修改方案
只需要给np.sum指定axis=1参数,指定求和维度为行维度,就能和循环逻辑对齐:
sum_b = np.sum(np.exp(np.sum(W * X, axis=1)))
这个写法里,np.sum(W * X, axis=1)会直接返回每行的乘积和组成的一维数组,再对数组里的每个元素求exp,最后对所有exp结果求和,和循环逻辑完全一致,同时是纯numpy向量化实现,适合大规模计算场景。
内容的提问来源于stack exchange,提问作者GratefulDeadpool
相关产品推荐
相关产品推荐

