SGD = Stochastic Gradient Descent
신경망 학습에서 '확률적으로 무작위로 골라낸 데이터'에 대해 수행하는 경사 하강법.
신경망 학습에서는 데이터를 미니배치로 무작위로 선정해서 학습하므로, SGD라 지칭함.
신경망 학습에서는 데이터를 미니배치로 무작위로 선정해서 학습하므로, SGD라 지칭함.
- 경사법 = Gradient Method 현 위치에서 기울어진 방향으로 일정 거리만큼 이동함. 그 뒤 이동한 부분에서 다시 기울기를 구하고, 또 그 기울어진 방향으로 이동을 반복함.
- 경사 하강법 = Gradient Descent Method 경사법 중 최솟값을 찾는 방법. 일반적으로 신경망 분야에서는 경사법이 경사 하강법으로 등장함(손실 함수의 최솟값을 찾아야 하므로)
- 파이썬 구현 수치 미분 구현(numerical_gradient 함수)은 이곳 참조.
- SGD의 단점 비등방성 = anisotropy 함수(방향에 따라 성질=기울기 가 달라지는 함수.)에서는 탐색 경로가 비효율적이다.
이런 방법으로 함수의 값을 줄여나가거나(경사 하강법) 늘려나가며(경사 상승법) 기울기가 0인 지점을 찾음.
이 방법의 경우, 복잡한 함수일 때 고원 = plateau 이라는 평평한 곳으로 파고들며 학습이 진행되지 않는 정체기에 빠질 수 있음.
또한 기울기가 0인 곳은 최솟값이나 최댓값 뿐만 아니라 극솟값/극댓값/안장점 이 될 수도 있음.
매개변수의 갱신과정은 아래와 같음.($h$,$b$ : 가중치, 편향과 같은 매개변수, $\eta$ : 학습률 = learning rate, $f$ : 손실 함수) $$ w = w - \eta\frac{\partial f}{\partial w} \\ b = h - \eta\frac{\partial f}{\partial b} $$ 여기서 학습률이란 갱신하는 양으로, 한 번의 학습으로 얼마만큼 학습해야 하는지를 정함. 일반적으로 0.01, 0.001과 같이 미리 특정 값으로 정함.
이 학습률이 너무 크거나 작으면 목표하고자 하는 곳에 도달할 수 없음.
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(x_0,x_1) = x_0^2 + x_1^2$의 최솟값을 찾아보자.def function_2(x):
return x[0]**2 + x[1]**2
init_x = np.array([-3.0, 4.0])
lr = 0.1
step_num = 100
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()
결과는 다음과 같다.학습률에 따른 차이를 알아보기 위해 위 소스의 lr값을 0.005로 바꾸면 다음과 같다.
위에서 확인 할 수 있듯이, 학습률이 낮으면 100번 반복해도(step_num 값) 최솟값인 ($x_0$,$x_1$) = (0,0)에 다가가지 못한다.
이번엔 반대로 학습률을 높여보자.(lr을 1과 0.9로 설정)
1의 경우가 주황색이고, 0.9가 파란색이다. 그림에서 볼 수 있듯이, 0.9는 결과적으로는 찾아갔지만 1은 두 점만 반복하며 못 찾는 것을 볼 수 있다.
실제로 x_history의 변수를 보면 아래와 같다.
# lr = 0.9
x_history
array([[ -3.00000000e+00, 4.00000000e+00],
[ 2.40000000e+00, -3.20000000e+00],
[ -1.92000000e+00, 2.56000000e+00],
...,
[ 1.19357577e-09, -1.59143436e-09],
[ -9.54860614e-10, 1.27314749e-09],
[ 7.63888491e-10, -1.01851799e-09]])
# lr = 1
x_history
array([[-3., 4.],
[ 3., -4.],
[-3., 4.],
...,
[ 3., -4.],
[-3., 4.],
[ 3., -4.]])
따라서 학습률의 설정은 중요하고, 이와 같은 매개변수를 하이퍼파라미터 = hyper parameter 로 지칭한다.
예를 들어 $f(x,y) = \frac{1}{20}x^2 + y^2$과 같은 함수의 탐색경로를 아래와 같이 찾는다.(시작 위치 : (-7,2))
위와 같이 탐색하는 이유는 SGD가 무작정 기울어진 방향으로 탐색하기 때문이고, 이 방향이 본래의 최솟값과는 다른 방향을 가리키기 때문이다.
이러한 단점을 개선해주는 모델로 Momentum, AdaGrad, Adam 등이 있다.
댓글
댓글 쓰기