【问题标题】:Different results in Matlab and Python for matrix multiplication and exponentiationMatlab 和 Python 中用于矩阵乘法和求幂的不同结果
【发布时间】:2019-07-03 13:50:06
【问题描述】:

从 Matlab 迁移到 Python 时,我得到了不同的矩阵乘法和求幂结果。

这是一个简单的 softmax 分类器实现。我运行 Python 代码,将变量导出为 mat 文件,然后运行原始 Matlab 代码,加载从 Python 导出的变量,并进行比较。

Python 代码:

f = np.array([[4714, 4735, 4697], [4749, 4748, 4709]])
f = f.astype(np.float64)
a = np.array([[0.001, 0.001, 0.001], [0.001, 0.001, 0.001], [0.001, 0.001, 0.001]])

reg = f.dot(a)
omega = np.exp(reg)
sumomega = np.sum(omega, axis=1)

io.savemat('python_variables.mat', {'p_f': f,
                                    'p_a': a,
                                    'p_reg': reg,
                                    'p_omega': omega,
                                    'p_sumomega': sumomega})

Matlab 代码:

f = [4714, 4735, 4697; 4749, 4748, 4709];
a = [0.001, 0.001, 0.001; 0.001, 0.001, 0.001; 0.001, 0.001, 0.001];

reg = f*a;
omega = exp(reg);
sumomega = sum(omega, 2);
load('python_variables.mat');

我通过检查以下内容来比较结果:

norm(f - p_f) = 0
norm(a - p_a) = 0
norm(reg - p_reg) = 3.0767e-15
norm(omega - p_omega) = 4.0327e-09
norm(omega - exp(p_f*p_a)) = 0

所以差异似乎是由乘法引起的,并且使用 exp() 会变得更大。而我的原始数据矩阵比这个大。我得到了更大的 omega 值:

norm(reg - p_reg) = 7.0642e-12
norm(omega - p_omega) = 1.2167e+250

这也导致在某些情况下 sumomega 在 Python 中变为 inf 或零,但在 Matlab 中却没有,因此分类器输出不同。

我在这里缺少什么?我怎样才能得到完全相同的结果?

【问题讨论】:

  • 顺便说一句,在您的真实代码中,a 元素是否完全相同?
  • @Brenlla 是的。在 Matlab 和 Python 代码中它们是相同的。这是softmax分类器的参数矩阵,0.001s是初始值。我使用数值优化迭代更新它们。
  • 对我来说,这实际上表明,您的结果可能会因浮点精度而有很大差异,这意味着您可能应该重新考虑您的算法

标签: python matlab numpy


【解决方案1】:

对我来说,差异看起来像是数值精度。对于浮点运算,运算顺序很重要。重新排序操作时,您会得到(略微)不同的结果,因为舍入发生的方式不同。

Python 和 MATLAB 实现矩阵乘法的方式可能略有不同,因此您不应期望得到完全相同的结果。

如果您需要将 e 提高到该乘法结果的幂,您将产生一个更不精确的结果。这正是浮点运算的本质。

这里的问题不是您在 MATLAB 和 Python 中没有得到完全相同的结果,而是两者都产生不精确的结果,而且您​​不知道自己得到的精度是多少。


已知 softmax 函数会溢出。解决方案是从所有输入值中减去最大输入值。有关详细信息,请参阅this other question

【讨论】:

  • 我期待看到一些差异,因为浮点表示不精确,但 1e+250 不是一个巨大的差异吗?也许通过将 omega 除以 sumomega 进行归一化会减少差异,并且两个平台最终会给出相同的分类结果,但我不确定它们是否会。
  • @groove:exp 函数会产生巨大的价值。我不确定你为什么使用它。但是这些巨大的值,如果它们相差很小的一部分,仍然会有巨大的绝对差异。你确定你需要exp吗?你从哪里得到这个操作的?我从来没有在分类中看到过这样的事情。
  • 这是softmax函数。 exp(x_i * a_k) / sum_{j=1}^K exp(x_i * a_j) 给出了数据点 x_i 来自第 k 个类别的概率。
  • @groove:查看我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
  • 1970-01-01
  • 2020-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多