본문 바로가기
AI/파이썬

Autograd

by 알푼 2024. 3. 4.
728x90
728x90

Autograd는 파이토치를 이용해 Back Propagation을 할 수 있도록 도와주는 방식이다.

 

코드로 이해해보자.

import torch

DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# parameter 설정
BATCH_SIZE = 64
INPUT_SIZE = 1000
HIDDEN_SIZE = 100
OUTPUT_SIZE = 10

 

우선 이와 같이 파라미터를 설정한다. BATCH_SIZE는 파라미터를 업데이트 할 때, 계산되는 데이터의 개수이다. BATCH_SIZE 수 많큼 계산하여 loss를 구한다.

INPUT_SIZE는 입력층의 노드 수이다. 여기서는 1000인데, 따라서 input의 모양은 (64, 1000)이 된다.

HIDDEN_SIZE는 input을 통해서 들어온 데이터가 파라미터에 의해 계산이 된 결과에 한 번 더 계산되는 파라미터의 수이다. 

OUTPUT_SIZE는 최종 출력되는 벡터의 크기이다. 

이걸 그림으로 보면 다음과 같다.

 

 

이제 input인 x와, output인 y, 그리고 각 단계의 가중치가 되는 w1, w2를 설정한다.

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)

 

randn은 평균이 0, 표준편차가 1인 정규분포에서 샘플링한 값이며, requires_grad는 gradient를 계산할지 지정해주는 것이다. Gradient는 w만 계산하면 되므로 x와 y는 False, w1, w2는 True로 지정한다.

 

그런데 여기서 w의 size를 결정짓는 요소를 살펴보면, x상태에서 hidden 상태로 갈때 사이즈는 (64, 1000) → (64, 100) 가 된다. 따라서 w1는 행렬 곱에 의해서 (64, 1000) X (1000, 100) = (64, 100), 즉 w1의 size는 (1000, 100)이 되어야 한다. 따라서 INPUT_SIZE, HIDDEN_SIZE 순으로 크기를 입력한다. 마찬가지의 원리로 w2의 크기는 (100, 10)이 된다.

 

learning_rate = 1e-6
for t in range(1, 501):
    y_pred = x.mm(w1).clamp(min=0).mm(w2)
    
    loss = (y_pred - y).pow(2).sum()
    if t % 100 == 0:
        print(f"Iteration : {t}, \t Loss : {loss.item()}")
    loss.backward()

    with torch.no_grad():
        w1 -= learning_rate * w1.grad    
        w2 -= learning_rate * w2.grad

        w1.grad.zero_()
        w2.grad.zero_()

 

Learning_rate를 지정해주고, 500번 반복하여 loss를 계산하도록 설정하였다. x.mm(w1)는 x와 w1의 matmul, 즉 행렬곱을 나타내며, clamp(min=0)는 비선형 함수로 ReLU라고 이해하고 넘어가자. 따라서 loss는 예측값과 실제값을 뺀 후 제곱차의 합을 이용해서 구할 수 있다.

 

그렇게 계산한 loss값에 backward() 메서드를 이용하면 각 파라미터 값에 대한 gradient를 계산하고 이를 통해 Back Propagation을 진행한다는 것을 의미한다.

 

with torch.no_grad() 부분은 계산된 gradient 값이 고정된 상태에서 작업을 하겠다는 것을 뜻한다. 즉 gradient가 고정된 상태에서 아래 w1 -= learning_rate * w1.grad 처럼 w값이 업데이트 된다. 결과적으로 우리가 계산해야하는 파라미터가 업데이트 되는 것이며, 파라미터가 없데이트 되었다면 grad_zero_() 메서드를 통해서 gradient 값을 0으로 설정한다. 다음 Back Propagation 수행 시 gradient값을 새로 계산하기 위해서 0으로 설정해준다.

728x90
반응형

댓글