티스토리 뷰

딥러닝

매개변수 갱신

4567은 소수 2021. 1. 15. 02:00

공부 : 밑바닥부터 시작하는 딥러닝 1 chapter 6.1

 

이전에는 매개변수 갱신을 경사 강하법(SGD)을 이용해 구현하였습니다. 

SGD 이외의 방법에 대해서도 알아봅시다.

 

매개변수 갱신은 매개변수의 손실함수의 기울기를 최소화하는 방향으로 이루어져야 합니다. 이를 하는 방법에는 SGD, Momentum, AdaGrad, Adam 등이 있습니다.

 

1. SGD : 확률적 경사 강하법

 

가장 구현이 쉬운 방법입니다. 하지만 속도가 느리고 경우에 따라 다른 최적화 방법보다 성능이 떨어지기도 합니다.

하지만 아직 많이 사용 중입니다.

 

식과 코드는 다음과 같습니다.

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] 

W가 매개변수이고, 에타는 학습률, dL/dW는 W에 대한 손실함수의 기울기입니다. 

 

SGD의 단점 : SGD는 비등방성 함수 (방향에 따라 성질이 달라지는 함수)에서는 경로 탐색 (손실함수의 기울기 최소화 과정)에서 비효율적입니다.

( 책의 예 : f(x, y) = (x^2)/20 + y^2 )

 

2. Momentum

모멘텀은 운동량을 뜻하는 물리 용어입니다. 기울기 방향으로 물체가 가속된다는 것을 이용한 것입니다.

 

식과 코드는 다음과 같습니다.

class Momentum:
    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr
        self.momentum = momentum
        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 params.keys():
            self.v[key] = self.momentum*self.v[key] - self.lr*grads[key] 
            params[key] += self.v[key]

위 과정이 적용되는 이유는 따로 책에 나와있지 않아 넘어가겠습니다.

 

3. AdaGrad

AdaGrad는 기존의 SGD는 학습률을 정하여 계산한 것과 다르게, 매개변수의 학습률을 조절하면서 기울기를 갱신합니다.

 

식과 코드는 다음과 같습니다. ( dot 연산은 행렬의 원소 별 곱을 나타낸 것)

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. Adam

 

새로운 기법으로, AdaGrad와 Momentum을 합친 것입니다. 책에 식이 따로 나와있지 않아 코드만 나타내겠습니다.

class Adam:
    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.iter = 0
        self.m = None
        self.v = None
        
    def update(self, params, grads):
        if self.m is None:
            self.m, self.v = {}, {}
            for key, val in params.items():
                self.m[key] = np.zeros_like(val)
                self.v[key] = np.zeros_like(val)
        
        self.iter += 1
        lr_t  = self.lr * np.sqrt(1.0 - self.beta2**self.iter) / (1.0 - self.beta1**self.iter)         
        
        for key in params.keys():
            self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])
            self.v[key] += (1 - self.beta2) * (grads[key]**2 - self.v[key])
            
            params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함