상세 컨텐츠

본문 제목

[PyTorch 시작하기] 1. 텐서(TENSOR)

PROGRAMMING/AI

by koharin 2023. 7. 10. 23:24

본문

728x90
반응형

텐서(TENSOR)

  • 배열(array)이나 행렬(matrix)과 유사한 특수한 자료구조
  • PyTorch에서는 텐서를 사용해서 모델의 입력(input)과 출력(output), 모델 매개변수들을 부호화(encode)함
  • GPU나 다른 하드웨어 가속기에서 실행 가능
  • 텐서와 Numpy 배열은 동일한 내부(underly) 메모리를 공유할 수 있어 데이터를 복사할 필요없음
  • 자동 미분(automatic differentiation)에 최적화됨

 

Dependency 추가

import torch
import numpy as np

 

텐서(tensor) 초기화

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

data = [[1,2], [3,4]] 
x_data = torch.tensor(data) 
print(x_data)
tensor([[1, 2],
        [3, 4]])
  • 데이터로부터 직접 텐서를 생성하는 방법.
  • 데이터의 자료형(data type)은 자동으로 유추함.

 

2. Numpy 배열로부터 생성하기

 
np_array = np.array(data) 
x_np = torch.from_numpy(np_array) 
print(x_np)
tensor([[1, 2],
        [3, 4]])
  • Numpy 배열로 텐서를 생성하는 방법.
  • 텐서로 Numpy 변환도 가능? (t가 텐서면 t.numpy()₩는 Numpy 배열로 변환된 것)

 

3. 다른 텐서로부터 생성하기

x_ones = torch.ones_like(x_data) # x_data 속성 유지 
print(f"Ones Tensor: {x_ones}") 

x_rand = torch.rand_like(x_data, dtype=torch.float) # x_data 속성 덮어씀 
print(f"Random Tensor: {x_rand}")
Ones Tensor: tensor([[1, 1],
        [1, 1]])
Random Tensor: tensor([[0.5537, 0.7568],
        [0.8950, 0.5985]])
  • 명시적으로 재정의(override)하지 않는 한, 인자로 준 텐서의 속성(모양(shape), 자료형(data type)) 유지함.

 

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

shape = (2,3,) 

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

print(f"Random Tensor: {rand_tensor}") 
print(f"Ones Tensor: {ones_tensor}") 
print(f"Zeros Tensor: {zeros_tensor}")
Random Tensor: tensor([[0.6368, 0.1620, 0.9743],
        [0.3274, 0.8058, 0.1275]])
Ones Tensor: tensor([[1., 1., 1.],
        [1., 1., 1.]])
Zeros Tensor: tensor([[0., 0., 0.],
        [0., 0., 0.]])
  • shape: 텐서의 차원(dimension) 나타내는 튜플(tuple)로, 함수들에서의 출력 텐서의 차원을 결정함

 

텐서의 속성(Attribute)

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}")
Shape of tensor: torch.Size([3, 4])
Datatype of tensor: torch.float32
Device tensor is stored on: cpu
  • shape: 텐서의 모양(shape)
  • dtype: 자료형(data type)
  • device: 텐서가 어느 장치에 저장되는지

 

텐서 연산(Operation)

텐서 이동

print(f"Device tensor is stored on: {tensor.device}") 

# GPU가 존재하면, 텐서를 GPU로 이동 
if torch.cuda.is_available(): 
	tensor = tensor.to("cuda") 
    print(f"Device tensor is stored on: {tensor.device}")
Device tensor is stored on: cpu
  • 디폴트로 텐서는 CPU에 저장되는데, .to 메소드를 사용하여 GPU로 텐서를 명시적으로 이동 가능.
  • 그러나, 장치 간 텐서 복사하는 것은 시간과 비용이 많이든다.

 

Numpy식의 표준 인덱싱과 슬라이싱

tensor = torch.ones(4,4) # 4 x 4 shape의 1로만 구성된 텐서 생성 

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

tensor[:,1] = 0 # Second column을 모두 0로 설정 

print(tensor)
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.]])

 

텐서 합치기

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

print(t1)
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.]])
  • torch.cat: 주어진 차원에 따라 일련의 텐서 연결.

 

산술 연산(Arithmetic operations)

# 두 텐서 간 행렬 곱(matrix multiplication) 계산 
# `tensor.T`는 텐서의 전치(transpose)를 반환 
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 = tensor * tensor 
z2 = tensor.mul(tensor) 
z3 = torch.rand_like(tensor) 
torch.mul(tensor, tensor, out=z3)
tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

 

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

agg = tensor.sum() # 텐서의 모든 값을 하나로 집계(aggregate) 
agg_item = agg.item() # 요소가 하나인 텐서의 경우, item() 사용하여 숫자값으로 반환 
print(agg_item, type(agg_item))
12.0 <class 'float'>

 

바꿔치기(in-place) 연산

print(f"{tensor}") 
tensor.add_(5) p
rint(tensor)
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.]])
  • 연산 결과를 피연산자(operand)에 저장하는 연산으로, _ 접미사를 갖는다.
  • x.copy(y)나 x.t_()는 x를 변경
  • 바꿔치기 연산은 메모리 일부 절약하지만, 기록(history)dㅣ 즉시 삭제되어 도함수(derivative) 계산 문제 발생할 수 있어 사용 권장 X
728x90
반응형

관련글 더보기