파이토치 프레임워크에 사용되는 요소
데이터 표현 단위
1. Scalar
상수값
import torch
scalar1 = torch.tensor([1.
print(scalar1)
#tensor([1.])
2. Vector
하나의 값을 표현할 때 2개 이상의 수치로 표현한 것
vector1 = torch.tensor([1.,2.,3.])
print(vector1)
#tensor([1., 2., 3.])
3. Matrix
2개 이상의 벡터 값을 통합해 구성된 값
matrix1 = torch.tensor([[1.,2.],[3.,4.]])
print(matrix1)
#tensor([[1., 2.],
# [3., 4.]])
4. Tensor
2차원 이상의 배열
tensor1 = torch.tensor([[[1.,2.],[3.,4.]],[[5.,6.],[7.,8.]]])
print(tensor1)
#tensor([[[1., 2.],
# [3., 4.]],
#
# [[5., 6.],
# [7., 8.]]])
각 데이터 단위는 torch.tensor(.)로 동일하게 작성한다. 데이터의 차원에 따라서 이름만 다르게 부른다.
Autogard
"PyTorch의 모든 신경망의 중심에는 autograd 패키지가 있습니다.
autograd 패키지는 Tensor의 모든 연산에 대해 자동 미분을 제공합니다. 이는 실행-기반-정의(define-by-run) 프레임워크로, 이는 코드를 어떻게 작성하여 실행하느냐에 따라 역전파가 정의된다는 뜻이며, 역전파는 학습 과정의 매 단계마다 달라집니다."
9bow.github.io/PyTorch-tutorials-kr-0.3.1/beginner/blitz/autograd_tutorial.html
Pytorch의 Autogard에 Back Propagation을 이용해 파라미터를 업데이트하는 방법을 쉽게 구현할 수 있도록 설정되어 있다.
간단한 딥러닝 모델 설계하고 방정식 내에 존재하는 파라미터 업데이트하는 방법
1. 자신의 PC가 cuda를 사용하고 있는지에 따라 DEVICE 선택
import torch
if torch.cuda.is_available():
DEVICE = torch.device('cuda')
else:
DEVICE = torch.device('cpu')
2. 딥러닝 모델 파라미터
BATCH_SIZE = 64
INPUT_SIZE = 1000
HIDDEN_SIZE = 100
OUTPUT_SIZE =10
- BATCH_SIZE : 파라미터를 업데이트할 때 계산되는 데이터의 개수
BATCH_SIZE 수만큼 데이터를 이용해 Output을 계산하고 BATCH_SIZE 수만큼 출력된 결과값에 대한 오찻값을 계산한다.
계산된 오찻값을 평균해 Back Propagation을 적용하고 이를 바탕으로 파라미터를 업데이트.
BATCH_SIZE가 64이므로 Input으로 이용되는 데이터가 64라는 의미이다.
- INPUT_SIZE : Input의 크기이자 입력층의 노드 수
INPUT_SIZE가 1000이므로 입력 데이터 크기가 1000이라는 의미.
1000크기의 벡터 값을 가진다.
BATCH_SIZE 64이니깐 1000크기의 벡터 값을 64개 사용한다는 의미.
(64, 1000)
- HIDDEN_SIZE : Input을 다수의 파라미터를 이용해 계산한 결과에 한 번 더 계산되는 파라미터 수
은닉층의 노드 수
HIDDEN_SIZE가 100이므로 (64, 1000)의 Input들이 (1000, 100)크기의 행렬과 행렬 곱을 계산하기 위해 설정한 수
- OUTPUT_SIZE : 최종으로 출력되는 값의 벡터의 크기
최종으로 비교하고자 하는 레이블의 크기와 동일하게 설정
x = torch.randn(BATCH_SIZE,
INPUT_SIZE,
device = DEVICE,
dtype = torch.float,
requires_grad = False)
y = torch.randn(BATCH_SIZE,
OUTPUT_SIZE,
device = DEVICE,
dtype = torch.float,
requires_grad = False)
w1 =torch.randn(INPUT_SIZE,
HIDDEN_SIZE,
device = DEVICE,
dtype = torch.float,
requires_grad = True)
w2 = torch.randn(HIDDEN_SIZE,
OUTPUT_SIZE,
device = DEVICE,
dtype = torch.float,
requires_grad = True)
torch.randn(SIZE_1,
SIZE_2, # (SIZE_1, SIZE_2) 모양
device = DEVICE, # 1번에서 선택한 device
dtype = torch.float, # float 형식
requires_grad = False) # gradient 계산 True/False
업데이트할 파라미터
w1 - Input 데이터와 행렬 곱 연산
w2 - w1과 x를 행렬 곱한 결과에
3. 모델 학습
learning_rate = 1e-6 #(1)
for t in range(1,501): #(2)
y_pred = x.mm(w1).clamp(min = 0).mm(w2) #(3)
loss = (y_pred - y).pow(2).sum() #(4)
if t% 100 == 0: #(5)
print("Iteration: ", t, "\t", "Loss: ", loss.item()) #(6)
loss.backward() #(7)
with torch.no_grad(): #(8)
w1 -= learning_rate * w1.grad #(9)
w2 -= learning_rate * w2.grad #(10)
w1.grad.zero_() #(11)
w2.grad.zero_() #(12)
# Iteration: 100 Loss: 823.9583129882812
# Iteration: 200 Loss: 17.120134353637695
# Iteration: 300 Loss: 0.8147668838500977
# Iteration: 400 Loss: 0.05780751258134842
# Iteration: 500 Loss: 0.005106800701469183
(1) learning_rate 설정
(2) 500번 반복
(3) x.mm(w1) : x와 w1의 행렬 곱
x.mm(w1).clamp(min = 0) : 행렬 곱의 결과에 clamp함수 min 0으로
* clamp (비선형 함수 ReLU)
x.clamp(min =0) : x 값이 0보다 크면 x, 작으면 0
(4) loss계산 오차 제곱의 합
(5) 100번에 한번씩
(6) 횟수랑, loss 출력
(7) 각 파라미터에 대해 Gradient를 계싼하고 계산된 결과로 Back Propagation진행
(8) 파라미터 값을 업데이트할 때에 Gradient값을 고정
(9-10) Gradient descent로 파라미터 업데이트
(11-12) Gradinet초기화 (다음 Backpropagatoni을 진행할 때 gradient값을 loss.packward()를 통해 새로 계산