본문 바로가기
머신러닝

Momentum과 Adagrad를 쉽게 이해해보자!

by 볼록티 2020. 12. 16.
728x90
반응형

 

 이전에 gradient descent 방식의 계산량이 많아 시간이 많이 소요된다는 한계점을 해결하는 방법인 Stochastic Gradient descent 방식과 mini-batch gradient descent 방식에 대해 알아보았다.

data-science-hi.tistory.com/164

 

Stochastic Gradient Descent 를 쉽게 이해해보자.

 이전에 GD(Gradient Descent) 를 간단한 회귀분석 예제를 들어 GD로 학습하는 과정을 거쳐 parameter 를 추정하는 연습을 통해 GD 를 이해해 보았다. data-science-hi.tistory.com/163 gradient descent(경사하..

data-science-hi.tistory.com

 

 

 기존의 SGD 방식에다가 추가로 업그레이드를 시켜서 local minimum에 빠져버리는 문제를 해결하는 Momentum 방법과 Adagrad 방법에 대해 알아본다.

 

 

 

 

Momentum

 

 

 SGD 는 아래의 왼쪽 그림처럼 최적의 지점인 한가운데까지 가지 못하고 그전에 수렴을 해버린다. 이것이 바로 local minimum 에 빠지는 모습이다. 하지만 오른쪽의 그림과 같이 momentum과  함께라면 local minimum 을 지나 global minimum 에 더 가깝게 갈 수 있다. 즉, 성능이 더 좋아지게 된다.

 

 

 Momentum은 SGD가 중구난방으로 최적점을 찾아가는 것에 대해서 그 진동을 줄이고, 최적점에 연관된 방향으로 더 가속을 해주는 방법이다. 아래의 수식을 보면 기존에 Gradient Descent 와 비교했을 때 식이 하나 더 늘어난 느낌이다. 그것은 바로 $\nu_{t}$ 라는 것이 추가되었기 때문이다. 

 이 식을 보았을 때 직관적으로 보이는 것은 기존의 업데이트 요소인 $\eta \triangledown _{\theta}J(\theta)$ 에 다가 무엇을 더해서 새로운 무언가 $\nu_{t}$ 를 만들고, 이것을 기존의 parameter에 빼줌으로써 weight 를 업데이트 한다.

 그렇다면 기존 업데이트 요소에 더해주는 term에 있는 $\gamma$ 와 $\nu$ 가 무엇인지 알아보자.

 

 

 먼저 $\gamma$ 의 경우는 momentum term 이라 정의하고, 1 보다 작은 0.9와 같은 값으로 지정해준다. $\gamma$ 가 하는 역할은 momentum(운동량) 을 얼마나 줄 것인지를 의미한다. 

 좀 더 직관적으로 이해하기 위해 간단한 연산을 보여주는 예시를 가져왔다. 아래의 수식은 gradient descent 방식으로 weight 를 업데이트 하는 과정을 나타낸다. 여기서 learning rate는 0.1 로 하여 계산하였다.

 이제 Momentum 을 적용하여 weight 를 업데이트하는 과정을 살펴보자.  초기에 $\nu_{1}$ 은 0으로 주고 시작한다. 그리고 hyperparameter 이자 momentum 크기를 의미하는 $\gamma$ 여기 예제에서는 $\alpha$로 표기 되어있는데, 0.9로 설정을 하고 계산한다.

 처음에는 GD가 했던 weight 업데이트하는 방법과 동일하게 진행이 된다. 그러나, 이후 부터는 업데이트 양이 달라지기 시작한다. 왜냐하면 이전에 저장해두었던 $\nu_{1}$ 이 -0.5 라는 값을 가지고 있는 상태이고, 이를 다음 2번째 iteration 에서부터 사용하기 시작한다. 아래의 수식을 보면 기존 parameter에 0.3만 빼주면 되는데 여기에 이제는 더이상 0이 아닌 $nu_{1}$을 gradient 정보와 더해서 만든 0.75를 parameter에 빼주게 된다.

 여기서 Momentum 의 장점을 얘기해보면, 이렇게 이전의 방향과 동일하게 되면 가속을 주면서 더 멀리 짚어나가게 된다. 물론 최적점을 또 지나면 방향이 바뀌어서 값이 다시 줄어들게 되어 돌아가게 되고, 반복을 하게 된다.

이제 아래의 그림을 보면 더 직관적으로 이해가 간다. 

Momentum 을 사용해서 GD를 한 것인데, 일반적으로 GD 만 사용한다면 반대편으로 또르르 굴러가지 않는다. 그냥 내려가다가 가운데쯤에서 수렴을 하고 멈춘다. 또한, 가장 왼쪽 그림처럼 큼직하게 떨어지지도 않고 찔끔씩 내려간다. 

 

 1.  Momentum은 방향이 같으면 훅훅 내려가게 되어 더 빨리 최적점을 찾을 수 있다.

 2. 가운데 그림처럼 가속도 때문에 잠시 최적점을 지나치기도 하는데 이럴 경우에는 local minimum 을 지나치고 다른 곳으로 빠져나가서 더 좋은 minumum 찾아 갈 수도 있게 한다. 즉, 좀 더 global minimum 에 더 가까워 지게 된다. 결과적으로 성능이 좋아진다.

 

 

 

 

 

 

 

Adagrad

 

앞에 Momentum 같은 경우는 step 을 가는 방향 대로 가속을 받아 가는 gradient의 방향에 초점을 두어 SGD 를 업그레이드 시켰다고 한다면 Adagrad 같은 경우는 step 의 size에 초점을 맞춘 알고리즘이다. 

 Adagrad 를 수식을 통해 살펴보자. 우선 간결하게 보기 위해 기존의 gradient 정보를 $g_{t,i}$ 로 표현하자.

 

 그리고 아래의 수식을 살펴보자. 아래의 수식은 SGD 가 $t$ 단계에서 parameter $\theta$를 업데이트하는 것을 나타내고 있다. 

그리고 아래의 수식을 보면 learning rate 인 $\eta$ 를 루트가 씌인 term 으로 나누어 주는 부분을 볼 수 있다. 여기서 이렇게 나눠주는 것은 다시 말해서 hyperparameter 인 learning rate 에 대해 수동적으로 조절을 할 필요가 없다는 것도 알 수 있다. 그래서 0.01로 두고 시작을 한다. 이것은 learning rate가 너무 낮으면 학습속도가 너무 느리고, learning rate가 너무 크면 발산해버리는 문제를 learning rate decay를 통해서 해결한다고 할 수 있다.

 여기서 $G_{t,ii}$ 는 gradient 정보인 $g_{t,i}$ 제곱의 합을 의미한다. 그리고 $\epsilon$ 은 0으로 나눠지는 ZeroDivisionError를 피하기 위해 추가한 값(smoothing term)이다. 일반적으로 1e-8 이라는 작은 값을 사용한다.

 

위에 gradient 앞에 $\cdot$ 곱은 행렬의 element wise 으로 이루어지는 연산이다. 최종적으로 아래와 같은 수식으로 표현한다. $G_{t}$ 는 과거의 $t$ 시점에서의 gradient 제곱합을 의미하고, 이 대각선을 따라서 모든 paramater $\theta$에 요소별로 행렬 벡터 곱셈을 수행해서 구현을 벡터화 할 수 있게 된다.

 

 Adagrad는 이렇게 과거 gradient 의 양을 토대로 학습을 하면서, learning rate을 조절해가면서 다음 parameter 업데이트 값을 결정짓게 한다. 그래서 학습을 진행하면서 이미 학습이 많이 된 변수라면 최적점에 이미 가까이 갔을 것이라 판단, 학습이 아직 덜 된 드물게 등장한 변수라면 학습을 더 빨리 하게 함으로써 최적점으로 이끈다. 이렇게 되면 랜덤으로 들어오는 변수들에 대해서 효율적으로 학습을 시켜서 빨리 최적점을 찾도록 할 수 있게 된다.

 Adagrad 는 수식에서 봄과 같이 $G_{t}$가 계속 누적되어 값이 계속해서 커질 수 밖에 없다. 이렇게 자꾸 커지다 보면, 전체 값이 궁극적으로 작아지게 되고 학습을 더이상 할 수 없게 된다. 이 단점을 해결하고자 하는 알고리즘으로는 Adadelta와 RMSprop 으로 이어지게 된다.

 

 

 

 

 

 

 

 

 

ref)

ruder.io/optimizing-gradient-descent/

light-tree.tistory.com/140

 

 

728x90
반응형

댓글