본문 바로가기
인공신경망(DL)/Neural Networks

Weight Regularization 과적합 방지

by kiimy 2021. 8. 15.
728x90
  • Part 1: 모델 아키텍쳐를 어떻게 선택하는 지 배우게 됩니다.
  • Part 2: 가중치의 규제(Regularization) 전략을 배웁니다.
  • Part 3: 다양한 활성함수를 사용함에 발생하는 trade-off에 대해서 논의해볼 수 있어야 합니다.

과적합을 피하는 방법

  • 데이터 양 늘리기
  • 모델 복잡도 줄이기 ( 학습할 파라미터 수 줄이기 )

복잡도는 은닉층(hidden layer)의 수나 매개변수의 수 등으로 결정

  • 인공 신경망에서는 모델에 있는 매개변수들의 수를 모델의 수용력(capacity)이라고 한다.
  • 적절한 layer 수, node 수, learning_rate ...(하이퍼파라미터 조정 GridSearchCV)
  • weight decay (정보에 제약을 가한다 )
  • Dropout

정규화를 한다는것은 신경망의 분산을 줄이는데 도움을 주는데 높은 분산을 가질때 w는 많은 매개변수를 갖는다.
과적합을 방지하기 위해서는 더 많은 학습 데이터를 얻는 것이 가장 좋습니다. 


더 많은 데이터로 학습된 모델은 자연스럽게 더 잘 일반화됩니다. 작은 규모의 데이터 셋의 경우 변수들의 관계에서 

노이즈로 고려될 만한 부분까지 학습될 확률이 증가합니다. 


이 경우 데이터 규모를 증가시키는 것으로 그 확률을 감소시킬 수 있습니다. 
기존 데이터의 인위적 변형이나 표집등의 방법으로 규모를 확장할 수 있으며 이를 데이터 증식 또는 증강 (Augmentation) 이라 합니다. == 이 경우는 힘들어 비용이 많이든다함



이것이 불가능할 때 차선책은 모델이 저장할 수 있는 정보의 양을 조정하거나

저장할 수 있는 정보에 대한 제약을 추가하는 것입니다. 


네트워크가 적은 수의 패턴만 기억할 수 있는 경우 최적화 프로세스는 일반화 가능성이 

더 높은 가장 두드러진 패턴에 집중하도록 합니다. 

이러한 방식으로 과적합을 방지하는 처리를 정규화(regularization)라고 합니다. 
이 방법은 결국 모델의 복잡도를 줄이는 것으로 신경망의 은닉층이나 매개변수의 수를 감소시키기 위해 적용됩니다. 

인공신경망에서 모델에 있는 매개변수들의 수를 모델의 수용역(Capacity)라고 합니다. 
복잡한 모델의 과적합 가능성은 단순한 모델에 비해 높습니다. 
즉, 매개변수의 수가 작은 모델이 일반화의 가능성이 높아집니다. 
이러한 모델의 구축은 가중치에 L1-norm 또는 L2-norm을 고려하여 변수를 선택하는 방법을 적용합니다. 

이를 각각 L1 정규화 (regularization), L2 정규화 (regularization)라고 합니다. 

참고: https://wikidocs.net/book/2155

학습 규제 전략 (Regularization Strategies)

Neural Networks는 매개변수가 아주 많은 모델이어서 훈련 데이터에 쉽게 과대적합(overfit) 될 수 있다

과대적합을 완화시키는 일반적인 방법은 가중치가 작은 값을 가지도록 네트워크의

복잡도에 제약을 가하는 것(= train data가 더 학습되기전에 멈춤)

일반적인 규제 방법

1. Early_stopping / Hyperparameter 

가중치의 최고 유용성 시점을 더 지나서 업데이트 되는 것을 방지

import keras
import tensorflow as tf
import numpy as np
from tensorflow.keras.datasets import cifar100
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import regularizers

# callbacks= [early_stop, save_best]
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=5)


# ModelCheckpoint == tf
save_best = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_filepath,
                                            monitor='val_loss',
                                            verbose=1,
                                            save_best_only=True,
                                            save_weights_only=True,
                                            save_freq='epoch')


model.fit(X_train,y_train, batch_size=batch_size, epochs=epochs,
          validation_data=(X_test, y_test),
          callbacks=[early_stop, save_best])
fit() is for training the model with the given inputs (and corresponding training labels).

evaluate() is for evaluating the already trained model using the validation (or test) data and the corresponding labels. Returns the loss value and metrics values for the model.

predict() is for the actual prediction. It generates output predictions for the input samples.

!ls == 파일 저장 확인

 

# 학습중 Accuacy, loss 확인 가능

history_df = pd.DataFrame(history.history)

history_df.head()

[출처] 간단한 tensorflow2 CNN 코드|작성자 Zinc

 

# 저장된 학습 데이터 불러오기

model.load_weights(checkpoint_filepath)

 

# 저장했던 모델 불러오기

model = tf.keras.models.load_model('./model.ckpt')


2. weight decay 가중치 감소

-  Weight의 학습 반경을 변경
-  Norm 은 벡터의 크기(혹은 길이)를 측정하는 방법(혹은 함수)
   두 벡터 사이의 거리를 측정하는 방법이기도 하다.

 

L(θw)=12Σi(outputitargeti)2+λ|θw| == L1 Lasso ( 가중치w들의 절대값합 추가 )

L(θw)=12Σi(outputitargeti)2+λ||θw||2 == L2 Ridge ( 가중치w들의 제곱합 추가 )

오차와 가중합의 값이 크면 역전파때 가중치가 작게 업데이트되고
오차와 가중합의 값이 작으면 역전파때 가중치가 크게 업데이트 된다.

 

# λ = 규제의 강도를 정하는 하이퍼파라미터

λ가 크다면 모델이 훈련 데이터에 대해서 적합한 매개 변수를 찾는 것보다

규제를 위해 추가된 항들을 작게 유지하는 것을 우선한다는 의미

 

(실제값 - 예측값) 제곱식 뒤에(비용함수에) 가중합을 더한다

가중치가 너무 커지게되는 overfit를 방지하고자, w 크기 자체가 error로 반영이 되면,

w의 크기가 커지지 않으면서도 output과 target의 차이가 줄어들게 하겠다는 의미

==  비용 함수를 최소화하기 위해서는 가중치 w들의 값( 가중합 )이 작아져야 한다는 것이다.

 

*L1 Lasso ( 미분 불가 == 경사하강법 X )

- 특정 Feature 값을 0으로 처리 

  절대값의 합으로 0이 나올 수 있고 해당 특성은 모델에 영향을 주지않는다고 판별할 수 있다.

 

*L2 Ridge

- 가중치들의 제곱을 최소화하므로 0에 가까워지는 경향을 띔

L1 규제는 어떤 특성들이 모델에 영향을 주고 있는지를 정확히 판단하고자 할 때 유용
아니면 L2 규제가 더 잘 동작하므로 L2 규제를 더 권장

Outlier 가 적당히 무시되길 원한다면 L1 Loss 를 사용하고,
Outlier 의 등장에 신경써야 하는 경우라면 L2

출처: 
https://light-tree.tistory.com/125
인공 신경망에서 L2 규제는 가중치 감쇠(weight decay)라고도 부릅니다.

### code ### 

  • kernel_regularizer: Regularizer to apply a penalty on the layer's kernel
  • bias_regularizer: Regularizer to apply a penalty on the layer's bias
  • activity_regularizer: Regularizer to apply a penalty on the layer's output
from tensorflow.keras.constraints import MaxNorm
from tensorflow.keras import regularizers


def model_builder():
  model = Sequential(
      [
      Flatten(input_shape=(28,28)),
      Dense(64,
            kernel_regularizer=regularizers.l2(0.01), # 0.01 == 람다 λ 
            activity_regularizer=regularizers.l1(0.01)),
      Dense(10, activation='softmax')
      ]
  )


  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])
                
  return model



model = model_builder()

batch_size = 64
epochs = 1

model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs)

3. weight constraint

- 가중치 크기 규제 ( 설정한 특정 가중치 값보다 높으면 설정한 값으로 변경)

from tensorflow.keras.constraints import MaxNorm
from tensorflow.keras import regularizers

def model_builder():
  model = Sequential(
      [
      Flatten(input_shape=(28,28)),
      Dense(64,
            kernel_regularizer=regularizers.l2(0.01), # 0.01 == 람다 λ 
            activity_regularizer=regularizers.l1(0.01),
            kernel_constraint=MaxNorm(2.)),   # 2가중치가 최대치
      Dense(10, activation='softmax')
      ]
  )

4. Dropout

- 신경망의 각 레이어 노드에서 학습할 때 마다 일부 노드를 사용하지 않고 학습을 진행하는 방법

 

ex) Dropout을 안하게 되면 그저 하나의 복잡한 모델

    ==> 램덤으로 노들르 삭제하여 간단한 모델로 예측하고 그 결과들을 합해서 사용

    == 앙상블 기법중 하나

* 모델 자체에 Layer를 추가하는 방식으로 진행

단, 임시로 차단을 하고, 그 연결이 없이 결과를 예측하도록 만들고, 해당 뉴런없이

학습을 진행하기 때문에 과적합을 어느정도 차단할 수 있다.

from tensorflow.keras.constraints import MaxNorm
from tensorflow.keras import regularizers


def model_builder():
  model = Sequential(
      [
      Flatten(input_shape=(28,28)),
      Dense(64,
            kernel_regularizer=regularizers.l2(0.01), # 0.01 == 람다 λ 
            activity_regularizer=regularizers.l1(0.01),
            kernel_constraint=MaxNorm(2.)),
      Dropout(0.3),                                # 30%는 안 쓰겠다
      Dense(10, activation='softmax')
      ]
  )

5. Batch Normaliztion( BN )

 Convolution - Batch Normalization - Activation - Dropout - Pooling 순서로 적용

Batch normlization은 미니배치의 데이터에서 각 feature별 평균과 분산을 구한 뒤 데이터를

표준정규분포(평균 0, 분산 1인 정규분포)를 따르도록 정규화한다.

그리고 그 값에 gamma를 곱하고 beta를 더해서 출력값을 조정한다.

배치 정규화 후의 데이터들은 대부분 0에 가까워지는데 일부 활성화 함수에서 문제가 될 수 있다.

(예를 들어 sigmoid 함수에서 비선형성이 감소하는 문제가 생긴다.) 따라서 gamma, beta와 같은

파라미터를 둬서 학습시 적절한 값으로 shift, scaling될 수 있도록 해준다.

  1. 그래디언트 소실 문제가 감소한다.
  2. 가중치 초기화(Xavior, He norm.) 문제를 신경쓰지 않아도 된다.
  3. learning rate를 크게 잡아도 학습이 잘 된다.
  4. 오버피팅을 억제한다. 이는 Batch Normalization이 Regularization의 역할도 하기 때문이다.

[출처] CNN 모델을 더 깊게 만들기 & 정규화, 규제 기법 정리|작성자 Zinc

 

분리수거장 : 네이버 블로그

성균관대학교 반도체시스템공학과, 주로 알고리즘 문제 풀이를 올립니다.

blog.naver.com

from tensorflow.keras.layers import Dense, Flatten, BatchNormaliztion

def model_builder():
  model = Sequential(
      [
      Flatten(input_shape=(28,28)),
      
      BatchNormalization(), # BatchNormalization추가
      
      Dense(64,
            kernel_regularizer=regularizers.l2(0.01), # 0.01 == 람다 λ 
            activity_regularizer=regularizers.l1(0.01),
            kernel_constraint=MaxNorm(2.)),
      Dropout(0.3),                                # 30%는 안 쓰겠다
      Dense(10, activation='softmax')
      ]
  )

6. learning_rate decay ( model.compile(optimizer ) )

def model_builder():
  model = Sequential(
      [
      Flatten(input_shape=(28,28)),
      Dense(64,
            kernel_regularizer=regularizers.l2(0.01), # 0.01 == 람다 λ 
            activity_regularizer=regularizers.l1(0.01)),
      Dense(10, activation='softmax')
      ]
  )

# decay
lr_schedule = keras.optimizers.schedules.ExponentialDecay(initial_learning_rate=1e-2,
                                                          decay_steps=10000,
                                                          decay_rate=0.9)

model.compile(optimizer= Adam(learning_rate= lr_schedule))
  adam=Adam(learning_rate=learning_rate,
                    beta_1=0.9,
                    beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)

  model.compile(optimizer=adam ...

  # or

  model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001,
                                                   beta_1=0.9, 
                                                   beta_2=0.999, 
                                                   epsilon=1e-07, 
                                                   amsgrad=False,
                                                   name= 'Adam')
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])

  return model
728x90

댓글