반응형

다층 퍼셉트론과 같은 인공신경망을 구현하는 것은 꽤 복잡하고 까다로운 작업이라는 것을 [37편]에서 잠시 느꼈을 것입니다. 그렇다면 우리가 구현한 인공신경망이 제대로 동작하는지, 혹은 정확도가 얼마인지 어떻게 측정해야 할까요?


인공신경망 구현의 핵심은 역전파라고 했으니, 역전파 알고리즘이 얼마나 정확하게 구현되었는지에 대해 검증하면 될 것 같습니다. 역전파 알고리즘을 우리가 직접 수동으로 검증하는 방법이 그라디언트 체킹(gradient checking)이라는 기법입니다.


이번 포스팅에서는 그라디언트 체킹에 대해 가볍게 살펴보고 넘어갑니다.


역전파에서 가중치를 업데이트하기 위해 계산해야 하는 식은 아래의 편미분 식이라는거 이미 알고 있습니다.



여기서 w는 신경망의 모든 가중치에 대한 행렬입니다. 이 미분값을 해석적 그라디언트(Analytical Gradient) 값이라 부릅니다.


도함수의 정의에 의해 해석적 그라디언트는 아래와 같이 표현됩니다.



[식1] 



[식1]의 오른쪽 항에서 ε이 매우 작은 값이라 할 때, 아래의 값으로 근사됩니다.



[식2] 



[식2]의 오른쪽 항의 값을 수치적 그라디언트(Numerical Gradient) 값이라 부릅니다.


아래 그림은 수치적 그라디언트의 기하학적인 의미를 나타낸 것입니다.


 



[식2]에서 ε을 -ε으로 바꾸어보면 아래의 식이 됩니다.



[식3]


[식2]와 [식3]의 양 변을 각각 더하면 아래의 식이 됩니다.




따라서,



[식4]



[식4]의 오른쪽 항을 새롭게 정의한 수치적 그라디언트로 채택합니다. 실제로 새롭게 정의한 수치적 그라디언트가 해석적 그라디언트와의 오차가 더 작게 나옵니다. 


수치적 그라디언트를 J'n 이라 하고 해석적 그라디어트를 J'a라 하면 절대오차 Err와 상대오차 Rerr는 다음과 같이 정의합니다.



[식5]






이 식에서 || ||는 행렬의 놈(norm)이며 행렬의 놈은 행렬의 모든 성분을 p제곱하여 더한 값의 p제곱근으로 정의됩니다.

n x m 행렬 A가 다음과 같을 때,

행렬 A의 놈은 아래와 같이 정의됩니다.



여기서 p=2인 경우를 프로베니우스 놈이라 부르며 가장 일반적으로 많이 사용되는 행렬 놈입니다.


우리가 구현한 역전파 알고리즘의 정확도는 해석적 그라디언트와 수치적 그라디언트의 상대 오차값으로 평가합니다. 역전파 알고리즘의 정확도를 평가하는 측도로써 절대 오차를 사용하지 않는 이유는 Err가 매우 작은 값이더라도 J'nJ'a  값 자체가 매우 작다면 상대적으로 오차율이 커지기 때문입니다.



상대오차 Rerr의 값에 따른 역전파 알고리즘의 정확도는 일반적으로 아래와 같은 규칙을 따릅니다.




이 규칙에 따라 [37편]에서 구현한 MLP를 검증해보도록 합니다.


아래의 코드를 [37편]의 dl_mlp_class.py에서 구현한 NeuralNetMLP 클래스의 메쏘드로 추가합니다.




이 코드는 [식5]의 Rerr를 계산하여 리턴하는 함수를 구현한 것입니다. 코드를 보면 그렇게 어려운 부분이 없습니다.


NeuralNetMLP 클래스의 fit() 메쏘드에서 역전파를 통해 경사를 계산하는 코드를 찾습니다.



이 코드 다음에 아래의 코드를 추가합니다.




그라디언트 체크 기능이 추가된 NeuralNetMLP 클래스가 완성되었습니다. 이제 아래의 코드를 작성합니다.




이 코드는 X_train, y_train의 5개 데이터에 대한 10회 학습의 그라디언트 체킹을 수행한 결과를 화면에 출력합니다. 시간이 제법 소요되므로 너긋하게 기다리면서 결과를 지켜보도록 합니다.


코드를 수행한 결과는 다음과 같습니다.


Warning: 3.537822909e-07
OK: 3.02628344172e-10
OK: 3.02609921621e-10
OK: 3.06158619281e-10
OK: 3.21874437906e-10
OK: 3.27658507646e-10
OK: 2.87684685361e-10
OK: 2.32833603418e-10
OK: 2.52932883134e-10
OK: 2.70109334393e-10



1회 학습을 빼고 2회~10회까지 그라디언트 체킹 결과는 매우 훌륭하다는 것을 알 수 있습니다. 따라서 [37편]에서 구현한 역전파 알고리즘은 제대로 구현한 것이라고 판단할 수 있습니다.


체킹이 마무리되면 fit()에 추가한 그라디언트 체킹 수행 코드를 주석 처리 해둡니다. 


반응형

+ Recent posts