수업 복습/머신러닝과 딥러닝
파이토치
김복칠
2024. 1. 9. 16:58
1. 파이토치(Pytorch)
- Tensorflow와 함께 머신러닝, 딥러닝에서 가장 널리 사용되는 프레임워크
- 초기에는 Torch라는 이름으로 Lua언어 기반으로 만들어졌으나, 파이썬 기반으로 변경한 것이 Pytorch
- 뉴욕대학교와 페이스북(메타)이 공동으로 개발하였고, 현재 가장 대중적인 머신러닝, 딥러닝 프레임워크
import torch
- 파이토치를 이용하고자 할때는 위와같이 import를 해주면 됩니다
1-1. 스칼라(Scalar)
- 하나의 상수를 의미 (데이터가 하나만 들어가 있는 경우)
var1 = torch.tensor([1])
var1
# 결과 : tensor([1])
type(var1)
# 결과 : torch.Tensor
# 두 스칼라의 사칙 연산
print(var1 + var2)
print(var1 - var2)
print(var1 * var2)
print(var1 / var2)
# 결과 : tensor([11.4000]) // tensor([-9.4000]) // tensor([10.4000]) // tensor([0.0962])
- import 한 torch를 이용해 보고자 임의로 1을 넣어서 입력해주면 tensor 형태의 데이터로 출력되는걸 볼수 있습니다
1-2. 벡터(Vector)
- 상수가 두 개 이상 나열된 경우
vec1 = torch.tensor([1,2,3])
vec1
# 결과 : tensor([1, 2, 3])
vec2 = torch.tensor([1.5,2.4,3.3])
vec2
# 결과 : tensor([1.5000, 2.4000, 3.3000])
# 두 벡터의 사칙연산
print(vec1 + vec2)
print(vec1 - vec2)
print(vec1 * vec2)
print(vec1 / vec2)
# 결과 : tensor([2.5000, 4.4000, 6.3000]) // tensor([-0.5000, -0.4000, -0.3000]) // tensor([1.5000, 4.8000, 9.9000]) // tensor([0.6667, 0.8333, 0.9091])
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)
print(mat1 - mat2)
print(mat1 * mat2)
print(mat1 / mat2)
# 결과 : tensor([[ 8, 10], [12, 14]]) // tensor([[-6, -6], [-6, -6]]) // tensor([[ 7, 16], [27, 40]]) // tensor([[0.1429, 0.2500], [0.3333, 0.4000]])
1-4. 텐서(Tensor)
- 다수의 행렬이 모이면 텐서
- 배열이나 행렬과 매우 유사한 특수 자료구조
- 파이토치는 텐서를 사용하여 모델의 입력과 출력, 모델의 매개변수들을 처리
- 텐서도 위의 자료구조와 동일하게 사칙연산으로 계산이 가능합니다
- 이외의 다양한 함수들로 계산식을 대체할 수 있습니다
# 덧셈
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))
# tensor1에 결과를 다시 저장. 모든 사칙연산자에 _를 붙이면 inplace가 됨
print(tensor1.add_(tensor2))
2. 텐서의 변환
data = [[1,2],[3,4]]
x_data = torch.tensor(data)
import numpy as np
np_array = np.array(data)
np_array
# 결과 : array([[1, 2], [3, 4]])
- 임의의 데이터를 생성한 뒤 텐서 형태로 만들어줍니다
- 이후 np_array 형태로 변환시켜서 확인해 주면 제약없이 변환되는걸 볼 수 있습니다
x_np_1 = torch.tensor(np_array)
x_np_1[0,0] = 100
x_np_1
# 결과 : tensor([[100, 2], [ 3, 4]])
- 다시 tensor 형태로 변환해 주고 [0,0] 위치에 있는 데이터에 다른 값을 넣어주면 데이터가 변환되는걸 확인할 수 있습니다
- 다만 np_array만 다시 찍게 되면 기존의 데이터는 고수되어 있습니다
- 따라서 기존의 데이터까지 변경해 주기를 원한다면 as_tensor를 사용해 주어야 합니다 (예시는 아래 참조)
# as_tensor : ndarray와 동일한 메모리 주소를 가리키는 뷰를 만듦
# as_tensor는 다양한 자료구조가 들어와도 상관없음
x_np_2 = torch.as_tensor(np_array)
print(x_np_2)
# 결과 : tensor([[1, 2], [3, 4]])
x_np_2[0,0] = 200
print(x_np_2)
# 결과 : tensor([[200, 2], [ 3, 4]])
print(np_array)
# 결과 : [[200 2] [ 3 4]]
# from_numpy : ndarray와 동일한 메모리 주소를 가리키는 뷰를 만듦
# from_numpy는 ndarray 자료구조만 들어와야 함
- 비슷한 타입으로 from_numpy 가 있으며 np_array와 다른 점은 ndarray 자료구조만 들어와야 합니다
3. 파이토치 주요 함수
a = torch.ones(2,3) # 입력한 행렬의 구조를 1로 채움
b = torch.zeros(2,3) # 입력한 행렬의 구조를 0으로 채움
c = torch.full((2,3),10) # 입력한 행렬의 구조를 정해준숫자(10)으로 채움
d = torch.empty(2,3) # 입력한 행렬의 구조를 임의의 수로 채움
e = torch.eye(5) # 입력한 숫자(5) * 입력한 숫자(5) 의 행렬을 만들어 0으로 채우고 행의 순서의 위치에만 1을 채움
f = torch.arange(10) # 입력한 숫자(10)의 길이만큼 숫자를 나열(0부터 시작)
g =torch.rand(2,3) # 입력한 행렬의 구조를 랜덤의 숫자로 채움(양수로만)
h =torch.randn(2,3) # 입력한 행렬의 구조를 랜덤의 숫자로 채움 (음수도 포함)
i = torch.arange(45).reshape(3,3,5) # 첫번째 숫자는 메트릭스, 뒤의 두 숫자는 행렬
- arange() 함수에 reshape() 를 활용해 위와같이 데이터를 출력할 수 있습니다
- 여기서 permute() 함수를 이용해 행렬의 구조를 변환시킬 수 있는데 아래와 같습니다
# 차원을 지정한 인덱스로 변환
# 3,3,5
j = i.permute((2,0,1)) # 3,3,5 -> 5,3,3 , 변환과정에서 열방향으로 데이터 변경
print(j, j.shape)
- 이를 통해 나중에 배울 이미지 데이터 변환과정에서 유용하게 사용할 수 있습니다
4. 텐서의 인덱싱과 슬라이싱
- 텐서 또한 일반적인 데이터 구조처럼 인덱싱과 슬라이싱이 가능합니다
a = torch.arange(1,13).reshape(3,4)
print(a[1])
# 결과 : ensor([5, 6, 7, 8])
print(a[0,-1])
# 결과 : tensor(4)
print(a[:2,2:])
# 결과 : tensor([[3, 4], [7, 8]])
5. 코랩의 GPU 사용
- 코랩에서 device 변경하는 방법
- 상단메뉴 -> 런타임 -> 런타임 유형변경 -> 하드웨어 가속기를 GPU로 변경 -> 저장 ->세션 다시 시작 및 모두 실행
tensor = torch.rand(3,4)
print(f'device:{tensor.device}')
# 결과 : device : cpu
# is_available(): gqu 사용할 수 있는지 여부
tensor = tensor.reshape(4, 3)
tensor = tensor.int()
if torch.cuda.is_available():
tensor = tensor.to('cuda')
print(f'device:{tensor.device}')
# 결과 : device:cuda:0