我是 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)))
这是丑陋的!
请注意,您需要决定是要为扩展数组分配新内存,还是只需要原始数组的现有内存的新视图。
在 PyTorch 中,这种区别产生了两种方法expand()
和repeat()
. 前者仅在现有张量上创建一个新视图,其中通过将步幅设置为 0 将大小为 1 的维度扩展到更大的大小。大小为 1 的任何维度都可以扩展到任意值而无需分配新内存。相反,后者复制原始数据并分配新内存。
在 PyTorch 中,您可以使用expand()
andrepeat()
来满足您的目的:
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()
over 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))
如果您不介意创建新内存:
np.repeat()
或np.tile()
。考虑到效率,您应该选择一个为您的目的组织内存的内存,而不是事后重新安排:
np.repeat([1, 2], 2) == [1, 1, 2, 2]
np.tile([1, 2], 2) == [1, 2, 1, 2]
tensor.repeat()
. 注意:这匹配np.tile
,不是np.repeat
。如果您不想创建新内存:
np.broadcast_to()
. 这将创建内存的只读视图。tensor.expand()
. 这会创建一个可编辑的内存视图,因此类似的操作+=
会产生奇怪的效果。输入numpy
repeat
更快:
np.repeat(M[None,...], N,0)
我扩展 的维度M
,然后沿着新维度重复。