[PyTorch] Tensor Manipulation 2 실습 : 모두를 위한 딥러닝 시즌2

2024. 8. 30. 17:31Artificial Intelligence/모두를 위한 딥러닝 (PyTorch)

Torch.FloatTensor.view로 텐서 모양 변형시키기

 괄호가 복잡하다보니 조금 헷갈렸지만, 예제마다 Shape를 (a, b, c)로 표현했을 때 각각의 값이 무엇인지 정확하게 이해하려고 노력했다. view에 인자로 주어지는 값 중 -1이 있는 곳은 PyTorch가 자동으로 크기를 계산하도록 하는 자리이다.

 

라이브러리 import

import numpy as np
import torch

 

View (Reshape)

# View (Reshape)
t = np.array([[[0, 1, 2],
               [3, 4, 5]],

              [[6, 7, 8],
              [9, 10, 11]]])
ft = torch.FloatTensor(t)
print(ft.shape)

print(ft.view([-1, 3]))
print(ft.view([-1, 3]).shape)

print(ft.view([-1, 1, 3]))
print(ft.view([-1, 1, 3]).shape)

Squeeze와 Unsqueeze로 차원 변형시키기

 Squeeze와 Unsqueeze는 텐서의 차원을 조작하는 데 주로 사용되며, 인자로 차원(dimension)을 받는다. Squeeze는 지정된 위치에 있는 크기가 1인 차원을 제거하며, Unsqueeze는 지정된 위치에 차원을 추가한다. 언제나 그렇듯이 dim은 0은 첫 번째 차원, -1은 가장 마지막 차원(뒤에서부터 첫 번째)을 의미한다.

 

Squeeze & Unsqueeze

# Squeeze
ft = torch.FloatTensor([[0], [1], [2]])
print(ft)
print(ft.shape)

print(ft.squeeze(1))
print(ft.squeeze().shape)
# Unsqueeze
ft = torch.Tensor([0, 1, 2])
print(ft.shape)

print(ft.unsqueeze(0)) # 텐서의 첫 번째 위치에 새로운 차원 추가
print(ft.unsqueeze(0).shape)

print(ft.view(1, -1))
print(ft.view(1, -1).shape)

print(ft.unsqueeze(1))  # 텐서의 두 번째 위치에 새로운 차원 추가
print(ft.unsqueeze(1).shape)

print(ft.unsqueeze(-1))  # 텐서의 마지막 위치에 새로운 차원 추가 
print(ft.unsqueeze(-1).shape)

나머지 기본 연산

 타입 캐스팅, 텐서의 병합 및 스택, 동일한 모양의 0 또는 1로 채워진 텐서 생성, 대체 연산자 등은 비교적 간단한 내용이라서 가볍게 짚고 넘어가면 될 것 같다.

 

타입 캐스팅

# Type Casting
lt = torch.LongTensor([1, 2, 3, 4])
print(lt)

print(lt.float())

bt = torch.ByteTensor([True, False, False, True])
print(bt)

print(bt.long())
print(bt.float())

 

병합

# Concatenate
x = torch.FloatTensor([[1, 2], [3, 4]])
y = torch.FloatTensor([[5, 6], [7, 8]])
print(torch.cat([x, y], dim=0))
print(torch.cat([x, y], dim=1))

 

스택

# Stacking
x = torch.FloatTensor([1, 4])
y = torch.FloatTensor([2, 5])
z = torch.FloatTensor([3, 6])

print(torch.stack([x, y, z]))
print(torch.stack([x, y, z], dim=1))
print(torch.cat([x.unsqueeze(0), y.unsqueeze(0), z.unsqueeze(0)], dim=0))

 

동일한 모양의 0 또는 1로 채워진 텐서

# Ones and Zeros
x = torch.FloatTensor([[0, 1, 2], [2, 1, 0]])
print(x)

print(torch.ones_like(x))
print(torch.zeros_like(x))

 

대체 연산자 (기존 값 덮어쓰기)

# In-place Operation
x = torch.FloatTensor([[1, 2], [3, 4]])
print(x.mul(2.))
print(x)
print(x.mul_(2.))  # _ 를 사용하면 값을 덮어씀.
print(x)

느낀 점

  • 텐서의 모양 및 차원에 대한 내용은 복잡하기 때문에, 함수의 인자가 의미하는 바를 정확히 알고 사용해야 할 것 같다.
  • view 함수에서 -1은 단순 인덱스가 아니라, PyTorch가 자동으로 계산하도록 지정하는 것임을 알게 되었다.
  • unsqueeze에서 지정된 곳에 차원을 추가한다는 개념이 조금 어색했는데, 인자로 -1, 0, 1을 주었을 때의 결과를 비교해 보면서 이해할 수 있었다. 

 

*참고 자료

모두를 위한 딥러닝 시즌2 - PyTorch: [PyTorch] Lab-01-2 Tensor Manipulation 2

https://youtu.be/XkqdNaNQGx8?feature=shared