오차역전파를 사용하는 것은 미분을 할때 평균 변화율의 극한으로 미분을 계산하는 것에서 미분의 공식을 이용하는 것으로의 변화이다. 계산 비용이 줄어든다.
1.함수의 그래프
2.node를 연결하는 방식
chain rule은 현재 flow의 순간 변화율을 구할때 upstream gradient와 local gradeint를 곱해주는 것이다.
class mullayer:
def __init__(self):
self.x = None
self.y = None
def forward(self, x, y):
self.x = x
self.y = y
out = x * y
return out
def backward(self, dout):
dx = dout * self.y
dy = dout * self.x
return dx, dy
class addlayer:
def __init__(self):
self.x = None
self.y = None
def forward(self, x, y):
self.x = x
self.y = y
out = x + y
return out
def backward(self, dout):
dx = dout * 1
dy = dout * 1
return dx, dy
apple = 100
apple_num = 2
tax = 1.1
mul_apple_layer = mullayer()
mul_tax_layer = mullayer()
apple_price = mul_apple_layer.forward(apple, apple_num)
price = mul_tax_layer.forward(apple_price, tax)
dprice = 1
dapple_price, dtax = mul_tax_layer.backward(dprice)
dapple, dapple_num = mul_apple_layer.backward(dapple_price)
print(dapple, dapple_num, dtax)
X dot W 형태의 순방향의 역전파를 할때 upstream gradient를 ug라고 한다면
dX = ug dot WT, dW = XT dot ug가 된다. 또한 연산이 2가지 밖에 없기 때문에 더하기는 ug를 그대로 나눠가지고 곱하기는 ug에 상대방의 값을 그대로 가져오면 된다.
아래의 문제는 dx, dw, db를 구하는 문제이다.
답은 db = [2,1,-1], dx = [1,7], dw = [[2,1,-1],[2,1,-1]]이다.
import numpy as np
class Affine:
def __init__(self, W, b):
self.W = W
self.b = b
self.x = None
self.original_x_shape = None
self.dW = None
self.db = None
def forward(self, x):
self.original_x_shape = x.shape
x = x.reshape(x.shape[0], -1)
self.x = x
out = np.dot(self.x, self.W) + self.b
return out
def backward(self, dout):
dx = np.dot(dout, self.W.T)
self.dW = np.dot(self.x.T, dout)
self.db = np.sum(dout, axis=0)
dx = dx.reshape(*self.original_x_shape)
return dx
x = np.array([[1,1]])
W = np.array([[1,2,3],[4,5,6]])
b = np.array([7,8,9])
affine = Affine(W,b)
affine.forward(x)
affine.backward(np.array([[2,1,-1]]))
affine.dW
affine.db
배치처리를 하게되면 인풋의 shape의 첫번째 값은 batch_num(N)이 된다.
다만 db의 경우에 그렇게 되는 것을 증명하기가 좀 까다로운데 여기서에서는 numpy.sum(dout, axis=0)을 하는 것으로 shape을 맞춰주는 것으로 충분하다고 하고 넘어가기로 한다.
repeat 노드를 통해 벡터가 행렬이 된다. sum 노드를 통해 행렬이 벡터가 된다.
또한 repeat노드의 역전파는 sum 노드가 되고, sum노드의 역전파는 repeat 노드가 된다.
repeat 노드의 역전파라는 관점에서 db를 구하는 원리를 알 수 있다.