본문 바로가기
AI/딥러닝

[ML/DL] 파이토치,텐서,GPU

by 바다의 공간 2024. 7. 18.

<DL>에서는 용어 정말 중요하니까 용어!!!꼭!!! 숙지해두기


1. 파이토치(Pytorch)

  • 텐서플로우와 함께 머신러닝, 딥러닝에서 가장 널리 사용되는 프레임워크
  • 초기에는 Torch라는 이름으로 Lua언어 기반으로 만들어졌으나, 파이썬기반으로 변경한 것이 파이토치입니다.
  • 뉴욕대학교와 페이북(메타)이 공동으로 개발하였고, 현재 가장 대중적이고 사용자가 많은 머신러닝, 딥러닝 프레임워크 입니다.
import torch
print(torch.__version__) #파이토치 버전확인방법
#2.3.0+cu121

1-1. 스칼라(Scalar)

  • 하나의 상수를 의미 
var1 = torch.tensor([10]) #텐서함수의 표현방법
var1
# tensor([10])

type(var1)
# torch.Tensor

var2 = torch.tensor([10.5]) #실수
var2 
# tensoor([10.5])

 

스칼라의 사칙연산

print(var1 + var2) #tensor([20.5000])
print(var1 - var2) #tensor([-0.5000])
print(var1 * var2) #tensor([105.])
print(var1 / var2) #tensor([0.9524])

파이토치에서 계산을 하려고하면 텐서함수로 만들어야합니다.

1+ 1.4

2+2.5

3+3.3각가 이렇게 연산이 되는것을 확인할 수 있습니다.


1-2.벡터(Vector)

  • 상수가 두 개 이상 나열된 경우.
  • 데이터가 두개 이상 배열되어있는 것
vec1 = torch.tensor([1,2,3])
vec1
# tensor([1, 2, 3])

vec2 = torch.tensor([1.4, 2.5, 3.3])
vec2
# tensor([1.4000, 2.5000, 3.3000])

 

두 벡터의 사칙 연산

print(vec1 + vec2) #tensor([2.4000, 4.5000, 6.3000])
print(vec1 - vec2) #tensor([-0.4000, -0.5000, -0.3000])
print(vec1 * vec2) #tensor([-0.4000, -0.5000, -0.3000])
print(vec1 / vec2) #tensor([0.7143, 0.8000, 0.9091])
vec3 = torch.tensor([5, 10])
vec3 #tensor([ 5, 10])

에러가 나는 경우

#vec1 + vec3 은 에러가 납닌다 그 이유는 사이즈가 맞지 않아서입니다.

1-3.행렬(Matrix)

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

#tensor([[1, 2],
#        [3, 4]])
-----------------------------------------
mat2 = torch.tensor([[7,8], [9,10]])
mat2

#tensor([[ 7,  8],
#        [ 9, 10]])

 

두 행렬의 사칙 연산

print(mat1 + mat2)

#tensor([[ 8, 10],
#        [12, 14]])
---------------------------
print(mat1 - mat2)

#tensor([[-6, -6],
#        [-6, -6]])

---------------------------
print(mat1 * mat2)

#tensor([[ 7, 16],
#        [27, 40]])

---------------------------
print(mat1 / mat2)

#tensor([[0.1429, 0.2500],
#        [0.3333, 0.4000]])

1-4.텐서(Tensor)

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


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

#tensor([[[1, 2],
#         [3, 4]],

#        [[5, 6],
#         [7, 8]]])
tensor2 = torch.tensor([[[9,10], [11,12]], [[13,14], [15,16]]])
tensor2

#tensor([[[ 9, 10],
#         [11, 12]],

#        [[13, 14],
#         [15, 16]]])

두 텐서의 사칙 연산

print(tensor1 + tensor2)

#tensor([[[10, 12],
#         [14, 16]],

#        [[18, 20],
#         [22, 24]]])
-----------------------------------

print(tensor1 - tensor2)

#tensor([[[-8, -8],
#         [-8, -8]],

#        [[-8, -8],
#         [-8, -8]]])
-----------------------------------
print(tensor1 * tensor2)

#tensor([[[  9,  20],
#         [ 33,  48]],

#        [[ 65,  84],
#         [105, 128]]])

-----------------------------------
print(tensor1 / tensor2)

#tensor([[[0.1111, 0.2000],
#         [0.2727, 0.3333]],

#        [[0.3846, 0.4286],
#         [0.4667, 0.5000]]])

함수를 이용한 사칙연산

print(torch.add(tensor1, tensor2))

#tensor([[[10, 12],
#         [14, 16]],

#        [[18, 20],
#         [22, 24]]])
-----------------------------------------
print(torch.subtract(tensor1, tensor2))

#tensor([[[-8, -8],
#         [-8, -8]],

#        [[-8, -8],
#         [-8, -8]]])


-----------------------------------------
print(torch.multiply(tensor1, tensor2))

#tensor([[[  9,  20],
#         [ 33,  48]],

#        [[ 65,  84],
#         [105, 128]]])


-----------------------------------------
print(torch.divide(tensor1, tensor2))

#tensor([[[0.1111, 0.2000],
#         [0.2727, 0.3333]],

#        [[0.3846, 0.4286],
#         [0.4667, 0.5000]]])

-----------------------------------------
print(torch.matmul(tensor1, tensor2))

#tensor([[[ 31,  34],
#         [ 71,  78]],

#        [[155, 166],
#         [211, 226]]])

 

변수에넣지않고 인플레이스 할 수 있습니다.

print(tensor1.add_(tensor2)) #tensor1의 결과를 다시 저장

#tensor([[[10, 12],
#         [14, 16]],

#        [[18, 20],
#         [22, 24]]])

--------------------------------------------------------------------------
print(tensor1.subtract_(tensor2)) #_(언더바)를 치면 인플레이스가 가능함

#tensor([[[1, 2],
#         [3, 4]],

#        [[5, 6],
#         [7, 8]]])

2.파이토치와 텐서

data = [[1,2], [3,4]]
data

#[[1, 2], [3, 4]]

 

 

텐서형으로 변경해보기

data_tensor = torch.tensor(data)
data_tensor

#tensor([[1, 2],
#        [3, 4]])

 

 

ndarray형으로 변경하기 위한 임포트

import numpy as np

 

텐서-> ndarray로 변경해보기

 

ndarray = np.array(data_tensor) #텐셔형이 dnarry로 변경된것을 확인할 수 있음.
ndarray

#array([[1, 2],
#       [3, 4]])

 ndarray-> 텐서 로 변경해보기

data_tensor = torch.tensor(ndarray)
data_tensor

#tensor([[1, 2],
#        [3, 4]])

a = torch.ones(2, 3)
a
#요소들을 모두 행렬로 만들어줌 2행 3열짜리

ones = 요소들을 1로 만들어줌 

사용이 없어보이지만 vision할때 이미지 활용할떄 굉장히 많이 씁니다.

 

b = torch.zeros(3,4)
b

c = torch.full((3,4), 7)
c

원하는 크기에 원하는 숫자를 넣어줄 수 있습니다.

3*4짜리 7로 채워진 행렬을 만들게됩니다.

 

d = torch.empty(2,3)
d

랜덤한 값을 실수로 채워줍니다.(의미없는 값)

 

e = torch.eye(5)
e

5*5 정방향렬에 1을 사선으로 채웁니다 \ 

6을 넣으면 6*6이 되겠죠.

f = torch.arange(10)
f

순서대로 0부터 10이되기 직전까지숫자를 나열하게 됩니다.

g = torch.rand(2,3)
g

 

0부터 1이되기직전까지의 랜덤한 숫자를 써줍니다. 아래와 비슷합니다.

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

 

평균이 0이고 표준편차가 1인 정규분포라는점이 살짝 다릅니다.

 

이것은 필수입니다.
i = torch.arange(16).reshape(2, 2, 4) #너무너무너무너무 필수로 알아야함#####
i, i.shape

0부터 15까지의 순차적인 정보를 저장하고 reshape를 하게되면 이것은 차원을 바꾸겠다는 의미입니다.

1. 만든것을 reshape하고 2행4열짜리 2개를 넣는다는 말입니다.

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

텐서의 인덱싱, 슬라이싱

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

a[1]
#tensor([5, 6, 7, 8])

a[0,-1]
#tensor(4)

덱싱을하면 차원이 줄어든다는 점을 확인해야합니다

매트릭스->하나 줄어들어서 스라가 됩니다.

a[1:-1]
>>>1번 행에서부터 -1이되기 직전까지의 행
#tensor([[ 5,  6,  7,  8]])


a[:2, 2:]
>>>행은 0이 되기 직전까지의 행,
>>>열은 2부터~
그러면 2열 3열이 됩니다. 여기서는 차원축소가 이루어지지않기에
#tensor([[3, 4],
#        [7, 8]])

3. 코랩에서 GPU 사용하기

  • 코랩에서 device 변경하는 방법
    • 상단 메뉴 -> 런타임 유형 변경-> GPU변경 -> 하드웨어 가속기를 GPU로 변경 -> 저장 -> 세션 다시 시작 및 모두 실행 (처음부터 다시 시작)
    •  
tensor = torch.rand(3,4)
tensor

print(f'shape: {tensor.shape}')
print(f'type: {type(tensor)}')
print(f'dtype: {tensor.dtype}')

# is_available(): gpu를 사용할 수 있는지 여부
if torch.cuda.is_available():
  print('GPU 사용할 수 있음')
  tensor = tensor.to('cuda')
print(f'device: {tensor.device}')

이렇게 gpu까지 확인할 수 있었습니다.