如何在python中为每对矩阵向量内积分开? [英] How to do matrix vector inner products for each pair separate in python?

查看:183
本文介绍了如何在python中为每对矩阵向量内积分开?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说,我有一堆矩阵As和向量bs.

Lets say, I have bunch of matrices As and vectors bs.

As = array([[[1, 7], [3, 8]],
            [[2, 1], [5, 9]],
            [[7, 2], [8, 3]]])
bs = array([[8, 0], [8, 8], [7, 3]])

当我执行np.inner(As,bs)时,我得到:

When I do np.inner(As, bs), I get:

array([[[  8,  64,  28], [ 24,  88,  45]],
       [[ 16,  24,  17], [ 40, 112,  62]],
       [[ 56,  72,  55], [ 64,  88,  65]]])

但是我不需要所有内部产品.我想要的是一次计算每个向量的每个矩阵. 我可以做这样的事情:

But I do not need all inner products. What I want is, to calculate each matrix with each vector once. I can do something like this:

np.array(map(lambda (a, b): np.inner(a, b), zip(As, bs)))

然后我得到了预期的矩阵:

Then I get the expected matrix:

array([[  8,  24], [ 24, 112], [ 55,  65]])

现在,我不想使用zip,map等,因为我需要> 10 ** 6的时间进行此操作(用于图像处理,完全用于GMM). 有什么方法可以使用numpy,scipy等为我做这件事吗? (快速高效)

Now I do not want to use zip, map etc. because I need this operation > 10**6 time (for image processing, exactly for GMM). Is there any way to use numpy, scipy etc. that can do this for me? (fast and efficent)

推荐答案

您可以使用 np.einsum -

You can use np.einsum -

np.einsum('ijk,ik->ij',As, bs)

说明

对于np.array(map(lambda (a, b): np.inner(a, b), zip(As, bs))),我们正在选择As以外的第一个元素作为a,选择bs以外的第一个元素作为b并进行内积.因此,我们正在做:

With np.array(map(lambda (a, b): np.inner(a, b), zip(As, bs))), we are selecting the first element off As as a and off bs as b and doing inner product. Thus, we are doing :

In [19]: np.inner(As[0],bs[0])
Out[19]: array([ 8, 24])

In [20]: np.inner(As[1],bs[1])
Out[20]: array([ 24, 112])

In [21]: np.inner(As[2],bs[2])
Out[21]: array([55, 65])

将其视为循环,我们迭代3次,对应于As第一轴的长度,与bs相同.因此,查看lambda表达式,在每次迭代中,我们都有a = As[0] & b = bs[0]a = As[1] & b = bs[1]等.

Think of it as a loop, we iterate 3 times, corresponding to the length of first axis of As, which is same as for bs. Thus, looking at the lambda expression, at each iteration, we have a = As[0] & b = bs[0], a = As[1] & b = bs[1] and so on.

Asbs分别是3D2D,让我们将它们表示为在我们思想中想象内部产品的迭代器.因此,在迭代时,我们将有a : j,kb : m.如果该内积在ab之间,我们将丢失a的第二个轴和b的第一个轴.因此,我们需要将km对齐.因此,我们可以假设b具有与k相同的迭代器.从a回到As,从b回到bs,从本质上讲,我们将丢失As的第三个轴,而bs的第二个轴丢失,具有内积/总和减少.沿Asbs的第一个轴进行迭代表示我们需要在这些总和减少的情况下保持对齐.

As and bs being 3D and 2D, let's represent them as iterators imagining the inner-product in our minds. Thus, at iteration, we would have a : j,k and b : m. With that inner product between a and b, we would lose the second axis of a and first of b. Thus, we need to align k with m. Thus, we could assume b to have the same iterator as k. Referencing back from a to As and b to bs, in essence, we would lose the third axis from As and second from bs with the inner product/sum-reduction. That iterating along the first axis for As and bs signifies that we need to keep those aligned under these sum-reductions.

我们总结一下.

我们有涉及输入数组的迭代器,就像这样-

We have the iterators involved for the input arrays like so -

As :  i x j x k 
bs :  i x k

与预期操作有关的步骤:

Steps involved in the intended operation :

  • 保持As的第一轴与bs的第一轴对齐.
  • 相对于bs的第二个轴,减去和减少的As的第三轴.
  • Keep the first axis of As aligned with first of bs.
  • Lose the third axis of As with sum-reduction against second of bs.

因此,我们将剩下用于输出的迭代器i,j.

Thus, we would be left with the iterators i,j for the output.

np.einsum是一种非常有效的实现,在我们需要使输入数组的一个或多个轴彼此对齐时特别方便.

np.einsum is a pretty efficient implementation and is specially handy when we need to keep one or more of the axes of the input arrays aligned against each other.

有关einsum的更多信息,我建议遵循先前提供的docs链接,以及 this Q&A 可能会有所帮助!

For more info on einsum, I would suggest following the docs link supplied earlier and also this Q&A could be helpful!

这篇关于如何在python中为每对矩阵向量内积分开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆