이전에 GD(Gradient Descent) 를 간단한 회귀분석 예제를 들어 GD로 학습하는 과정을 거쳐 parameter 를 추정하는 연습을 통해 GD 를 이해해 보았다.
data-science-hi.tistory.com/163
이번 장에서 알아볼 SGD(Stochastic Gradient Descent)는 GD 에 시간비용 단점을 보완할 확장판이다.
GD 의 문제점.
이전에 봤던 GD 예제를 다시 상기해보자. 가중치를 한번 업데이트 하기 위해서 전체 error 를 구하고 이 전체 error 를 미분하여 parameter 를 업데이트할 요소를 만들었는데, 이 때 문제가 되는 것이 바로 전체 error 를 구하고 미분하는 부분이다.
아래의 $\theta$ 는 학습시키는 parameter 를 의미하고, $\eta$ 는 learning rate(학습률)을 의미한다. $\triangledown_{\theta}J(\theta)$ 는 objective function(loss function, 목적함수)에 대한 gradient 를 의미한다.
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
GD의 경우는 한번 업데이트(an epoch)를 할 때마다 전체의 train data 를 input 으로 넣어서 전체 error 를 구하는데 드는 시간 비용이 많이 든다. 학습시 걸리는 시간은 데이터의 크기에 비례하기 때문에 전체를 다 보면서 parameter 를 업데이트를 하는 것은 비효율적으로 오래 걸린다는 것이다.
이를 해결하기 위해 등장한 것이 바로 Stochastic Gradient Descent(Mini Batch Gradient Descent) 방법이다.
Stochastic Gradient Descent
먼저 아래의 수식을 보면, 위의 GD 와의 차이는 jacobian function에 input 부분이 달라진 것을 알 수 있다. 여기서, $\theta$ 는 역시 parameter를 의미하며, $x^{(i)}$, $y^{(i)}$ 가 의미하는 것은 전체 데이터가 아닌 샘플을 가지고 생성된 샘플들에 대해서 gradient 를 구하며 parameter 를 업데이트 해가는 방식이다.
아래의 수식에서 $m$ 이 곧 아래의 코드에서 random 을 돌리고, 두번째 for 문에서 example 을 뽑는 그 과정에서 생겨난 sample 들이라고 생각하면 된다.
for i in range(nb_epochs):
np.random.shuffle(data)
for example in data:
params_grad = evaluate_gradient(loss_function, example, params)
params = params - learning_rate * params_grad
아래의 그림은 우리가 이미 알고 있는 Gradient Descent 방식이 최적의 해를 찾아가는 과정(검은색)과 Stochastic Gradient Descent 방식으로 최적의 해를 찾아가는 과정(빨간색)을 나타낸 그림이다.
그림에서 보면 GD 의 경우 일정한 방향으로 해를 찾아가는 반면에 SGD의 경우는 방향이 여기저기로 바뀌면서 해를 찾아간다. 또한 SGD 의 경우는 더 많은 epoch 를 한 것으로 보인다.
하지만 먼저 핵심을 말하면 SGD 의 경우에는 GD 보다 많은 epoch 를 돌렸지만, 결과적으로 시간이 더 적게 든다.
그 이유는 GD 가 전체 데이터에 대한 모든 error 를 다 계산해서 겨우 한번 업데이트하는 것이 아닌 보다 적은 데이터를 뽑고 그에 대한 gradient 를 빨리 빨리 구해서 parameter 를 자주 업데이트 하되 전체적인 시간은 줄일 수 있기 때문이다.
Mini-Batch Gradient Descent
MBGD(Mini-Batch Gradient Descent)는 SGD 랑 혼용이 되어 사용된다. SGD를 위에서 다음과 같이 언급하였다. Stochastic Gradient Descent(Mini Batch Gradient Descent) 이렇게 언급한 이유는 엄밀하게 말하면 SGD와 MBGD 는 다르지만 범용적으로 통용되어 사용되고 있다. 왜 이렇게 사용되냐면, MBGD 같은 경우는 GD와 SGD의 장점을 모아서 이뤄지게끔 설계되었기 때문이기도 하고, 어차피 mini-batch를 사용하고, 전체 데이터셋을 한번에 다 넣어서 gradient 를 구하는게 아닌 소규모를 짜잘하게 고려하자는 것이므로 그 비슷한 맥락 때문에 그렇게 불려지는 것 같다.
MBGD 는 SGD 처럼 전체 데이터셋에 대한 error 가 아닌 더 작은 데이터에 대한 error 를 구하는데, SGD 와의 차이점은 mini-batch 를 사용한다는 점이다. batch_size는 직접 설정을 해주어야하는 부분이다. 보통 2의 제곱 수로 설정을 한다. 256, 512, 1024 와 같이 말이다. 계산효율이 더 좋다고 한다.
위의 SGD 와 코드를 통해 비교해보면, 두번째 for 문을 들어갈 때, SGD가 전체 데이터에 대해 한땀한땀 iteration 을 돈다면, MBGD의 경우는 전체 데이터셋을 batch size 만큼 뚝 잘라서 나누어 놓고, 그들에 대한 각각의 gradient 를 계산하여 그들의 평균 gradient 를 계산하여 업데이트에 사용한다.
for i in range(nb_epochs):
np.random.shuffle(data)
for batch in get_batches(data, batch_size=50):
params_grad = evaluate_gradient(loss_function, batch, params)
params = params - learning_rate * params_grad
Gradient Descent 방식에서 명확한 문제점을 해결하기 위해 SGD나 MBGD 방식이 등장했고, 이것들은 local minimum 에 빠질 확률은 줄일 수 있으나 역시 빠질 수 있고 또, 헤어나오지 못함으로써 최적의 성능을 낼 수 없는 한계를 가지고 있다. 장점이라하면 지금까지 얘기했듯 계산량을 줄이게 되어 시간단축을 할 수 있다.
이러한 한계점을 해결하기 위해서 step size 를 조절하거나, step direction 을 조절하는 최적화 방법론들이 등장하게 된다.
ref)
1) www.slideshare.net/yongho/ss-79607172
2) ruder.io/optimizing-gradient-descent/
'머신러닝' 카테고리의 다른 글
Momentum과 Adagrad를 쉽게 이해해보자! (0) | 2020.12.16 |
---|---|
gradient descent(경사하강법) 를 쉽게 이해해보자. (0) | 2020.12.14 |
Ensemble Methods (0) | 2020.11.29 |
Expectation Maximization (1) | 2020.11.24 |
Dimensionality Reduction (0) | 2020.11.16 |
댓글