딥러닝 3.2 신경망 학습
이번 글에서는 앞 글에서 봤던 편미분을 묶어서 동시에 계산하는 방법을 알아보겠다.
이 묶어서 계산하는 방법이 바로 기울기라는 것이다.
지금부터 기울기에 대해 알아보겠다.
그림 1처럼 모든 변수의 편미분을 벡터로 정리한 것을 기울기라고 한다.
이 기울기를 파이썬으로 구현해보겠다.
기울기 코드
import numpy as num
def numerical_gradient ( f, x ) :
h = 1e-4
grad = num.zeros_like ( x )
for idx in range ( x.size ):
tmp_val = x [ idx ]
x [ idx ] = tmp_val + h
fxh1 = f ( x )
x [ idx ] = tmp_val - h
fxh2 = f ( x )
grad [ idx ] = ( fxh1 -fxh2 ) / ( 2 * h )
x [ idx ] = tmp_val
return grad
코드 해석을 해보겠다.
numerical_gradient ( f, x ) 함수의 동작 방식은 변수가 하나일 때의 수치 미분과 같다.
num.zeros_like ( x )는 x와 형상이 같고 그 원소가 모두 0인 배열을 만든다.
numerical_gradient ( f, x ) 함수의 인수인 f는 함수고 x는 넘 파이 배열이므로 넘파이 배열 x의 각 원소에 대해서 수치 미분을 구한다.
이제 이 함수를 사용해서 실제로 기울기를 계산해보겠다.
세 점 ( 3, 4 ), ( 0, 2 ), ( 3, 0 )에서의 기울기를 구해보겠다.
print ( numerical_gradient ( function_2, num.array ( [ 3.0, 4.0 ] ) ) )
print ( numerical_gradient ( function_2, num.array ( [ 0.0, 2.0 ] ) ) )
print ( numerical_gradient ( function_2, num.array ( [ 3.0, 0.0 ] ) ) )
한번 출력을 해본다.
결괏값은
[6. 8.]
[0. 4.]
[6. 0.]
이 나온다.
( 3, 4 )의 기울기는 ( 6, 8 )
( 0, 2 ) 의 기울기는 ( 0, 4 )
( 3, 0 ) 의 기울기는 ( 6, 0 )
이란 걸 알 수 있다.
그런데 이 기울기라는 게 의미하는 것이 뭘까 라는 의문점이 든다.
# coding: utf-8
# cf.http://d.hatena.ne.jp/white_wheels/20100327/p3
import numpy as num
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D
def _numerical_gradient_no_batch ( f, x ) :
h = 1e-4 # 0.0001
grad = num.zeros_like ( x ) # x와 형상이 같은 배열을 생성
for idx in range ( x.size ) :
tmp_val = x [ idx ]
# f(x+h) 계산
x [ idx ] = float ( tmp_val ) + h
fxh1 = f ( x )
# f(x-h) 계산
x [ idx ] = tmp_val - h
fxh2 = f ( x )
grad [ idx ] = ( fxh1 - fxh2 ) / ( 2 *h )
x [ idx ] = tmp_val # 값 복원
return grad
def numerical_gradient ( f, X ) :
if X.ndim == 1:
return _numerical_gradient_no_batch ( f, X )
else:
grad = num.zeros_like ( X )
for idx, x in enumerate ( X ) :
grad [ idx ] = _numerical_gradient_no_batch ( f, x )
return grad
def function_2 ( x ) :
if x.ndim == 1 :
return num.sum ( x**2 )
else:
return num.sum ( x**2, axis=1 )
def tangent_line ( f, x ) :
d = numerical_gradient ( f, x )
print ( d )
y = f ( x ) - d*x
return lambda t: d*t + y
if __name__ == '__main__':
x0 = num.arange ( -2, 2.5, 0.25 )
x1 = num.arange ( -2, 2.5, 0.25 )
X, Y = num.meshgrid ( x0, x1 )
X = X.flatten()
Y = Y.flatten()
grad = numerical_gradient ( function_2, num.array ( [ X, Y ] ) )
plt.figure()
plt.quiver ( X, Y, -grad [ 0 ], -grad [ 1 ], angles= "xy",color = "#666666" )#,headwidth=10,scale=40,color="#444444")
plt.xlim ( [ -2, 2 ] )
plt.ylim ( [ -2, 2 ] )
plt.xlabel ( 'x0' )
plt.ylabel ( 'x1' )
plt.grid()
plt.legend()
plt.draw()
plt.show()
위 코드를 실행시키면
기울기는 그림 2처럼 방향을 가진 화살표로 그려진다.
기울기 함수는 가장 낮은 장소 ( 최솟값 )를 가리킨다.
기울기가 가리키는 쪽은 각 장소에서 함수의 출력 값을 가장 크게 줄이는 방향이다.
이까지 기울기에 대해 알아봤다.