2. 파이토치(PyTorch) 튜토리얼 - 텐서(Tensor)

Yeonghyeon·2022년 7월 27일
0
post-custom-banner

본 포스팅은 파이토치(PYTORCH) 한국어 튜토리얼을 참고하여 공부하고 정리한 글임을 밝힙니다.


텐서(TENSOR)

  • 텐서(tensor): 배열이나 행렬과 매우 유사한 특수한 자료구조
  • 모델 입력과 출력, 모델의 개매변수들을 부호화(encode) 함
import torch
import numpy as np

텐서(tensor) 초기화

데이터로부터 직접(directly) 생성하기

data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)

NumPy 배열로부터 생성하기

텐서는 numpy 배열로 생성 가능 (그 반대도 가능)

np_array = np.array(data)
x_np = torch.from_numpy(np_array)

다른 텐서로부터 생성하기:

x_ones = torch_ones_like(x_data) # x_data 속성 유지
print(f"Ones Tensor: \n {x_ones} \n")

x_rand = torch.rand_like(x_data, dtype=torch.float) # x_data 속성 덮어씀
print(f"Random Tensor: \n {x_rand} \n")

Out:

Ones Tensor:
 tensor([[1, 1],
        [1, 1]])

Random Tensor:
 tensor([[0.0965, 0.2738],
        [0.9675, 0.2934]])

무작위(random) 또는 상수(constant) 값을 사용하기:

shape = (2,3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)

print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")

Out:

Random Tensor:
 tensor([[0.8398, 0.8787, 0.4099],
        [0.6517, 0.2316, 0.1294]])

Ones Tensor:
 tensor([[1., 1., 1.],
        [1., 1., 1.]])

Zeros Tensor:
 tensor([[0., 0., 0.],
        [0., 0., 0.]])

텐서의 속성(Attribute)

텐서의 모양(shape), 자료형(datatype) 및 어느 장치에 저장되는지를 나타냄

tensor = torch.rand(3,4)

print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")

텐서 연산(Operation)

전치(transposing), 인덱싱(indexing), 슬라이싱(slicing), 수학 계산, 선형 대수, 임의 샘플링(random sampling) 등, 100가지 이상의 텐서 연산 가능

기본적으로 텐서는 CPU에 생성되는데, .to 메소드 사용하면 GPU로 텐서를 명시적으로 이동 가능

# GPU가 존재하면 텐서 이동
if torch.cuda.is_available():
	tensor = tensor.to("cuda")

NumPy식의 표준 인덱싱과 슬라이싱:

tensor = torch.ones(4,4)
print(f"First row: {tensor[0]}")
print(f"First column: {tensor[:, 0]}")
print(f"Last column: {tensor[..., -1]}")
tensor[:, 1] = 0
print(tensor)

Out:

First row: tensor([1., 1., 1., 1.])
First column: tensor([1., 1., 1., 1.])
Last column: tensor([1., 1., 1., 1.])
tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

텐서 합치기

torch.cat을 사용하면 주어진 차원에 따라 일련의 텐서 연결 가능
(torch.stack과 미묘하게

t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)

Out:

tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])

산술 연산(Arithmetic operations)

# 두 텐서 간의 행렬 곱(matrix multiplication) 계산
# y1, y2, y3은 모두 같은 값 가짐
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)

y3 = torch.rand_like(y1)
torch.matmul(tensor, tensor.T, out=y3)

# 요소 곱(element-wise product) 계산
# z1, z2, z3은 모두 같은 값 가짐
z1 = tensor * tensor
z2 = tensor.mul(tensor)

z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)

element-wise product: 행렬의 같은 위치의 성분들을 곱한 것(shape은 유지되겠지 / 브로드캐스팅 후)

단일-요소(single-element) 텐서

텐서의 모든 값을 하나로 집계(aggregate)하여 요소가 하나인 텐서의 경우 ìtem()을 사용하여 python 숫자 값으로 변환 가능

agg = tensor.sum()
agg_item = agg.item()
print(agg_item, type(agg_item))

Out:

12.0 <class 'float'>

바꿔치기(in-place) 연산

연산 결과를 피연산자에 저장하는 연산
ex) x.copy_(y) or x.t_()x를 변경함

print(f"{tensor} \n")
tensor.add_(5)
print(tensor)

Out:

tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

tensor([[6., 5., 6., 6.],
        [6., 5., 6., 6.],
        [6., 5., 6., 6.],
        [6., 5., 6., 6.]])

NumPy 변환(Bridge)

CPU 상의 텐서와 NumPy 배열은 메모리 공간을 공유 ➡️ 하나를 변경하면 다른 하나도 변경됨

텐서를 NumPy 배열로 변환하기

t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")

Out:

t: tensor([1., 1., 1., 1., 1.])
n: [1. 1. 1. 1. 1.]

텐서의 변경 사항이 NumPy 배열에 반영됨

t.add_(1)
print(f"t: {t}")
print(f"n: {n}")

Out:

t: tensor([2., 2., 2., 2., 2.])
n: [2. 2. 2. 2. 2.]

NumPy 배열을 텐서로 변환하기

n = np.ones(5)
t = torch.from_numpy(n)

NumPy 배열의 변경 사항이 텐서에 반영됨

np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")

Out:

t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
n: [2. 2. 2. 2. 2.]
post-custom-banner

0개의 댓글