다시 이음

딥러닝(3) - Regularization, Learning rate Decay, Scheduling 본문

AI 일별 공부 정리

딥러닝(3) - Regularization, Learning rate Decay, Scheduling

Taeho(Damon) 2021. 10. 21. 01:51

안녕하세요.

 

오늘은 딥러닝의 overfitting(과적합)을 방지할 수 있는 방법에 대해서 알아보겠습니다.

 

 

Regularization

 

머신러닝에서 과적합이 생긴 것과 같이 딥러닝에서도 과적합이 발생합니다.

 

더욱이 신경망 알고리즘에서는 복잡한 구조덕에 훈련데이터에 쉽게 과적합 되는 경향이 있습니다.

 

이러한 과적합을 방지하는 방법 4가지를 알아볼게요.

 

 

1. 조기 종료 (Early Stopping)

 

조기 종료는 머신러닝의 과적합을 방지하는 방법으로도 소개한 적이 있습니다.

 

머신러닝과 비슷한 맥락으로 훈련데이터에 대한 손실이 계속 줄어들지만 검증데이터의 손실은 증가한다면 학습을 종료하게 하는 것입니다.

 

# 변수 설정을 따로 하는 방법을 적용하기 위한 코드입니다. 
batch_size = 10
epochs_max = 1

# 학습시킨 데이터를 저장시키기 위한 코드입니다. 
checkpoint_filepath = "FMbest.hdf5"

# overfitting을 방지하기 위해서 학습 중 early stop을 수행하기 위한 코드입니다.
# monitor는 관찰하는 파라미터를 설정하는 하이퍼파라미터입니다.
# patience 파라미터는 관찰하는 파라미터의 값이 훈련,검증 데이터에서 더이상 변화가 없는 그 기점으로부터 몇회 더 학습을 진행할지 정합니다.
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=1)


# Validation Set을 기준으로 가장 최적의 모델을 찾기 위한 코드입니다.
save_best = tf.keras.callbacks.ModelCheckpoint(
    filepath=checkpoint_filepath, monitor='val_loss', verbose=1, save_best_only=True,
    save_weights_only=True, mode='auto', save_freq='epoch', options=None)

# 모델 학습 코드 + early stop + Best model
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs_max, verbose=1, 
          validation_data=(X_test,y_test), 
          callbacks=[early_stop, save_best])
          
# 학습된 모델을 테스트하는 코드(1)
test_loss, test_acc = model.evaluate(X_test,  y_test, verbose=2)

# 체크포인트에 저장된 가중치들을 불러들이는 코드
model.load_weights(checkpoint_filepath)

# best model을 이용한 테스트 데이터 예측 정확도 재확인 코드(2)
test_loss, test_acc = model.evaluate(X_test,  y_test, verbose=1)

 

위의 코드를 보면 학습된 모델을 테스트하는 코드(1),(2)가 있습니다.

 

이 값들은 같을 수도 있고 다를 수도 있습니다.

 

왜냐하면 (1)은 학습이 종료된 시점(관찰하는 파라미터(val_loss)가 변화를 멈춘 시점으로부터 patience 파라미터 만큼 더 학습)에서 loss값과 accuracy를 보여줍니다.

(2)은 학습이 종료된 시점까지 가장 accuracy가 높았던 epoch의 loss값과 accuracy를 보여줍니다.

 

 

2. 가중치 감소(Weight Decay)

 

L1(왼쪽,LASSO), L2(오른쪽,RIDGE)

위의 그림을 통해 설명을 이어가겠습니다.

 

위의 그림은 가중치1,2를 축으로 L1,L2 Regularization을 시각화 한 것 입니다.

 

L1은 가중치에 대해 절대값을 씌움으로써 마름모형태의 규제형태를 띄고,

L2는 가중치에 대해 제곱값을 가짐으로써 원형의 규제형태를 띕니다.

 

원래 우리가 학습한 모델의 최적점은 베타^으로 현재 과적합이 되어 있는 형태입니다.

 

그래서 가중치의 값을 규제(감소)시킴으로써 일반화를 시키려는 목적을 가지고 있습니다.

 

규제란, 사용자가 선택한 가중치 값 내에서 현재 학습된 최적점 사이에 교차점을 찾고 싶어서 만드는 것입니다.

 

파란색 영역은 규제된 가중치를 나타내고 규제(lambda)가 크면 파란색 영역이 줄어들고, 규제가 작으면 파란색 영역이 커집니다.

 

파란색 영역과 타원형의 구간이 맞닿는 부분이 일반화된 새로운 최적점 입니다.

 

 

밑의 식은 LOSS = Cost function + 가중치 합 의 구조를 띄고 있습니다.

 

여기서 lambda는 페널티 조정 계수이며 lambda값이 크면 규제가 크고, 작으면 규제가 작습니다.

 

1) L1 Regularization

- 작은 가중치는 0이 됩니다.

- 규제가 크면 0이 되는 가중치가 많아집니다.

 

2) L2 Regularization

- 작은 가중치라도 0이 되진 않습니다.

- 규제가 커도 0이 되는 가중치는 없습니다.

 

# 가중치 감소(Weight Decay)를 반영한 예시 코드
from tensorflow.keras import regularizers

# 모델 구성을 확인합니다.
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(64, 
            kernel_regularizer=regularizers.l2(0.01),    # L2 Regularization 적용
            activity_regularizer=regularizers.l1(0.01)), # L1 Regularization 적용 (kernel, activity 의 차이에 대해서는 일단 넘어갑시다.)
    Dense(10, activation='softmax')
])

 

 

3. 가중치 제한(Weight Constraints)

 

가중치 제한은 가중치 감소보다 훨씬더 강력한 규제입니다.

 

왜냐하면 사용자가 직접적으로 가중치의 값의 최소값,최대값을 지정해서 제한하기 때문입니다.

 

# 가중치 제한(Weight Constraints)를 반영한 예시 코드
from tensorflow.keras.constraints import MaxNorm

# 모델 구성을 확인합니다.
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(64, 
            kernel_regularizer=regularizers.l2(0.01),
            activity_regularizer=regularizers.l1(0.01),
            kernel_constraint=MaxNorm(2.)), # 가중치 제한(Weight Constraints)을 추가로 적용
    Dense(10, activation='softmax')
])

 

 

4. 드롭아웃(Dropout)

 

드롭아웃은 사용자가 지정한 비율만큼의 노드의 연결을 강제로 끊는 것입니다.

 

사용자는 각 층(layer)마다 드롭아웃을 설정해줘야 하고, 이렇게 연결이 끊기는 노드는 iteration마다 랜덤으로 결정됩니다.

 

이러한 방법으로 과적합이 방지되는 이유는 랜덤하게 노드가 연결해제되면서 그 외의 노드가 다른 가중치를 학습하게 되면서 여러가지 가중치에 대한 학습을 통해 일반화가 됩니다.

 

❄️  학습을 할 때는 드롭아웃을 통해 학습하고, 테스트할 때에는 전체노드를 연결하고 테스트합니다.

❄️  드롭아웃 비율을 설정했을 경우, 모델을 테스트하고 싶을 때에는 드롭아웃 비율을 가중치에 곱해서 진행하여야 합니다.

이유는 각 노드가 가중치 학습이 드롭아웃 비율만큼 더 많이 된 것이기 때문에 테스트할 때는 비율을 맞추어 진행해야 합니다.

 

from tensorflow.keras.layers import Dropout

# 모델 구성을 확인합니다.
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(64, 
            kernel_regularizer=regularizers.l2(0.01),
            activity_regularizer=regularizers.l1(0.01),
            kernel_constraint=MaxNorm(2.)),             
    Dropout(0.5),  # 드롭아웃(Dropout)을 추가합니다.
    Dense(10, activation='softmax')
])

 

 

 

학습률 감소(Learning rate decay)

 

Learning Rate를 크게 하면 최적점을 지나 학습이 될 수도 있고, 작게 하면 학습에 시간이 너무 많이 들고 최적점을 못찾을 수도 있습니다.

 

그래서 우리는 학습률 감소(Learning rate decay)을 통해 처음 시작시 Learning Rate 값을 크게 준 후 일정 epoch 마다 값을 감소시켜서 최적의 학습까지 더 빠르게 도달할 수 있게 하는 방법을 말합니다.

 

❄️ 학습률 감소의 종류에 대해서 알아보세요.

-step, cosine, linear, inverse sqrt, constant

 

#옵티마이저의 하이퍼파라미터를 조정하여 적용가능
#예시

tf.keras.optimizers.Adam(
  learning_rate=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-07, amsgrad=False,
  name='Adam'
)

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001, beta_1 = 0.89)
             , loss='sparse_categorical_crossentropy'
             , metrics=['accuracy'])

 

 

학습률 계획(Learning rate scheduling)

 

학습률 를 결정함에 있어 고정된 하나의 값으로 학습률을 사용하지 않고 학습 반복이 진행됨에 따라 미리 정해놓은 스케쥴대로 학습률을 변경하는(늘리거나 줄이는) 방법 입니다.

 

❄️ 학습률 계획의 종류에 대해서 알아보세요.

  • power scheduling
  • exponential scheduling
  • piecewise constant scheduling
  • performance scheduling
  • 1 cycle scheduling
#학습률에 대한 다양한 파라미터를 지정하고 옵티마이저에 적용

lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
  initial_learning_rate=1e-2,
  decay_steps=10000,
  decay_rate=0.9)
  
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=lr_schedule)
             , loss='sparse_categorical_crossentropy'
             , metrics=['accuracy'])