티스토리 뷰

2020/10/22 - [Study/인공지능] - Optimizer: SGD ( 인공지능 기초 #13 )

 

물리계에서는 공이 굴러가는 방향은 중력뿐 아니라 기존의 관성에도 영향을 받습니다.

 

Momentum은 현실 물리계에서 관성이 모티브입니다.

 

Momentum은 Gradient Descent에 현재의 관성을 추가하여 생각합니다.

 

경사하강법의 문제점

 

현실에서 실제로 공을 굴렸다고 생각한다면, 첫번째 로컬 미니멈의 최소에 멈추지않고 관성을따라 오른쪽으로 더 움직였을 것입니다. (즉 글로벌 미니멈에 다가갈 수 있습니다.) 이러한 관성의 특징으로 안장점에서도 멈추지않고 글로벌 미니멈을 향해 다가갈 수 있습니다.

 

Momentum : 관성이 추가된 경사하강법
등위선

등위선에서도 SGD보다 더 효율적으로 (적은 진동으로) 목표지점에 다가가는 것을 볼 수 있습니다.

 

이유는 관성때문에 다음 스텝으로 정확한 수직을 그리며 가던 발걸음이 가는 방향에 대한 관성의 힘을 받아 목표지점에 조금 더 가까이 움직이기 때문입니다.

 

Momentum의 점화식입니다.

 

Momentum의 점화식

관성이란 ? 과거의 속도이기도 합니다.

 

Vn이 현재속도라고 생각을하면, Vn-1을 과거의 속도(관성)라고 생각합니다. α는 관성계수입니다. 관성계수가 커지면, 관성의 값이 더 커지게 되고 이는 관성의 영향을 더 크게 받는다는것을 의미합니다.

 

러닝레이트가 보폭의 크기를 정해주는것처럼, 관성계수는 과거의 속도의 영향역을 정해준다고 생각할 수 있습니다.

 

class Momentum:

    """모멘텀 SGD"""

    def __init__(self, lr=0.01, momentum=0.9):#러닝레이트와 관성계수
        self.lr = lr
        self.momentum = momentum
        self.v = None
        
    def update(self, params, grads):#params : 가중치와 편향, #grads : 그레디언트
        if self.v is None:
            self.v = {}
            for key, val in params.items():                                
                self.v[key] = np.zeros_like(val) #출발할 땐 관성이 없으므로 0으로 놔라
                
        for key in params.keys():
            self.v[key] = self.momentum*self.v[key] - self.lr*grads[key] #현재 속도 구하기 Vn, 관성계수*과거속도 + 러닝레이트*그레디언트반대방향(-)
            params[key] += self.v[key] #구해진 현재 속도를 다음 속도로 

 

NAG(Nesterov Accelated Gradient) 는 Momentum을 개량한 것입니다.

 

NAG는 모멘텀보다 더 공격적인 방식으로 내려갑니다. 그레디언트의 반대방향을 생각할 때, 현재 위치에서 그레디언트를 생각하는것이 아닌, 모멘텀 스텝으로 간 후의 그레디언트를 구해 반대방향으로 갑니다.

 

아래는 NAG의 점화식입니다.

 

NAG의 점화식

그레디언트를 구할 때 보면 +αVn-1이 추가된것을 볼 수 있습니다. 

 

이것은 관성만큼만 미리 간 다음에 거기서 그레디언트를 구하라는 의미입니다.

 

 

하지만 NAG는 신경망에는 적합하지 않습니다. Xn은 편향과 가중치인데, 그레디언트에 넣을 편향과 가중치를 관성을 넣어 바꿔가면서 까지 계산을 하면 역전파를 이용해서 계산을 더 효율적이게 하려는 목적과 반대되는 영향을 주기 때문입니다. 즉 Xn이 아닌 다른 점에서 그레디언트를 구하기 때문에 적합하지 않다는 것입니다.

 

Bengio의 근사적 접근을 사용하면 편향과 가중치를 건들지 않기때문에 신경망 학습에도 사용할 수 있습니다. 

 

X' 는 X의 좌표에서 관성의 크기만금 이동한 좌표입니다.

 

여기서 Vn을 현재 모르기때문에 점화식에서 Vn-1로 바꾸어 표현해줍니다.

 

class Nesterov:

    """Nesterov's Accelerated Gradient (http://arxiv.org/abs/1212.0901)"""
    # NAG는 모멘텀에서 한 단계 발전한 방법이다. (http://newsight.tistory.com/224)
    
    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) #키는 동일한데, shape이 동일한 값으로 바꾸어라
            
        for key in params.keys():#여기가 점화식
            self.v[key] *= self.momentum   #V는 관성계수 곱한다음에
            self.v[key] -= self.lr * grads[key] # 그레디언트 빼줘라
            params[key] += self.momentum * self.momentum * self.v[key]  # + α^2Vn-1
            params[key] -= (1 + self.momentum) * self.lr * grads[key]  #-(1+α)*그레디언트

 여기서는 X1 X2를 구하는것이아닌 X1` X2` X3`를 구하여 따라갑니다.

 

파란색과 빨간색은 길이 분명 다릅니다. 하지만, 관성이 진행될수록 관성의 크기는 점점 작아질것이고, 그 뜻은 두 길은 거의 비슷해질 것을 의미합니다.

 

파란색이 Bengio의 근사적 접근을 사용한 것입니다. 

 

그레디언트를 구하는 지점을 길로 사용한것입니다. 

댓글
최근에 올라온 글
최근에 달린 댓글
250x250