eigen库里面vector或者matrix的sum函数的累加过程,是按照什么顺序累加的?

在调用tensorflow框架的某个算子接口的时候,发现接口的返回值与自己通过naive的c++或者numpy实现的结果不一样。追根溯源发现是这个算子计算过程中有一个累加的步骤,参与累加运算的数据(单精度浮点类型)如下附的代码中:

#include <iostream>
#include <eigen3/Eigen/Eigen>
int main() {
  Eigen::VectorXf v(10);
  v << 0.0, 2.33559305e-09, 4.00294277e-11, 1.03000897e-08, 5.31838147e-08, 1.12467995e-11, 1.0, 5.30462119e-09, 9.12710463e-11, 3.25927199e-14;
  std::cout.precision(15);
  std::cout << "eigen sum result:" << std::endl << v.sum() << std::endl;

  float result = 0.0;
  std::cout << "sum in order: " << std::endl;
  for (int i = 0; i < v.size(); i++) {
    result += v(i);
    std::cout << "step " << i << ": " << result << std::endl;
  }
  return 0;
}

测试发现将这些数据逐个按顺序累加的结果与直接调用eigen中的vector中的sum方法的结果会有微小区别:前者的结果比1.0大一些,后者的结果为1.0:

eigen sum result:
1
sum in order: 
step 0: 0
step 1: 2.33559305229392e-09
step 2: 2.37562258753599e-09
step 3: 1.26757120355592e-08
step 4: 6.58595240565774e-08
step 5: 6.58707719480844e-08
step 6: 1.00000011920929
step 7: 1.00000011920929
step 8: 1.00000011920929
step 9: 1.00000011920929

初步定位是累加顺序不一致导致这种现象,因为累加过程中会引入数据舍入误差,顺序不同会导致最终结果不同。故有了这个提问,后续按照 @赵智源 给出的解答的方法对这组数据进行验证,结果与eigen的结果一致。DL领域中涉及到数据累加的问题,不同的软件框架、硬件架构可能会有不同的实现,导致同一组输入的累加结果不能保持bit级一致,在合理的范围内应该都是可以接受的。但如果仅仅是从数据的来说,累加步骤中引入的微小误差会导致最终计算的结果天差地别。例如上述这组数据不同的累加结果,乍一看相差极小,但如果将这个累加结果先做 l o g log log 计算,再乘以 i n f inf inf ,根据 IEEE754的标准:
l o g ( 1 ) ∗ i n f = n a n log(1)∗inf=nan log(1)inf=nan
l o g ( 1.00000011920929 ) ∗ i n f = i n f log(1.00000011920929)∗inf=inf log(1.00000011920929)inf=inf
一个仍为无穷大,一个却成了非数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值