6.1 Variable 클래스 추가 구현
class Variable:
def __init__(self, data):
self.data = data # 통상값
self.grad = None # 미분값
- grad는 None으로 초기화해두고 실제 역전파 계산 할때 미분값 계산
- 벡터나 행렬등 다변수에 대한 미분은 기울기라고 함
6.2 Function 클래스 추가 구현
class Function:
def __call__(self, input):
x = input.data
y = self.forward(x)
output = Variable(y)
self.input = input # 입력 변수 기억
return output
def forward(self, x):
raise NotImplementedError()
def backward(self, gy):
raise NotImplementedError()
6.3 Square Exp 클래스 추가 구현
class Square(Function):
def forward(self, x):
y = x ** 2
return y
def backward(self, gy):
x = self.input.data
gx = 2 * x * gy
return gx
class Exp(Function):
def forward(self, x):
y = np.exp(x)
return y
def backward(self, gy):
x = self.input.data
gx = np.exp(x) * gy
return gx
- x ** 2은 미분하면 2x인데 여기에 인수로 전달된 미분(=gy)를 곱해줌
- 지수함수는 상수여서 미분해도 그대로라서 np.exp(x)에 인수로 전달된 미분(=gy)를 곱해줌
6.4 역전파 구현
순전파 먼저!

위의 이미지처럼 순전파 먼저 진행된다고 했을 때

a = A(x)만 봤을때
x는 파란색 글자인 <__main__.Variable object at 0x0000028F5D55D060> 메모리 주소에 저장되고
x.data로 0.5의 값을 꺼내
square의 forward 메서드를 통해 제곱을 연산해서 0.25을 리턴 후 y에 담아서
y(0.25)를 Variable에 담아(주소는 보라색 글자) 값(output)을 반환해줌
그리고, input(파란색 메모리 주소 있는거)을 역전파 시 꺼내 쓸수 있게 self.input안에 담아줌
위의 순서는 b = B(a), y = C(b)도 메서드나 인풋값이 다를 뿐 동일한 순서대로 진행됨

그리고, self.input 부분때문에 input 3개가 저장되어있음

역전파 구현

이제, 위의 이미지 처럼 역전파의 값을 구해줘야하는데 역전파는 dy/dy=1에서 시작하기 때문에 y.grad = np.array(1.0)이 된다.

x 변수에 들어간 self.input.data는 y = C(b)일때 self.input에 저장된 값 그대로 가져온것임

각각의 역전파 연산을 순서대로 가져오면 아래 이미지 처럼 됨

# 전체 소스 코드
import numpy as np
class Variable:
def __init__(self, data):
self.data = data
self.grad = None
class Function:
def __call__(self, input):
x = input.data
y = self.forward(x)
output = Variable(y)
self.input = input
input2 = self.input
return output
def forward(self, x):
raise NotImplementedError()
def backward(self, gy):
raise NotImplementedError()
class Square(Function):
def forward(self, x):
y = x ** 2
return y
def backward(self, gy):
x = self.input.data
gx = 2 * x * gy
return gx
class Exp(Function):
def forward(self, x):
y = np.exp(x)
return y
def backward(self, gy):
x = self.input.data
gx = np.exp(x) * gy
return gx
A = Square()
B = Exp()
C = Square()
x = Variable(np.array(0.5))
a = A(x)
b = B(a)
y = C(b)
y.grad = np.array(1.0)
b.grad = C.backward(y.grad)
a.grad = B.backward(b.grad)
x.grad = A.backward(a.grad)
print(x.grad)
'Study 공부할레나' 카테고리의 다른 글
| [스터디/밑시딥3] 제 1고지 미분 자동 계산_8. 재귀에서 반복문으로 (0) | 2023.08.13 |
|---|---|
| [스터디/밑시딥3] 제 1고지 미분 자동 계산_7.역전파 자동화 (0) | 2023.08.13 |
| [스터디/밑시딥3] 제 1고지 미분 자동 계산_5.역전파 이론 (0) | 2023.08.13 |
| [스터디/밑시딥3] 제 1고지 미분 자동 계산_4.수치 미분 (0) | 2023.08.12 |
| [스터디/밑시딥3] 제 1고지 미분 자동 계산_3.함수 연결 (0) | 2023.08.12 |