如何在python中为每对矩阵向量内积分开? [英] How to do matrix vector inner products for each pair separate in 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.
As
和bs
分别是3D
和2D
,让我们将它们表示为在我们思想中想象内部产品的迭代器.因此,在迭代时,我们将有a : j,k
和b : m
.如果该内积在a
和b
之间,我们将丢失a
的第二个轴和b
的第一个轴.因此,我们需要将k
与m
对齐.因此,我们可以假设b
具有与k
相同的迭代器.从a
回到As
,从b
回到bs
,从本质上讲,我们将丢失As
的第三个轴,而bs
的第二个轴丢失,具有内积/总和减少.沿As
和bs
的第一个轴进行迭代表示我们需要在这些总和减少的情况下保持对齐.
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 ofbs
. - Lose the third axis of
As
with sum-reduction against second ofbs
.
因此,我们将剩下用于输出的迭代器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屋!