1. Affine 계층
신경망의 feed-forward를 위해 입력값 X와 가중치 W와 편향 B를 Y = np.dt(X, W) + B와 같이 계산한 후 Y를 활성화 함수로 변환하여 다음 Layer로 전파하였다. 기하학에서는 순전파 때 수행하는 행렬의 곱을 어파인 변환(Affine transformation)이라고 한다. 어파인 변환은 대응하는 차원의 원소의 수를 일치시키는 것이 핵심이다.
위에서는 데이터 하나만 고려한 Affine계층을 보았는데, 이제 데이터 N개를 묶어서 순전파하는 Affine계층을 다룰 것이다.
순전파에서는 matrix인 X·W 와 vector인 B 를 더하기 위해서 vector인 B 에 repeat을 적용하여 matrix로 만들어 '+' 노드를 실행하고, 역전파에서는 matrix인 ∂L/∂Y에서 vector인 B로 전파하기 위해 ∂L/∂Y에 repeat을 적용하여 vector로 만든다. repeat노드의 순전파와 역전파를 보면 다음과 같다.
repeat노드의 순전파에서는 vector에 1로 이루어진 열벡터를 좌측에 곱하여 행마다 기존의 vector가 반복되는 matrix를 만들고,
repeat노드의 역전파에서는 matrix에 1로 이루어진 행벡터를 우측에 곱하여 기존의 matrix 각각의 열을 더한 값의 vector을 만든다.
<코드>
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
위 코드에서 axis=0은 편향 B의 형상에 맞도록 vector로 변환하기 위해 repeat노드를 역전파하며 열별로 sum하는 과정이다.
2. Softmax-with-Loss 계층
Softmax층과 Cross Entropy Error층은 각 도함수를 따로 구하는 것보다 두 함수를 합성하여 도함수를 구하는 것이 깔끔하므로 Softmax-with-Loss계층이라는 합친 층으로 만들 것이다.
-Softmax 계층 : 출력층 이전의 Layer에서 Score를 받아 정규화(=Softmax적용)하여 출력한다.
-Cross Entropy Error 계층: Softmax의 출력과 정답 레이블로 손실 함수의 값을 구한다.
입력 데이터가 Affine계층과 ReLU계층을 통과하며 변환되고, 마지막 출력층인 Softmax계층에서 10개의 score가 정규화되어 확률로 변환된다.
이제 역전파를 위해 Softmax-with-Loss함수를 미분할 것이다. Softmax층과 Cross Entropy Error층은 도함수를 따로 구하는 것보다 두 함수를 합성하여 미분하는 것이 깔끔하므로 Softmax-with-Loss라는 합성함수로 미분하는 것이다.
이때 y는 Affine을 거친 score가 아닌 Softmax까지 거친 probability이다.
Cross Entropy Error함수를 손실 함수로 하여 식으로 나타내면 다음과 같다.
이 손실 함수를 score값에 대해 미분하면 다음과 같다.
Softmax 계층의 역전파는 (y1 - t1, y2 - t2, y3 - t3)으로 깔끔하게 Softmax의 출력값과 정답 레이블의 차이인 오차가 앞 계층에 전파된다. 즉, 신경망의 현재 출력과 정답 레이블의 오차를 그대로 드러낸다.
<코드>
#softmax함수
def softmax(a):
exp_a = np.exp(a)
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
#cross-entropy-error함수
def cross_entropy_error(y, t):
delta = 1e-7
return -np.sum(t*np.log(y+delta))
#softmax-with-loss계층
class SoftmaxWithLoss:
def __init__(self):
self.loss = None
self.y = None
self.t = None
def foward(self, x, t):
self.t = t
self.y = softmax(x)
self.loss = cross_entropy_error(self.y, self.t)
return self.loss
def backward(self, dout=1):
batch_size = self.t.shape[0]
dx = (self.y - self.t) / batch_size
return dx
출처: 사이토 고키, 『밑바닥부터 시작하는 딥러닝』, 한빛미디어(2017), p170-179.
'AI > 밑딥' 카테고리의 다른 글
딥러닝) optimizer ( SGD , Momentum , AdaGrad , RMSProp, Adam ) (0) | 2021.03.23 |
---|---|
딥러닝) 신경망 학습 전체 알고리즘 (코드) (0) | 2021.03.18 |
딥러닝) 활성화 함수 ReLU 계층 , Sigmoid 계층 구현 (0) | 2021.03.15 |
딥러닝) 오차 역전파 backpropagation , 연쇄법칙 chain rule , 기울기 효율적으로 구하기 (0) | 2021.03.08 |
딥러닝) 신경망 학습 알고리즘 , Stochasitc Gradient Descent , epoch, iteration , batch size (0) | 2021.03.02 |
댓글