개발로 자기계발
article thumbnail
728x90

형태 변환

1) Reshape

원하는 형상의 새로운 텐서를 얻을 수 있다. reshape 함수는 원본 텐서의 데이터를 보존하면서 새로운 형상의 텐서를 생성한다.

원본 텐서와 새로운 형상의 텐서는 동일한 메모리를 공유하므로, 하나를 변경하면 다른 하나도 변경된다.

 

원본 데이터

import torch
x = torch.arange(1., 10.)
x, x.shape

형태 변환(2차원의 텐서)

x_reshaped = x.reshape(1,9)
x_reshaped, x_reshaped.shape

* 대신 형태를 변환할 때 기존 원본 데이터의 범위 안에서만 가능하다.

형태 변환(3차원의 텐서)

x_reshaped = x.reshape(1,1,9)
x_reshaped, x_reshaped.shape

동일한 메모리 공유 확인(x의 1번째 인덱스 값을 변경한다.)

x[0] = 100
print('x:', x)
print('x_reshaped:', x_reshaped)


## 결과 ##
x: tensor([100.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.])
x_reshaped: tensor([[100.,   2.,   3.],
        [  4.,   5.,   6.],
        [  7.,   8.,   9.]])

 

2) View

개념은 Reshape와 동일하나 무조건 원본 데이터를 참조해야 하는 차이가 있다.

형태 변환(2차원의 텐서)

x_view = x.view(1,9)
x_view, x_view.shape

형태 변환(3차원의 텐서)

x_view = x.view(1,1,9)
x_view, x_view.shape

동일한 메모리 공유 확인(x의 1번째 인덱스 값을 변경한다.)

x[0] = 100
print('x:', x)
print('x_view:', x_view)


## 결과 ##
x: tensor([100.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.])
x_reshaped: tensor([[100.,   2.,   3.],
        [  4.,   5.,   6.],
        [  7.,   8.,   9.]])

 

Reshape와 View의 차이점

import torch

# 임의의 텐서 생성
x = torch.randn(2, 3)
print("Original tensor:")
print(x)

# 텐서 형상 변경: reshape
y = x.reshape(3, 2)
print("\nReshaped tensor using reshape:")
print(y)

# 텐서 형상 변경: view
z = x.view(3, 2)
print("\nReshaped tensor using view:")
print(z)

# 연속 메모리를 가지지 않은 텐서 생성
a = x.t()  # x의 전치행렬(transpose)를 구한다.
print("\nTransposed tensor:")
print(a)

# 텐서 형상 변경: reshape (연속 메모리가 아닌 경우에도 작동)
b = a.reshape(3, 2)
print("\nReshaped transposed tensor using reshape:")
print(b)

# 텐서 형상 변경: view (연속 메모리가 아닌 경우에는 오류 발생)
try:
    c = a.view(3, 2)
except RuntimeError as e:
    print("\nError using view on non-contiguous tensor:")
    print(e)

 

차원 쌓기

 텐서를 결합하는 함수 중 하나

import torch

x1 = torch.tensor([1.,2., 3.])
x2 = torch.tensor([4.,3., 5.])
x3 = torch.tensor([5.,6., 7.])
# 행
x_stack = torch.stack([x1, x2, x3], dim=0)
# 열
x_1_stack = torch.stack([x1, x2, x3], dim=1)

결과값

tensor([[1., 2., 3.],
        [4., 3., 5.],
        [5., 6., 7.]])
tensor([[1., 4., 5.],
        [2., 3., 6.],
        [3., 5., 7.]])

 

압착

1) Squeeze

import torch

a = torch.rand(2, 1, 3)

print('a:', a)
print('a shape:', a.shape)

a_squeezed = a.squeeze()

print('a_squeezed:', a_squeezed)
print('a_squeezed shape:', a_squeezed.shape)

결괏값

a: tensor([[[0.5874, 0.9864, 0.7887]],

        [[0.0157, 0.1888, 0.4364]]])
a shape: torch.Size([2, 1, 3])
a_squeezed: tensor([[0.5874, 0.9864, 0.7887],
        [0.0157, 0.1888, 0.4364]])
a_squeezed shape: torch.Size([2, 3])

 

2) Unsqueeze

import torch

a = torch.rand(2, 3)

print('a:', a)
print('a shape:', a.shape)

a_unsqueezed = a.unsqueeze(dim=0)

print('a_unsqueezed:', a_unsqueezed)
print('a_unsqueezed shape:', a_unsqueezed.shape)

* dim 0을 전달하면 첫 번째 차원이 추가되고, 전체적으로 한 차원씩 밀려나게 됩니다.

* dim 1을 전달하면 두 번째 차원이 추가된다.

결괏값

a: tensor([[0.7256, 0.1291, 0.2008],
        [0.0711, 0.8476, 0.0352]])
a shape: torch.Size([2, 3])
a_unsqueezed: tensor([[[0.7256, 0.1291, 0.2008],
         [0.0711, 0.8476, 0.0352]]])
a_unsqueezed shape: torch.Size([1, 2, 3])

 

순서 변경

import torch

a = torch.rand(2, 3, 4)

print('a:', a)
print('a shape:', a.shape)

a_permuted = a.permute(1, 2, 0)

print('a_permuted:', a_permuted)
print('a_permuted shape:', a_permuted.shape)

* permute() 안의 매개변수는 순서가 된다.

a: tensor([[[0.3253, 0.6912, 0.4481, 0.5024],
         [0.7467, 0.9732, 0.8194, 0.5306],
         [0.7311, 0.0787, 0.2829, 0.8404]],

        [[0.1298, 0.9801, 0.8141, 0.0554],
         [0.5422, 0.9722, 0.7657, 0.1052],
         [0.4986, 0.0543, 0.0366, 0.2813]]])
a shape: torch.Size([2, 3, 4])
a_permuted: tensor([[[0.3253, 0.7467],
         [0.6912, 0.9732],
         [0.4481, 0.8194],
         [0.5024, 0.5306]],

        [[0.1298, 0.5422],
         [0.9801, 0.9722],
         [0.8141, 0.7657],
         [0.0554, 0.1052]],

        [[0.7311, 0.4986],
         [0.0787, 0.0543],
         [0.2829, 0.0366],
         [0.8404, 0.2813]]])
a_permuted shape: torch.Size([3, 4, 2])
728x90
SMALL

'인공지능 > PyTorch' 카테고리의 다른 글

PyTorch - GPU 설정 (7)  (0) 2023.04.24
PyTorch - 파이토치 기초 (6)  (0) 2023.04.23
PyTorch - 파이토치 기초 (4)  (2) 2023.04.23
PyTorch - 파이토치 기초 (3)  (0) 2023.04.18
PyTorch - 텐서란? (2)  (0) 2023.04.18
profile

개발로 자기계발

@김잠봉

틀린부분이나 조언이 있다면 언제든 환영입니다:-)