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 |