main-qimg-135b981c38fcd7226730eb974ec33fe8

간단한 네트워크라도, Hyperparameter의 세팅에 따라 성능이 크게 차이납니다.

네트워크에 관련된 대표적인 Hyperparameter에는 Hidden Layer의 갯수, Hidden Layer의 Node의 개수, Dropout, Activation Function, Optimizer등이 있습니다. 또한 학습에 관련된 대표적인 Hyper Parameter에는 Epoch의 수, Batch의 사이즈, Learning Rate등이 있겠지요.

이번에는 이렇게 다양한 Hyperparameter들을 바꾸어가면서 그 영향을 살펴보겠습니다.

실험을 위해 먼저 간단한 네트워크를 만들어보겠습니다. 손글씨를 인식하는 Multi Layer Perceptrons 네트워크를 구성하겠습니다. MNIST Dataset을 이용해 Preprocessing을 하고, Keras로 네트워크를 빌드해 출력을 살펴보겠습니다.

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten_17 (Flatten)         (None, 784)               0         
_________________________________________________________________
dense_54 (Dense)             (None, 512)               401920    
_________________________________________________________________
dropout_36 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_55 (Dense)             (None, 512)               262656    
_________________________________________________________________
dropout_37 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_56 (Dense)             (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________
MNIST MLP Project Code

이 네트워크의 Code는 Github에 올려놓았습니다. 위 버튼을 누르시면 Github Repository로 이동합니다.

그럼, 시작하겠습니다.

Hidden Layer의 Node 개수가 미치는 영향

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten_17 (Flatten)         (None, 784)               0         
_________________________________________________________________
dense_54 (Dense)             (None, 512)               401920    
_________________________________________________________________
dropout_36 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_55 (Dense)             (None, **512**)           262656    
_________________________________________________________________
dropout_37 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_56 (Dense)             (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________

Hidden Layer의 Node의 숫자를 증가시키거나 감소시키보겠습니다. 이때 Overfitting이 일어나는지 살펴보겠습니다.

Layers Nodes Val_acc val_loss Best_Epoch
2 128 0.9757 0.08874 10
2 256 0.9773 0.08073 5
2 512 0.978 0.09107 5
2 1024 0.972 0.09616 2
2 2048 0.967 0.10435 2

Hidden Layer의 Node가 적을수록 Training하는데 더 많은 Epoch이 필요했고, Node가 많을 수록 더욱 빠르게 훈련이 완료되고 급속도로 Overfitting이 진행되었습니다.

Hidden Layer의 Node가 많다고 결과가 더 좋은 것은 아니었습니다. Node의 수가 512개 일때 가장 좋은 모델을 얻을 수 있었습니다.

Hidden Layer의 층수가 미치는 영향

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten_17 (Flatten)         (None, 784)               0         
_________________________________________________________________
dense_54 (Dense)             (None, 512)               401920    
_________________________________________________________________
dropout_36 (Dropout)         (None, 512)               0         
_________________________________________________________________
**dense_55 (Dense)**         (None, 512)               262656    
_________________________________________________________________
dropout_37 (Dropout)         (None, 512)               0         
_________________________________________________________________
dense_56 (Dense)             (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________

이번에는 Hidden Layer의 층을 더욱 깊게, 또는 얕게 하면서 결과를 살펴보겠습니다. 이때 Node의 개수는 512개, Dropout은 0.2로 고정하겠습니다.

Hidden_Layer Val_acc val_loss Best_Epoch
1 0.979 0.07738 7
2 0.978 0.09107 5
4 0.974 0.10722 4
8 0.975 0.13465 3

실험 결과, Hidden Layer가 얕을 수록 좋은 결과가 나왔습니다. 이는 Data가 Line, Edge위주의 저차원 feature들의 특징이 두드러지기때문이라고 볼 수 있습니다.

따라서 네트워크가 깊어진다고 무조건 좋은 결과를 내지는 않는다는 말입니다. 데이터의 특성을 파악하여 알맞는 네트워크를 구성하는 것이 중요합니다. 흥미로운 결과입니다.

Dropout의 영향

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten_17 (Flatten)         (None, 784)               0         
_________________________________________________________________
dense_54 (Dense)             (None, 512)               401920    
_________________________________________________________________
**dropout_36 (Dropout)**     (None, 512)               0         
_________________________________________________________________
dense_55 (Dense)             (None, 512)               262656    
_________________________________________________________________
**dropout_37 (Dropout)**     (None, 512)               0         
_________________________________________________________________
dense_56 (Dense)             (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________

이번에는 Dropout의 영향을 살펴보겠습니다. node는 512개, layer는 2로 고정하겠습니다.

Dropout Val_acc val_loss Best_Epoch
0.0 0.978 0.09107 5
0.2 0.977 0.08476 3
0.4 0.977 0.08654 5

Dropout 역시 결과에 영향을 주었다. Training시 Node를 일부를 일부러 제외함으로써 오히려 전체 네트워크가 더욱 잘 학습됩니다. 훈련속도면에서 이득일 뿐만이 아니라, 네트워크 성능도 좋아지는 것을 보았습니다.

Activation Function의 영향

이번에는 Relu Activaition Function의 종류에 따른 성능을 비교해보겠습니다. node= 512, layer= 2개, Dropout = 0.2로 고정하겠습니다.

Activation Val_acc val_loss Best_Epoch
Relu 0.977 0.08476 3
tanh 0.976 0.07864 10+
sigmoid 0.972 0.08626 9
No Activation 0.917 0.29475 8

Activation Function의 유무는 더욱 드라마틱합니다. Relu Activation Function이 있음으로해서 훈련도 짧아지고 성능도 약 5%가량 향상되었습니다. tanh, sigmoid 함수 역시 네트워크 성능을 크게 향상시켰으나, Training Time이 많이 필요합니다. 따라서 간단하고도 (Relu는 겨우 max(0,x)입니다! ) 파워풀한 Relu가 좋았습니다. 하지만 상황에 따라서 다른 Activation Function이 적합한 경우도 있으니 무조건 항상 특성을 인지하고 있어야 합니다.

Batch Size의 영향

이번에는 Batch Size에 따른 성능을 비교해보겠습니다. node= 512, layer= 2개, Dropout = 0.2, Activation=’Relu’로 고정하겠습니다.

Batch_size Val_acc val_loss Best_Epoch
128 0.977 0.08476 3
256 0.979 0.07610 4
512 0.982 0.08977 2
1024 0.981 0.09607 4
2048 0.984 0.09187 8

Batch Size가 증가할 수록 학습에 필요한 Epoch도 늘어나지만, Valdation Accuracy는 소폭 증가하는 것을 볼 수 있었습니다. 하지만 loss 또한 소폭 증가하는 모습을 보였습니다.

Grid Search : Sysmetic Hyperparameter Search

이와 같이 Hyperparameters에 여러가지 경우의 수를 바꿔가며 최적의 네트워크를 찾는 과정을 Grid Search라고 합니다. Scikit-learn과 keras을 이용하여 간단하게 구현할 수 있습니다.

02p4O {captureBefore} [ ] 이에 대해 더 익히기 위해서는Jason BrownleeHow to Grid Search Hyperparameters for Deep Learning Models in Python With Keras 포스트를 참조해주세요!

Comments

Eungbean Lee's Picture

About Eungbean Lee

Lee is a Student, Programmer, Engineer, Designer and a DJ

Seoul, South Korea https://eungbean.github.io