这里写自定义目录标题
欢迎使用Markdown编辑器
在看SSD的代码实现,里面出现了l(x).permute(0, 2, 3, 1).contiguous())
这样的用法。首先查了Tensor.permute()
,用作更换Tensor的维度顺序;
查Tensor.contiguous()
的用法花了蛮多心思,做一下记录:
Tensor.contiguous()
x = torch.arange(12).view(4, 3)
print(x, x.stride())
> tensor([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
> (3, 1)
y = x.t()
print(y, y.stride())
print(y.is_contiguous())
> tensor([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])
> (1, 3)
> False
try:
y = y.view(-1)
except RuntimeError as e:
print(e)
> invalid argument 2: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Call .contiguous() before .view().
y = y.contiguous()
print(y.stride())
> (4, 1)
y = y.view(-1)
总结几点如下:
x.stride()
返回元素个数对应于x的维度数,其返回的 (3, 1)代表每个元素需要经过3个值才能到下一row, 需要经过1个值就到下一column;- 当每个元素仅需经过1个值就到下一column,张量是contiguous的(个人理解是这么个意思)
- 当我们将x转置成y,y不再contiguous,原因是每个元素需要经过3个值才能到下一column.
- 只有contiguous的Tensor可以被flatten
y = y.contiguous()
将y变为连续状态,其原理可能是开辟了一块新的内存,并将张量内的值按连续的方式复制过去(存疑)