view()
vs. transpose()
vs. reshape()
¶import torch
import torch.nn as nn
t = torch.tensor([[[0, 1], [2,3], [4,5]], \
[[6,7], [8,9], [10,11]], \
[[12, 13], [14, 15], [16, 17]], \
[[18, 19], [20, 21], [22, 23]]])
t.shape
torch.Size([4, 3, 2])
t
tensor([[[ 0, 1], [ 2, 3], [ 4, 5]], [[ 6, 7], [ 8, 9], [10, 11]], [[12, 13], [14, 15], [16, 17]], [[18, 19], [20, 21], [22, 23]]])
t[0][0][0]
tensor(0)
t[0][0][1]
tensor(1)
t[0][1][0]
tensor(2)
tv = t.view(4, 2, 3)
tv
tensor([[[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]], [[12, 13, 14], [15, 16, 17]], [[18, 19, 20], [21, 22, 23]]])
tv[0][0][0]
tensor(0)
tv[0][0][1]
tensor(1)
tv[0][0][2]
tensor(2)
tv.is_contiguous()
True
t.flatten() == tv.flatten()
tensor([True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True])
t.storage().data_ptr() == tv.storage().data_ptr() # 물리적 pointer 값이 일치함
True
# Modifying view tensor changes base tensor as well.
t[0][0][0] = 99
tv[0][0][0]
tensor(99)
tt = t.transpose(2, 1) # (4, 2, 3)
tt
tensor([[[ 0, 2, 4], [ 1, 3, 5]], [[ 6, 8, 10], [ 7, 9, 11]], [[12, 14, 16], [13, 15, 17]], [[18, 20, 22], [19, 21, 23]]])
tt.shape == b.shape
True
t.storage().data_ptr() == tt.storage().data_ptr()
True
tt.is_contiguous()
False
tt.flatten()
tensor([ 0, 2, 4, 1, 3, 5, 6, 8, 10, 7, 9, 11, 12, 14, 16, 13, 15, 17, 18, 20, 22, 19, 21, 23])
t.flatten() == tt.flatten() # since tt is not contiguous
tensor([ True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True])
tt.contiguous() == tt # 겉보기에는 tt와 같음
tensor([[[True, True, True], [True, True, True]], [[True, True, True], [True, True, True]], [[True, True, True], [True, True, True]], [[True, True, True], [True, True, True]]])
tt.contiguous().storage().data_ptr() == tt.storage().data_ptr() # 하지만 물리적 pointer는 다름
False
== contiguous().view()
tt.view(4, 3, 2) # transpose -> view (x)
--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-92-785954c0ff12> in <module> ----> 1 tt.view(4, 3, 2) # transpose -> view (x) 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.
tt.contiguous().view(4, 3, 2) # transpose -> contiguous -> view (o)
tensor([[[ 0, 2], [ 4, 1], [ 3, 5]], [[ 6, 8], [10, 7], [ 9, 11]], [[12, 14], [16, 13], [15, 17]], [[18, 20], [22, 19], [21, 23]]])
tt.reshape(4, 3, 2) # transpose -> reshape (o)
tensor([[[ 0, 2], [ 4, 1], [ 3, 5]], [[ 6, 8], [10, 7], [ 9, 11]], [[12, 14], [16, 13], [15, 17]], [[18, 20], [22, 19], [21, 23]]])
tt.reshape(4, 3, 2).is_contiguous()
True