【问题标题】:Understanding einsum in Python [closed]在 Python 中理解 einsum [关闭]
【发布时间】:2014-08-07 05:31:55
【问题描述】:

我正在使用einsum,因为它非常快并且每次使用它都可以为我节省 2-3 行代码。但我很难理解它。

我举个例子:我想训练一个神经网络。为了计算与梯度相关的东西,我需要执行以下操作:

给定一个矩阵W(行ij 是从神经元i 到下一层神经元j 的连接权重)和一个神经元输出向量S(希望底部的视觉示例会有所帮助),我需要执行以下操作:

S[i]*W[i,:] 是新矩阵中的一行

我发现下面的代码可以完成:

 einsum('ji,kj->ij',W,S)

现在这对我来说很有意义,但我花了很长时间才把它弄好。大量的试验和许多错误(有些事情成功了但错误,有些在尝试运行时给了我错误)。

现在我想一次计算一批这些——也就是说,不是S 是一个向量,而是一个大小为(NeuronsNum, BatchSize) 的矩阵,我想计算:

einsum('ji,kj->ij',W,S[:,b])

对于所有b=0BatchSize-1。为了节省时间(并理解einsum),我想一次完成所有操作,并将结果作为矩阵(Neurons in layer l-1, Neurons in layer l, BatchSize)

我似乎无法正确理解。因此,我感谢您阅读所有这些内容,如果我能获得理解此功能的任何帮助,我将不胜感激

视觉示例:

ith 神经元发送一些值,根据它与目标的连接强度来衡量。我们对每个i 都这样做。

【问题讨论】:

  • 对于神经网络算法,np.dot 优先于np.einsum。如果 NumPy 有良好的 BLAS 支持,dot 将把einsum 从水中吹出来进行矩阵乘法。
  • 我需要做的一些事情不能用dot 完成(除非我对矩阵进行一些更改然后将它们改回来,我宁愿不这样做 - 因为大多数的代码是由其他人编写的,我宁愿不要更改太多)。另外,无论如何我想了解einsum。另外,我想了解我的问题有什么问题,以至于有人认为它应该被否决。
  • 如果你像通常在 for 循环中那样写出来(如果你不知道 numpy 等中存在点积,那就太天真了),它是什么样子的?当我尝试使用 einsum 时,我就是这样做的。一旦你把它写出来,它只是删除所有的for循环结构,只保留最后的 C[i,j,k,l]+=A[m,n,o,p]*B[p,q, r](但在 c 的正确位置有正确的索引)。
  • @usethedeathstar 听起来很简单。没有这么想。谢谢!如果您想将其写为答案,我会投票并将其标记为答案:) 谢谢!
  • 你能解释一下这些东西的所有形状吗?我了解 einsum,但不是您使用的问题:-)

标签: python numpy neural-network matrix-multiplication


【解决方案1】:

只需将它写在嵌套的 for 循环中,就好像您不知道 numpy 可以做到这一点,而不是保留 numpy einsum 的索引。这样你就可以写下确切的公式了。

在你的情况下:

R = einsum('ki,jk->kij',W,S)

会给你一个 3d 数组,其中结果 R 满足:

R[:,:,b] = einsum('ki,k->ki',W,S[:,b])

【讨论】:

    【解决方案2】:

    感谢usethedeathstar,我设法找到了解决方案:

    einsum('ki,jk->kij',W,S)
    

    会给我一个 3d 数组,结果R 满足:

    R[:,:,b]=einsum('ji,kj->ij',W,S[:,b])
    

    他的建议是:在循环中编写代码,删除循环,然后您将获得索引!

    【讨论】:

    • 好吧,S[:,b] 是二维的。我刚刚实现了别人代码的某些部分。他们可能使用newaxis 将一维S 向量设为二维。至于这里的代码S[:,b] - 我还没有真正尝试过,但我认为它仍然取决于数据类型。有时当我这样做时,我仍然得到一个只有 1 行/列的 2D 数组
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 2019-09-17
    • 2016-01-16
    • 2021-03-02
    • 2019-07-25
    • 2010-10-17
    • 2021-11-28
    相关资源
    最近更新 更多