针对view()只能处理contiguous之说的大体解释
>>> y = torch.Tensor(5, 3)
>>> y
tensor([[7.0975e+22, 7.9309e+34, 7.9439e+08],
[3.2604e-12, 1.1625e+33, 8.9605e-01],
[1.1632e+33, 5.6003e-02, 7.0374e+22],
[6.9983e+28, 1.9859e+29, 4.3218e+27],
[4.7423e+30, 2.2856e+20, 3.2607e-12]])
>>> z = y.t()
>>> z
tensor([[7.0975e+22, 3.2604e-12, 1.1632e+33, 6.9983e+28, 4.7423e+30],
[7.9309e+34, 1.1625e+33, 5.6003e-02, 1.9859e+29, 2.2856e+20],
[7.9439e+08, 8.9605e-01, 7.0374e+22, 4.3218e+27, 3.2607e-12]])
>>> z.view(15)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
这边在官方文档view()与reshape()的区别中解释如下:
To ensure that the new tensor always shares its data with the original, torch.view imposes some contiguity constraints on the shapes of the two tensors [docs]. More often than not this is not a concern, but sometimes torch.view throws an error even if the shapes of the two tensors are compatible. Here’s a famous counter-example.
大概意思就是:
.view()方法只能改变连续的(contiguous)张量,否则需要先调用.contiguous()方法。而reshape()不受此约束。
大概意思就是张量在进行形状变化时,还受stride控制,因此可能导致变行后的数据不连续。具体看下例子:
>>> z
tensor([[7.0975e+22, 3.2604e-12, 1.1632e+33, 6.9983e+28, 4.7423e+30],
[7.9309e+34, 1.1625e+33, 5.6003e-02, 1.9859e+29, 2.2856e+20],
[7.9439e+08, 8.9605e-01, 7.0374e+22, 4.3218e+27, 3.2607e-12]])
>>> y
tensor([[7.0975e+22, 7.9309e+34, 7.9439e+08],
[3.2604e-12, 1.1625e+33, 8.9605e-01],
[1.1632e+33, 5.6003e-02, 7.0374e+22],
[6.9983e+28, 1.9859e+29, 4.3218e+27],
[4.7423e+30, 2.2856e+20, 3.2607e-12]])
>>> z.stride()
(1, 3)
>>> z.view(15)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
>>> y.stride()
(3, 1)
>>> y.view(15)
tensor([7.0975e+22, 7.9309e+34, 7.9439e+08, 3.2604e-12, 1.1625e+33, 8.9605e-01,
1.1632e+33, 5.6003e-02, 7.0374e+22, 6.9983e+28, 1.9859e+29, 4.3218e+27,
4.7423e+30, 2.2856e+20, 3.2607e-12])
然而当加入.contiguous()后,则变成:
>>> z.contiguous().stride()
(5, 1)
>>> z.contiguous().view(15)
tensor([7.0975e+22, 3.2604e-12, 1.1632e+33, 6.9983e+28, 4.7423e+30, 7.9309e+34,
1.1625e+33, 5.6003e-02, 1.9859e+29, 2.2856e+20, 7.9439e+08, 8.9605e-01,
7.0374e+22, 4.3218e+27, 3.2607e-12])