본문 바로가기
AI/밑딥

딥러닝) optimizer ( SGD , Momentum , AdaGrad , RMSProp, Adam )

by 채채씨 2021. 3. 23.
728x90
반응형
1. Stochastic Gradient Descent (SGD)

SGD

 

SGD는 현재 위치에서 기울어진 방향이 전체적인 최솟값과 다른 방향을 가리키므로 지그재그 모양으로 탐색해나간다. 즉, SGD의 단점은 비등방성(anisotropy)함수에서는 탐색 경로가 비효율적이라는 것이다. 무작정 기울어진 방향으로 나아가는 방식보다 더 효율적인 방식이 필요하다. SGD를 보완한 기법으로 Momentum, AdaGrad, Adam이 있다.

 

 

<SGD 코드>

 

class SGD:
    def __init__(self, lr = 0.01):
        self.lr = lr
        
    def update(self, params, grads):
        for key in params.keys():
            params[key] -= self.lr * grads[key]

 

 

 

 

 

2. Momentum

Momentum

 

SGD와 달리 새로운 변수 v가 나오는데 이는 물리에서 말하는 속도(velocity)이다. Momentum은 '운동량'을 뜻하는 단어로 기울기 방향으로 힘을 받아 물체가 가속되어 공이 구르는 듯한 움직임을 보인다. 위의 식에서 알파가 가속도와 관련된 파라미터이다. SGD와 최적화 과정을 비교하면 지그재그 정도가 덜하다. x축의 힘은 작지만 방향이 변하지 않으므로 일정하게 가속하여 SGD보다 x축 방향으로 빠르게 나아가므로 지그재그 정도가 덜한 것이다.

 

 

<Momentum 코드>

 

class Momentum:
    def __init__(self, ir = 0.01, momentum = 0.9):
        self.lr = lr
        self.momentum = momemtum
        self.v = None
        
    def update(self, params, grads):
        if self.v is None:
            self.v = {}
            for key, val in params.items():
                self.v[key] = np.zeros_like(val)
            
            for key in parmas.keys():
                self.v[key] = self.momentum * self.v[key] - self.lr * grads[key]
                params[key] += self.v[key]

 

 

 

 

 

 

 

3. AdaGrad

신경망 학습에서 학습률(learning rate)을 적절하게 설정하는 것이 중요하다. 학습률을 적절하게 설정하기 위해 학습률 감소(learning rate decay)라는 기술을 사용하는데 이는 학습 진행 중에 learning rate을 줄여가는 방법이다. 즉 처음에는 크게 학습을 하다가 점점 작게 학습한다는 의미이다. 이 방법을 발전시킨 것이 AdaGrad이며 AdaGrad는 각 매개변수에 Adaptive하게 조정하여 맞춤형 learning rate을 만든다.

 

AdaGrad

 

SGD와 달리 새로운 변수 h가 나오는데 이는 기존의 기울기 값을 제곱한 값을 더하여 학습률을 조정하기 위한 변수이다(⊙기호는 행렬의 원소별 곱셈을 의미함). 매개변수의 원소 중 크게 갱신된 원소는 학습률이 낮아지며 학습률 감소가 매개변수의 원소마다 다르게 적용된다.

 

 

<AdaGrad 코드>

 

class AdaGrad:
    def __init__(self, lr = 0.01):
        self.lr = lr
        self.h = None
        
    def update(self, params, grads):
        if self.h is None:
            self.h = {}
            for key, val in params.items():
                self.h[key] = np.zeros_like(val)
                
        for key in params.keys():
            self.h[key] += grads[key] * grads[key]
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)

 

 

 

 

 

 

4. RMSProp

RMSProp은 AdaGrad의 단점을 보완한 기법이다. AdaGrad는 과거의 기울기를 제곱하여 더하는 방식으로 학습을 진행하므로 점점 갱신 정도가 약해진다. 무한히 학습한다면 갱신량이 0이 되어 전혀 갱신되지 않는 일이 발생하게 된다. 이를 개선한 것이 RMSProp이다. RMSProp은 과거의 기울기들을 똑같이 더해가는 것이 아니라 먼 과거의 기울기는 조금 반영하고 최신의 기울기를 많이 반영한다. 이를 지수이동평균(Exponential Moving Average, EMA)이라 한다.

 

 

RMSProp 갱신 식

 

 

 

 

 

5. Adam

Adam

 

공 구르는 듯한 Momentum과 적응적인 AdaGrad를 융합한 기법이 Adam이다. Adam은 학습률, 일차 모멘텀용 계수, 이차 모멘텀용 계수로 3개의 hyperparameter를 설정한다. 일차 모멘텀용 계수=0.9, 이차 모멘텀용 계수=0.999를 기본 설정값으로 하면 보통 좋은 결과를 얻을 수 있다.

 

※ 추가자료 논문: https://arxiv.org/pdf/1412.6980.pdf

 

 

 

 

 

 

6. optimizer 비교

MNIST 데이터셋으로 SGD, Momentum, AdaGrad, Adam 네 가지의 optimizer를 비교하면 아래와 같다.

 

 

학습률과 신경망 구조에 따라 결과가 다르게 나타나지만, 일반적으로 SGD보다 Momentum, AdaGrad, Adam의 최종 정확도가 높게 나온다.

 

 

 

 

 

출처: https://www.slideshare.net/yongho/ss-79607172

 

 

위 그림은 optimzer의 발달 계보와 관련된 그림이다.

 

 

 


출처: 사이토 고키『밑바닥부터 시작하는 딥러닝』, 한빛미디어(2017), p189-202.

728x90
반응형

댓글