Home [Tensorflow] 과대적합 방지 방법
Post
Cancel

[Tensorflow] 과대적합 방지 방법

과소적합(Underfitting)

  • 학습 데이터를 충분히 학습하지 않아 성능이 매우 안 좋은 경우
  • 모델이 지나치게 단순한 경우

해결 방안

  • 충분한 학습 데이터 수집
  • 복잡한 모델 사용
  • epochs를 늘려 충분히 학습

과대적합(Overfitting)

  • 모델이 학습 데이터에 지나치게 맞추어진 상태
  • 새로운 데이터에서는 성능 저하
  • 데이터에 잡음이나 오류가 포함
  • 학습 데이터가 매우 적을 경우
  • 모델이 지나치게 복잡할 경우
  • 학습 횟수가 매우 많을 경우

해결 방안

  • 다양한 학습 데이터 수집 및 학습
  • 정규화(Regularization)
  • 하이퍼 파라미터

과대적합과 과소적합 방지 방법

  • 모델의 크기 축소
  • 가중치 초기화(Weight Initializer)
  • 옵티마이저(Optimizer)
  • 배치 정규화(Batch Normalization)
  • 규제화(Regularization)
  • 드롭아웃(Dropout)

1.모델 크기 조절

모델 크기 감소

  • 모델의 크기를 줄인하는 것은 학습 파라미터의 수를 줄이는 것

모델 크기 증가

  • 모델의 크기를 증가시키는 것은 학습 파라미터의 수를 늘리는 것

2. 옵티마이저(Optimizer)

확률적 경사하강법(SGD)

  • Stochastic Gradient Descent
  • 전체를 한 번에 계산하지 않고 확률적으로 일부 샘플을 뽑아 조금씩 나누어 학습

Momentum

  • 운동량을 의미
  • 공이 그릇의 경사면을 따라서 내려가는 듯한 모습
1
2
3
4
import tensorflow as tf
from tensorflow.keras.optimizers import SGD

optimizer = SGD(learning_rate=0.001, momentum=0.9)

AdaGrad

  • 가장 가파른 경사를 따라 빠르게 하강하는 방법
  • 학습률이 너무 감소되어 전역 최소값에 도달하기 전에 학습이 빨리 종료되는 문제
1
2
3
from tensorflow.keras.optimizers import Adagrad

optimizer = Adagrad(learning_rate=0.001)

RMSProp

  • AdaGrad를 보완하기 위한 방법
1
2
3
from tensorflow.keras.optimizers import RMSprop

optimizer = RMSprop(learning_rate=0.001, rho=0.9)

Adam

  • 모멘텀 최적화와 RMSProp의 아이디어를 합친 것
  • 가장 많이 사용되는 최적화 방법
1
2
3
from tensorflow.keras.optimizers import Adam

optimizer = Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999)

3. 가중치 초기화

Xavier

  • 활성화 함수 : tanh, sigmoid, softmax

He

  • 활성화 함수 : ReLU, LeakyReLU
1
2
3
from tensorflow.keras.layers import Dense, Input, Flatten, Softmax, LeakyReLU, Activation
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.utils import plot_model
1
2
3
4
5
6
7
8
9
# 함수형 API
inputs = Input(shape=(10, 10), name='input')
x = Dense(units=30, kernel_initializer='he_normal', name='dense1')(inputs)
x = LeakyReLU(alpha=0.2, name='leaky')(x)
x = Dense(units=1, kernel_initializer='he_normal', name='dens2')(x)
x = Softmax(name='softmax')(x)

model = Model(inputs=inputs, outputs=x)
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Model: "model_17"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input (InputLayer)          [(None, 10, 10)]          0         
                                                                 
 dense1 (Dense)              (None, 10, 30)            330       
                                                                 
 leaky (LeakyReLU)           (None, 10, 30)            0         
                                                                 
 dens2 (Dense)               (None, 10, 1)             31        
                                                                 
 softmax (Softmax)           (None, 10, 1)             0         
                                                                 
=================================================================
Total params: 361
Trainable params: 361
Non-trainable params: 0
_________________________________________________________________
1
2
3
4
5
6
7
8
# Sequential API
model = Sequential([
    Dense(30, kernel_initializer='he_normal', input_shape=[10, 10], name='dens1'),
    LeakyReLU(alpha=0.2),
    Dense(1, kernel_initializer='he_normal', name='dens2'),
    Activation('softmax')
])
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Model: "sequential_7"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dens1 (Dense)               (None, 10, 30)            330       
                                                                 
 leaky_re_lu_14 (LeakyReLU)  (None, 10, 30)            0         
                                                                 
 dens2 (Dense)               (None, 10, 1)             31        
                                                                 
 activation_5 (Activation)   (None, 10, 1)             0         
                                                                 
=================================================================
Total params: 361
Trainable params: 361
Non-trainable params: 0
_________________________________________________________________

4. 배치 정규화(Batch Normalization)

  • 모델에 주입되는 샘플들을 균일하게 만드는 방법
  • 가중치의 활성화 값이 적당히 퍼지게끔 적용
  • 과대적합 방지
  • 주로 Dense 또는 Conv2D Layer후, 활성화 함수 이전에 놓임
1
from tensorflow.keras.layers import BatchNormalization, Flatten
1
2
3
4
5
6
7
8
9
# 함수형 API
inputs = Input(shape=(28, 28), name='input')
x = Flatten(input_shape=(28, 28), name='flatten')(inputs)
x = Dense(units=32, kernel_initializer='he_normal', name='dense1')(x)
x = BatchNormalization(name='batch')(x)
x = Activation('relu', name='relu')(x)

model = Model(inputs=inputs, outputs=x)
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Model: "model_23"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input (InputLayer)          [(None, 28, 28)]          0         
                                                                 
 flatten (Flatten)           (None, 784)               0         
                                                                 
 dense1 (Dense)              (None, 32)                25120     
                                                                 
 batch (BatchNormalization)  (None, 32)                128       
                                                                 
 relu (Activation)           (None, 32)                0         
                                                                 
=================================================================
Total params: 25,248
Trainable params: 25,184
Non-trainable params: 64
_________________________________________________________________
1
2
3
4
5
6
7
# Sequential API
model = Sequential()

model.add(Dense(units=32, input_shape=(28 * 28, ), kernel_initializer='he_normal'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Model: "sequential_11"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_12 (Dense)            (None, 32)                25120     
                                                                 
 batch_normalization_3 (Batc  (None, 32)               128       
 hNormalization)                                                 
                                                                 
 activation_7 (Activation)   (None, 32)                0         
                                                                 
=================================================================
Total params: 25,248
Trainable params: 25,184
Non-trainable params: 64
_________________________________________________________________

5. 규제화(Regularization)

  • 과대적합 방지하는 방법
  • 큰 가중치 값에 큰 규제를 가하는 것
  • L1 : 가중치의 절댓값에 비례하는 비용이 추가
  • L2 : 가중치의 제곱에 비례하는 비용이 추가
  • L1 + L2
1
from tensorflow.keras.regularizers import l1, l2, l1_l2

L2 규제

  • kernel_regularizer=l2(0.001)
1
2
3
4
5
6
7
8
# 함수형 API
inputs = Input(shape=(10000, ), name='input')
x = Dense(units=16, kernel_regularizer=l2(0.001), activation='relu', name='dense1')(inputs)
x = Dense(units=16, kernel_regularizer=l2(0.001), activation='relu', name='dense2')(x)
x = Dense(units=1, activation='sigmoid', name='output')(x)

model = Model(inputs=inputs, outputs=x)
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Model: "model_22"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input (InputLayer)          [(None, 10000)]           0         
                                                                 
 dense1 (Dense)              (None, 16)                160016    
                                                                 
 dense2 (Dense)              (None, 16)                272       
                                                                 
 output (Dense)              (None, 1)                 17        
                                                                 
=================================================================
Total params: 160,305
Trainable params: 160,305
Non-trainable params: 0
_________________________________________________________________
1
2
3
4
5
6
7
# Sequential API
l2_model = Sequential([
    Dense(units=16, kernel_regularizer=l2(0.001), activation='relu', input_shape=(10000, ), name='dense1'),
    Dense(units=16, kernel_regularizer=l2(0.001), activation='relu', name='dense2'),
    Dense(units=1, activation='sigmoid', name='output')
])
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Model: "model_22"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input (InputLayer)          [(None, 10000)]           0         
                                                                 
 dense1 (Dense)              (None, 16)                160016    
                                                                 
 dense2 (Dense)              (None, 16)                272       
                                                                 
 output (Dense)              (None, 1)                 17        
                                                                 
=================================================================
Total params: 160,305
Trainable params: 160,305
Non-trainable params: 0
_________________________________________________________________

L1 규제

  • kernel_regularizer=l1(0.0001)

L1 + L2

  • kernel_regularizer=l1_l2(l1=0.0001, l2=0.0001)

6. Dropout

  • 과대적합 방지 방법
  • 학습할 때 사용하는 노드의 수를 전체 노드 중 일부만을 사용
  • 훈련하는 동안 무작위로 층의 일부 노드를 제외
  • 테스트 단계에서는 드롭아웃 되지 않음
1
from tensorflow.keras.layers import Dropout
1
2
3
4
5
6
7
8
9
10
# 함수형 API
inputs = Input(shape=(10000, ), name='input')
x = Dense(units=16, activation='relu', name='dense1')(inputs)
x = Dropout(0.5, name='dropout1')(x)
x = Dense(units=16, activation='relu', name='dense2')(x)
x = Dropout(0.5, name='dropout2')(x)
x = Dense(units=1, activation='sigmoid', name='output')(x)

model = Model(inputs=inputs, outputs=x)
model.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Model: "model_20"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 input (InputLayer)          [(None, 10000)]           0         
                                                                 
 dense1 (Dense)              (None, 16)                160016    
                                                                 
 dropout1 (Dropout)          (None, 16)                0         
                                                                 
 dense2 (Dense)              (None, 16)                272       
                                                                 
 dropout2 (Dropout)          (None, 16)                0         
                                                                 
 output (Dense)              (None, 1)                 17        
                                                                 
=================================================================
Total params: 160,305
Trainable params: 160,305
Non-trainable params: 0
_________________________________________________________________

7. 하이퍼 파라미터

  • 사람이 직접 설정해야 하는 매개변수
  • Learning Rete, Epochs, Mini Batch Size, Validation Data
This post is licensed under CC BY 4.0 by the author.