편미분과 편미분의 기울기
지난 글에서 편미분의 개념과 편미분의 기울기에 대해서 정리했습니다.
이에 더 나아가 이번 글에서는 경사법에 대해서 정리하도록 하겠습니다.
경사법
경사법(gradient method) 최적의 매개변수를 탐색하기 위해 기울기를 사용해 함수의 최솟값을 찾으려는 방법입니다. 각 지점에서 함수의 값을 낮추는 방안을 제시하는 지표가 기울기가 됩니다. 하지만, 기울기가 제시하는 방향이 최솟값이 있는지는 보장하지 않습니다. 꼭 최솟값을 가리키지는 않지만, 그 방향으로 가야 함수의 값을 줄일 수 있습니다.
경사법은 현 위치에서 기울어진 방향으로 일정 거리만큼 이동하는 과정을 반복합니다.
흔히 경사 하강법이라고 하는 것은 손실 함수의 최솟값을 찾기 때문에 경사 하강법이라고 합니다.
반대의 경우에는 경사 상승법이 됩니다.
경사법을 수식으로 나타내면 다음과 같습니다.
$$x_{0}=x_{0}-\eta \dfrac{\partial f}{\partial x_{0}}$$
$$x_{1}=x_{1}-\eta \dfrac{\partial f}{\partial x_{1}}$$
\(\eta\)(에타, eta)기호는 갱신하는 양을 뜻합니다. 신경망 학습에서는 우리가 흔히 많이 들어본 학습률(learning rate)이라고 합니다. 한 번의 학습으로 매개변수 값을 얼마나 갱신하느냐를 정하는 것이 학습률입니다.
앞서 말한 동작 방식처럼 위의 식을 계속 반복하는 과정을 거치게 됩니다.
변수가 2개이지만, 변수의 개수가 늘어나도 같은 식으로 갱신하게 됩니다. (각 변수들의 편미분 값)
학습률 값은 보통 0.01 혹은 0.001 등 사전에 특정 값으로 지정해둡니다. 일반적으로 값이 너무 크거나 작으면 좋은 학습을 할 수 없습니다. 신경망 학습에서는 보통 이 학습률 값을 변경하면서 학습이 잘 되고 있는지 확인하며 진행합니다.
경사하강법의 구현 코드입니다.
import numpy as np
def numerical_gradient(f,x):
h = 1e-4
grad = np.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
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
def function(x):
return x[0]**2 + x[1]**2
init_x = np.array([-3.0, 4.0])
print(gradient_descent(function, init_x=init_x, lr=0.1, step_num=100))
[-6.11110793e-10 8.14814391e-10]
numerical_gradient()는 변수들의 편미분을 구해 벡터로 정리하는 코드(기울기)입니다.
gradient_descent()는 경사법을 구현한 코드입니다.
function()은 함수의 식을 정의한 코드입니다.
초깃값 (-3.0, 4.0)을 설정한 후 경사법을 사용해 최솟값을 탐색합니다.
결과는 위와 같이 거의 (0, 0)에 가까운 결과를 얻게 됩니다.
이 과정을 그림으로 나타내면 다음과 같습니다.
위에서 학습률이 너무 크거나 작으면 좋은 결과를 얻을 수 없다고 했는데 학습률을 조정해 결과를 확인해 보도록 하겠습니다.
print(gradient_descent(function, init_x=init_x, lr=10.0, step_num=100))
print(gradient_descent(function, init_x=init_x, lr=1e-10, step_num=100))
[-2.58983747e+13 -1.29524862e+12]
[-2.99999994 3.99999992]
결과에서 확인할 수 있듯이, 너무 크면 큰 값으로 발산해버립니다.
반대로 너무 작으면 갱신이 거의 이루어지지 않음을 확인할 수 있습니다.
이를 통해 학습률을 적절하게 설정하는 것이 왜 중요한지 배울 수 있습니다.
'머신러닝 & 딥러닝 > 기초 이론' 카테고리의 다른 글
[머신러닝/딥러닝 기초] 13. 편미분과 편미분의 기울기 (0) | 2022.02.18 |
---|---|
[머신러닝/딥러닝 기초] 12. 미분과 수치미분 (0) | 2022.02.17 |
[머신러닝/딥러닝 기초] 11. 정확도 대신 손실 함수를 사용하는 이유 (0) | 2022.02.17 |
[머신러닝/딥러닝 기초] 10. 손실 함수: 평균 제곱 오차와 교차 엔트로피 오차 (0) | 2022.02.16 |
[머신러닝/딥러닝 기초] 9. 항등 함수와 소프트맥스 함수 (0) | 2022.02.15 |
댓글