본문 바로가기

Python/머신러닝(ML)

Python(28)- 파이토치

*이 글을 읽기전에 작성자 개인의견이 있으니, 다른 블로그와 교차로 읽는것을 권장합니다.*

1. 파이토치(Pytorch)

  • Tensorflow와 함께 머신러닝, 딥러닝에서 가장 널리 사용되는 프레임워크
  • 초기에는 Torch라는 이름으로 Lua언어 기반으로 만들어졌으나, 파이썬 기반으로 변경한 것이 Pytorch
  • 뉴욕대학교와 페이스북(메타)이 공동으로 개발하였고, 현재 가장 대중적인 머신러닝, 딥러닝 프레임워크
  • 파이토치는 배포과정에서 tensorflow보다 복잡하고 어려움. -> 전반적인 MLops과정
import torch
print(torch.__version__)

1-1. 스칼라(Scalar)

  • 하나의 상수를 의미
var1 = torch.tensor([1])
var1

type(var1)

var2= torch.tensor([10.5])
var2

# 두 스칼라의 사칙 연산
print(var1 + var2)
print(var1 * var2)
print(var1 - var2)
print(var1 / var2)

1-2. 벡터(Vector)

  • 상수가 2개 이상 나열된 경우
vec1 = torch.tensor([1,2,3])
vec1

vec2 = torch.tensor([1.5, 2.4, 3.3])
vec2

# 두 벡터의 사칙 연산
print(vec1 + vec2)
print(vec1 - vec2)
print(vec1 * vec2)
print(vec1 / vec2)

vec3 = torch.tensor([5,10,15,20])

# vec1 + vec3 # RuntimeError: The size of tensor a (3) must match the size of tensor b (4) at non-singleton dimension 0

1-3. 행렬(Matrix)

  • 2개 이상의 벡터값을 가지고 만들어진 값으로 행과 열의 개념을 가진 데이터의 나열
mat1 = torch.tensor([[1,2],[3,4]])
print(mat1)

mat2 = torch.tensor([[7,8], [9,10]])
print(mat2)

# 두 행렬의 사칙연산
print(mat1 + mat2)
print(mat1 - mat2)
print(mat1 * mat2)
print(mat1 / mat2)

1-4. 텐서(Tensor)

  • 다수의 행렬이 모이면 텐서 (행렬들의 집합)
  • 배열이나 행렬과 매우 유사한 특수 자료구조
  • 파이토치는 텐서를 사용하여 모델의 입력과 출력, 모델의 매개변수들을 처리

tensor1 = torch.tensor([[[1,2], [3,4]], [[5,6], [7,8]]])
tensor1

tensor2 = torch.tensor([[[9,10], [11,12]], [[13,14], [15,16]]])
tensor2

# 두 텐서의 사칙연산
print(tensor1 + tensor2)
print(tensor1 - tensor2)
print(tensor1 * tensor2)
print(tensor1 / tensor2)

print(torch.add(tensor1, tensor2))
print(torch.subtract(tensor1, tensor2))
print(torch.multiply(tensor1, tensor2))
print(torch.divide(tensor1, tensor2))
print(torch.matmul(tensor1, tensor2))

print(tensor1.add_(tensor2)) # tensor1에 결과를 다시 저장
print(tensor1.subtract_(tensor2)) # 모든 사칙연산자에 _를 붙이면 inplace=True가 됨


2. 텐서의 변환

data = [[1,2], [3,4]]
print(data)

x_data = torch.tensor(data)
print(x_data)

import numpy as np

np_array = np.array(x_data)
np_array

x_np_1 = torch.tensor(np_array)
x_np_1

x_np_1[0,0] = 100
print(x_np_1)
print(np_array)

# as_tensor(): ndarray와 동일한 메모리 주소를 가리키는 뷰를 만듦
x_np_2 = torch.as_tensor(np_array)
print(x_np_2)
x_np_2[0,0] = 200
print(x_np_2)
print(np_array)

# from_numpy(): ndarray와 동일한 메모리 주소를 가리키는 뷰를 만듦
x_np_3 = torch.from_numpy(np_array)
print(x_np_3)
x_np_3[0,1] = 400
print(x_np_3)
print(np_array)

np_again = x_np_3.numpy()
print(np_again, type(np_again))


3. 파이토치 주요 함수

a = torch.ones(2,3)
print(a)

b = torch.zeros(2,3)
print(b)
# scaling값이 0~1인데, 컴퓨터비전에서  영상이 행렬형태로 되어있음
# 이미지색상이 0~256가지인데, 0~1사이로 scaling할때,
# 0은 검정색, 1은 흰색이기에 영상을 만듦
# 기본값을 0-흰색으로 하냐, 1-검정색으로 하냐 차이

c = torch.full((2,3), 10)
print(c)

d = torch.empty(2,3)
print(d)
# 아무 실수 채움

e = torch.eye(5)
print(e)
# 대각선이 1인 정방행렬 생성

f = torch.arange(10)
print(f)
# 0~10 값

g = torch.rand(2,3)
print(g)
# 0~1 사이 랜덤값

h = torch.randn(2,3)
print(h)
# 평균이 0 이고 표준편차가 1인 정규분포에서 무작위 샘플링
# 표준정규분포

i = torch.arange(24).reshape(3, 2, 4)
print(i, i.shape)
# (2,4) * 2 -> 2차원 2행4열

# permute(): 차원을 지정한 인덱스로 변환
# i = (2,2,4)
j = i.permute((2,0,1)) #(3,2,4) -> (4, 3, 2)
print(j, j.shape)


4. 텐서의 인덱싱과 슬라이싱

a = torch.arange(1,13).reshape(3,4)
print(a)

print(a[1]) #1행
# 인덱싱을 하면 차원 -1 기억✔

print(a[0, -1]) #0행 -1열 = 0행4열
# 인덱싱 2번

print(a[1:-1]) #슬라이싱: 대괄호(차원) 유지

print(a[:2, 2:]) # 0행 2열, 0행3열, 1행2열, 1행3열


5. 코랩에서 GPU 사용하기

  • 코랩에서 device 변경하는 방법
    • 상단 메뉴 -> 런타임 -> 런타임 유형변경 -> 하드웨어 가속기를 GPU로 변경 -> 저장 -> 세션 다시 시작 및 모두 실행 TPU는 학습용으로 CPU처럼 사용할 수 있는

tensor = torch.rand(3,4)
print(tensor)
print(f'shape: {tensor.shape}')
print(f'type: {type(tensor)}')
print(f'dtype: {tensor.dtype}')
print(f'device: {tensor.device}')

# is_available(): gpu를 사용할 수 있는지 여부
tensor = tensor.reshape(4,3)
tensor = tensor.int()
print(f'shape: {tensor.shape}')
print(f'type: {type(tensor)}')
print(f'dtype: {tensor.dtype}')
if torch.cuda.is_available():
    print('GPU 사용 가능')
    tensor = tensor.to('cuda')
print(f'device: {tensor.device}')