5

我是 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))) 

这是丑陋的!

4

3 回答 3

12

请注意,您需要决定是要为扩展数组分配新内存,还是只需要原始数组的现有内存的新视图。

在 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))
于 2017-06-17T18:57:58.850 回答
3

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

  • 在 numpy 中,您可以使用np.repeat()np.tile()。考虑到效率,您应该选择一个为您的目的组织内存的内存,而不是事后重新安排:
    • np.repeat([1, 2], 2) == [1, 1, 2, 2]
    • np.tile([1, 2], 2) == [1, 2, 1, 2]
  • 在 pytorch 中,您可以使用tensor.repeat(). 注意:这匹配np.tile,不是np.repeat

如果您不想创建新内存:

  • 在 numpy 中,您可以使用np.broadcast_to(). 这将创建内存的只读视图。
  • 在 pytorch 中,您可以使用tensor.expand(). 这会创建一个可编辑的内存视图,因此类似的操作+=会产生奇怪的效果。
于 2020-05-05T03:14:27.660 回答
-1

输入numpy repeat更快:

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

我扩展 的维度M,然后沿着新维度重复。

于 2017-06-16T16:54:50.720 回答