当前位置: 首页 > 面试题库 >

块元素逐点积

瞿宏儒
2023-03-14
问题内容

是否有一种优雅,麻木的方式逐点应用点积?或者如何将以下代码转换为更好的版本?

m0 # shape (5, 3, 2, 2)
m1 # shape (5,    2, 2)
r = np.empty((5, 3, 2, 2))
for i in range(5):
    for j in range(3):
        r[i, j] = np.dot(m0[i, j], m1[i])

提前致谢!


问题答案:

方法1

使用np.einsum-

np.einsum('ijkl,ilm->ijkm',m0,m1)

涉及的步骤:

  • 保持输入的第一个轴对齐。

  • 在减少总和中使最后一个轴相m0对于第二个轴丢失m1

  • 让其余的轴以外积方式从元素展开m0m1 展开 /扩展。

方法#2

如果您正在寻找性能并且求和轴的长度较小,那么最好使用单循环并使用matrix-multiplicationwith
np.tensordot,例如-

s0,s1,s2,s3 = m0.shape
s4 = m1.shape[-1]
r = np.empty((s0,s1,s2,s4))
for i in range(s0):
    r[i] = np.tensordot(m0[i],m1[i],axes=([2],[0]))

方法#3

现在,np.dot可以将其有效地用于2D输入,以进一步提高性能。因此,有了它,修改后的版本虽然更长一些,但希望性能最好的版本是-

s0,s1,s2,s3 = m0.shape
s4 = m1.shape[-1]
m0.shape = s0,s1*s2,s3   # Get m0 as 3D for temporary usage
r = np.empty((s0,s1*s2,s4))
for i in range(s0):
    r[i] = m0[i].dot(m1[i])
r.shape = s0,s1,s2,s4
m0.shape = s0,s1,s2,s3  # Put m0 back to 4D

运行时测试

功能定义-

def original_app(m0, m1):
    s0,s1,s2,s3 = m0.shape
    s4 = m1.shape[-1]
    r = np.empty((s0,s1,s2,s4))
    for i in range(s0):
        for j in range(s1):
            r[i, j] = np.dot(m0[i, j], m1[i])
    return r

def einsum_app(m0, m1):
    return np.einsum('ijkl,ilm->ijkm',m0,m1)

def tensordot_app(m0, m1):
    s0,s1,s2,s3 = m0.shape
    s4 = m1.shape[-1]
    r = np.empty((s0,s1,s2,s4))
    for i in range(s0):
        r[i] = np.tensordot(m0[i],m1[i],axes=([2],[0]))
    return r

def dot_app(m0, m1):
    s0,s1,s2,s3 = m0.shape
    s4 = m1.shape[-1]
    m0.shape = s0,s1*s2,s3   # Get m0 as 3D for temporary usage
    r = np.empty((s0,s1*s2,s4))
    for i in range(s0):
        r[i] = m0[i].dot(m1[i])
    r.shape = s0,s1,s2,s4
    m0.shape = s0,s1,s2,s3  # Put m0 back to 4D
    return r

时间和验证-

In [291]: # Inputs
     ...: m0 = np.random.rand(50,30,20,20)
     ...: m1 = np.random.rand(50,20,20)
     ...:

In [292]: out1 = original_app(m0, m1)
     ...: out2 = einsum_app(m0, m1)
     ...: out3 = tensordot_app(m0, m1)
     ...: out4 = dot_app(m0, m1)
     ...: 
     ...: print np.allclose(out1, out2)
     ...: print np.allclose(out1, out3)
     ...: print np.allclose(out1, out4)
     ...: 
True
True
True

In [293]: %timeit original_app(m0, m1)
     ...: %timeit einsum_app(m0, m1)
     ...: %timeit tensordot_app(m0, m1)
     ...: %timeit dot_app(m0, m1)
     ...: 
100 loops, best of 3: 10.3 ms per loop
10 loops, best of 3: 31.3 ms per loop
100 loops, best of 3: 5.12 ms per loop
100 loops, best of 3: 4.06 ms per loop


 类似资料:
  • 块元素是和para同级的元素,它们比较复杂,后面会分别介绍 类别 元素 说明 列表 calloutlist   bibliolist 书目列表 glosslist 词汇列表 itemizedlist 无序列表 orderedlist 有序列表 segmentedlist 成分列表 simplelist 简单列表 variablelist 定义列表 告示 caution 小心 important 重

  • 本文向大家介绍块元素和行元素区别?相关面试题,主要包含被问及块元素和行元素区别?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 块元素:独占一行,并且有自动填满父元素,可以设置margin和pading以及高度和宽度 行元素:不会独占一行,width和height会失效,并且在垂直方向的padding和margin会失

  • 我如何从1不透明度到0但逐渐?我是javascript的新手,想知道如何通过单击按钮来淡化元素。这段代码是用来播放和暂停我网站上的一个视频的。这个想法是,一旦你点击播放按钮,按钮就会逐渐消失,显示视频。据我所知,我已经设置了一个变量,它可以一次性降低不透明度,但现在是逐步的。以下是到目前为止尝试的结果:

  • 在盒模型中,一切皆为框,即页面上的每个元素会生成一个矩形框。默认情况下,一个元素的类型,决定了该元素生成框的类型。块级元素生成块级框,行内级元素生成行内级框,没有被任何元素所包含的文本生成匿名框。 也可以通过元素的 display 属性,来改变框的显示类型。可以把块级元素的 display 属性设置为 inline 或 inline-block,让它生成行内级框;也可以把行内块级元素的 displ

  • 本文向大家介绍行内元素、块级元素、空(void)元素分别有哪些?相关面试题,主要包含被问及行内元素、块级元素、空(void)元素分别有哪些?时的应答技巧和注意事项,需要的朋友参考一下 行内元素 a, b, input, span, label, button, textarea... 块级元素 div, form, table, h1...h6, p 空元素 img, input, hr, br,

  • 用我在selenium的初学者知识,我试图找到点击元素,打开链接。这些项目的链接没有href。我如何执行点击正确的元素打开链接。 我正在使用python、selenium、chrome web驱动程序、BeautifulSoup。所有库都已更新。 下面是示例html片段,其中有一个我需要使用selenium点击的标题。请让我知道,如果你需要更多的html源。此代码来自仅限“登录”的网站。