[python] 파이썬에서 지수와 로그 사용하려면?

코딩/python|2020. 7. 2. 18:04

파이썬에서 지수와 로그를 사용하기 위해서는 math 모듈을 import 해주셔야 합니다. 

 

만약 $e^{0.5}$를 구하시고 싶다면,

 

 

위와 같이 math.exp(0.5)를 입력해주시면 됩니다.

 

만약 밑이 e인 로그, 즉 자연로그 ln5를 구하시고 싶다면, 아래와 같이 코딩하시면 됩니다.

 

 

또한 밑이 10인 로그, 즉 상용로그 log200을 구하시고 싶다면, 다음과 같이 코딩하시면 됩니다. 

 

 

만약 밑이 2인 로그, $log_2{4}$를 구하고 싶다면, math.log2(4)를 사용하시면 됩니다.

 

  1. BlogIcon 바밸 : 균형-건강을 위한 시작 2020.07.07 08:52 신고 댓글주소  수정/삭제  댓글쓰기

    잘보고 가요~^^ 구독합니다^^

오차 역전파(error backpropagation) 개념 제대로 파악하기

공부/머신러닝, 딥러닝|2020. 7. 2. 09:53

미리 말씀드리지만 이 글은 좀 깁니다. 그리고 수식이 많아서 언뜻 보면 너무 어렵게 느껴질 수 있습니다. 하지만 이 글을 끝까지 인내하시면서 읽어내려가신다면 분명 오차 역전파(error backpropagation)가 무엇인지에 대한 지식과 더 나아가서 딥러닝의 본질에 대해 통찰력을 얻으실 수 있을 것입니다. 수식들을 직접 손으로 쓰시면서 살펴보신다면, 이해하는데 큰 도움이 될 것입니다. 

 

"인내는 쓰다. 그러나 그 열매는 달다."

 

오차 역전파는 딥러닝 모델을 훈련시키는데 있어서 가장 흔히 사용되는 방법입니다. 오늘은 간단한 예를 통해 실제로 딥러닝 모델이 어떻게 훈련되는지에 대해서 살펴보고자 합니다. 저는 이 글을 작성하는데 있어서 [1]을 주로 참고했습니다. 

 

다음과 같은 간단한 네트워크가 있다고 가정해봅시다. 단 하나의 은닉층(hidden layer)이 있는 인공신경망(artificial neural network)입니다. 

 

 

w1, w2, w3,...,w8 까지 총 8개의 가중치(weight)가 훈련되어야합니다. 문제를 단순화시키기 위해 편향(bias)은 포함시키지 않았습니다. 단 하나의 훈련 데이터 샘플로 이 네트워크를 훈련시켜보겠습니다. 그 샘플은 (0.05, 0.1)이고 타겟값은 (0.01, 0.99)입니다. 그리고 가중치들은 다음과 같이 초기화시켜주겠습니다. 

 

 

우선 이러한 상황에서 훈련 데이터를 네트워크에 통과시키면 어떤 출력값이 나오는지 살펴보도록 하겠습니다. 바로 타겟값인 (0.01, 0.99)와 비슷한 값이 나오면 좋겠지만, 확률적으로 그럴리는 거의 없습니다. 

 

먼저 은닉층의 첫번째 노드의 net input은 얼마인지 구해보겠습니다. net input이라는 것은 입력값과 그와 연관된 가중치와 편향을 곱해서 더한 것을 의미합니다. 

 

$\begin{align*}
net_{h1} &= i1\cdot w1 + i2\cdot w2\\ 
 &= 0.05\cdot 0.15 + 0.1\cdot 0.2 = 0.0275
\end{align*}$

 

이것을 로지스틱(logistic) 함수로 활성화(activation)시켜준 것을 저는 $out_{h1}$이라고 표기하겠습니다. 로지스틱 함수는 입력값에 관계없이 항상 0과 1사이의 값을 출력해주는 함수입니다. 

 

$y = \frac{1}{1+e^{-x}}$

 

그러면 $out_{h1}$은 다음과 같이 계산됩니다. 

 

$\begin{align*}
out_{h1} &= \frac{1}{1+e^{-net_{h1}}} \\ 
 &= \frac{1}{1+e^{-0.0275}} = 0.5069
\end{align*}$

 

유효숫자 4개만 쓰겠습니다. 시간적 여유가 있는 분들은 손으로 수식 전개를 따라가시면서 이해하시는 것을 권해드립니다. 이 과정은 손으로 몇번 따라해봐야 자기 것이 될 수 있습니다. 

 

이번에는 $net_{h2}$와 $out_{h2}$를 계산해보겠습니다. 

 

$\begin{align*} 
net_{h2} &= i1\cdot w3 + i2\cdot w4\\  
 &= 0.05\cdot 0.25 + 0.1\cdot 0.3 = 0.0425 
\end{align*}$

 

$\begin{align*}
out_{h2} &= \frac{1}{1+e^{-net_{h2}}} \\ 
 &= \frac{1}{1+e^{-0.0425}} = 0.5106
\end{align*}$

 

이제 $out_{h1}$과 $out_{h2}$는 다음 층의 인풋이 됩니다. $net_{o1}$과 $out_{o1}$을 구하면,

 

$\begin{align*} 
net_{o1} &= out_{h1}\cdot w5 + out_{h2}\cdot w6\\  
 &= 0.5069\cdot 0.35 + 0.5106\cdot 0.4 = 0.3817
\end{align*}$

 

$\begin{align*} 
out_{o1} &= \frac{1}{1+e^{-net_{o1}}} \\  
 &= \frac{1}{1+e^{-0.3817}} = 0.5943 
\end{align*}$

 

이 됩니다. 마찬가지로 $net_{o2}$와 $out_{o2}$를 구하겠습니다.

 

$\begin{align*}  
net_{o2} &= out_{h1}\cdot w7 + out_{h2}\cdot w8\\   
 &= 0.5069\cdot 0.45 + 0.5106\cdot 0.5 = 0.4834 
\end{align*}$

$\begin{align*}  
out_{o2} &= \frac{1}{1+e^{-net_{o2}}} \\   
 &= \frac{1}{1+e^{-0.4834}} = 0.6186  
\end{align*}$

 

이제 $out_{o1}$, $out_{o2}$를 타겟값과 비교해서 오차를 계산해보겠습니다. 총 오차(total eror)는 오차 제곱의 합, 즉 다음과 같은 식으로 계산하도록 하겠습니다.  

 

$\begin{align*}
E_{total} &= E_{o1} + E_{o2}\\ 
 &= \frac{1}{2}(target_{o1} - out_{o1})^2 + \frac{1}{2}(target_{o2} - out_{o2})^2
\end{align*}$

 

앞에 $1/2$는 이후에 미분을 할때 계산하기 용이하도록 붙여준 것입니다. 뒷부분에 가시면 저절로 이해가 되실 것입니다. 자, 그럼 지금 상황에서 오차는 얼마인지 계산해보겠습니다. 

 

$\begin{align*}
E_{total} &= E_{o1} + E_{o2}\\ 
 &= \frac{1}{2}(0.01 - 0.5943)^2 + \frac{1}{2}(0.99 - 0.6186)^2 \\
 &= 0.2397
\end{align*}$

 

0.2397의 오차가 계산되었습니다. 아직 출력값인 (0.5943, 0.6186)과 타겟값인 (0.01, 0.99) 사이에는 차이가 많이 있습니다. 우리의 목적은 이 오차가 0에 가까워지도록 네트워크의 가중치를 업데이트시켜가는 것입니다. 

 

지금부터 출력단에서 가까운 $w5, w6, w7, w8$부터 어떻게 갱신해가는지 확인해보도록 하겠습니다. 핵심은 경사감소법 또는 경사하강법을 이용한다는 점입니다. 

 

 

w5 업데이트 과정

 

$E_{total}$ 함수의 최소값은 각 가중치로 편미분했을 때 0이 되는 지점일 것입니다. 만약 현재의 가중치가 그 최소값을 갖게하는 위치에서 왼쪽에 있다면 오른쪽으로 가도록 보정하면 되는 것이고, 오른쪽에 있다면 왼쪽으로 가도록 보정하면 되는 것이죠. 아래 그림을 참고하세요(설명을 위해 8차원의 그래프를 2차원의 그래프로 단순화시켜서 그렸습니다). 

 

 

최소값을 갖게 하는 점에서 가중치가 왼쪽에 있다면 그때 편미분한 결과는 음수일 것입니다. 따라서 그것에 마이너스를 붙여서 현재의 가중치에 더해준다면 오른쪽으로 이동할 것입니다. 이동하는 정도를 정해주기 위해서 학습률(learning rate) $\alpha$를 곱해서 더해줍니다. 학습률이 크면 한번에 많이 움직이고, 작으면 적게 움직입니다. 이것을 식으로 나타내면 다음과 같습니다.

 

$w5^+ = w5 - \alpha\frac{\partial E_{total}}{\partial w5}$

 

여기서 $w5^+$는 갱신된 w5를 의미합니다. 

 

 

이러한 방식으로 가중치를 갱신하기 때문에 w5를 갱신하기 위해서는 $\frac{\partial E_{total}}{\partial w5}$를 계산해줘야 합니다. $E_{total}$을 $w5$에 대해 편미분해야하는데 $E_{total}$ 대한 식을 살펴보면 $w5$가 딱 보이지 않습니다. $w5$에 대한 식으로 바꿀 수는 있겠지만 너무 복잡해집니다. 따라서 체인 룰(chain rule)을 이용해서 $\frac{\partial E_{total}}{\partial w5}$을 다음과 같이 바꿔줍니다. 

 

$\frac{\partial E_{total}}{\partial w5} = \frac{\partial E_{total}}{\partial out_{o1}}\times \frac{\partial out_{o1}}{\partial net_{o1}}\times \frac{\partial net_{o1}}{\partial w5}$

 

위 식의 의미는 다음 그림과 같습니다. 오차를 $w5$까지 역전파시켜가는 것입니다.

 

 

먼저 $\frac{\partial E_{total}}{\partial out_{o1}}$부터 구해보면, 

 

$\begin{align*}
\frac{\partial E_{total}}{\partial out_{o1}} &= -(target_{o1} - out_{o1})\\ 
 &= -(0.01 - 0.5943) = 0.5843
\end{align*}$

 

이 됩니다. 그 다음에 $\frac{\partial out_{o1}}{\partial net_{o1}}$를 구해보겠습니다. 로지스틱 함수 $y = \frac{1}{1+e^{-x}}$의 미분은 

 

$\frac{dy}{dx} = y(1-y)$

 

이므로,

 

$\begin{align*}
\frac{\partial out_{o1}}{\partial net_{o1}} &= out_{o1}(1 - out_{o1})\\ 
 &= 0.5943(1 - 0.5943) = 0.2411
\end{align*}$

 

입니다. 또한 $\frac{\partial net_{o1}}{\partial w5}$는 

 

$\begin{align*}
\frac{\partial net_{o1}}{\partial w5} &= out_{h1}\\ 
 &= 0.5069
\end{align*}$

 

이 됩니다. 이것들을 모두 곱하면,

 

$\frac{\partial E_{total}}{\partial w5} = 0.5843 \times 0.2411 \times 0.5069 = 0.0714$

 

이 되고, 이것을 가지고 우리는 $w5$를 업데이트시킬 수 있습니다. 학습률 $\alpha$은 0.5로 해주겠습니다. 

 

$\begin{align*}
w5^+ &= w5 - \alpha\frac{\partial E_{total}}{\partial w5} \\ 
 &= 0.35 - 0.5\cdot0.0714 = 0.3143
\end{align*}$

 

0.35였던 $w5$가 0.3143으로 갱신된 것입니다. 타겟값 $target_{o1} = 0.01$에 비해서는 너무 큰 $out_{o1} = 0.5943$을 출력했었기 때문에 그것에 관여하는 $w5$가 작아진 것은 긍정적이라고 볼 수 있습니다. 그런데 바로 갱신시키지는 않고 모든 가중치의 갱신값을 구한 다음에 갱신시킵니다. 

 

 

w6 업데이트 과정

 

이번에는 $w6$의 업데이트 과정을 살펴보겠습니다. $w5$와 같은 원리로 갱신되니 빠르게 설명하겠습니다. $w6$을 갱신하기 위해서는 이것을 풀어야합니다. 

 

$\frac{\partial E_{total}}{\partial w6} = \frac{\partial E_{total}}{\partial out_{o1}}\times \frac{\partial out_{o1}}{\partial net_{o1}}\times \frac{\partial net_{o1}}{\partial w6}$

 

첫번째 인수와 두번째 인수는 이미 구한 값들이므로 세번째 인수만 계산하겠습니다. 

 

$\begin{align*}
\frac{\partial net_{o1}}{\partial w6} &= out_{h2}\\ 
 &= 0.5106
\end{align*}$

 

따라서, 

 

$\begin{align*}
\frac{\partial E_{total}}{\partial w6} &= \frac{\partial E_{total}}{\partial out_{o1}}\times \frac{\partial out_{o1}}{\partial net_{o1}}\times \frac{\partial net_{o1}}{\partial w6}\\ 
 &= 0.5843 \times 0.2411 \times 0.5106 = 0.07193
\end{align*}$

 

이 됩니다. 이것을 가지고 $w6$를 갱신하면 다음과 같이 됩니다. 

 

$\begin{align*} 
w6^+ &= w6 - \alpha\frac{\partial E_{total}}{\partial w6} \\  
 &= 0.4 - 0.5\cdot0.07193 = 0.364 
\end{align*}$

 

0.4였던 $w6$이 0.364로 갱신되었습니다. $w6$도 $out_{o1}$에 관여하기 때문에 작아진 것은 긍정적입니다. 

 

 

w7 업데이트 과정

 

$w7$을 갱신하기 위해서는 다음 식을 풀어야 합니다.

 

$\frac{\partial E_{total}}{\partial w7} = \frac{\partial E_{total}}{\partial out_{o2}}\times \frac{\partial out_{o2}}{\partial net_{o2}}\times \frac{\partial net_{o2}}{\partial w7}$

 

하나씩 풀어가면, 

 

$\begin{align*}
\frac{\partial E_{total}}{\partial out_{o2}} &= -(target_{o2} - out_{o2})\\ 
 &= -(0.99 - 0.6186) = -0.3714
\end{align*}$

 

$\begin{align*} 
\frac{\partial out_{o2}}{\partial net_{o2}} &= out_{o2}(1 - out_{o2})\\  
 &= 0.6186(1 - 0.6186) = 0.2359 
\end{align*}$

 

$\begin{align*} 
\frac{\partial net_{o2}}{\partial w7} &= out_{h1}\\  
 &= 0.5069 
\end{align*}$

 

이 되고, 이것들을 모두 곱하면 

 

$\begin{align*}
\frac{\partial E_{total}}{\partial w7} &= \frac{\partial E_{total}}{\partial out_{o2}}\times \frac{\partial out_{o2}}{\partial net_{o2}}\times \frac{\partial net_{o2}}{\partial w7}\\ 
 &= -0.3714\times 0.2359 \times 0.5069 = -0.04441
\end{align*}$

 

이 됩니다. 따라서 $w7$은 다음과 같이 갱신됩니다. 

 

$\begin{align*}  
w7^+ &= w7 - \alpha\frac{\partial E_{total}}{\partial w7} \\   
 &= 0.45 - 0.5\cdot(-0.04441) = 0.4722  
\end{align*}$

 

0.45였던 $w7$이 0.4722로 커졌습니다. $target_{o2} = 0.99$에 비해 $out_{o2} = 0.6186$이 작았던 상황에서 $out_{o2}$ 계산에 관여하는 $w7$이 커진 것은 긍정적입니다.

 

 

w8 업데이트 과정

 

$w8$을 갱신하기 위해서는,

 

$\frac{\partial E_{total}}{\partial w8} = \frac{\partial E_{total}}{\partial out_{o2}}\times \frac{\partial out_{o2}}{\partial net_{o2}}\times \frac{\partial net_{o2}}{\partial w8}$

 

를 풀어야하겠죠. 첫번째, 두번째 인수는 이미 위에서 구했으므로 세번째 인수만 구하면 됩니다.

 

$\begin{align*}  
\frac{\partial net_{o2}}{\partial w8} &= out_{h2}\\   
 &= 0.5106 
\end{align*}$

 

이므로,

 

$\begin{align*} 
\frac{\partial E_{total}}{\partial w8} &= \frac{\partial E_{total}}{\partial out_{o2}}\times \frac{\partial out_{o2}}{\partial net_{o2}}\times \frac{\partial net_{o2}}{\partial w8}\\  
 &= -0.3714\times 0.2359 \times 0.5106 = -0.04474 
\end{align*}$

 

이 됩니다. 또한 $w8$은 다음과 같이 업데이트 되겠죠. 

 

$\begin{align*}   
w8^+ &= w8 - \alpha\frac{\partial E_{total}}{\partial w8} \\    
 &= 0.5 - 0.5\cdot(-0.04474) = 0.5224  
\end{align*}$

 

0.5였던 $w8$이 0.5224로 커진 것도 긍정적인 일입니다. 왜냐하면 $w8$도 $out_{o2}$의 연산에 관여하기 때문입니다. 

 

 

여기까지 오시느라 수고하셔습니다. 잠시 숨을 고르고 가겠습니다. 지금까지 우리는 은닉층과 출력층 사이의 가중치들을 갱신해왔습니다. 이제 더 나아가서 입력층과 은닉층 사이의 가중치들 $w1, w2, w3, w4$를 갱신할 차례입니다. 자, 다시 펜을 손에 쥐고 가볼까요? 

 

 

w1 업데이트 과정

 

이번에도 역시 $\frac{\partial E_{total}}{\partial w1}$를 구해야 합니다. 이것을 체인 룰을 이용해서 다음과 같이 바꿔주겠습니다. 

 

$\frac{\partial E_{total}}{\partial w1} = \frac{\partial E_{total}}{\partial out_{h1}}\times \frac{\partial out_{h1}}{\partial net_{h1}}\times \frac{\partial net_{h1}}{\partial w1}$ ... (식1)

 

여기서 두번째 인수와 세번째 인수는 쉽게 구할 수 있습니다. 그러나 첫번째 인수는 당장 구하기는 어렵습니다. 그래서 첫번째 인수를 다음과 같이 분리시키겠습니다.

 

$\frac{\partial E_{total}}{\partial out_{h1}} = \frac{\partial E_{o1}}{\partial out_{h1}} + \frac{\partial E_{o2}}{\partial out_{h1}}$

 

각각의 항은 또 다음과 같이 분해가 가능합니다. 

 

$\begin{align*}
\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 net_{o1}}\times\frac{\partial net_{o1}}{\partial out_{h1}} + \frac{\partial E_{o2}}{\partial net_{o2}}\times\frac{\partial net_{o2}}{\partial out_{h1}} 
\end{align*}$

 

이것은 또 다음과 같이 분해할 수 있습니다.

 

$\begin{align*}
\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 net_{o1}}\times\frac{\partial net_{o1}}{\partial out_{h1}} + \frac{\partial E_{o2}}{\partial net_{o2}}\times\frac{\partial net_{o2}}{\partial out_{h1}} \\
&= \left ( \frac{\partial E_{o1}}{\partial out_{o1}}\times\frac{\partial out_{o1}}{\partial net_{o1}} \right )\times\frac{\partial net_{o1}}{\partial out_{h1}} + \left ( \frac{\partial E_{o2}}{\partial out_{o2}}\times\frac{\partial out_{o2}}{\partial net_{o2}} \right )\times\frac{\partial net_{o2}}{\partial out_{h1}}
\end{align*}$

 

이제 모두 계산하기 쉽게 되었습니다. 계산해야할 것은 많지만요. 이것을 식1에 대입시키면, 다음과 같이 됩니다.

 

$\frac{\partial E_{total}}{\partial w1} = \left [ \frac{\partial E_{o1}}{\partial out_{o1}}\times\frac{\partial out_{o1}}{\partial net_{o1}} \times\frac{\partial net_{o1}}{\partial out_{h1}} + \frac{\partial E_{o2}}{\partial out_{o2}}\times\frac{\partial out_{o2}}{\partial net_{o2}} \times\frac{\partial net_{o2}}{\partial out_{h1}}  \right ]\times \frac{\partial out_{h1}}{\partial net_{h1}}\times \frac{\partial net_{h1}}{\partial w1}$

 

이 식이 의미하는 바는 다음 그림과 같습니다. 

 

 

이런 식으로 에러를 역전파시키는 방법으로 가중치를 보정하기 때문에 에러 역전파라고 불리는 것입니다. 모든 값을 구해서 대입해서 계산해주겠습니다. 

 

$\frac{\partial E_{total}}{\partial w1} = \left [ 0.5843 \times 0.2411 \times 0.35 + (-0.3714)\times 0.2359 \times 0.45 \right ]\times 0.25 \times 0.05 = 0.0001235$

 

이 값을 가지고 $w1$을 갱신시켜줍니다. 

 

$\begin{align*}    
w1^+ &= w1 - \alpha\frac{\partial E_{total}}{\partial w1} \\     
 &= 0.15 - 0.5\cdot(0.0001235) = 0.1499   
\end{align*}$

 

0.15였던 $w1$이 0.1499로 갱신되었습니다. $w5, w6, w7, w8$에 비해 변화한 정도가 상당히 작죠. 이런 이유로 인공신경망에는 경사소멸(vanishing gradient) 문제가 있다고 평가되는 것입니다. 

 

 

w2 업데이트 과정

 

$w2$를 업데이트하기 위해서는 아래 식을 풀어야 합니다. 

 

$\frac{\partial E_{total}}{\partial w2} = \frac{\partial E_{total}}{\partial out_{h1}}\times \frac{\partial out_{h1}}{\partial net_{h1}}\times \frac{\partial net_{h1}}{\partial w2}$

 

첫번째 인수와 두번째 인수의 값은 방금 모두 구했으므로 세번째 인수에 대해서만 푼 후에 대입시키면 됩니다. 

 

$\frac{\partial net_{h1}}{\partial w2} = i2 = 0.1$

 

이므로, 

 

$\frac{\partial E_{total}}{\partial w2} = 0.0099 \times 0.25 \times 0.1 = 0.0002475$

 

가 됩니다. 이것을 가지고 $w2$를 갱신시키겠습니다.

 

$\begin{align*}     
w2^+ &= w2 - \alpha\frac{\partial E_{total}}{\partial w2} \\      
 &= 0.2 - 0.5\cdot(0.0002475) = 0.1999  
\end{align*}$

 

0.2였던 $w2$가 0.1999로 갱신되었습니다. 마찬가지로 아주 미세하게 조정되었습니다. 

 

 

w3 업데이트 과정

 

$w3$을 구하는 것도 마찬가지입니다. 한 번에 전개된 식을 적고 넘어가겠습니다. 

 

$\frac{\partial E_{total}}{\partial w3} = \left [ \frac{\partial E_{o1}}{\partial out_{o1}}\times\frac{\partial out_{o1}}{\partial net_{o1}} \times\frac{\partial net_{o1}}{\partial out_{h2}} + \frac{\partial E_{o2}}{\partial out_{o2}}\times\frac{\partial out_{o2}}{\partial net_{o2}} \times\frac{\partial net_{o2}}{\partial out_{h2}}  \right ]\times \frac{\partial out_{h2}}{\partial net_{h2}}\times \frac{\partial net_{h2}}{\partial w3}$

 

모든 값을 계산한 후에 대입해서 계산해주면 다음과 같은 값이 나옵니다. 

 

$\frac{\partial E_{total}}{\partial w3} = \left [ 0.5843\times0.2411\times0.4 + (-0.3714)\times0.2359\times0.5 \right ]\times 0.2499 \times 0.05 = 0.0001567$

 

이것을 가지고 $w3$을 갱신해주겠습니다. 

 

$\begin{align*}      
w3^+ &= w3 - \alpha\frac{\partial E_{total}}{\partial w3} \\       
 &= 0.25 - 0.5\cdot(0.0001567) = 0.2499
\end{align*}$

 

0.25였던 $w3$이 0.2499로 갱신되었습니다.

 

 

w4 업데이트 과정

마지막 가중치입니다. 이를 업데이트시키기 위해서는 아래 식을 풀어야 합니다. 

 

$\frac{\partial E_{total}}{\partial w4} = \frac{\partial E_{total}}{\partial out_{h2}}\times \frac{\partial out_{h2}}{\partial net_{h2}}\times \frac{\partial net_{h2}}{\partial w4}$

 

여기서 첫번째 인수와 두번째 인수는 $w3$을 다루는 과정에서 이미 구했으므로, 세번째 인수의 값만 구하면 됩니다. 

 

$\frac{\partial net_{h2}}{\partial w4} = i2 = 0.1$

 

이네요. 모든 인수를 대입해서 곱해주면 다음과 같이 됩니다.

 

$\frac{\partial E_{total}}{\partial w4} =0.01255 \times 0.2499 \times 0.1 = 0.0003136$

 

이것을 가지고 $w4$를 갱신하겠습니다. 

 

$\begin{align*}       
w4^+ &= w4 - \alpha\frac{\partial E_{total}}{\partial w4} \\        
 &= 0.3 - 0.5\cdot0.0003136 = 0.2998
\end{align*}$

 

0.3이었던 $w4$가 0.2998로 조정되었습니다.

 

 

드디어 모든 가중치를 한번씩 업데이트 시켰습니다. 여기까지도 읽어내려오신 분들의 끈기에 박수를 드립니다. 이제 업데이트된 가중치를 가진 네트워크에 다시 훈련 데이터를 통과시켜보겠습니다. 오차가 줄어들었는지 확인해봅시다. 

 

 

$net_{h1} = 0.05\cdot 0.1499 + 0.1\cdot 0.1999 = 0.02749$

$out_{h1} = \frac{1}{1 + e^{-0.02749}} = 0.5069$

 

$net_{h2} = 0.05\cdot 0.2499 + 0.1\cdot 0.2998 = 0.04248$

$out_{h2} = \frac{1}{1 + e^{-0.04248}} = 0.5106$

 

$net_{o1} = 0.5069\cdot 0.3143 + 0.5106\cdot 0.364 = 0.3452$

$out_{o1} = \frac{1}{1 + e^{-0.3452}} = 0.5855$

 

$net_{o2} = 0.5069\cdot 0.4722 + 0.5106\cdot 0.5224 = 0.5061$

$out_{o2} = \frac{1}{1 + e^{-0.5061}} = 0.6239$

 

이므로, $E_{total}$을 구하면 다음과 같은 값이 나옵니다. 

 

$\begin{align*} 
E_{total} &= \frac{1}{2}(0.01 - 0.5855)^2 + \frac{1}{2}(0.99 - 0.6239)^2 \\ 
 &= 0.2326 
\end{align*}$

 

가중치가 초기값으로 설정되었을 때의 오차보다는 작아졌음을 알 수 있습니다. 0.2397에서 0.2326으로 0.0071만큼 줄어들었네요. 이 훈련 과정을 여러번 반복하면 가중치들은 계속해서 갱신되어갈 것이고, 점차 $E_{total}$은 0에 가까워지게 될 것입니다. 물론 제대로 훈련되었을 경우에 그렇습니다. 

 

 

드디어 끝입니다. 따라오시느라 정말 수고 많으셨습니다. 지루할 수 있는 글을 끝까지 읽으신 분들께 감사드립니다. 이번에는 저 스스로도 칭찬해주고 싶네요. 수식을 일일이 쓰느라 꽤나 고생했습니다.^^; 오차 역전파에 대해서 이해가 되셨나요? 도움이 되셨다면 공감과 댓글을 남겨주시길 부탁드리며 이 글을 맺겠습니다. 

 

 

bskyvision의 추천글 ☞

경사감소법(경사하강법)이란?

배치(batch)와 에포크(epoch)란?

딥러닝 알고리즘의 대세, 컨볼루션 신경망(convolutional neural network, CNN)

 

 

<참고자료>

[1] https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/, Matt Mazur, "A Step by Step Backpropagation Example"

[2] https://www.mathworks.com/help/deeplearning/ug/choose-neural-network-input-output-processing-functions.html;jsessionid=e1d5d9c3e80282fd1084cde13e45, MathWorks, "Choose Neural Network Input-Output Processing Functions" => net input 정의 부분 참고함.

  1. 이창민 2020.07.02 12:58 댓글주소  수정/삭제  댓글쓰기

    설명이 정말 잘 되어 있네요 ^^

더이상 vs 더 이상

공부/언어|2020. 7. 1. 16:17

"더 이상"이 맞는 표현이라고 합니다. 논문 또는 제안서와 같은 중요한 문서를 작성할 때 이러한 맞춤법이 틀리면 안 되겠죠. 저도 자주 헷갈려서 이제는 "더 이상" 틀리지 않기 위해 정리해봅니다.

 

"더이상" 아니죠~

"더 이상" 맞습니다~

[MATLAB] 그래프를 그릴 때 유용하게 사용되는 linspace 함수

코딩/matlab|2020. 6. 30. 07:10

오늘은 함수의 그래프를 그릴 때 유용하게 사용되는 함수인 linspace를 소개시켜 드리려고 합니다. 함수의 그래프를 매트랩을 이용해서 그리려고 한다면, 구간을 정해줘야합니다. "x의 값이 얼마에서 얼마일 때까지 그에 해당하는 그래프를 그리겠다." 

 

그러면 

 

$y = x^2 + 2x + 1$

 

에 대한 그래프를 그려보도록 하겠습니다. 구간을 linspace 함수를 이용해서 만들어줄 것입니다. -10이상 10이하의 구간에 대해서 그래프를 그리겠습니다. 

 

1
2
3
4
5
6
7
clc, clear, close all
 
= linspace(-10, 10);
= x.^2 + 2.*+ 1;
 
plot(x, y)
grid on
cs

 

이 코드를 실행하면 다음과 같은 그래프가 그려집니다. 

 

 

위 코드에서 linspace(-10, 10)의 의미는 "-10부터 10사이에 100개의 숫자를 균등하게 만들어줘"입니다. 

 

 

보시다시피 -10에서 10까지 항이 100개인 등차수열이 생성되었습니다. 

 

위와 같은 그래프가 그려지는 원리에 대해서 설명드리겠습니다. linspace를 통해 생성된 100개의 숫자들을 함수에 대입시켜서 y값을 모두 구해줍니다. 총 100개의 y값이 생성되겠죠. 즉, 100개 점의 위치를 알게 된 것입니다. 이 점들을 찍은 후에 선으로 이은 결과가 저 그래프인 것입니다. 저 그래프는 엄밀히 따지면 곡선이 아닙니다. 

 

만약에 linspace(-10, 10, 5)과 같이 linspace에 세번째 인수를 넣어주면 -10부터 10까지 5개의 항을 가진 등차수열을 생성하게 됩니다.

 

 

그러면 점들끼리 떨어져있게 되기 때문에, 그래프를 그리면 더 이상 아까처럼 곡선으로 보이지 않습니다. 

 

 

 

bskyvision의 추천글 ☞

헷갈리는 코딩용어, 매개변수(parameter)와 인수(argument)

 

 

동적 텍스처(dynamic texture) 분류란?


texture라는 것은 이미지 안에 있는 어떠한 질감이나 패턴을 의미합니다. 나무 사진만의 질감이 있고, 자갈밭의 사진에서 느낄 수 있는 질감이 있고, 하늘 사진이 주는 질감이 있죠. 각기 모두 다른 질감을 가지고 있습니다. 이러한 이미지들의 특징은 공간적으로 어떠한 패턴이 반복된다는 점입니다.  

 

여기서 더 나아가서, 앞에 동적이란 말이 붙었을 때는 공간적으로뿐만 아니라 시간적으로도 특정한 질감이 반복 유지되는 텍스처를 의미한다고 보시면 됩니다. 이러한 이유로 동적 텍스쳐는 temporal texture라고 불리기도 합니다. 동적 텍스처를 가진 영상을 몇 개 예시로 보여드리겠습니다. 

 

출처: [1]

 

이러한 동적 텍스처를 분류하는 연구 과제도 있습니다. 일종의 이미지 분류 과제라고 볼 수 있습니다. 이 동영상이 폭포수에 관한 영상인지, 피어오르는 연기에 관한 영상인지, 바람에 흩날리는 나뭇잎에 관한 영상인지 분류하는 과제가 바로 동적 텍스처 분류(classification), 다른 말로 하면 동적 텍스처 인식(recognition)입니다. 

 

대표적인 동적 텍스처 데이터셋에는 UCLA dataset과 Dyntex++ dataset이 있습니다. Dyntex++ dataset이 UCLA dataset에 비해 좀 더 분류하기 어려운 샘플들로 구성되어 있습니다. 

 

동적 텍스처 분류라는 기술이 실생활에서 어떻게 사용될 수 있을까요? 하나의 예를 들어보겠습니다. CCTV에 화재로 인한 연기를 분류하는 기능을 넣는 것은 어떨까요? 그것을 건물의 경보 시스템과 연동한다면, 건물 내 사람들이 빠르게 대피하게 하고 또 화재를 조기에 진압하는데 도움이 될 수도 있을 것입니다. 

 

 

<참고자료>

[1] Saisan, Payam, et al. "Dynamic texture recognition." Proceedings of the 2001 IEEE Computer Society Conference on Computer Vision and Pattern Recognition. CVPR 2001. Vol. 2. IEEE, 2001.