관리 메뉴

ComputerVision Jack

PyTorch Lecture 04 : Back-propagation and Autograd 본문

DeepLearning/Pytorch_ZeroToAll

PyTorch Lecture 04 : Back-propagation and Autograd

JackYoon 2020. 10. 6. 14:20
반응형

Computing gradient in Simple Network

단순히 x -> Linear Model -> y 관계에서 추출된 cost(loss)에 대한 기울기 값은 dloss / dw (미분)을 통하여 알 수 있습니다. 코드 적으로 본다면 전에 작성 했던 gradient(x, y) 함수의 return 값  2 * x * (x * w - y) 입니다.

Complicated network

하지만 이런 복잡한 네트워크 상황에서 dloss / dw (미분)의 값을 우리는 예측하기 쉽지 않습니다.

Chain Rule

따라서 이런 복잡한 네트워크 상황에 대해 우리는 체인 룰 방식을 적용하여 그 값을 역 추적해 나아갑니다.

Chain Rule

김성훈 교수님이 강의해주신 내용을 바탕으로 체인룰을 적용해보겠습니다.

우선 f 로 표시 되어 있는 원은 퍼셉트론으로 생각하시면 됩니다.  x 와 y는 전 퍼셉트론에서 도출된 결과라고 생각하시면 편합니다. 도출된 결과가 다음 뒤에 있는 퍼셉트론의 입력으로 들어가는 상황입니다.

 

따라서 우리는 z에 대해 체인룰을 적용해서 해당x와 y 값에 대한 gradient를 미분을 통해 접근할 수 있습니다.

 

x = 2, y = 3, z = 6 경우

x가 2, y 가 3이면 f관련해 f = x * y라는 수식을 알 수 있습니다.

z가 6인 값에 대해 기울기가 5가 나왔다고 강의에서 말씀해주셨습니다. 즉 dLoss / dz (미분) 값이 5입니다. 

 

이를 토대로 dLoss / dz 값 , dLoss / dy 값을 찾아보겠습니다. 

dLoss / dx = dLoss / dz * dz / dx로 나타낼 수 있습니다. dLoss / dz 값은 제시한 5 입니다. 그럼 dz / dw 값을 알아야 합니다. z에 대해 x로 미분을 진행하면  z가 x * y 이기 때문에 x 는 사라지고 y만 남게 됩니다.

즉, dLoss = dLoss / dz * dz / dx = dLoss / dz * y = 5 * y = 5 * 3 = 15가 됩니다.

위 과정을 y에도 적용한다면 dLoss / dy = dLoss / dz * dz / dy = dLoss / dz * x = 5 * x = 5 * 2 = 10이 됩니다.

 

즉 연산의 결과를 역으로 추적하기 때문에 위와 같은 과정을 역전파 (Back Propagation) 이라고 합니다.

 

1. Forward pass x = 1 y = 2 where w = 1 경우

이제 우리가 실습해온 선형 모델에 대해 역전파를 적용해 봅시다.

예시 적용

이제 w에 대해 dLoss / dw를 역전파로 계산해 봅시다.

우선 loss에 대해 s로 미분을 진행합니다. dLoss / ds = 2s가 됩니다. 따라서 제시된 조건에 의해 dLoss / ds = 2s = -2가 됩니다. 그 다음 loss에 대해 y^으로 미분을 진행 합니다. dLoss / dy^ = dLoss / ds * ds / dy^ 입니다.

dLoss / ds의 값은 -2로 아까 구했고, s = y^ - y 이기 때문에 ds / dy^ = d(y^ - y) / dy^로 만들 수 있습니다.

즉 y는 상수 취급되어 없어지고 결국 값은 1이됩니다. 따라서 -2 * 1  = -2가 됩니다.

마지막으로 dLoss / dw = dLoss / dy^ * dy^ / dw가 됩니다.  dLoss / dy^은 -2로 전의 과정을 통해 정리할 수 있었습니다. y^ 경우 x * w로 표현이 가능하고 d(x * w) / dw = x 가 됩니다. x의 값은 1로 문제에서 조건을 정의했고 최종 적으로 연산을 진행하면 -2 * x  = -2 * 1 즉 -2가 됩니다.

 

2. Forward pass x = 2, y = 4 where w = 1인 경우

예시2 적용

마찬가지로 위 방법을 통해 역전파를 적용하면 dLoss / dw의 값은 -8이 나옵니다.

 

3. Forward pass x = 1, y = 2, w = 1, b = 2 경우

bias가 추가된 경우

위 예시 경우는 역전파를 적용하여 결과를 정의하기 보단 새롭게 추가된 b에 대해서 바라보겠습니다.

추가된 b는 결국 상수이고 역전파의 미분 과정에 있어서 날라가버립니다. 따라서 b가 추가된들 크게 상관은 없습니다.

하지만 b가 추가되므로 y^의 값은 변경이 될 수 있기 때문에 y^에 대해 값의 변경이 더 강조 될 수 있습니다.

[03.Auto_gradient.py]

import torch

import pdb

# 필요한 라이브러리를 import 합니다.

 

x_data = [1.0, 2.0, 3.0]

y_data = [2.0, 4.0, 6.0]

# 해당 실습에 필요한 데이터 셋을 정의합니다.

 

w = torch.tensor([1.0], requires_grad = True)

# w 값에 대한 tensor를 제작합니다. requires_grad 인자는 tensor에서 이뤄진 모든 연산을 추적하는 인자입니다.

계산이 완료된 후, .backward()를 호출하여 변화도를 자동으로 계산할 수 있다.

 

def forward(x):

    return x * w

# 선형 모델을 함수로 생성합니다.

 

def loss(y_pred, y_val):

    return (y_pred - y_val) ** 2

# 모델을 토대로 손실 함수를 생성합니다.

 

print("Prediction (before training)", 4, forward(4).item())

# 우선 학습 전 value 4에 대해서 forward(4)를 진행하고 출력을 확인합니다.

 

for epoch in range(10):

    for x_val, y_val in zip(x_data, y_data):

        y_pred = forward(x_val)

        l = loss(y_pred, y_val)

        l.backward()

        print('\tgrad : ', x_val, y_val, w.grad.data[0])

        

        w.data = w.data - 0.01 * w.grad.data

        w.grad.data.zero_()

 

    print(f"Epoch : {epoch} | Loss : {l.item()}")

# 10번의 반복동안 기울기를 계속 업데이트 하면서 결과를 출력합니다. 0.01은 learning_rate입니다.

 

print("Prediction (after training)", 4, forward(4).item())

# 학습 후 value 4에 대해서 결과룰 출력하여 확인합니다.

학습 결과

반응형
Comments