경사하강법(Gradient Descent method)
* 경사하강법은 최적의 가중치와 편향을 찾기 위한 알고리즘이다. 여기서 최적이란 손실함수의 값을 최소화 하는, 즉 다시 말해 예측값과 정답 레이블의 차이를 최소화 하는 것을 뜻한다. 경사하강법은 방대한 크기의 공간에서 최적의 값을 찾기 위해 '기울기'를 이용한다.
$x_0 = x_0 - \eta {\partial f \over \partial x_0}$
$x_1 = x_1 - \eta {\partial f \over \partial x_1}$
* 가중치의 갱신은 위와 같이 이뤄진다. 위 식은 가중치 1회 갱신에 대해 나타내고 있다.
* 여기서 $\eta$는 learning rate이라고 한다. learning rate은 가중치 update에 기울기를 얼마나 반영할 것인지를 나타내는 parameter이다.
def numerical_gradient(f,x):
h = 1e-4 #0.0001
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
def gradient_descent(f, init_x, lr=0.01, step_num=100):
x = init_x
for i in range(step_num):
grad = numerical_gradient(f,x)
x -= lr * grad
return x
* gradient_descent 함수는 위에서 설명한 수식을 그대로 구현한 것이다. numerical_gradient는 주어진 점의 기울기를 구하는 함수로 이전 포스팅에
경사하강법의 문제
* 경사가 0인 지점을 따라 내려가다보면 global minimum이 아닌 local minimum에 빠질 위험이 있다.
* 비슷한 개념이지만, 위와 같이 saddle point(안장점) 에서 gradient가 0이 되어 학습이 멈출 위험이 있다.
신경망에서의 기울기
* 지금까지 배운 것 처럼 손실함수를 최소화 하기 위해서는 gradient descent 방법을 사용하고, gradient descent를 사용하기 위해서는 기울기를 구해야 한다.
* 만약 신경망의 특정 뉴런의 가중치가 W라고 했을 때 가중치 W의 기울기는 위 그림처럼 각 원소의 기울기를 편미분한 값이다.
* 실제로 기울기를 구하는 코드를 구현하기 앞서
import sys, os
sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정
import numpy as np
from common.functions import softmax, cross_entropy_error
from common.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): # Loss Function
z = self.predict(x)
y = softmax(z)
loss = cross_entropy_error(y, t)
return loss
* 뉴런의 개수가 3개인 layer가 1 개로 구성된 neural network를 정의하였다. 다중 label 분류 문제를 위해 마지막 layer는 softmax를 사용하였다.
x = np.array([0.6, 0.9])
t = np.array([0, 0, 1])
net = simpleNet()
f = lambda w: net.loss(x, t) # 인수로 w를 받아 손실 함수를 계산
dW = numerical_gradient(f, net.W) # 미분을 사용하여 기울기를 구한다.
print(dW)
>> [[ 0.25448428 0.03691667 -0.29140095]
[ 0.38172642 0.05537501 -0.43710143]]
* 인수를 w로 받아 손실함수를 계산하는 lambda 함수를 정의하고, 이를 통해 가중치의 기울기 dw를 구하였다.
* 위 결과를 보면 알 수 있다시피 $w_11$의 편미분 값은 약 0.25이다. 편미분 값이 0.25라는 것은 $w_11$이 0에 한없이 가까운 수인 h만큼 증가할 때 손실함수의 값은 0.25h 만큼 증가한다는 것을 뜻한다. 우리의 목표는 손실함수의 값을 최소로 하는 가중치를 찾는 것이기 떄문에 $w_11$을 음의 방향으로 갱신해 손실함수의 값을 줄여야 할 것이다.
학습 알고리즘 구현하기
1단계 - 미니배치
* 훈련 데이터를 random으로 sampling한다.
2단계 - 기울기 산출
* 미니배치의 손실함수를 최소로 하는 기울기를 찾기 위해 일단 현재 가중치의 기울기를 계산한다.
3단계 - 매개변수 갱신
* 가중치 매개변수를 기울기 방향으로 아주 조금 갱신한다.
4단계 - 반복
* 1~3단계를 반복한다.
'Deep Learning > 밑바닥부터 시작하는 딥러닝' 카테고리의 다른 글
Optimizer (0) | 2022.01.27 |
---|---|
Backpropagation (0) | 2022.01.27 |
수치 미분 (0) | 2022.01.25 |
손실 함수 (0) | 2022.01.25 |
신경망 (0) | 2021.11.23 |