【问题标题】:How can I avoid a loop if I need to do a matrix multiplication?如果需要进行矩阵乘法,如何避免循环?
【发布时间】:2021-06-09 15:43:38
【问题描述】:

我有以下代码:

import numpy as np
import torch

y = torch.ones((1000,10)) #This is the output of a neural network which does not matter here
theta_min = 0; theta_max = np.pi; K = 10; sigma = 10;
z = torch.zeros(y.shape)
for i in range(0,y.shape[0]):
    theta = np.random.uniform(theta_min, theta_max)
    vector = np.reshape(np.exp(-1j * np.arange(0,K) * np.pi * np.sin(theta)),(-1,1))
    vector = torch.tensor(vector)
    alpha = sigma * np.random.randn()
    z[i,:] = alpha * vector @ vector.T @ y[i,:].T

如何避免循环以使代码更快?

【问题讨论】:

  • 你能做一个可重现的例子吗?您可能只需要将向量复制到矩阵并让 alpha 绘制矩阵。
  • 是的,我也将y 更改为矩阵。这不是向量,那是个错误

标签: python performance matrix pytorch


【解决方案1】:

我相信这会奏效:

import numpy as np
import torch

y = torch.ones((1000,10))
theta_min = 0; theta_max = np.pi; K = 10; sigma = 10;
z = torch.zeros(y.shape)

theta = np.random.uniform(theta_min, theta_max, y.shape)
vector = np.exp(-1j * np.arange(0,K) * np.pi * np.sin(theta))
vector = torch.FloatTensor(vector)

temp = (vector.T @ vector)
alpha = sigma * torch.rand(temp.shape)
z = (alpha*temp @ y.T).T

为了进一步加快速度,您可以在整个过程中使用 torch:

import numpy as np
import torch

y = torch.ones((1000,10)).float()
theta_min = 0; theta_max = np.pi; K = 10; sigma = 10;
alpha = sigma * torch.rand(1)

theta = torch.rand(y.shape)*(np.pi)
vector = torch.exp(-1j * torch.arange(0,K) * np.pi * torch.sin(theta)).float()

temp = (vector.T @ vector)
alpha = sigma * torch.rand(temp.shape)
z = (alpha*temp @ y.T).T

【讨论】:

  • 但问题是在我的代码中,对于θ的每个随机值我都有一个向量,所以1θ乘以0,1,2,...,K-1。但是,在您的代码中,1 theta 乘以 1,另一个 theta 乘以 2,依此类推。我希望只有 1 个 theta 随机值定义数组 vector
【解决方案2】:

按照 Megan Hardy 的解决方案,我尝试使用 3d 数组而不是使用 3d 数组。我们会做一些无用的操作,但比for循环要好。代码如下所示:

y = torch.ones((1000,10)).type(torch.complex64) 
theta_min = 0; theta_max = np.pi; K = 10; sigma = 10;

theta = torch.rand(y.shape[0],1,1) * np.pi  #Each slice in the 0 dimension will be treated separately
temp = torch.reshape(torch.arange(0,K),(-1,1))    #Necessary so that it doesn't have dimensions (10,), but (10,1)
vector = torch.exp(-1j * temp * np.pi * torch.sin(theta))
matrix = vector @ torch.transpose(vector,1,2)   #Maintain the 0 dimension but exchange dimension 1 and 2

alpha = sigma * torch.rand(1)

z = alpha * matrix @ y.T    #This makes more operations that necessary
temp = range(0,y.shape[0])  
z = alpha * z[temp,:,temp]  #Take only the desired columns

【讨论】:

    猜你喜欢
    • 2017-08-16
    • 2022-11-28
    • 1970-01-01
    • 2013-10-21
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多