如何矢量化这个乘法?

2024-05-08 11:31:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个X矩阵,它的形状是(ni*43*91)x67,W张量的形状是67x43x91。ni变化

我需要得到一个(ni*43*91)向量y,方法是在X的第一行ni上加上W的第一列,得到y的第一个ni元素,X的第二个ni行,得到y的第二个ni元素,依此类推。当W中的列用完时,我转到下一个维度继续。在

我有两个面具dim2和dim3,都是形状(ni*43*91),按顺序排列。现在这就是我正在做的(简化),而且速度很慢

for d3 in range(91):
  for d2 in range(43):
    mask = ((dim3 == d3) & (dim2 == d2))
    curr_X = X[mask, :]
    curr_W = W[:,d2,d3]
    curr_y = numpy.dot(curr_X,curr_W)
    y[mask] = curr_y

在没有for循环的情况下,这是可能的吗?在


Tags: in元素forrange矩阵mask向量d2
3条回答

首先,不清楚您想做什么,因为您的代码不起作用。我只能猜测你想这么做:

from numpy import *
from numpy.random import rand

ni=12
A=67
B=43
C=91


X = rand(ni*B*C,A) 
W = rand(A,B,C)

y = zeros((ni*B*C))

for k in xrange(len(y)):
    b = (k/ni)/C
    c = (k/ni) % C

    #print 'y[%i] = dot(X[%i,:],W[:,%i,%i])'%(k,k,b,c)

    y[k] = dot(X[k,:],W[:,b,c])

如果您只需将A,B,C,ni设置为一些较低的值并取消对print-行的注释,您将很快看到该算法的作用。在

如果这正是您想要的,那么您可以使用这一行程序更快地完成:

^{pr2}$

尽管有一些索引重新排列,这里的关键技巧是使用repeat,因为在循环中,b,cni步骤“冻结”,而k在增长。在

我现在有点赶时间,但如果你需要进一步的解释,请留言。在

我不完全理解您的dim2dim3数组是什么,以及mask是如何构造的,但是根据您的描述,您需要与此类似的内容:

ni = 10
a, b, c = 43, 91, 67
X = np.random.rand(ni*a*b, c)
W = np.random.rand(c, a, b)

X = X.reshape(ni, a*b, c)
W = W.reshape(c, a*b)

y = np.einsum('ijk, kj -> ij', X, W)
y = y.reshape(-1)

如果您使用工作代码更新问题,即dim2dim3的完整描述,我们可以对其进行微调以返回完全相同的结果(如果还没有)。在

从这个问题中很难理解你想要的结果是什么,但我认为你所追求的结果可以很容易地得到,就像这样:

y = (X.T * W[:,dim2,dim3]).sum(axis=0)

比较正确性和速度:

^{pr2}$

再快一点就可以用了

y = np.einsum('ij,ji->i', X, W[:,dim2,dim3])

相关问题 更多 >

    热门问题