我正在 github (link) 上浏览这个 LSTM 语言模型的例子。
它的一般作用对我来说很清楚。但我仍在努力理解调用 contiguous()
的作用,这在代码中出现了多次。
例如在代码的第 74/75 行中创建了 LSTM 的输入和目标序列。
数据(存储在 ids
中)是二维的,其中第一维是批量大小。
for i in range(0, ids.size(1) - seq_length, seq_length):
# Get batch inputs and targets
inputs = Variable(ids[:, i:i+seq_length])
targets = Variable(ids[:, (i+1):(i+1)+seq_length].contiguous())
作为一个简单的例子,当使用批量大小 1 和 seq_length
10 inputs
和 targets
时,如下所示:inputs Variable containing:
0 1 2 3 4 5 6 7 8 9
[torch.LongTensor of size 1x10]
targets Variable containing:
1 2 3 4 5 6 7 8 9 10
[torch.LongTensor of size 1x10]
所以总的来说,我的问题是,contiguous()
做什么,我为什么需要它?此外,我不明白为什么该方法被称为目标序列而不是输入序列,因为两个变量都由相同的数据组成。
targets
怎么可能不连续而 inputs
仍然是连续的?编辑:
我试图省略调用
contiguous()
,但这会导致计算损失时出现错误消息。RuntimeError: invalid argument 1: input is not contiguous at .../src/torch/lib/TH/generic/THTensor.c:231
所以显然在这个例子中调用 contiguous()
是必要的。 最佳答案
PyTorch 中对张量的一些操作不会改变张量的内容,但会改变数据的组织方式。这些操作包括:
例如:当您调用 transpose()
时,PyTorch 不会生成具有新布局的新张量,它只是修改 Tensor 对象中的元信息,以便偏移量和步幅描述所需的新形状。在这个例子中,转置张量和原始张量共享相同的内存:
x = torch.randn(3,2)
y = torch.transpose(x, 0, 1)
x[0, 0] = 42
print(y[0,0])
# prints 42
这就是连续概念的用武之地。在上面的例子中,x
是连续的,但 y
不是因为它的内存布局与从头开始制作的相同形状的张量的内存布局不同。请注意,“连续”这个词有点误导,因为张量的内容并不是分散在断开连接的内存块周围。这里的字节仍然分配在一块内存中,但元素的顺序不同!当您调用
contiguous()
时,它实际上会复制张量,使其元素在内存中的顺序与使用相同数据从头开始创建时相同。通常你不需要担心这个。您通常可以安全地假设一切都会正常工作,并等到您得到
RuntimeError: input is not contiguous
,其中 PyTorch 期望连续张量添加对 contiguous()
的调用。关于python - PyTorch - contiguous() 有什么作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48915810/