연속적인 메모리 Tensor를 반환한다!
특정 연산은 이를 해주지 않으면 에러가 난다
Example
>>> a = torch.randn(2, 3, 6)
>>> a
tensor([[[ 1.7584e+00, 9.2055e-01, 4.6850e-01, 6.4279e-01, -3.6610e-01,
1.9589e+00],
[ 9.8600e-01, 3.4744e-01, -5.7159e-01, -2.3593e-01, -1.6692e+00,
-3.6157e-04],
[ 1.7516e+00, -1.1490e+00, -7.9862e-01, 6.8282e-01, -5.8972e-01,
-4.4164e-01]],
[[ 1.0348e+00, -7.5774e-01, -7.2701e-01, 1.0653e+00, -4.8248e-01,
-2.7340e-01],
[-6.7566e-02, 1.6268e+00, -7.1940e-01, 2.4111e-01, 7.3485e-01,
2.8317e-01],
[-7.0272e-01, -3.9150e-01, -1.3037e+00, -9.7168e-01, 4.4148e-01,
6.2360e-01]]])
>>> a.shape
torch.Size([2, 3, 6])
>>> a.stride()
(18, 6, 1)
Python
복사
이러한 모양의 텐서를 생성하고, shape와 stide속성을 확인하면
>>> a.shape
torch.Size([2, 3, 6])
>>> a.stride()
(18, 6, 1)
Python
복사
stride가 (18, 6, 1)이라는 것은
0차원에서 다음 원소를 가져올때는 18개의 원소를 뛰어넘어야하고
1차원에서 다음원소를 가져올때는 6개, 2차원에선 1개를 뛰어넘어야한다는 것이다.
이렇게 그림으로보면 잘 이해가 간다. 말이되는 소리다
그러나 메모리에 연속적으로 값이 들어있지않다면?
>>> a = a.transpose(0,1)
>>> a.shape
torch.Size([3, 2, 6])
Python
복사
>>> a.stride()
(6, 18, 1)
>>> a.is_contiguous()
False
Python
복사
같은 사이즈의 텐서 b를 만들어본다
>>> b = torch.randn(3,2,6)
>>> b.stride()
(12, 6, 1)
>>> b.is_contiguous()
True
Python
복사
아닛 a와 달리 b는 contiguous하다고 한다
그리고 stride도 다르다
왜?
a가 transpose로 형태가 변화될 때, 실제로 해당 원소가 저장되어있는 메모리 위치는 변화하지 않고 접근 인덱스만 변화되었기 때문이다.
텐서의 형태가 변할 때마다 메모리의 위치도 재할당하는 연산이 잦아지면 성능이 떨어질 수 있기 때문일 것이다
그래서 이러한 비연속적인 텐서를 .contiguous를 통해 연속적으로 만들어줄 수 있다.
>>> a.view(-1)
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.
Python
복사
다음과 같이 contiguous하지 않으면 에러가 나는 함수들이 있다(텐서를 flatten해주는 함수)
reshape같은 경우에는 contiguous없이 사용 가능하다
>>> a.reshape(-1)
tensor([ 1.7584e+00, 9.2055e-01, 4.6850e-01, 6.4279e-01, -3.6610e-01,
1.9589e+00, 1.0348e+00, -7.5774e-01, -7.2701e-01, 1.0653e+00,
-4.8248e-01, -2.7340e-01, 9.8600e-01, 3.4744e-01, -5.7159e-01,
-2.3593e-01, -1.6692e+00, -3.6157e-04, -6.7566e-02, 1.6268e+00,
-7.1940e-01, 2.4111e-01, 7.3485e-01, 2.8317e-01, 1.7516e+00,
-1.1490e+00, -7.9862e-01, 6.8282e-01, -5.8972e-01, -4.4164e-01,
-7.0272e-01, -3.9150e-01, -1.3037e+00, -9.7168e-01, 4.4148e-01,
6.2360e-01])
Python
복사
.contiguous를 적용해주면
>>> a = a.contiguous()
>>> a = a.view(-1)
>>> a.shape
torch.Size([36])
Python
복사
이렇게 사용이 가능하다 ~~