꺼내먹는지식 준
Backpropagation 개념, 수식 이해 본문
Backpropagation 간단한 정리
$\frac{\partial net_{o1}}{\partial out_{h1}} = w_5 = 0.40$
우리가 원하는 타겟 2의 값을 키우고, 나머지 값들을 줄여야 한다.
각각의 output은 바로 전 단계의 layer가 어떻게 되어야 한다는 각각의 다른 desire이 있다. (target label은 키워야하고, weight에 따라 0이 되어야 하는 neuron 즉 노드들도 각자의 다른 desire을 가지고 있다.)
이에 따라 output의 바로 전 단계의 layer에 어떤 일을 일으켜내기 위해 target label의 neuron (2)의 desire과 다른 모든 output neuron의 desire과 결합한다. (corresponding 하는 weight의 값과, neuron 들이 얼마나 바뀌어야 하는가에 따라 )
여기서 Back Propagation 이라는 아이디어가 등장한다.
# 왼쪽 사진의 모든 desired effect를 결합하여 output 의 전 layer에 영향을 끼치고 싶은 리스트를 만든다.
음... 일단 뭐 개념적으로 각각의 neuron을 어떻게 조정해야 하는지에 대해서는 알겠으니, 이제 수식을 살펴보자.
https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/
A Step by Step Backpropagation Example
Background Backpropagation is a common method for training a neural network. There is no shortage of papers online that attempt to explain how backpropagation works, but few that include an example…
mattmazur.com
대충 그냥 이거 보고 이해하자.
다음과 같은 간단한 신경망이 있다고 하자.
2 step 으로 신경망이 업데이트 된다.
1. W 업데이트
간단하다.
즉 chain rule에 의해서
\[ \frac{\partial E_{total} }{\partial w_5 } = \frac{\partial E_{total} }{\partial out_{o1} } \frac{\partial out_{o1} }{\partial net_{o1} } \frac{\partial net_{o1} }{\partial w_5 } \]
하나씩 구해보자.
즉 cost function (loss function)으로 구한 모든 E 값들을 더해준다.
그 후, 신경망을 통해 구했던 output 으로 미분을 한다.
out 을 activation 통과하기 전 net 으로 미분
net 을 w 로 미분
다 합치면 $\frac{\partial E_{total}}{\partial w_{5}}$의 값을 구할 수 있다.
$\delta_{o1} = \frac{\partial E_{total}}{\partial out_{o1}} * \frac{\partial out_{o1}}{\partial net_{o1}} = \frac{\partial E_{total}}{\partial net_{o1}}\\ \delta_{o1} = -(target_{o1} - out_{o1}) * out_{o1}(1 - out_{o1})$
$\frac{\partial E_{total}}{\partial w_{5}} = \delta_{o1} out_{h1}$
$\frac{\partial E_{total}}{\partial w_{5}} = -\delta_{o1} out_{h1}$
delta 라는 기호로 표기를 하기도 한다 .
\[ w_5^{+} = w_5 - \eta * \frac{\partial E_{total}}{\partial w_{5}} = 0.4 - 0.5 * 0.082167041 = 0.35891648 \]
다음과 같이 weight 가 업데이트 된다.
그렇다면 그 아래 layer의 weight 는 어떻게 업데이트 될 까?
Hidden Layer를 통해서 업데이트 한다. (이 부분을 많이 놓치는 것 같다. 대부분 1개의 layer weight만 업데이트 되는 과정을 알려주고 넘어간다.)
2. hidden layer
hidden layer neuron(node)으로 이어지는 새로운 weight를 모두 얻은 후에 신경망에서 실제 업데이트를 수행한다(아래 역전파 알고리즘을 계속할 때 업데이트된 가중치가 아닌 원래 가중치를 사용함).
$w_1, w_2, w_3, w_4$의 새로운 값을 계산하여 backpropagation을 이어간다.
$\frac{\partial E_{total}}{\partial w_{1}} = \frac{\partial E_{total}}{\partial out_{h1}} * \frac{\partial out_{h1}}{\partial net_{h1}} * \frac{\partial net_{h1}}{\partial w_{1}}$
시각적으로는 다음과 같다.
hidden layer 은 weight와 다르게, 모든 output에게 영향을 끼친다. (weight는 각각 1개의 output 과 연결되지만, hidden은 모든 output과 연결 그래서 weight의 개수가 hidden 보다 많은 것)
즉, $out_{h1}$ 은 $out_{o1}$과 $out_{o2}$ 모두에 영향을 미치므로 $\frac{\partial E_{total}}{\partial out_{h1}}$ 은 두 출력 뉴런에 미치는 영향을 고려해야 한다.
\[ \frac{\partial E_{total}}{\partial out_{h1}} = \frac{\partial E_{o1}}{\partial out_{h1}} + \frac{\partial E_{o2}}{\partial out_{h1}} \]
$\frac{\partial E_{o1}}{\partial out_{h1}}$ 를 먼저 보자.
$\frac{\partial E_{o1}}{\partial out_{h1}} = \frac{\partial E_{o1}}{\partial net_{o1}} * \frac{\partial net_{o1}}{\partial out_{h1}}$
w 계산할 때 계산한 값이 있다.
$\frac{\partial E_{o1}}{\partial net_{o1}} = \frac{\partial E_{o1}}{\partial out_{o1}} * \frac{\partial out_{o1}}{\partial net_{o1}} = 0.74136507 * 0.186815602 = 0.138498562$
$\frac{\partial net_{o1}}{\partial out_{h1}}$ 은 $w_5$ 와 같다:
$net_{o1} = w_5 * out_{h1} + w_6 * out_{h2} + b_2 * 1$
$\frac{\partial net_{o1}}{\partial out_{h1}} = w_5 = 0.40$
다 합치면 다음과 같다.
$\frac{\partial E_{o1}}{\partial out_{h1}} = \frac{\partial E_{o1}}{\partial net_{o1}} * \frac{\partial net_{o1}}{\partial out_{h1}} = 0.138498562 * 0.40 = 0.055399425$
같은 방법으로 $\frac{\partial E_{o2}}{\partial out_{h1}}$ 도 구한다.
$\frac{\partial E_{o2}}{\partial out_{h1}} = -0.019049119$
이에 따라
$\frac{\partial E_{total}}{\partial out_{h1}} = \frac{\partial E_{o1}}{\partial out_{h1}} + \frac{\partial E_{o2}}{\partial out_{h1}} = 0.055399425 + -0.019049119 = 0.036350306$
$\frac{\partial E_{total}}{\partial out_{h1}}$를 구할 수 있다.
이제 각각의 weight에 대해서 $\frac{\partial out_{h1}}{\partial net_{h1}}$ 그리고 나서 $\frac{\partial net_{h1}}{\partial w}$ 를 구해보자.
$out_{h1} = \frac{1}{1+e^{-net_{h1}}}$
$\frac{\partial out_{h1}}{\partial net_{h1}} = out_{h1}(1 - out_{h1}) = 0.59326999(1 - 0.59326999 ) = 0.241300709$
출력 뉴런에 대해 수행한 것과 동일하게 $w_1$에 대해 $h_1$, $h_1$에 대한 총 net 입력의 편미분을 계산합니다.
$net_{h1} = w_1 * i_1 + w_3 * i_2 + b_1 * 1 $
$\frac{\partial net_{h1}}{\partial w_1} = i_1 = 0.05$
다 합치면 다음과 같다.
$\frac{\partial E_{total}}{\partial w_{1}} = \frac{\partial E_{total}}{\partial out_{h1}} * \frac{\partial out_{h1}}{\partial net_{h1}} * \frac{\partial net_{h1}}{\partial w_{1}}$
$\frac{\partial E_{total}}{\partial w_{1}} = 0.036350306 * 0.241300709 * 0.05 = 0.000438568$
다음과 같이 계산 된다.
다음과 같이 표현이 되기도 한다.
$\frac{\partial E_{total}}{\partial w_{1}} = (\sum\limits_{o}{\frac{\partial E_{total}}{\partial out_{o}} * \frac{\partial out_{o}}{\partial net_{o}} * \frac{\partial net_{o}}{\partial out_{h1}}}) * \frac{\partial out_{h1}}{\partial net_{h1}} * \frac{\partial net_{h1}}{\partial w_{1}}$
$\frac{\partial E_{total}}{\partial w_{1}} = (\sum\limits_{o}{\delta_{o} * w_{ho}}) * out_{h1}(1 - out_{h1}) * i_{1}$
$\frac{\partial E_{total}}{\partial w_{1}} = \delta_{h1}i_{1}$
이제 $w_1$의 값도 조정이 가능하다.
$w_1^{+} = w_1 - \eta * \frac{\partial E_{total}}{\partial w_{1}} = 0.15 - 0.5 * 0.000438568 = 0.149780716$
마지막으로 모든 가중치를 업데이트 했다! 원래 0.05 및 0.1 입력을 전달했을 때 네트워크의 오류는 0.298371109였다. 이 첫 번째 backpropagation 후 총 오류는 이제 0.291027924로 줄어든다. 별 것 아닌 것 같지만 이 과정을 10,000번 반복하면 오류가 0.0000351085로 곤두박질친다. 이 시점에서 0.05와 0.1을 피드포워드하면 두 개의 출력 뉴런은 0.015912196(vs 0.01 target)과 0.984065734(vs 0.99 target)를 생성한다.
정답에 영향을 끼치는 정도에 따라 다르게 업데이트가 되어야 한다. 어떻게 가능할까?
output 전 단계의 weight 는 해당 output과 target의 차이의 총합을 미분하여 업데이트 한다. 이 지점에서 차이가 발생한다.