函数计算与人工计算的区别
Computation difference between function and manual computation
我现在正面临一个谜。我在某些程序中得到了奇怪的结果,我认为这可能与计算有关,因为与手动计算相比,我的函数得到了不同的结果。
这是我的程序,我正在打印预先计算的值:
print("\nPrecomputation:\nmatrix\n:", matrix)
tmp = likelihood_left * likelihood_right
print("\nconditional_dep:", tmp)
print("\nfinal result:", matrix @ tmp)
我得到以下输出:
Precomputation:
matrix:
[array([0.08078721, 0.5802404 , 0.16957052, 0.09629893, 0.07310294])
array([0.14633129, 0.45458744, 0.20096238, 0.02142105, 0.17669784])
array([0.41198731, 0.06197812, 0.05934063, 0.23325626, 0.23343768])
array([0.15686545, 0.29516415, 0.20095091, 0.14720275, 0.19981674])
array([0.15965914, 0.18383683, 0.10606946, 0.14234812, 0.40808645])]
conditional_dep: [0.01391123 0.01388155 0.17221067 0.02675524 0.01033257]
final result: [0.07995043 0.03485223 0.02184015 0.04721548 0.05323298]
问题是当我计算以下代码时:
matrix = [np.array([0.08078721, 0.5802404 , 0.16957052, 0.09629893, 0.07310294]),
np.array([0.14633129, 0.45458744, 0.20096238, 0.02142105, 0.17669784]),
np.array([0.41198731, 0.06197812, 0.05934063, 0.23325626, 0.23343768]),
np.array([0.15686545, 0.29516415, 0.20095091, 0.14720275, 0.19981674]),
np.array([0.15965914, 0.18383683, 0.10606946, 0.14234812, 0.40808645])]
tmp = np.asarray([0.01391123, 0.01388155, 0.17221067, 0.02675524, 0.01033257])
matrix @ tmp
使用的值与之前计算中的值完全相同,但我得到以下结果:
array([0.04171218, 0.04535276, 0.02546353, 0.04688848, 0.03106443])
这个结果明显不同于上一个,是真实的(我手工计算了点积)。
我整天都在面对这个问题,我在网上没有找到任何有用的东西。如果你们中的任何人有任何一点点想法,我会很高兴 :D
提前致谢
雅恩
PS:如果需要,我可以展示更多代码。
PS2: 不知道有没有关系,但是这个在动态规划算法中用到了
看起来您在矩阵乘法之一中切换了操作数。
使用您提供的 matrix
和 tmp
的相同值,matrix @ tmp
和 tmp @ matrix
提供您显示的两个结果。1
matrix = [np.array([0.08078721, 0.5802404 , 0.16957052, 0.09629893, 0.07310294]),
np.array([0.14633129, 0.45458744, 0.20096238, 0.02142105, 0.17669784]),
np.array([0.41198731, 0.06197812, 0.05934063, 0.23325626, 0.23343768]),
np.array([0.15686545, 0.29516415, 0.20095091, 0.14720275, 0.19981674]),
np.array([0.15965914, 0.18383683, 0.10606946, 0.14234812, 0.40808645])]
tmp = np.asarray([0.01391123, 0.01388155, 0.17221067, 0.02675524, 0.01033257])
print(matrix @ tmp) # [0.04171218 0.04535276 0.02546353 0.04688848 0.03106443]
print(tmp @ matrix) # [0.07995043 0.03485222 0.02184015 0.04721548 0.05323298]
为了让您的代码在做什么更加明显,您还可以考虑使用 np.dot
而不是 @
。如果您将 matrix
作为第一个参数传递,将 tmp
作为第二个参数传递,它将得到您想要的结果,并更清楚地表明您是在概念上计算点积而不是矩阵相乘。
另外请注意,如果您要对 matrix
执行矩阵运算,最好是单个二维数组而不是一维数组列表。如果您尝试 运行 matrix @ matrix
,这将防止您现在看到的那种错误。如果你愿意,这也可以让你说 matrix.dot(tmp)
而不是 np.dot(matrix, tmp)
。
(我猜你可以使用 np.stack
或类似的函数来创建 matrix
,或者你可以在创建后在 matrix
上调用 np.stack
。 )
1 因为 tmp
只有一维而 matrix
有两个,NumPy 可以并将 tmp
视为任何一种向量使乘法工作(使用 broadcasting)。因此 tmp
在 matrix @ tmp
中被视为列向量,在 tmp @ matrix
中被视为行向量。
回顾一下我们在评论中的讨论,在第一部分 ("pre-computation") 中,以下关于 matrix
对象的说法是正确的:
>>> matrix.shape
(5,)
>>> matrix.dtype
dtype('O') # aka object
正如您所说,这是因为 matrix
是更大的非均匀数组的一部分。让我们重现这种情况:
>>> matrix = np.array([[], np.array([0.08078721, 0.5802404 , 0.16957052, 0.09629893, 0.07310294]), np.array([0.14633129, 0.45458744, 0.20096238, 0.02142105, 0.17669784]), np.array([0.41198731, 0.06197812, 0.05934063, 0.23325626, 0.23343768]), np.array([0.15686545, 0.29516415, 0.20095091, 0.14720275, 0.19981674]), np.array([0.15965914, 0.18383683, 0.10606946, 0.14234812, 0.40808645])])[1:]
它现在不再是行列标量矩阵,而是列向量的列向量。从技术上讲,matrix @ tmp
是两个一维数组之间的运算,因此 NumPy 应该根据 documentation 计算两者的内积。在这种情况下是这样,约定总和在第一个轴上:
>>> np.array([matrix[i] * tmp[i] for i in range(5)]).sum(axis=0)
array([0.07995043, 0.03485222, 0.02184015, 0.04721548, 0.05323298])
>>> matrix @ tmp
array([0.07995043, 0.03485222, 0.02184015, 0.04721548, 0.05323298])
这与在乘法之前对适当的二维矩阵进行转置基本相同:
>>> np.stack(matrix).T @ tmp
array([0.07995043, 0.03485222, 0.02184015, 0.04721548, 0.05323298])
等同于@jirasssimok 指出的:
>>> tmp @ np.stack(matrix)
array([0.07995043, 0.03485222, 0.02184015, 0.04721548, 0.05323298])
因此出现错误或意外的结果。
正如您在评论中已经解决的那样,将来可以通过确保所有矩阵都是正确的二维数组来避免这种情况。
我现在正面临一个谜。我在某些程序中得到了奇怪的结果,我认为这可能与计算有关,因为与手动计算相比,我的函数得到了不同的结果。
这是我的程序,我正在打印预先计算的值:
print("\nPrecomputation:\nmatrix\n:", matrix)
tmp = likelihood_left * likelihood_right
print("\nconditional_dep:", tmp)
print("\nfinal result:", matrix @ tmp)
我得到以下输出:
Precomputation:
matrix:
[array([0.08078721, 0.5802404 , 0.16957052, 0.09629893, 0.07310294])
array([0.14633129, 0.45458744, 0.20096238, 0.02142105, 0.17669784])
array([0.41198731, 0.06197812, 0.05934063, 0.23325626, 0.23343768])
array([0.15686545, 0.29516415, 0.20095091, 0.14720275, 0.19981674])
array([0.15965914, 0.18383683, 0.10606946, 0.14234812, 0.40808645])]
conditional_dep: [0.01391123 0.01388155 0.17221067 0.02675524 0.01033257]
final result: [0.07995043 0.03485223 0.02184015 0.04721548 0.05323298]
问题是当我计算以下代码时:
matrix = [np.array([0.08078721, 0.5802404 , 0.16957052, 0.09629893, 0.07310294]),
np.array([0.14633129, 0.45458744, 0.20096238, 0.02142105, 0.17669784]),
np.array([0.41198731, 0.06197812, 0.05934063, 0.23325626, 0.23343768]),
np.array([0.15686545, 0.29516415, 0.20095091, 0.14720275, 0.19981674]),
np.array([0.15965914, 0.18383683, 0.10606946, 0.14234812, 0.40808645])]
tmp = np.asarray([0.01391123, 0.01388155, 0.17221067, 0.02675524, 0.01033257])
matrix @ tmp
使用的值与之前计算中的值完全相同,但我得到以下结果:
array([0.04171218, 0.04535276, 0.02546353, 0.04688848, 0.03106443])
这个结果明显不同于上一个,是真实的(我手工计算了点积)。
我整天都在面对这个问题,我在网上没有找到任何有用的东西。如果你们中的任何人有任何一点点想法,我会很高兴 :D
提前致谢 雅恩
PS:如果需要,我可以展示更多代码。 PS2: 不知道有没有关系,但是这个在动态规划算法中用到了
看起来您在矩阵乘法之一中切换了操作数。
使用您提供的 matrix
和 tmp
的相同值,matrix @ tmp
和 tmp @ matrix
提供您显示的两个结果。1
matrix = [np.array([0.08078721, 0.5802404 , 0.16957052, 0.09629893, 0.07310294]),
np.array([0.14633129, 0.45458744, 0.20096238, 0.02142105, 0.17669784]),
np.array([0.41198731, 0.06197812, 0.05934063, 0.23325626, 0.23343768]),
np.array([0.15686545, 0.29516415, 0.20095091, 0.14720275, 0.19981674]),
np.array([0.15965914, 0.18383683, 0.10606946, 0.14234812, 0.40808645])]
tmp = np.asarray([0.01391123, 0.01388155, 0.17221067, 0.02675524, 0.01033257])
print(matrix @ tmp) # [0.04171218 0.04535276 0.02546353 0.04688848 0.03106443]
print(tmp @ matrix) # [0.07995043 0.03485222 0.02184015 0.04721548 0.05323298]
为了让您的代码在做什么更加明显,您还可以考虑使用 np.dot
而不是 @
。如果您将 matrix
作为第一个参数传递,将 tmp
作为第二个参数传递,它将得到您想要的结果,并更清楚地表明您是在概念上计算点积而不是矩阵相乘。
另外请注意,如果您要对 matrix
执行矩阵运算,最好是单个二维数组而不是一维数组列表。如果您尝试 运行 matrix @ matrix
,这将防止您现在看到的那种错误。如果你愿意,这也可以让你说 matrix.dot(tmp)
而不是 np.dot(matrix, tmp)
。
(我猜你可以使用 np.stack
或类似的函数来创建 matrix
,或者你可以在创建后在 matrix
上调用 np.stack
。 )
1 因为 tmp
只有一维而 matrix
有两个,NumPy 可以并将 tmp
视为任何一种向量使乘法工作(使用 broadcasting)。因此 tmp
在 matrix @ tmp
中被视为列向量,在 tmp @ matrix
中被视为行向量。
回顾一下我们在评论中的讨论,在第一部分 ("pre-computation") 中,以下关于 matrix
对象的说法是正确的:
>>> matrix.shape
(5,)
>>> matrix.dtype
dtype('O') # aka object
正如您所说,这是因为 matrix
是更大的非均匀数组的一部分。让我们重现这种情况:
>>> matrix = np.array([[], np.array([0.08078721, 0.5802404 , 0.16957052, 0.09629893, 0.07310294]), np.array([0.14633129, 0.45458744, 0.20096238, 0.02142105, 0.17669784]), np.array([0.41198731, 0.06197812, 0.05934063, 0.23325626, 0.23343768]), np.array([0.15686545, 0.29516415, 0.20095091, 0.14720275, 0.19981674]), np.array([0.15965914, 0.18383683, 0.10606946, 0.14234812, 0.40808645])])[1:]
它现在不再是行列标量矩阵,而是列向量的列向量。从技术上讲,matrix @ tmp
是两个一维数组之间的运算,因此 NumPy 应该根据 documentation 计算两者的内积。在这种情况下是这样,约定总和在第一个轴上:
>>> np.array([matrix[i] * tmp[i] for i in range(5)]).sum(axis=0)
array([0.07995043, 0.03485222, 0.02184015, 0.04721548, 0.05323298])
>>> matrix @ tmp
array([0.07995043, 0.03485222, 0.02184015, 0.04721548, 0.05323298])
这与在乘法之前对适当的二维矩阵进行转置基本相同:
>>> np.stack(matrix).T @ tmp
array([0.07995043, 0.03485222, 0.02184015, 0.04721548, 0.05323298])
等同于@jirasssimok 指出的:
>>> tmp @ np.stack(matrix)
array([0.07995043, 0.03485222, 0.02184015, 0.04721548, 0.05323298])
因此出现错误或意外的结果。
正如您在评论中已经解决的那样,将来可以通过确保所有矩阵都是正确的二维数组来避免这种情况。