반응형
Pytorch를 이용하여 코드를 구현할 때 데이터의 차원을 수정하거나 조작할 때 가장 많이 사용되는 함수는 view, reshape, transpose, permute이다. 이 함수들에 대해 제대로 된 사용법과 특징을 정리할 필요가 있다 생각하여 남겨두고자 한다. 또한 contiguous한 특성에 따라 어떤 함수를 사용하여야 하는지도 함께 정리하려 한다.

view()
- 메모리를 공유하며 차원 변경
- 연속된(Contiguous) 메모리를 사용할 때만 가능
- 원본 텐서와 메모리를 공유 (즉, view()를 바꿔도 원본도 바뀜)
import torch
x = torch.arange(6) # [0, 1, 2, 3, 4, 5]
y = x.view(2, 3)
print(y)
# 출력
# tensor([[0, 1, 2],
# [3, 4, 5]])
- view()는 x의 메모리를 그대로 사용하여 2x3 행렬로 변경
- 하지만 메모리가 연속적(contiguous)이지 않으면 view() 사용이 불가
reshape()
- 새로운 메모리 또는 기존 메모리 사용
- 내부적으로 view()를 시도하지만, 필요하면 새로운 메모리를 할당함
- 메모리를 공유할 수도 있고, 새로 만들 수도 있음
x = torch.arange(6)
y = x.reshape(2, 3)
print(y)
# 출력
# tensor([[0, 1, 2],
# [3, 4, 5]])
- reshape()는 view()와 비슷하지만 연속적인 메모리가 아니어도 동작 가능
- view()가 안 되면 자동으로 새로운 메모리를 할당해서 reshape 처리
transpose()
- 두 차원의 위치 변경
- 메모리 구조는 유지하면서 차원만 바꿈
- view()처럼 메모리를 공유하지만, 연속적이지 않게 될 수 있음
1D
x = torch.tensor([[1, 2, 3],
[4, 5, 6]])
y = x.transpose(0, 1) # (2x3) -> (3x2)
print(y)
# 출력
# tensor([[1, 4],
# [2, 5],
# [3, 6]])
- transpose(0, 1) → 0번 차원과 1번 차원을 바꿈
- 메모리가 연속적이지 않아서 view()를 사용할 수 없을 수도 있음
2D
import torch
x = torch.tensor([[1, 2, 3],
[4, 5, 6]])
y = x.transpose(0, 1) # 0번(행)과 1번(열) 차원을 바꿈
print(y)
# 출력
# tensor([[1, 4],
# [2, 5],
# [3, 6]])
3D
x = torch.randn(2, 3, 4) # (batch, height, width)
y = x.transpose(1, 2) # height와 width를 바꿈
print(y.shape) # (2, 4, 3)
- x.shape = (2, 3, 4)
- y.shape = (2, 4, 3) → 1번(height)과 2번(width) 차원이 변경됨
permute()
- 새로운 메모리 또는 기존 메모리 사용
- 내부적으로 view()를 시도하지만, 필요하면 새로운 메모리를 할당함
- 메모리를 공유할 수도 있고, 새로 만들 수도 있음
x = torch.randn(2, 3, 4) # (batch, height, width)
y = x.permute(1, 0, 2) # (height, batch, width)
print(y.shape)
# 출력
# torch.Size([3, 2, 4])
- permute(1, 0, 2) → 1번 차원을 앞으로, 0번 차원을 뒤로, 2번 차원은 그대로 유지
- transpose()보다 더 유연함
contiguous()
- 메모리를 연속적으로 변경
- transpose()나 permute() 후 비연속적(non-contiguous)인 텐서를 연속적(contiguous)으로 변경
- view()를 사용하려면 contiguous()를 먼저 호출해야 할 수도 있음
x = torch.tensor([[1, 2, 3],
[4, 5, 6]])
y = x.transpose(0, 1) # 비연속적인 메모리
z = y.contiguous().view(1, 6) # 연속적인 메모리로 변환 후 view() 적용
print(z)
# 출력
# tensor([[1, 4, 2, 5, 3, 6]])
- transpose()는 비연속적이므로 view()를 바로 사용할 수 없음
- contiguous()를 호출해서 메모리를 새로 정렬한 후 view() 사용
반응형
반응형
Pytorch를 이용하여 코드를 구현할 때 데이터의 차원을 수정하거나 조작할 때 가장 많이 사용되는 함수는 view, reshape, transpose, permute이다. 이 함수들에 대해 제대로 된 사용법과 특징을 정리할 필요가 있다 생각하여 남겨두고자 한다. 또한 contiguous한 특성에 따라 어떤 함수를 사용하여야 하는지도 함께 정리하려 한다.

view()
- 메모리를 공유하며 차원 변경
- 연속된(Contiguous) 메모리를 사용할 때만 가능
- 원본 텐서와 메모리를 공유 (즉, view()를 바꿔도 원본도 바뀜)
import torch
x = torch.arange(6) # [0, 1, 2, 3, 4, 5]
y = x.view(2, 3)
print(y)
# 출력
# tensor([[0, 1, 2],
# [3, 4, 5]])
- view()는 x의 메모리를 그대로 사용하여 2x3 행렬로 변경
- 하지만 메모리가 연속적(contiguous)이지 않으면 view() 사용이 불가
reshape()
- 새로운 메모리 또는 기존 메모리 사용
- 내부적으로 view()를 시도하지만, 필요하면 새로운 메모리를 할당함
- 메모리를 공유할 수도 있고, 새로 만들 수도 있음
x = torch.arange(6)
y = x.reshape(2, 3)
print(y)
# 출력
# tensor([[0, 1, 2],
# [3, 4, 5]])
- reshape()는 view()와 비슷하지만 연속적인 메모리가 아니어도 동작 가능
- view()가 안 되면 자동으로 새로운 메모리를 할당해서 reshape 처리
transpose()
- 두 차원의 위치 변경
- 메모리 구조는 유지하면서 차원만 바꿈
- view()처럼 메모리를 공유하지만, 연속적이지 않게 될 수 있음
1D
x = torch.tensor([[1, 2, 3],
[4, 5, 6]])
y = x.transpose(0, 1) # (2x3) -> (3x2)
print(y)
# 출력
# tensor([[1, 4],
# [2, 5],
# [3, 6]])
- transpose(0, 1) → 0번 차원과 1번 차원을 바꿈
- 메모리가 연속적이지 않아서 view()를 사용할 수 없을 수도 있음
2D
import torch
x = torch.tensor([[1, 2, 3],
[4, 5, 6]])
y = x.transpose(0, 1) # 0번(행)과 1번(열) 차원을 바꿈
print(y)
# 출력
# tensor([[1, 4],
# [2, 5],
# [3, 6]])
3D
x = torch.randn(2, 3, 4) # (batch, height, width)
y = x.transpose(1, 2) # height와 width를 바꿈
print(y.shape) # (2, 4, 3)
- x.shape = (2, 3, 4)
- y.shape = (2, 4, 3) → 1번(height)과 2번(width) 차원이 변경됨
permute()
- 새로운 메모리 또는 기존 메모리 사용
- 내부적으로 view()를 시도하지만, 필요하면 새로운 메모리를 할당함
- 메모리를 공유할 수도 있고, 새로 만들 수도 있음
x = torch.randn(2, 3, 4) # (batch, height, width)
y = x.permute(1, 0, 2) # (height, batch, width)
print(y.shape)
# 출력
# torch.Size([3, 2, 4])
- permute(1, 0, 2) → 1번 차원을 앞으로, 0번 차원을 뒤로, 2번 차원은 그대로 유지
- transpose()보다 더 유연함
contiguous()
- 메모리를 연속적으로 변경
- transpose()나 permute() 후 비연속적(non-contiguous)인 텐서를 연속적(contiguous)으로 변경
- view()를 사용하려면 contiguous()를 먼저 호출해야 할 수도 있음
x = torch.tensor([[1, 2, 3],
[4, 5, 6]])
y = x.transpose(0, 1) # 비연속적인 메모리
z = y.contiguous().view(1, 6) # 연속적인 메모리로 변환 후 view() 적용
print(z)
# 출력
# tensor([[1, 4, 2, 5, 3, 6]])
- transpose()는 비연속적이므로 view()를 바로 사용할 수 없음
- contiguous()를 호출해서 메모리를 새로 정렬한 후 view() 사용
반응형