【问题标题】:numpy - matrix multiple 3x3 and 100x100x3 arrays?numpy - 矩阵多个 3x3 和 100x100x3 数组?
【发布时间】:2018-05-18 17:03:52
【问题描述】:

我有以下几点:

import numpy as np

XYZ_to_sRGB_mat_D50 = np.asarray([
    [3.1338561, -1.6168667, -0.4906146],
    [-0.9787684, 1.9161415, 0.0334540],
    [0.0719453, -0.2289914, 1.4052427],
])

XYZ_1 = np.asarray([0.25, 0.4, 0.1])
XYZ_2 = np.random.rand(100,100,3)

np.matmul(XYZ_to_sRGB_mat_D50, XYZ_1) # valid operation
np.matmul(XYZ_to_sRGB_mat_D50, XYZ_2) # makes no sense mathematically

如何在 XYZ_2 上执行与在 XYZ_2 上相同的操作?我是否先以某种方式重塑数组?

【问题讨论】:

    标签: python numpy matrix-multiplication


    【解决方案1】:

    你可能只是想要这个:

    XYZ_2.dot(XYZ_to_sRGB_mat_D50.T)
    

    np.matmul(XYZ_to_sRGB_mat_D50, XYZ_1) 等价于XYZ_1.dot(XYZ_to_sRGB_mat_D50.T),然后您可以简单地将操作广播到 100 x 100 x 3 矩阵。

    【讨论】:

      【解决方案2】:

      您似乎正在尝试sum-reduce XYZ_to_sRGB_mat_D50 (axis=1) 的最后一个轴与XYZ_2 (axis=2) 的最后一个轴。所以,你可以像这样使用np.tensordot -

      np.tensordot(XYZ_2, XYZ_to_sRGB_mat_D50, axes=((2),(1)))
      

      Related post to understand tensordot.


      为了完整起见,在交换XYZ_2 的最后两个轴之后,我们当然也可以使用np.matmul,就像这样 -

      np.matmul(XYZ_to_sRGB_mat_D50, XYZ_2.swapaxes(1,2)).swapaxes(1,2)
      

      这不会像tensordot 那样高效。


      运行时测试-

      In [158]: XYZ_to_sRGB_mat_D50 = np.asarray([
           ...:     [3.1338561, -1.6168667, -0.4906146],
           ...:     [-0.9787684, 1.9161415, 0.0334540],
           ...:     [0.0719453, -0.2289914, 1.4052427],
           ...: ])
           ...: 
           ...: XYZ_1 = np.asarray([0.25, 0.4, 0.1])
           ...: XYZ_2 = np.random.rand(100,100,3)
      
      # @Julien's soln
      In [159]: %timeit XYZ_2.dot(XYZ_to_sRGB_mat_D50.T)
      1000 loops, best of 3: 450 µs per loop
      
      In [160]: %timeit np.tensordot(XYZ_2, XYZ_to_sRGB_mat_D50, axes=((2),(1)))
      10000 loops, best of 3: 73.1 µs per loop
      

      一般来说,当涉及到张量上的sum-reductions 时,tensordot 的效率要高得多。由于sum-reduction的轴只有一个,我们可以通过reshape将张量变成2D数组,使用np.dot,得到结果并reshape回3D

      【讨论】:

      • 谢谢——这个答案非常好。有趣的是,张量点在这里用转置击败了常规点,速度方面。
      • @BrandonDube 我的理解是,对于张量,dot 在某个级别(很可能在 C 级别)循环,而 tensordot 避免它。
      • 哇!不知道!关于为什么改变形状可以使速度提高 10 倍的任何见解?这似乎没有任何意义......
      • @Julien 你的意思是为什么带有 reshape step 的点:XYZ_2.reshape(-1,3)...XYZ_2.dot(XYZ_to_sRGB_mat_D50.T) 快?因为,使用重构的 2D 版本,np.dot 没有循环。
      • @Julien np.dot 利用 BLAS 而不是实际循环。因此,对于这种情况,如果不进行整形,它会进行 100 次 BLAS 调用,而使用 2D 整形版本只需进行一次 BLAS 调用。 tensordot 可能会重塑为 2D(可能在 C 级别),然后利用一个 BLAS 调用。100 个 BLAS 调用会带来缓慢,这是我的理解。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 2019-10-08
      • 2017-03-17
      • 1970-01-01
      相关资源
      最近更新 更多