본문 바로가기

Deep Learning

0. 딥러닝 기초지식

*** 해당 포스트는 "밑바닥부터 시작하는 딥러닝" 책을 바탕으로 작성되어 있음을 알려드립니다 :)

4장. 신경망 학습

ㅁ 신경망을 학습하는데 있어 필요한 데이터

  • 훈련 데이터 : 훈련하는데 있어 필요한 데이터
  • 시험 데이터 : 훈련이 잘 되었는지 측정을 위한 데이터 ( 해당 데이터는 훈련데이터에 포함되어 있어서는 안된다. 왜냐하면 이미 훈련되는데 쓰여진 데이터는 시험을 하기에는 오염되었다고 판단되기 때문이다. )
  • 추후에 다시 얘기 되겠지만 이것이 "오버피팅 ( 훈련데이터에만 너무 잘 맞춰진 모델의 문제)" 문제와도 연결된다.


ㅁ 손실함수 

성능의 "나쁨"을 나타내는 지표로 딥러닝의 목적을 구체화 하면 이 손실함수의 값을 Minimize 하는 것이다. 손실함수를 예시로 하나 들어보면 손글씨를 보고 이 손글씨가 나타내는 숫자를 예측하는 MINIST 에서 내가 예측한 값이 실제 값과 얼마나 차이가 나느냐 이다.

얼마나 차이가 나? 라는 수식적인 표현을 위해 2가지의 Loss function 이 존재한다.

  • 평균 제곱 오차 ( Mean squared error, MSE )

  • 교차 엔트로피 오차 ( Cross entropy error, CEE )



  • 왜 손실함수 값을 설정해?

 - 손실함수 값을 가능한 작게 만드는 매개변수를 찾는다.

 - 신경망을 학습할때 정확도를 지표로 삼으면 절대 안된다! 왜냐면 정확도는 대부분의 장소에서 0이 되기 때문이다. 신경망 학습이란 W ( weight ) 값을 조금씩 바꿔가면서 개선이 되는가를 보는건데 정확도를 보는 방법으로 해버리면 W 값을 조금씩 바꿔도 정확도가 개선되지는 않기 때문이다.


ㅁ 미니배치 학습

모든 훈련데이터를 대상으로 매번 일일이 손실함수 값을 계산하는것은 현실적이지 않을테니 일부를 추려 "근사치"로 이용하는것을 미니배치라 한다.


ㅁ 미분하는 방법

미분 하는 방법은 크게 두가지가 있다. 수식자체를 미분하는법 ( 수치 미분 ), 도함수의 미분으로 실제로 미분을 해보는 법( 해석적 미분 ).

해석적 미분에 대한 설명은 은 아래 링크를 참조하기로 하자.

# coding: utf-8
import numpy as np
import matplotlib.pylab as plt


def numerical_diff(f, x):
    h = 1e-4 # 0.0001
    return (f(x+h) - f(x-h)) / (2*h)


def function_1(x):
    return 0.01*x**2 + 0.1*x 


def tangent_line(f, x):
    d = numerical_diff(f, x)
    print(d)
    y = f(x) - d*x
    return lambda t: d*t + y
     
x = np.arange(0.0, 20.0, 0.1)
y = function_1(x)
plt.xlabel("x")
plt.ylabel("f(x)")

tf = tangent_line(function_1, 5)
y2 = tf(x)

plt.plot(x, y)
plt.plot(x, y2)
plt.show()



ㅁ 경사법 ( 경사 하강법 - Gradient descent method )

  • 미분 값이 작아지는 쪽으로 조금식 W 값을 조정한다. 이때 얼만큼 조정할 지를 η ( 에타 ) 로 표현하고 이를 학습률 ( learning rate ) 라고 부른다.
  • 이런 학습률 ( learning rate ) 같은 값을 실제 딥러닝 프레임워크에서는 입력값으로 넣게 되는데 이러한 값들에 따라 학습이 얼마나 빨리 혹은 잘 되는지가 달라진다. 그래서 이런 값들을 하이퍼 파라미터라고 부르게 된다.
  • 하이퍼 파라미터는 신경망의 매개변수와는 성질이 다른 매개변수이다. 매개변수는 알고리즘에 의해서 자동으로 획득되는 반면, 학습률 같은것은 사람이 직접 설정해서 최적의 값을 찾아 내야 한다.

# coding: utf-8
import numpy as np
import matplotlib.pylab as plt
from gradient_2d import numerical_gradient


def gradient_descent(f, init_x, lr=0.01, step_num=100):
    x = init_x
    x_history = []

    for i in range(step_num):
        x_history.append( x.copy() )

        grad = numerical_gradient(f, x)
        x -= lr * grad

    return x, np.array(x_history)


def function_2(x):
    return x[0]**2 + x[1]**2

init_x = np.array([-3.0, 4.0])    

lr = 0.1
step_num = 20
x, x_history = gradient_descent(function_2, init_x, lr=lr, step_num=step_num)

plt.plot( [-5, 5], [0,0], '--b')
plt.plot( [0,0], [-5, 5], '--b')
plt.plot(x_history[:,0], x_history[:,1], 'o')

plt.xlim(-3.5, 3.5)
plt.ylim(-4.5, 4.5)
plt.xlabel("X0")
plt.ylabel("X1")
plt.show()

ㅁ 정리 ( 학습 알고리즘 구현하기 )

  • 1단계 - 미니배치
  • 2단계 - 기울기 산출
  • 3단계 - 매개변수 갱신
  • 4단계 - 1,2,3 단계 반복
참고로 미니배치에 의한 경사하강법을 구하는 것을 SGD ( Stochastic gradient descent ) 라고 한다.








'Deep Learning' 카테고리의 다른 글

4. RNN  (0) 2017.05.30
3. CNN  (0) 2017.05.26
2. 학습관련 기술들  (0) 2017.05.14
1. 오차역전파법 ( Backpropagation )  (0) 2017.05.14