신경망 학습 - 기울기

AI / / 2020. 10. 29. 22:14
728x90
반응형

편미분에서는 변수 하나를 고정하고 변수별로 따로 계산햇는데. 변수를 같이 계산하고 싶다면 어떻게 해야 하는가?

x0 = 3, x1 = 4일 경우(x0,x1) 양쪽의 편미분을 묶어서 모든 변수의 편미분을 벡터로 정리한 것을 기울기라고 한다.

 

 

기울기 코드

# 기울기
import numpy as np

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


def numerical_gradient(f, x):
    h = 1e-4 # 10e-50의 경우에는 반올림 오차 때문에 1e-4로 사용
    grad = np.zeros_like(x) # x와 형상이 같은 배열을 생성
    
    for idx in range(x.size):
        tmp_val = x[idx]
        # f(x+h) 계산
        x[idx] = 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

# np.zeros.like(x)는 x와 형상이 같고 그 원소가 모두 0인 배열을 만든다.


# (3,4),(0,2),(3,0) 에서의 기울기 구하기

print(numerical_gradient(function_2, np.array([3.0, 4.0])))
print(numerical_gradient(function_2, np.array([0.0, 2.0])))
print(numerical_gradient(function_2, np.array([3.0, 0.0])))

 

경사법(경사 하강법)

 

* 기계학습 문제 대부분은 학습 단계에서 최적의 매개변수를 찾아낸다.

신경망 역시 최적의 매개변수(가중치와 편향)을 학습 시에 찾아야 한다.

최적이란 손실 함수가 최솟값이 될 때의 매개변수 값이다.

일반적인 문제의 손실 함수는 매우 복잡하다. 매개변수 공간이 광대해 어디가 최솟값이 되는 곳인지 알아내기가 어렵다. 

이런 상황에서는 기울기를 잘 이용해 함수의 최솟값(또는 가능한 한 작은 값)을 찾으려는 것이 경사법이다.

주의할 점 각 지점에서 함수의 값을 낮추는 방안을 제시하는 지표가 기울기라는 것이다.

기울기가 가리키는 곳에 정말 함수의 최솟값이 있는지, 그쪽이 정말로 나아갈 방향인지는 보장할 수 없다.

 

*함수가 극솟값, 최솟값, 안정점이 되는 장소에서는 기울기가 0이다.

기울어진 방향이 꼭 최솟값을 가리키는 것은 아니나, 그 방향으로 가야 함수의 값을 줄일 수 있다.

 

경사법

  • 현 위치에서 기울어진 방향으로 일정 거리만큼 이동한다.
  • 다음 이동한 곳에서도 기울기를 구하고, 또 그 기울어진 방향으로 나아가는 일을 반복한다.
  • 이렇게 함수의 값을 줄이는 것이 경사법이다.
  • 신경망 학습에서 많이 사용한다.

[그림1] 경사법 수식

 

수식에서는 갱신하는 양을 나타낸다. 이를 신경망에서는 학습률이라고 한다.

한 번의 학습으로 얼마만큼 학습해야 할지, 즉 매개변수 값을 얼마나 갱신하느냐를 정하는 것이 학습률이다.

 

경사법 코드

#  경사법
import numpy as np
import matplotlib.pylab as plt


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)

# 인수 f는 최적화하려는 함수, init_x는 초깃값, lr은 learning rate를 의미하는 학습률,
# step_num은 경사법에 따른 반복 횟수를 뜻한다.
# 함수의 기울기는 numerical_gradient(f, x)로 구하고 
# 그 기울기에 학습률을 곱한 값으로 갱신하는 처리를 step_num으로 반복한다.


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()

[그림2] 경사법

 

학습률이 너무 크거나 작으면 좋은 결과를 얻을 수 없다.

 

 

신경망에서의 기울기

 

수식

[그림3] 신경망에서의 기울기 수식 출처 : https://m.blog.naver.com/PostView.nhn?blogId=dsz08082&logNo=221192744946&proxyReferer=https:%2F%2Fwww.google.com%2F

 

신경망에서의 기울기 구하는 코드

# 신경망에서의 기울기

import sys,os
sys.path.append(os.pardir)
import numpy as np
from functions import softmax, cross_entropy_error
from gradient import numerical_gradient

class simpleNet:
    def __init__(self):
        self.W = np.random.randn(2,3) # 정규분포로 초기화
        
    def predict(self, x):
        return np.dot(x, self.W)
    
    def loss(self, x, t):
        z = self.predict(x)
        y = softmax(z)
        loss = cross_entropy_error(y, t)
        
        return loss
    
net = simpleNet()
print(net.W) # 가중치 매개변수


x = np.array([0.6, 0.9])
p = net.predict(x)
print(p)

np.argmax(p) # 최대값의 인덱스

t = np.array([0, 0 , 1]) #  정답 레이블
print(net.loss(x, t))

[그림4] 신경망에서의 기울기 결과

 

기울기 구하기

def f(W):
    return net.loss(x, t)

dW = numerical_gradient(f, net.W)
print(dW)

[그림5] 기울기

dW는 numerical_gradient(f, net.W)의 결과로 형상은 2*3의 2차원 배열이다. W의 w11은 대략 0.2다.

w11을 h만큼 늘리면 손실 함수의 값은 0.2h만큼 증가한다는 의미다. 마찬가지로 w23은 대략 -0.5이니 w23을 h만큼 늘리면 손실 함수의 값은 0.5만큼 감소한다는 의미다. 

그래서 손실 함수를 줄인다는 관점에서는 w23은 양의 방향으로 갱신하고 w11은 음의 방향으로 갱신해야 함을 알 수 있다.

 

lambda 활용

# lambda 기법

f = lambda w : net.loss(x, t)
dW = numerical_gradient(f, net.W)

 

신경망의 기울기를 구한 다음에는 경사법에 따라 가중치 매개변수를 갱신하기만 하면 된다.

 

 

출처 : 밑바닥부터 시작하는 딥러닝

https://www.hanbit.co.kr/store/books/look.php?p_code=B8475831198

 

밑바닥부터 시작하는 딥러닝

직접 구현하고 움직여보며 익히는 가장 쉬운 딥러닝 입문서

www.hanbit.co.kr

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기