有效地堆叠阵列/火炬张量的副本?

时间:2017-06-16 15:39:56

标签: arrays numpy pytorch tensor

我是Python / Pytorch用户。首先,在numpy中,让我们说我有一个大小为LxL的数组M,我希望有以下内容 数组:A =(M,...,M)的大小,比方说,NxLxL,是否有比这更优雅/更有效的内存方式:

A=np.array([M]*N) ?

与火炬张量相同的问题! 原因,现在,如果M是一个变量(torch.tensor),我必须这样做:

A=torch.autograd.Variable(torch.tensor(np.array([M]*N))) 

这太丑了!

3 个答案:

答案 0 :(得分:2)

请注意,您需要决定是否要为扩展阵列分配新内存,或者是否只需要原始阵列的现有内存的新视图。

在PyTorch中,这种区别产生了两种方法expand()repeat()。前者仅在现有张量上创建新视图,其中通过将步幅设置为0,将尺寸1的尺寸扩展为更大尺寸。尺寸1的任何尺寸都可以扩展为任意值而无需分配新存储器。相反,后者复制原始数据并分配新内存。

在PyTorch中,您可以按照以下方式使用expand()repeat()

import torch

L = 10
N = 20
A = torch.randn(L,L)
A.expand(N, L, L) # specifies new size
A.repeat(N,1,1) # specifies number of copies

在Numpy,有许多方法可以更优雅,更有效地实现您的目标。出于特定目的,我建议np.tile()超过np.repeat(),因为np.repeat()旨在对数组的特定元素进行操作,而np.tile()则设计为对整个阵列。因此,

import numpy as np

L = 10
N = 20
A = np.random.rand(L,L)
np.tile(A,(N, 1, 1))

答案 1 :(得分:2)

如果您不介意创建新内存,则:

如果您不想创建新的内存:

  • 在numpy中,您可以使用np.broadcast_to()。这将创建内存的只读视图。
  • 在pytorch中,您可以使用tensor.expand()。这样会创建一个可编辑的内存视图,因此+=之类的操作会产生怪异的效果。

答案 2 :(得分:0)

numpy repeat更快:

np.repeat(M[None,...], N,0)

我展开M的尺寸,然后沿着这个新尺寸重复。