순방향과 반대방향으로 국소적 미분을 곱하는 방식이다.
계산 그래프로 표현하면, 아래 빨간색 선과 같다.
역전파 종류에는 덧셈 노드, 곱셈 노드 역전파가 있다.
요약을 하면 다음과 같다.
- 덧셈 노드 역전파: 입력 값을 그대로 흘려보낸다.
- 곱셈 노드 역전파: 입력 신호들을 '서로 바꾼 값'을 곱해서 보낸다.
먼저 덧셈 노드 역전파를 알아보자
덧셈 노드 역전파는 입력값을 그대로 흘려보내기 때문에 gradient distributor라고 하기도 한다.
덧셈 노드의 순전파는 이전 입력 신호들의 총합이지만, 역전파는 동일한 값으로 분배된다.
구현 코드는 다음과 같다.
class AddLayer:
def __init__(self):
pass
def forward(self, x, y):
out = x + y
return out
def backward(self, dout):
dx = dout * 1
dy = dout * 1
return dx, dy
곱셈 노드의 역전파는 상류의 값에 순전파 때의 입력 신호들을 '서로 바꾼 값'을 곱해서 하류로 보낸다. 이러한 모습을 보고 gradient swithcher라고 부르기도 한다.
구현 코드는 다음과 같다.
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 # x와 y를 바꾼다.
dy = dout * self.x
return dx, dy
신경망의 순전파에서는 가중치 신호의 총합을 계산하기 때문에 행렬의 곱(np.dot)을 사용했다. 행렬의 곱 계산은 대응하는 차원의 원소 수를 일치시키는 것이 핵심이다.
여기서, 신경망의 순전파 때 수행하는 행렬의 곱은 기하학에서 어파인 변환 (Affine transformation)이라고 한다.
Affine 계층은 어파인 변환을 수행하는 처리를 의미하며 아래와 같이 표현된다.
위 자료는 입력 데이터로 X하나만 고려한 것이다.
데이터를 N개를 묶어 순전파를 하는 경우, 즉 배치용 Affine 계층은 다음과 같다.
파이썬 구현 코드는 아래와 같다.
class Affine:
def __init__(self, W, b):
self.W = W
self.b = b
self.x = None
self.dW = None
self.db = None
def forward(self, x):
self.x = x
out = np.dot(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)
return dx