Blog Full Notice
back to main page

1 분 소요

motivation: torch.contiguous(), is_contiguous(), view(), reshape() 를 알아보자.

Pytorch에서 tensor의 내용을 바꾸지 않고, data가 어떻게 보이는지만 바꿔서 표현하는 함수들이 있다. 그 함수들에는 narrow(), view(), expand(), transpose()가 있다.1 이게 무슨 말이냐면, transpose를 시킨 객체와 아닌 객체는, 같은 메모리를 가르키고 있는 것이다.

그래서 같은 row에 data가 나열되어 있다면, C contiguous 라고 한다. 아마 C언어가 row에 대해서 먼저 memory에 쌓아두기 때문인 것 같다. 즉 대괄호로 가장 밖에 있는 괄호부터 일렬로 쌓지 않는가.

근데 transpose를 하게 되면, 해당 배열이 저장된 메모리는 그대로 두고, 즉 transpose하기 전 tensor와 같은 메모리를 쓰되, 그냥 그 순서 정보만 바꾸게 된다.2

원래 이런 data를 transpose 시키면, 이렇게 메모리를 접근하는 방식이 달라진다. (이게 이해가 안되도 된다. 아래 글을 보면 이해할 수 있을 것이다.)

결국 tensor가 다음 element (row에 대해서 다음 element)를 찾는 방식은, stride()를 통해서 유추해 볼 수 있다.

t = torch.tensor([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]])

t.stride()   # (4, 1)  # 다음 row로 가려면 4칸 이동해야 하고, 다음 element(column)을 이동하려면 1칸 이동해야 한다.
t.is_contiguous() # True

t.T.stride() # (1, 4)
t.T.is_contiguous() # False

위 코드를 이해하는 것이 가장 중요하다. stride()를 하면 (4,1) 이런 값을 볼 수 있는데, 각 숫자는 n번째 차원 방향으로 메모리를 몇개를 이동해야 다음 element를 찾을 수 있는지를 보는 것이다. (4,1)은 다음 row에 있는 element를 구하려면 4개의 메모리를 이동해야 한다는 것이고, 다음 column에 있는 element를 구하려면 1개의 메모리만 이동해도 된다는 것이다.

2차원 tensor의 경우, 어떤 tensor를 stride() 했을 떄, 2번쨰 나오는 값이 1이면 contiguous한 것이다. pytorch에서는.

다음 element를 찾기 위해서(row 방향으로), 한칸만 이동해도 된다면, contiguous(C contiguous)하다는 것이다.

contiguous 하지 않은 tensor contiguous하게 만드는 법

t.T.contiguous().stride() # (3, 1)
# 를 하면 contiguous 해진다.

According to the documentation:

For a tensor to be viewed, the new view size must be compatible with its original size and stride, i.e., each new view dimension must either be a subspace of an original dimension, or only span across original dimensions d, d+1, …, d+k that satisfy the following contiguity-like condition that ∀i=d,…,d+k−1,
stride[i]=stride[i+1]×size[i+1] 2

즉 contiguous한 경우, view를 할 수 있게 된다.

view가 안되는 경우 reshape을 써서, 하면 새로운 memory를 할당하게 해준다.

또 contiguous() method는 새로운 memory를 할당해주는데, 이거는 또 그냥 신경쓰지 말고 쓰다가, input이 contiguous하지 않다 라는 표현이 나오면 그떄 tensor에 .contiguous()를 해주면 된다고 한다.3

카테고리:

업데이트:

댓글남기기