논문

하루에도 수만개의 글자를 읽고 있습니다. 하루에도 수백장의 종이를 들춰 읽습니다.
이것은 그 읽기에 대한 일기입니다.

UFLDL Tutorial 13. Supervised Convolutional Neural Network – Optimization: Stochastic Gradient Descent

http://deeplearning.stanford.edu/tutorial/

Optimization: Stochastic Gradient Descent

Overview

Limited memory BFGS와 같은 배치 방식의 방법들은 매 반복마다 전체 트레이닝 셋을 이용하여 파라미터의 다음 위치를 찾기 때문에 지역 최저점에 잘 빠지는 경향이 있습니다. 이러한 방법들은 튜닝을 위한 하이퍼 파라미터들의 수가 매우 적기 때문에, 우리가 사용했던 minFunc 함수처럼 미리 제공되는 함수에서도 잘 동작하는 편입니다. 하지만, 전체 트레이닝 샘플의 cost와 그래디언트를 한번에 계산하는 것은 사실은 매우 느릴뿐더러, 데이터가 큰 경우 하나의 컴퓨터에서 계산하기에는 메인 메모리에 넣는 것 자체가 버거울 수 있습니다. 배치 방식의 또 다른 문제는 '온라인' 환경에서 새로운 데이터가 주어지는 경우, 이를 기존 데이터에 통합하는 것이 쉽지 않습니다. Stochastic Gradient Descent (SGD)는 한개 혹은 몇개의 트레이닝 샘플을 살펴본 뒤, 나아갈 negative gradient를 결정함으로써 이 두가지 이슈를 해결합니다. 신경망에서 SGD를 사용하는 것은 전체 데이터셋에서 역전파 알고리즘을 사용하는 것이 비용이 비싸다는 점에서 착안하였습니다. SGD는 이 비용을 극복하면서 빠른 수렴을 이끌어냅니다.

Stochastic Gradient Descent

기존의 gradient descent 방법은 목적 함수 $J(\theta)$의 파라미터 $\theta$를 다음과 같이 업데이트합니다.

$$ \theta = \theta - \alpha \nabla_\theta E[J(\theta)] $$

이 식에서 기대값(expectation)은 전체 트레이닝 셋의 cost와 그래디언트를 평가하여 추정되고 잇습니다. 반면에 Stochastic Gradient Descent (SGD)는 업데이트할 때 필요한 기대값과 파라미터의 그래디언트 계산을 한개 혹은 약간의 트레이닝 샘플만을 이용하여 계산합니다. 새로운 업데이트 방법은 다음과 같습니다.

$$ \theta = \theta - \alpha \nabla_\theta J(\theta; x^{(i)},y^{(i)}) $$

여기서 $(x^{(i)}, y^{(i)})$는 트레이닝 셋의 입력, 출력 짝입니다.

기본적으로 SGD에서 각 파라미터의 업데이트는 하나의 샘플을 이용하기 보다는 일부 트레이닝 샘플이나 미니 배치(minibatch)를 이용하여 이루어집니다. 그 이유는 다음 두가지와 관련되어있습니다. 먼저 이렇게 하면 파라미터 업데이트에서의 분산(variance)를 줄일 수 있어 안정적으로 수렴될 수 있습니다. 두번째는 이런 계산 방법은 cost와 그래디언트를 계산할 때 벡터화된 계산 방법을 이용할 수 있도록 행렬 계산에 최적화되어있다는 장점이 있습니다. 보통 미니배치의 크기는 256을 사용하지만, 최적의 크기는 응용이나 그 구조에 따라 달라지게 됩니다.

SGD의 학습률(learning rate) $\alpha$는 일반적으로 batch gradient descent의 그것보다 매우 낮은 값을 사용합니다. 그 이유는 업데이트 시에 variance가 매우 크기 때문입니다. 적절한 학습률과 학습 과정에서 학습률을 변경할 정책을 정하는 것은 꽤 어려운 일입니다. 한가지 많이 쓰는 방법은 충분히 작은 값을 정하여 한두번째 epoch에서 사용하여 안정적으로 수렴할 수 있도록 하는 것입니다. 여기서 epoch이란 전체 트레이닝 셋을 모두 처리하는 것을 의미합니다. 다음 epoch부터는 수렴이 잘 늦어질 수록 학습률을 반으로 줄여나가면 됩니다. 이보다 더 나은 방법은 각 epoch마다 그 세트를 평가하고, 어떤 임계값보다 목적 함수의 값이 적게 변하면 학습률을 줄여주는 것입니다. 이것은 지역 최저점에 대해서 좋은 수렴성을 보여줍니다. 또 스케쥴링 방법은 각 반복 $t$ 마다 학습률을 $\frac{a}{b+t}$으로 줄여나가는 것입니다. $a$는 초기 학습률을 결정하고 $b$ 학습률을 어느 수준부터 줄여나갈지를 결정합니다. 더 복잡한 방법들은 최적의 업데이트를 찾기 위해서 backtracking line search 방법을 포함합니다.

SGD에서 중요한 부분은 알고리즘으로 데이터를 제공하는 순서입니다. 데이터가 어떤 의미를 가지는 순서로 주어진다면 이것은 평향된(biased) 그래디언트를 가져올 수 있으며, 때문에 좋지 않은 수렴성을 보여줍니다. 일반적으로 좋은 방법은 이를 피하기 위해서 각 epoch마다 데이터를 무작위로 섞어서 사용합니다.

Momentum

만약 목적 함수의 모양이 최적점을 향해서 길고 좁은 협곡(ravine)의 모양에 가파른 벽으로 둘러싸인 모양을 띄고 있으면, 보통의 SGD는 좁은 협곡을 가로지르며 진동하는 모양을 띕니다. 이는 negative 그래디언트는 협곡을 따라서 계산되기보다는 가파른 방향을 향하도록 계산되기 때문입니다. 이 깊은 구조(deep architectures)에서의 목적 함수는 지역 최적점 근처에서 이런 모양새를 띄고 따라서 보통의 SGD는 첫번째 가파른 게인 이후 매우 느린 수렴을 보입니다. 모멘텀(Momentum)은 이런 경우 협곡을 따라서 목적 함수를 빠르게 이동할 수 있도록 밀어주는 한 방법입니다. 모멘텀의 갱신 방법은 다음과 같습니다.

$$ \begin{align} v &= \gamma v+ \alpha \nabla_{\theta} J(\theta; x^{(i)},y^{(i)}) \\ \theta &= \theta - v \end{align} $$

위 식에서 $v$는 현재 벡터의 속도는 나타내고 이는 파라미터 벡터 $\theta$와 같은 차원을 갖습니다. 학습률 $\alpha$는 앞에서 설명했던 것과 같지만, 보통보다 더 작은 값을 사용하여야 합니다. 모멘텀을 사용할 경우 그래디언트의 크기가 더 커질 수 있기 때문입니다. 마지막으로 $\gamma \in (0, 1]$는 이전의 그래디언트가 현재 업데이트에 얼마나 많은 반복동안 사용될지를 결정합니다. 보통 $\gamma$는 처음에 0.5를 사용하다가 안정화되면 0.9로 올려 사용합니다.


Tags:
Add a Comment Trackback