앞으로 전개할 내용은 Coursera 강의의 내용을 기반으로 필자가 직접 정리하는 내용이며 해당 컨텐츠 이외의 다른 강의에 관심이 있다면 여기를 참고해 수강해보자.
저번 포스팅에서는 주로 딥러닝이 학습 데이터와 닮아 있지 않은 낯선 데이터를 마주하더라도 제대로 예측하도록 하는 일반화(Regularization) 방법들에 대해 알아보았다. 이번 포스팅에서는 딥러닝의 성능을 개선하는 또 다른 방법으로 Optimization(학습 최적화)과 하이퍼파라미터를 튜닝하는 방법에 대해 알아보려고 한다. 목차는 다음과 같다.
1. Optimization
1-1. Mini-batch Gradient Descent
1-2. Momentum
1-3. RMSProp
1-4. Adam Optimizer
1-5. Batch Normalization
1-6. Learning rate decay
2. Hyperparameter Tuning
2-1. How to model in many hyperparameters
2-2. Using scaling to hyperparameters
1. Optimization
Optimization이란 사전적인 의미로 '최적화'를 뜻한다. 딥러닝에서 최적화란 딥러닝 모델이 최적의 파라미터를 찾아가는 것을 의미한다. 그런데 최적의 파라미터를 찾아가는 과정이 빠르면 빠를수록 모델의 학습 시간을 줄어들며 그 만큼 원하는 결과를 빨리 얻을 수 있을 것이다. 마치 위 그림처럼 산 꼭대기 정상으로부터 산 밑까지 내려가는 루트를 이미 알고 있다면 다른 길로 헤매지 않고 곧장 빠르게 내려갈 수 있는 것처럼 말이다.
산 정상에서 산 밑으로 내려가는 데 여러가지 루트가 있는 것처럼 딥러닝 모델이 최적의 파라미터(Global minimum)를 찾아가는 방법도 여러가지가 존재한다. 이 방법들에 대해 알아보자.
1-1. Mini-batch Gradient Descent
Mini-batch란, 전체 학습 데이터 샘플 중 일부(Mini)를 뜻한다고 보면 된다. 그냥 Batch라고 한다면 전체 데이터 샘플 전체를 의미한다. 그래서 이 전체 데이터 샘플을 특정 개수(Batch size라고 부른다)만큼 분할해서 분할된 양 만큼 Gradient Descent를 수행하고 다음 분할된 양(Mini-batch)을 Gradient Descent 한다.
위 그림은 Batch와 Mini-batch 일 때 Gradient Descent를 수행하면서 Cost function 값들의 그래프를 나타낸 것이다. Mini-batch는 Batch와는 다르게 그래프 선이 들쑥날쑥하는 형태를 보는 것을 알 수 있다. 왜냐하면 전체 데이터 중 Batch size만큼 분할시킨 각각의 Mini-batch들은 서로 다른 데이터들을 담고 있기 때문이다. 즉, 모델의 입장에서 어떤 Mini-batch에는 분류하기 쉬운 데이터가, 어떤 Mini-batch에는 분류하기 어려운 데이터가 있을 수 있기 때문이다.
이렇게 Mini-batch는 Batch를 이용할 때보다 Gradient Descent를 훨씬 더 빠르게 수행하게 해준다. 즉, 최적화를 더 빠르게 해준다. 왜냐하면 Batch는 전체 데이터 샘플을 한 번에 집어넣기 때문에 하나의 Epoch당 너무 긴 시간이 소요되기 때문이다.
반면에 Stochastic Gradient Descent라는 개념도 존재한다. 바로 데이터 샘플 1개씩 학습시키는 방식을 말한다. 이 방식은 Gradient Descent를 수행할 때 Converge가 잘 되지 않으며 Global minimum을 잘 찾지 못한다. 또한 한 개씩 학습하게 되면 학습속도가 느려지는 단점도 존재한다. 참고로 Stochastic 방법은 2000개 이하의 데이터셋일 때 사용하는 것이 바람직하다고 한다.
그래서 가장 이상적인 방법은 Mini-batch 방법인데, 이 때 몇 개의 데이터로 쪼갤지에 대한 Batch size 설정에 대한 것도 고민일 것이다. 이는 주로 2의 제곱값 즉, 64, 128, 512 ,1024 등이 적절하다고 한다. 이유는 컴퓨터 메모리가 배치되어 있는 방식이 2의 제곱방식과 동일하다고 하여 더 빨리 실행된다고 한다. 또한 Mini-batch가 CPU/GPU 메모리에 들어가도록 하는 것이 성능 저하를 막는다고 한다.
앞으로 소개할 3가지의 최적화 알고리즘은 Exponentially Weighted Average(지수 가중 평균) 공식에 기반하여 만들어진 알고리즘이다.
1-2. Momentum
이전에 소개했던 방법은 데이터를 얼마나 한 번에 학습시킬지에 대한 것이었다. 이번부터 소개할 방법들은 학습을 어떤 방향으로 진행할지에 대한 것이다. 먼저 소개할 방법은 Momentum이라는 방법이다. Momentum은 '기세, 운동량' 이라는 사전적인 의미를 가지며 딥러닝 분야에서는 '이리저리 발산하는 학습 방향에 Momentum을 적용해 발산하는 정도를 줄여줌으로써 학습 속도를 더 빨리하도록 시켜준다' 라고 이해할 수 있겠다.
위 사진을 보면 빨간색인 일반 Gradient Descent는 위 아래로 발산하는 모양을 띄면서 Global minimum에 도착하는 것을 볼 수 있다. 하지만 파란색인 Momentum이 적용된 Gradient Descent를 보면 위 아래로 발산하는 모양을 띄지 않고 더 빨리 Global minimum에 도착하는 것을 볼 수 있다. 이렇게 Momentum은 위 아래로 발산하는 동작을 없애준다고 보면 된다.
1-3. RMSProp
다음은 Momentum과 유사한 작용을 하는 최적화 알고리즘이다. 정확한 이름은 Root Mean Squared Propagation이라고 하며 Momentum과의 차이는 파라미터 변화량을 계산하는 공식에서 차이가 존재한다. 이름에 Root Mean Squared가 있는 것처럼 Momentum 공식과는 다르게 지수 가중 평균값을 구할 때 제곱을 취하고 파라미터를 업데이트할 때 Root를 적용하는 것이 차이점이다. Momentum 과 RMSProp의 수학적 수식 차이는 여기를 참고해서 살펴보자. 이 최적화 알고리즘 또한 Momentum과 동일하게 위 아래로 발산하는 것을 제한하는 역할을 한다.
1-4. Adam Optimizer
Adam Optimizer는 Momentum 과 RMSProp을 합친 것이다. 하지만 Bias correction(편향 보정)이라는 항을 추가적으로 같이 사용하는 것이 차이점이다. 효과는 결합한 알고리즘들의 효과와 동일하다.
1-5. Batch Normalization(BN)
Batch Normailization은 활성함수를 적용하기 이전의 출력 노드값에 Normalization을 적용해 학습 속도를 빠르게 해주는 방법이다.
위 그림처럼 최종 출력값 이전의 모든 은닉층에서 선택적으로 BN을 사용할 수 있다. 물론 활성함수 적용 이후에도 BN을 사용할 수는 있지만 수 많은 연구 결과, 활성함수 이전의 출력값에 BN을 사용하는 것이 학습 속도를 더 높인다고 한다.
따라서 활성함수 적용 이전의 출력값(z값)들에 대해 평균과 표준편차를 구해주고 이 두 개의 값을 이용해 표준 정규화를 수행해준다. 하지만 표준 정규화를 수행하게 되면 z값들의 분포가 표준정규분포 형태로 될 가능성이 높다. 이렇게 되면 sigmoid, relu, tanh와 같은 비선형 함수 형태가 되지 않기 때문에 문제가 발생한다. 따라서 z값들을 표준화 시켜준 이후 베타와 감마값이라는 학습 파라미터를 추가해 표준정규분포 형태로부터 벗어나도록 해준다.
결국 BN은 z값인 은닉층들의 출력값들을 Scaling 해줌으로써 값의 범위들을 좁혀준다. 이는 입력 데이터를 Normalization해서 학습 속도를 올려주는 경우와 동일하다. 따라서 BN은 결국 학습 속도 즉, 최적화의 속도를 올려준다.
참고적으로 BN은 일반화(Regularization)의 효과가 존재한다. 만약 Mini-batch를 이용해 모델을 학습시킬 때 Mini-batch 당 BN이 적용된다고 하면 BN을 수행할 때 베타와 감마라는 파라미터가 추가되어 일종의 noise 데이터가 들어가게 된다. 그렇게 되면 noise가 들어가 있는 데이터들이 하나의 Mini-batch가 학습될 때마다 계속적으로 학습이 되며 결국 이는 Dropout 효과와 마찬가지로 Overfitting을 예방하는 일반화 효과를 일으키기도 한다.
하지만 BN의 본질적인 목적은 Normalization으로 학습 속도를 빠르게 하는 것이므로 일반화를 하기 위한 1차적인 방법으로 사용해서는 바람직하지 못하다. 저번 포스팅에서 배운 일반화 방법들을 모두 사용해본 후 BN의 일반화 효과를 기대하는 것은 괜찮아도 이 순서가 서로 뒤바뀌어서는 안 된다.
1-6. Learning rate decay
저번 포스팅에서 잠깐 언급한 개념으로 Learning rate를 처음엔 크게 설정하고 학습이 진행됨에 따라 학습률을 작게 설정해 천천히 학습되도록 하는 것이다.
지금까지 여러가지 최적화 알고리즘을 살펴보았다. 이러한 알고리즘을 하는 본질적인 이유는 최적의 파라미터를 누가누가 더 빠르게 잘 찾아가는지 경쟁하는 셈이다. 물론 이러한 알고리즘을 사용하기 이전에 해당 모델이 Local minimum에 빠지지 않아야 한다는 전제가 있어야 하지만 이는 어느정도 크기가 큰 신경망 구조가 되면 만족되는 사항이다.
2. Hyperparameter Tuning
지금까지 많은 내용을 배워오면서 딥러닝에는 사용자가 직접 설정해야 하는 하이퍼파라미터 종류가 다양하다는 것을 확인할 수 있었다. 기본적으로 DNN의 layer, unit 개수가 있고 1번 목차에서 배운 최적화 알고리즘 종류에 따라 추가적으로 설정해야 할 하이퍼파라미터가 나타난다. 그런데 이 수많은 하이퍼파라미터를 어떻게 일일이 다 확인하고 최적의 파라미터를 찾을 수 있을까?
2-1. How to model in many hyperparameters
최적의 하이퍼파라미터를 찾기 위한 방법으로서 우선은 무식하게 '일일이 다 확인해보기' 이다. 이러한 방법은 Grid Search라고도 부른다. Scikit-learn과 같은 패키지에서 GridSearch 라이브러리를 제공하기도 한다. 일일이 다 확인해볼 수도 있지만 문제는 하이퍼파라미터 개수가 1개씩 늘어날 때마다 Grid Search할 하이퍼파라미터 조합 개수는 기하급수적으로 증가한다. 그렇다면 이러한 문제는 어떻게 해결할까? 다음 그림을 보자.
Grid Search의 단점을 해결할 수 있는 방법으로서 Random Search가 있다. 이는 Coarse to fine sampling 방법이라고도 하며 여러 하이퍼파라미터들 조합으로 부터 무작위 샘플링을 취한 후 모델의 성능이 좋다면 해당 파라미터 조합 주변의 영역에서 또 한번 재 샘플링하여 최적의 파라미터를 찾아가는 방식이다.
예를 들어, 위 오른쪽 그림에서 처음 무작위 샘플링으로 하늘색 동그라미의 파라미터 조합을 선택했다고 가정하자. 이 때 빨간색 동그라미가 가장 최적의 파라미터 조합 즉, 우리가 찾아야 할 파라미터 조합이다. 이 때 무작위로 샘플링한 하늘색 파라미터 조합에서 모델의 성능이 괜찮게 나왔다. 그렇다면 이 파라미터 조합이 있는 녹색 네모칸인 주변 영역에서 무작위로 재 샘플링을 하는 것이다. 이렇게 반복적인 과정을 거치면서 최적의 파라미터 조합인 빨간색 동그라미를 찾아가게 된다.
2-2. Using scaling to hyperparameters
위에서 봤던 Random Search로 최적의 파라미터 조합을 찾는 방법은 사실 균일된 분포에서 샘플링 하는 것이 아니다. 왜냐하면 하이퍼파라미터 값들의 raw값을 사용했기 때문이다. 예를 들어 learning rate값은 0.0001 ~ 1 범위를 설정하고 Random Search를 수행하게 되면 90%정도가 0.1 ~ 1사이의 범위의 값이 나오게 된다. 따라서 이를 균일하도록 만들어 주기 위해 log 변환과 같은 Scaling을 수행해준다.
즉, 0.0001 은 10^-4 이며 1 은 10^1 이다. 이 값들에 log를 취해줌으로써 log 10^-4 <= log 10^a <= log 10^1 가 된다. 그래서 결국 a의 범위는 -4 <= a <= 1의 범위로 좁혀진다. 이렇게 범위를 좁혀준(Scaling) 후 좁아진 범위에서 a값에 따라 learning rate 하이퍼파라미터를 샘플링하게 된다면 이전보다 더 균일한 분포에서 하이퍼파라미터 값을 샘플링하게 된다.
'Data Science > Machine Learning' 카테고리의 다른 글
[ML] 당신은 데이터를 올바르게 분할하고 있는가? (0) | 2020.11.12 |
---|---|
[ML] 데이터를 복구하는 Auto Encoder? (0) | 2020.11.07 |
[ML] How to improve Deep Neural Network? (2) | 2020.10.24 |
[ML] Recurrent Neural Network(RNN) (0) | 2020.10.16 |
[ML] Class imbalance 해결을 위한 다양한 Sampling 기법 (0) | 2020.09.20 |