Python

[Pytorch] torch.view와 torch.reshape의 차이점

shvtr159 2022. 4. 5. 16:52

torch.view()와 torch.reshape()

이 두 함수는 Numpy의 reshape를 기반으로 하는 함수로 두 함수 모두 tensor의 형태를 바꾸는 데 사용됩니다.

import torch

x = torch.arange(12)

>>> x
tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

>>> x.reshape(3,4)
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
        
>>> x.view(2,6)
tensor([[ 0,  1,  2,  3,  4,  5],
        [ 6,  7,  8,  9, 10, 11]])

위와 같이 동일한 tensor에 원하는 형태의 dimension을 입력해 주었을 때 두 함수 모두 입력에 맞는 형태로 tensor를 변환하여줍니다.

그러나 torch.view를 사용하였을 때 다음과 같은 에러가 발생하는 경우가 있습니다.

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를 사용할 경우 대부분 에러가 해결됩니다. view와 reshape는 같은 함수인 것 같은데 reshape를 사용했을 때 에러가 해결되는 이유는 contiguous 속성 차이에 있습니다. view 함수는 대상 tensor가 contiguous 하지 않을 경우 문제가 생깁니다.

contiguous

contiguous란 해석 그대로 인접성을 의미하는데 여기서 contiguous의 의미는 data들이 메모리상에서 실제로 인접해있는지를 의미합니다.

위 그림을 보면 A와 transpose 하기 이전의 B는 첫 번째 axis를 기준으로 1씩 커지고 있습니다. 이는 메모리상에서도 순서대로 저장되어있는 상태로 이 상태를 contiguous 하다고 합니다. 그러나 transpose 한 뒤의 B는 그림 아래와 같이 메모리에 순서대로 저장되어 있지 않습니다. 이런 경우에 view 함수를 사용했을 때 문제가 생기는 것입니다. contiguous 여부는 아래와 같이 is_contiguous() 함수를 이용해 확인할 수 있고, tensor 뒤에 .contiguous()를 사용하여 강제로 contiguous 하게 바꿔줄 수 있습니다.

>>> x
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
        
>>> x = x.transpose(0,1)
>>> x.is_contiguous()
False

>>> x = x.contiguous()
>>> x.is_contiguous()
True

이러한 이유로 변형하려는 tensor의 상태가 확실하지 않은 경우 reshape 함수를 사용하거나, contiguous 함수를 이용해 tensor의 속성을 바꿔준 뒤 view 함수를 사용하는 것이 좋습니다.

'Python' 카테고리의 다른 글

[Python] optimizer와 scheduler 변경  (0) 2022.11.26
[Python] pack, unpack 함수  (0) 2022.10.20
[PyTorch] BrokenPipeError: [Errno 32] Broken pipe  (0) 2022.04.05