juuuding

[Improving Deep Neural Networks: Hyperparameter Tuning, Regularization an Optimization] Optimization Algorithms 본문

인공지능/코세라 딥러닝 특화과정

[Improving Deep Neural Networks: Hyperparameter Tuning, Regularization an Optimization] Optimization Algorithms

jiuuu 2024. 7. 30. 02:17

 

 Mini-batch gradient descent

 

 mini-batch란 총 m개의 훈련 예제가 있다고 가정했을 때 일정한 크기(n)로 훈련 예제를 나누어서 여러 개의 부분으로 나누어 놓은 것을 의미한다. 예를 들어 100000개의 훈련 예제가 있다고 가정했을 때 미니 배치의 크기를 1000으로 설정하면 100개의 서로 다른 미니 배치가 생긴다. 이러한 미니 배치를 가지고 경사 하강을 하는 것을 "mini-batch gradient descent"라고 한다. 

 반대로 batch gradient descent가 있는데 이것은 모든 훈련 예제를 가지고 동시에 경사 하강을 진행하는 방식이다. 즉 이제까지 하던 경사하강 방식이다. mini-batch gradient descent는 각 배치를 벡터화시켜 경사 하강을 하고,  batch gradient descent는 모든 훈련 예제를 벡터화시켜 연산을 한다. batch가 아닌 mini-batch 경사 하강을 하는 이유는 훈련 예제의 수가 아주 크다면 한 번의 경사하강을 할 때마다 너무 많은 연산이 필요하여 속도가 느려질 수 있기 때문이다. 

 참고로 mini-batch의 순서 표기법은 X{t}, Y{t}와 같이 표현한다. t는 t번째 미니배치라는 의미다.

 

 

 

 Understanding mini-batch gradient descent

 

 미니 배치로 경사하강을 헀을 때와 일반적인 배치 경사 하강을 했을 때의 비용 감소 양상은 다르다. 일반 배치로 경사하강을 할 때는 항상 비용이 감소해야한다. 하지만 미니 배치를 사용할 때는 모든 미니 배치마다 비용이 감소하지는 않지만 전체적인 흐름은 감소하는 것을 볼 수 있다. 

 

 

 이제 미니 배치의 크기를 고르는 방법에 대해 알아보자. 우선 미니 배치의 크기를 극단적인 두 경우로 나누어 보면 size=m, size=1이다. 미니 배치의 크기가 m 이라는 것은 전체 훈련 세트를 훈련하는 것과 같은 의미이므로, 이것은 일반적인 배치 경사 하강과 동일하다. 반대로 미니 배치의 크기가 1이 되면 모든 훈련 예제를 각각의 미니 배치로 여긴다는 의미가 되는데, 이것은 "stochastic gradient descent"라고도 부른다. 미니 배치의 크기가 m과 같이 너무 크다면 한 반복에서 연산 시간이 너무 오래 걸리기 때문에 좋지 않다. 반대로 미니 배치의 크기가 1과 같이 너무 작다면 여러 훈련 예제를 한 번에 처리할 수 있도록 해주는 벡터화의 효과가 의미가 없어지기 때문에 좋지 않다. 따라서 미니 배치는 너무 크지도, 작지도 않은 중간의 적절한 크기를 선택해야한다. 예를 들어 256개로 미니배치의 크기를 정하면 벡터화로 인한 연산 효율을 얻을 수 있고, 크기가 그렇게 크지 않아 한 반복에 오랜 시간이 걸리지 않게 된다. 

 

파: batch(m), 초: In-between(ex.256), 보: stochastic(1)

 

 미니 배치는 너무 큰 훈련 예제를 작게 쪼개 여러번 계산하도록 하는 것이므로, 만약 훈련 예제가 크지 않다면 사용하지 않아도 된다. 참고로 미니 배치의 크기는 컴퓨터 메모리 접근 방식을 고려하여 2의 제곱수(64, 128, 256, 512...)를 사용하는 것이 좋다. 그리고 이 크기는 컴퓨터가 사용하는 cpu, gpu 메모리 크기에 맞게끔 정하면 된다. 

 

 

 

 Exponentially weighted averages

 

 지수 가중 평균은 최근 데이터에 더 높은 가중치를 두고 오래된 데이터에는 낮은 가중치를 부여하여 평균을 계산하는 방법이다. 이는 시간에 따른 데이터 변화를 더 민감하게 반영하기 위해 사용되는 것이다. 지수 가중 평균에 대한 이해를 위해 기온 평균 예제를 살펴보자. 

 다음은 런던의 하루 기온을 기록한 값이다. 이 값들로 지수 가중 평균을 이용하여 평균 기온 값을 구해볼 것이다.

 

 지수 가중 평균 식: V_t = beta*V_t-1 + (1-beta)*theta_t

 * V_t: t날까지의 평균 기온, theta_t: t날의 기온

 이 식을 이해하기 위해 V_100부터 거꾸로 평균 기온을 계산해보겠다. 여기서 beta는 0.9로 설정한다.

V_100 = 0.1*theta_100 + 0.9*V_99

            = 0.1*theta_100 + 0.9*(0.1 * theta_99 + 0.9*V_98)

            = 0.1*theta_100 + (0.9 * 0.1 * theta_99) + (0.9 * 0.9 * V_98)

            = 0.1*theta_100 + (0.9 * 0.1 * theta_99) + (0.9 * 0.9 * (0.1 * theta_98 + 0.9 * V_97))

            = 0.1*theta_100 + (0.9 * 0.1 * theta_99) + (0.9 * 0.9 * 0.1 * theta_98) + (0.9 * 0.9 * 0.9 * V_97)

            = 0.1*theta_100 + (0.1 * 0.9 * theta_99) + (0.1 * 0.9^2 * theta_98) + (0.1 * 0.9^3 * theta_97) + ...

 

 이 식을 보면 알 수 있 듯 과거의 기온에 점점 더 작은 가중치를 두며 평균을 계산을 하게 된다. 더 자세히 분석을 해보자면 하루 전날마다 0.9의 가중치가 더 곱해지는데, (0.9)^10≒1/3이므로 평균 기온이 1/3으로 감소하기까지 10일이 걸린다는 사실을 알 수 있다. 만약 beta를 0.98로 설정하였다면 (0.98)^50 ≒1/3이므로 평균 기온이 1/3 감소하기까지 50일정도가 걸린다는 사실도 알아낼 수 있다. 

 지수 가중 평균을 사용하면 평균을 계산할 때 하나의 실수를 저장하는 메모리만 있으면 되기 때문에 일반 평균 구하는 방식보다 메모리 사용이 적다는 것이 장점이다. 

 

 

 

 Bias correction in exponentially weighted average

 

 지수 가중 평균에서 beta 값을 높일수록 그래프 곡선은 더 스무스 해지지만 초기에 값이 잘 맞지 않는 bias가 발생한다. 많이 사용하지는 않지만, 이를 보정하는 bias correction에 대해 알아보자

 

보: beta를 높인 곡선

 

V_t = beta * V_t-1 + (1-beta) * theta_t 식에다 추정 초기 단계에서 더 정확히 보정을 하기 위해,
V_t / (1-beta^t) 식을 사용한다. t가 높을수록 beta^t가 0에 가까워지기 때문에 V_t를 더 큰 값으로 나누고 t가 작을수록 더 작은 값으로 나누어 초기 단계의 값을 상대적으로 더 크게 만들 수 있다. 

 

 

 

 Gradient descent with momentum

 

앞서 배운 지수 가중 평균의 개념을 사용하여 경사 하강에 적용해볼 것이다. 이 방법은 momentum이라고 불리며 매개변수를 경사하강 할 때 당시의 기울기와 이 전까지의 기울기 평균을 고려하겠다는 의미를 가진다. 그래서 미니 배치 경사 하강에서 각 미니 배치의 dW, db를 계산한 후 다음의 경사 하강 과정을 거친다. 

 

V_dw = beta * V_dw + (1-beta) * dW

V_db = beta * V_db + (1-beta) * db

W = W - learning_rate * V_dw

b = b - learning_rate * V-db

 

여기서 밑줄 친 (1-beta)을 생략한 식을 더 많이 사용하는데 

 

V_dw = beta * V_dw + dW

V_db = beta * V_db + db

W = W - learning_rate * (1-beta) * V_dw

b = b - learning_rate * (1-beta) * V-db

 

이때는 learning_rate이 learning_rate * (1-beta) 으로 바뀌어야 한다. 참고로 아까 배운 bias correction은 경사하강이나 모멘텀 구현시에는 거의 하지 않는다. 

 

 

 

 RMSprop

 

 RMSprop은 "Root Mean Square prop"의 줄임말로 경사 하강을 빠르게 해 학습 알고리즘의 속도를 높여준다. RMSprop의 주된 아이디어는 각 파라미터에 대해 학습률을 조정하여 학습의 안정성과 속도를 개선하는 것이다. 학습률은 해당 파라미터의 변화율이 크면 학습률을 줄이고, 변화율이 작으면 학습률을 높인다. 우선 RMSProp의 식은 다음과 같다. 

 

SdW = beta2 * SdW + (1-beta2) * dW^2

Sdb = beta2 * Sdb + (1-beta2) * db^2

W = W - learning_rate * dW / root(SdW+epsilon)

b = b - learning_rate * db / root(Sdb+epsilon)

 

 참고로 beta2를 사용한 이유는 나중에 이것을 모멘텀과 합칠 것(Adam)인데, 모멘텀의 beta와 구분하기 위함이다. 그리고 epsilon은 분모가 0이 되지 않도록 하기 위해 더해준 작은 값이다. 식을 더 잘 이해하기 위해 예를 들어보자면 만약 현재 미니배치에서의 dW값이 작으면 상대적으로 SdW가 작은 값이 된다. 따라서 W에 경사하강을 할 때 작은 값으로 dW을 나누게 되므로 큰 step으로 경사하강을 할 수 있게 된다. 

 

 

 이 그림으로 설명해보자면 파란색 선의 경사 하강은 수직 방향의 도함수(가파름 정도)가 크고 수평 방향의 도함수가 작다. 이를 조금 더 안정적으로 빨리 경사하강 하기 위해서는 수직 방향으로 움직이는 정도를 줄이고 수평 방향으로 움직이는 정도를 늘려 빨간 경로처럼 가도록 해주어야 한다. 여기에 RMSProp을 사용하면 학습이 안정적으로 빠르게 이루어진다는 것을 이해할 수 있을 것이다. 

 

 

 

 Adam optimization algorithm

 

 Adam(Adaptive moment estimation)은 RMSprop과 momentum 방식을 결합시킨 것으로, 많은 문제에서 잘 작동하기 때문에 망설이지 않고 사용해도 좋은 최적화 알고리즘이다.  Adam의 식은 다음과 같다.

 

V_dW = beta1 * V_dW + (1-beta1) * dW

V_db = beta1 * V_db + (1-beta1) * db

S_dW = beta2 * S_dW + (1-beta2) * dW^2

S_db = beta2 * S_db + (1-beta2) * db^2

 

# 편향 보정

V_dW_corr = V_dW / (1-beta1^t)

V_db_corr = V_db / (1-beta1^t)

S_dW_corr = S_dW / (1-beta2^t)
S_db_corr = S_db / (1-beta2^t)

 

W = W - learning_rate * V_dW_corr / root(S_dW_corr + epsilon) 

b = b - learning_rate * V_db_corr / root(S_db_corr + epsilon)

 

 여기서 하이퍼파라미터로는 다음 값들이 주로 쓰인다. 

- beta1: 0.9

- beta2: 0.999

- epsilon: 10^-8

- alpha: 튜닝되어야 함

 

 

 

 Learning rate decay

 

 learning decay는 학습 알고리즘의 속도를 높이는 방법 중 하나로 시간에 따라 학습률을 줄여가며 학습을 진행하는 것을 의미한다. 학습 초기에는 큰 학습률을 사용하여 빠르게 수렴하고, 후반에는 작은 학습률을 사용하여 최적점 근처에서 미세하게 조정하도록 해주는 것이다. 아주 작은 미니 배치를 사용하면 서로 다른 배치에 노이즈가 있어 최적점에 가까워질수록 정확히 수렴하지 못하고 주변을 돌아다니게 된다. 이러한 현상을 방하기 위해 learning decay를 사용한다. 

 

 

다음으로 learning decay를 하는 여러 방법에 대해 알아보자. 

 

①  1 / t 감소 (learning_rate_0, decay_rate은 하이퍼파라미터)

learning_rate = learning_rate_0 / (1 + decay_rate*epoch_num)

 

② 지수적 감소

learning_rate = ((0.95)^epoch_num) * learning_rate_0

 

③ 

learning_rate = (k/root(epoch_num)) * learning_rate_0

or

learning_rate = (k/root(t)) * learning_rate_0

* t : 미니배치 개수

 

④ discrete stair case

ex)

0~10 : learning_rate = 0.2

10~20 : learning_rate = 0.15

20~30 : learning_rate = 0.1

 

⑤ manual decay

 훈련을 지켜보며 학습률을 직접 조작하는 감쇠 방법

 

 

 

 The problem of local optima

 

 경사 하강을 하다보면 지역 최적값에 도달하여 경사하강에 문제가 생기는 일이 종종 발생한다. 하지만 이러한 경우보다 plateaus(안정 지대)에 도달하여 생기는 문제가 더 큰데, 여기서는 미분 값이 아주 오랫동안 0에 가깝게 유지된다.

 

 - 충분히 큰 신경망을 학습시킨다면 지역 최적값에 갇힐 일은 거의 없다. 

 - 안정 지대가 더 큰 문제인데 여기에는 모멘텀, RMSprop, Adam을 사용하면 도움이 된다.