본문 바로가기

머신러닝/[기타]

뉴럴 네트워크 디자인 팁(Designing Your Neural Networks)

앞서 뉴럴 네트워크의 일반적인 디자인 원칙(General Design Priciples of Neural Network)를 작성한 뒤, 조금 더 상세한 내용이 있었으면 좋겠다 싶었는데, 좋은 글을 발견하여 번역해보았습니다.

뉴럴 네트워크를 구성하고, 학습시키는 것은 굉장히 막막합니다!

어느정도의 Learning rate를 채택할지, 얼마나 많은 Hidden layer를 쌓을지, 어떤 Regularization 기법을 선택할지 등 정말 밑도끝도 없는 선택의 연속입니다. 이번 글에서는, 이런 선택의 갈림길에서, 당신이 조금 더 똑똑한 선택을 할 수 있도록 도움을 줄 것입니다. 동시에 나는 이 커널을 함께 보면서 아래의 내용을 공부하는 것을 추천합니다.

1. 기본적인 뉴럴 네트워크 구조

Input neurons

  • Input neurons의 수는 결국 네가 사용하고자 하는 Feature의 수와 동일합니다.
  • MNIST 데이터셋의 경우, 28x28 이미지를 Flatten시켜 사용하기에, Feature의 수는 784개가 되고, Input neurons의 수 또한 784개가 되어야합니다.

Output neurons

  • Output neurons의 수는, 네가 예측하고자 하는 경우의 수입니다.
  • 회귀(Regression): 회귀의 경우, Output은 단일값입니다. 
  • 분류(Classification): Binary classification(스팸 메일 구분 등)의 경우, 우리는 Output을 단일값으로 처리합니다. 이 때 단일값은 0과 1사이의 값으로 확률로 해석될 수 있으며, 1=True, 0=False로 해석합니다. Multi-class classification(Object detection 등)의 경우, 벡터로 처리할 수 있습니다. [0.2, 0.1, 0.7]과 같은 Output은 2번째 Class에 속할 확률이 70%라 해석될 수 있으며, Softmax 등의 activation을 통해 처리합니다.

Hidden Layers and Neurons per Hidden Layers

  • Hidden layers의 수는, 당신이 좋은 Neural network를 구성하는 중요요소입니다. 너무 크지도, 너무 작지도, 정말 적당하게만들어야 합니다.
  • 일반적으로, 1-5개의 Hidden layer로 대부분의 문제를 잘 해결할 수 있습니다. 물론 당신이 이미지 또는 언어 데이터를 다루고자 한다면, 몇 백개의 layer가 필요할 것이며, 이때 모든 레이어가 Fully connected여서는 안됩니다. 이런 용도로는 pre-trained model인 YOLO, ResNet, VGG를 기반으로 약간의 layer를 얹어 당신의 데이터를 추가학습하는 것으로 훨씬 빠르고, 좋은 결과를 얻어낼 수 있습니다.
  • 일반적으로, 모든 Hidden layer에 같은 수의 neurons을 사용하는 건 유효하며, 데이터에 따라 많은 수의 neurons에서 적은 수의 neurons로 layer의 폭을 줄여나가는 방법을 택할 수 있습니다. 이렇게하면, 첫번째 layer에서는 low level의 feature를 다루고, 마지막 layer에서는 high level의 feature를 처리하게 됩니다.

  • 보통, Neural network의 폭을 늘리는 것 보다는 깊이를 쌓는 것이 정확도 개선에 효과적입니다. (보통 width와 depth의 균형을 잡으라고 표현합니다만, 대개의 layer가 50개 이상의 neurons을 갖는 경우가 많아서 이렇게 표현한 것 같습니다.)
  • 처음에는 1-5개의 layer와 1-100개의 neurons에서 시작해 천천히 더 많은 layer와 neurons를 추가해나가는 것을 추천합니다. 사용할 수 있다면, 이것을 활용해 Weights와 Bias를 추적하여 최적의 layer와 neurons 조합을 찾으십시오.
  • 만약 layer/neurons의 수가 너무 작다면, 당신의 network는 데이터로부터 근본적인 패턴을 학습하는 것에 실패할 것입니다. 이를 방지하기 위해 많은 수의 layer/neurons를 갖는 network를 구성한 다음, dropout 또는 early stopping 등을 활용하여 적절한 사이즈를 찾아나갸아 합니다.
  • Andrej Karpathy also recommends the overfit then regularize approach — “first get a model large enough that it can overfit (i.e. focus on training loss) and then regularize it appropriately (give up some training loss to improve the validation loss).” 즉, 일단은 학습데이터에 충분히 오버피팅되는 모델을 구성한 뒤(training loss에만 집중함으로써), 정규화를 적절히 사용하여 validation loss를 줄여나가십시오.

Loss function

  • 회귀(Regression): MSE가 가장 일반적이며, 이상치가 많을 경우에는 MAE또는 Huber loss를 사용할 수 있습니다.
  • 분류(Classification): Cross-entropy loss function은 대부분의 분류문제에서 잘 작동합니다.

Batch Size

  • 큰 배치 사이즈는 같은 시간에 더 훌륭한 결과를 얻어낼 수 있게 합니다. 이미지 분류 또는 언어 모델링의 경우 기본적으로 데이터가 굉장히 크기에, 좋은 효과를 얻어낼 수 있습니다.
  • 그러나 batch size가 커질수록, 알맞는 learning rate의 범위가 좁아집니다. 때문에 데이터와 모델마다 적절한 batch size와 learning rate를 찾아나가야 합니다. 보통 최고의 performance는 2~32 batch size에서 얻어집니다. 특히나 다루는 데이터가 굉장히 거대하지 않다면, lower batch size에서 천천히 값을 키워나가며 performance를 monitoring하는 과정이 필요합니다. 

Number of epochs

  • 많은 수의 Epochs에서 시작하여 early stopping을 통해 조율하는 것을 추천합니다. (train_loss는 낮아지는데 val_loss는 증가하기 시작하는 시점에서 학습을 중지)

Scaling your features

  • 간단히, Feature를 scaling하면 학습 개선에 효과적입니다. 특히 모델 학습 과정에서 Batchnormalization을 적용하는 과정은 효과가 좋습니다.

2. 학습률(Learning Rate)

  • 적절한 learning rate를 찾는 것은 굉장히 중요합니다. network의 hyper-parameters를 조절할 때마다, learning rate도 같이 조절되어야합니다.
  • 최고의 learning rate를 찾기위해서 매우 낮은 값(10^-6)에서 부터 시작해서 10을 곱하면서 키워나가십시오. learning rate별 loss를 확인하며 최적의 값을 찾아내야합니다.
  • 할 수 있다면, 논문을 읽고 Learning rate finder method를 사용하십시오.

3. 관성(Momentum) 기법

  • 일반적으로 SGD는 모든 STEP을 밟아나가기에 많은, 오랜 연산이 필요합니다. 이 때, Momentum을 활용하면, local minima를 벗어나고, 학습 속도를 개선할 수 있습니다.
  • 일반적으로 momentum 값은 1과 가깝습니다. 작은 데이터셋이라면 0.9가 적당하며, 큰 데이터셋이라면 0.999를 사용해볼만합니다. 사실 이러한 옵션들을 활용한 다양한 optimizer가 존재하고, 아래에서 설명하도록 하겠습니다.

4. 기울기 소실, 폭팔(Vanishing + Exploding Gradients)

  • Neural network의 layers는 같은 정도로 학습되지 않습니다. Output layer로부터 발생된 error gradient는 역전파됨에따라 값이 점점 작아지고, 첫번째 layer에 도착했을 때는 값이 굉장히 작아집니다. 때문에 첫번째 layer는 거의 학습이 되지 않습니다.
  • 이것은 Vanishing gradient 문제입니다. (반대로 gradient가 과도하게 큰 문제를, exploding gradient 라 말합니다. 이 경우, 어느 한 레이어에 의해 output이 크게 좌우될 것입니다.)
  • 지금부터 이들을 해결할 방법을 알아봅시다.

활성 함수(Activation functions)

Hidden Layer Activation
일반적으로, logistic → tanh → ReLU → Leaky ReLU → ELU → SELU. 순으로 성능이 개선됩니다. 다만, 당연히 각각에 따른 연관 parameter 수정은 필요합니다.

ReLU는 가장 인기있는 Activation function입니다. 별 생각이 없다면 ReLU로 시작해도 무방합니다. 그러나 ELU와 SELU를 통한 모델 개선이 가능함을 명심하십시오.

If you’re feeling more adventurous, you can try the following:

  • overfitting으로 고민한다면: RReLU
  • runtime latency를 줄이고자 한다면: leaky ReLU
  • 데이터셋이 거대하다면: PReLU
  • 빠른 추론시간이 필요하다면: leaky ReLU
  • network가 자가적으로 정규화(normalization)를 시행할 수 없다면: ELU
  • robust한 activation이 필요하다면: SELU

다양한 activation에 대한 경험을 쌓도록 노력하십시오.

이것은 다양한 activation들을 비교한 좋은 논문입니다. 조금 더 깊은 내용을 알고 싶다면 읽어보는 것을 추천드립니다.

Output Layer Activation
회귀(Regression):
회귀 문제는 대개 activation function을 지정할 필요가 없습니다. 1 node를 갖는 dense layer에서 알아서 단일값을 뱉어주기 때문입니다. 만약 우리가 출력값을 특정 범위로 국한시키고 싶을 때는, tanh나 logistic function을 활용할 수 있습니다.

분류(Classification): Binary classification의 경우 sigmoid를 통해 0~1값을 출력하고, Multi-class classification의 경우 softmax를 사용하는 것이 일반적입니다.

Weight initialization method

  • 올바른 weight initialization method를 택하는 것은, 수렴에 걸리는 시간을 높이기 위해 중요하며 activation에 따라 선택되어야합니다.
  • ReLU or leaky RELU 라면 He initialization
  • SELU or ELU라면 LeCun initialization
  • softmax, logistic, or tanh라면 Glorot initialization
  • 대부분의 init method는 uniform and normal distribution의 특징을 가집니다.

BatchNorm

  • BatchNorm은 단순히, 각 layer의 inputs을 normalizing하는 것으로써, 모델이 평균과 스케일의 최적값을 배울 수 있게 합니다. 이를 사용할 경우 dropout, l2 정규화등을 사용할 필요가 없습니다.
  • BatchNorm을 사용하면 더 높은 Learning rate를 사용해볼 수 있습니다.
  • 한 가지 단점은, 각 계층마다 normalization을 진행하는 시간이 추가로 소요된다는 것입니다.

Gradient Clipping

  • 특히 RNN에서, gradients exploding을 줄이는 멋진 방법은, 단순히 gradient에 특정값으로 제약을 거는 것입니다. 나는 clipvalue대신 clipnorm을 사용하는 것을 추천합니다. clipnorm의 경우 gradient의 방향성을 유지시켜줍니다. clipnorm은 l2 norm이 threshold보다 높은 gradient를 제한합니다.
  • 최적의 threshold를 찾기 위해서는 여러 시도가 필요합니다.

Early Stopping

  • train loss는 계속해서 낮아지는데 valid loss는 증가하는 경우, trian set에 대한 학습을 종료하여 과대적합을 피하는 것이 나은 선택일 수 있습니다.

5. Dropout

  • Dropout은 간단히 사용할 수 있으면서도 모델의 개선을 이끌어낼 수 있는 좋은 테크닉입니다. 이는 학습 도중 일부 노드의 값을 0으로 만들어 버리는 것으로, Network를 Robust하게 만들 수 있습니다. 즉, 어떤 Neurons에 과의존하지 않습니다. 
  • Dropout의 비율은 0.1~0.5 정도가 좋으며 RNN의 경우 0.3, CNN의 경우 0.5가 일반적입니다. 거대한 Layer일수록 비율을 늘려야합니다.  Dropout의 증가는 Overfitting을 막으며, 작은 Dropout은 Underfitting을 방해합니다.
  • Output layer에는 Drouout을 사용하지 않습니다.
  • Dropout과 BatchNorm의 연결은 이 논문을 읽으십시오. (좋지 않습니다.)

6. Optimizers

  • 수렴의 질에 관심이 있고, 그에 대한 소요시간에 대한 걱정이 없다면, SGD를 사용하십시오.
  • 소요시간을 줄여야하고, 적당한 최적값을 원한다면, Adam, Nadam, RMSProp, Adamax optimizers를 시험하십시오.
  • Andrej Karpathy said “a well-tuned SGD will almost always slightly outperform Adam” in the case of ConvNets. / CNN의 경우 SGD를 잘 튜닝하는 것으로 Adam의 성능을 따라잡을 수 있습니다.
  • 앞선 커널의 경우, 저는 Nadam을 통해 최고 점수를 얻었습니다. Nadam은 Adam에 Nestreov trick을 추가한 것입니다.

7. Learning Rate Scheduling

  • 우리는 이미 Learning rate의 중요성에 대해 언급했습니다. 우리는 이것이 너무 높기를 원하지 않습니다. 이 경우, Loss function은 최적해 근처에서 수렴하지 못하고 튈 것입니다. 너무 낮기를 원하지도 않습니다. 이 경우, 수렴에 오랜 시간이 걸리게 됩니다.
  • 처음에는 높은 학습률을 설정하여 빠르게 학습하고, 이후에는 낮은 학습률을 설정하여 면밀히 탐색하는, Learning rate scheduling을 사용할 수 있습니다.
  • Learning rate를 점진적으로 감소시켜나가는 기법 외에도 Step function을 사용하거나, Performance가 변화하는 것을 보고 값을 수정하는 따위의 방법이 가능합니다. 앞선 커널에서는, ReduceLROnPlateau callback을 사용하여, Performance가 하락함에 따라 Learning rate를 줄여나가는 방법을 사용했습니다.
  • 1-cycle scheduling을 사용하는 것도 추천드립니다.
  • 다른 Hyper parameters를 찾을 때 까지는 고정된 Learning rate를 사용하고, 마지막에 Learning rate decay scheduling을 사용해야합니다.

8. A Few More Things

  • 효율적인 방법으로 당신의 Network를 Scaling하기위해 EfficientNets 를 시도해보십시오.
  • 논문 을 읽으시면 learning rate, batch sizes, momentum and weight decay techniques 에 대한 추가적인 내용을 학습할 수 있습니다.
  • 그리고 Stochastic Weight Averagin에 관한 이 글 은 더 좋은 일반화를 보여줍니다.
  • Andrej Karpathy’s excellent guide 를 읽으면 Network를 구성하는 더 많은 방법을 학습할 수 있습니다.

Results

우리는 이 글에서 Hidden layer, neurons의 수와 Batch size를 설정하는 등의 기본적인 Network 구성 방법과 Momentum의 역활, Learning rate를 효율적으로 사용하는 아이디어를 배웠습니다. 또한 Vanishing gradients, Activation function, Batchnormalization, weight initialization, callback technique 들을 배웠습니다.

Neural network는 네가 만드는 것에 따라 어떠한 문제도 풀 수 있는 최고의 모델이 될 수 있습니다. 이 글과 다양한 실습을 통해 좋은 모델을 구성할 수 있길 기원합니다.

만약 어떤 질문 또는 피드백이 있다면,  tweet me! 알려주십시오.