python - Matlab 和 Python 中用于矩阵乘法和求幂的不同结果
问题描述
从 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() 会变得更大。而我的原始数据矩阵比这个大。我得到更大的欧米茄值:
norm(reg - p_reg) = 7.0642e-12
norm(omega - p_omega) = 1.2167e+250
这也导致在某些情况下 sumomega 在 Python 中变为 inf 或零,但在 Matlab 中则不然,因此分类器输出不同。
我在这里想念什么?如何修复以获得完全相同的结果?
解决方案
对我来说,差异看起来像是数值精度。对于浮点运算,运算顺序很重要。重新排序操作时,您会得到(略微)不同的结果,因为舍入发生的方式不同。
Python 和 MATLAB 实现矩阵乘法的方式可能略有不同,因此您不应期望得到完全相同的结果。
如果您需要将e提高到此乘法结果的幂,您将产生一个不精确程度更高的结果。这正是浮点运算的本质。
这里的问题不是您在 MATLAB 和 Python 中没有得到完全相同的结果,而是两者都产生了不精确的结果,并且您不知道您获得的精度是多少。
已知 softmax 函数会溢出。解决方案是从所有输入值中减去最大输入值。有关更多详细信息,请参阅其他问题。
推荐阅读
- c# - 尝试使用 C# 在 Windows 注册表中设置 DWORD 值时出错
- operating-system - automating a chain of shell commands with os.popen Python and 'sudo' is not recognized
- javascript - VSCode colours are changing
- javascript - Javascript将多行缓冲区的条码扫描仪输出转换为数组或json
- mongodb - DocumentDb Compound Query really slow for Date
- r - Applying lm() using sapply or lapply
- php - .htaccess mod_rewrite on multiple PHP files issue
- java - JBPM 7 生成的 XML 中的递归节点
- python - 在 MacOS 上使用 PyInstaller 加载 Python 库时出错
- javascript - 无法从 webpackAsyncContext 读取未定义的属性“调用”(Webpack 错误)