전공공부/인공지능

Tensor manipulation -2

prefer_all 2022. 7. 27. 09:51

https://wikidocs.net/52846

<목차>
1. View
2. Squeeze
3. Unsqueeze
4. Type Casting
5. Concatenate, Stacking
*** dim
6. ones_like, zeros_like
7. In-place operation
**** _

 

View

  • 원소의 수를 유지하면서 텐서의 크기를 변경
  • numpy의 reshape와 같은 역할

import torch
import numpy as np

t = np.array([[[0, 1, 2],
               [3, 4, 5]],
              [[6, 7, 8],
               [9, 10, 11]]])
ft = torch.FloatTensor(t)
print(ft.shape) #torch.Size([2, 2, 3])

 

  • 3차원 텐서를 2차원 텐서로 변경
print(ft.view([-1, 3])) # ft라는 텐서를 (?, 3)의 크기로 변경
print(ft.view([-1, 3]).shape)
'''
tensor([[ 0.,  1.,  2.],
        [ 3.,  4.,  5.],
        [ 6.,  7.,  8.],
        [ 9., 10., 11.]])
torch.Size([4, 3])
'''

내부적인 크기 변환: (2, 2, 3) -> (2 × 2, 3) -> (4, 3)

  • view는 기본적으로 변경 전과 변경 후의 텐서 안의 원소의 개수가 유지되어야 합니다.
  • 파이토치의 view는 사이즈가 -1로 설정되면 다른 차원으로부터 해당 값을 유추합니다.

 

  • 3차원 텐서의 크기 변경
print(ft.view([-1, 1, 3]))
print(ft.view([-1, 1, 3]).shape)

'''
tensor([[[ 0.,  1.,  2.]],

        [[ 3.,  4.,  5.]],

        [[ 6.,  7.,  8.]],

        [[ 9., 10., 11.]]])
torch.Size([4, 1, 3])
'''

Squeeze

  • 차원이 1인 차원 제거
ft = torch.FloatTensor([[0], [1], [2]])
'''
tensor([[0.],
        [1.],
        [2.]])
torch.Size([3, 1])
'''

print(ft.squeeze())
print(ft.squeeze().shape)
'''
tensor([0., 1., 2.])
torch.Size([3])
'''

두번째 차원이 1이므로 (3,)를 가지는 텐서로 변경


Unsqueeze

  • 특정 위치에 1인 차원을 추가
ft = torch.Tensor([0, 1, 2])
print(ft.unsqueeze(0)) # 인덱스가 0부터 시작하므로 0은 첫번째 차원을 의미한다.
print(ft.unsqueeze(0).shape)
'''
tensor([[0., 1., 2.]])
torch.Size([1, 3])
'''

현재는 차원이 1개인 1차원 벡터. 첫번째 차원에 1인 차원 추가 (첫번째 차원의 index는 0임)

 

ft = torch.Tensor([0, 1, 2])
print(ft.unsqueeze(1))
print(ft.unsqueeze(1).shape)
'''
tensor([[0.],
        [1.],
        [2.]])
torch.Size([3, 1])
'''

 

 

ft = torch.Tensor([0, 1, 2])
print(ft.unsqueeze(-1))
print(ft.unsqueeze(-1).shape)
'''
tensor([[0.],
        [1.],
        [2.]])
torch.Size([3, 1])
'''

-1은 인덱스 상으로 마지막 차원을 의미. 현재 크기는 (3,)이었으므로 마지막 차원에 1인 차원을 추가하면 (3,1)의 크기를 가지게 됨


Type Casting

lt = torch.LongTensor([1, 2, 3, 4])
print(lt) #tensor([1, 2, 3, 4])
print(lt.float()) #tensor([1., 2., 3., 4.])
bt = torch.ByteTensor([True, False, False, True])
print(bt) #tensor([1, 0, 0, 1], dtype=torch.uint8)
print(bt.long()) #tensor([1, 0, 0, 1])
print(bt.float()) #tensor([1., 0., 0., 1.])

Concatenate

  • 두 개의 tensor 연결
x = torch.FloatTensor([[1, 2], [3, 4]])
y = torch.FloatTensor([[5, 6], [7, 8]])

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

print(torch.cat([x, y], dim=1))
'''
tensor([[1., 2., 5., 6.],
        [3., 4., 7., 8.]])
'''

torch.cat은 어느 차원을 늘릴 것인지를 인자로 줄 수 있음

예를 들어 dim=0은 첫번째 차원을 늘리라는 의미를 담고 있음

 

  • 딥 러닝에서는 주로 모델의 입력 또는 중간 연산에서 두 개의 텐서를 연결하는 경우가 많음 -> 두 텐서를 연결해서 입력으로 사용하는 것은 두 가지의 정보를 모두 사용한다는 의미

Stacking

  • 연결을 하는 또 다른 방법
x = torch.FloatTensor([1, 4])
y = torch.FloatTensor([2, 5])
z = torch.FloatTensor([3, 6])
print(torch.stack([x, y, z]))
'''
tensor([[1., 4.],
        [2., 5.],
        [3., 6.]])
'''

 

stacking을 torch.cat (concatenate)로 표현하면 아래와 동일

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

 

 

x = torch.FloatTensor([1, 4])
y = torch.FloatTensor([2, 5])
z = torch.FloatTensor([3, 6])
print(torch.stack([x, y, z], dim=1))
'''
tensor([[1., 2., 3.],
        [4., 5., 6.]])
'''

dim = 1은 두번째 차원이 증가하도록 쌓으라는 의미

(2,)의 크기를 가진 x,y,z에서 (2,3)이 되도록


ones_like /  zeros_like

  • 동일한 크기(shape)이지만 1 / 0 로만 값이 채워진 텐서 생성
x = torch.FloatTensor([[0, 1, 2], [2, 1, 0]])
print(torch.ones_like(x)) # 입력 텐서와 크기를 동일하게 하면서 값을 1로 채우기
'''
tensor([[1., 1., 1.],
        [1., 1., 1.]])
'''

print(torch.zeros_like(x)) # 입력 텐서와 크기를 동일하게 하면서 값을 0으로 채우기
'''
tensor([[0., 0., 0.],
        [0., 0., 0.]])
'''

In-place operation (덮어쓰기 연산)

x = torch.FloatTensor([[1, 2], [3, 4]])
print(x.mul(2.)) # 곱하기 2를 수행한 결과를 출력
print(x) # 기존의 값 출력
'''
tensor([[2., 4.],
        [6., 8.]])
tensor([[1., 2.],
        [3., 4.]])
'''

 곱하기 2를 수행했지만 이를 x에다가 다시 저장하지 않았으니, 곱하기 연산을 하더라도 기존의 값 x는 변하지 않음

 

x.mul_(2.)

x = torch.FloatTensor([[1, 2], [3, 4]])
print(x.mul_(2.))  # 곱하기 2를 수행한 결과를 변수 x에 값을 저장하면서 결과를 출력
print(x) # 기존의 값 출력
'''
tensor([[2., 4.],
        [6., 8.]])
tensor([[2., 4.],
        [6., 8.]])
'''