[ 머신러닝 순한맛 ] Regularization in 딥러닝의 모든 것
어제보다 나은 사람이 되기

걱정보단 실행을, 그러나 계획적으로

Box World 자세히보기

AI/Hands-On Machine Learning 2판

[ 머신러닝 순한맛 ] Regularization in 딥러닝의 모든 것

Box형 2021. 7. 5. 03:04
반응형

"나는 네 개의 파라미터가 있으면 코끼리 모양을 학습시킬 수 있고,

다섯 개가 있으면 코를 꿈틀거리게 할 수 있다."

- 존 폰 노이만 -

 Neural Network는 수만 개에서 수백만 개까지 파라미터를 가집니다. 그만큼 크고 복잡한 데이터셋을 학습할 수 있을만큼 네트워크의 자유도가 높다는 것을 의미합니다. 

 그러나 이러한 자유도가 높을 수록 네트워크는 Training set에 과대적합(Overfitting)되기 쉬워집니다. 이번 포스팅에서는 Neural Network에서 Overfitting을 막기 위해 사용하는 다양한 규제(Regularization) 방법들에 대해 알아보겠습니다.

 이번 포스팅은 다음 포스팅을 읽은 후 공부하시면 더욱 효과적입니다.

[AI/Coursera ( Machine Learning )] - [ 핸즈온 머신러닝 2판 ] Linear Regression 속 Regularization이란?

 

[ 핸즈온 머신러닝 2판 ] Linear Regression 속 Regularization이란?

"이끌거나, 따르거나, 비켜서라." - Ted Turner (CNN 설립자) - 4.5 선형 모델(Linear Model)에서의 규제(Regularization)  Regularization은 모델이 Overfit되었을 때, 이를 감소시키는 대표적인 방법입니다...

box-world.tistory.com


L1, L2 규제

 우리가 이전에 Linear Regression을 공부한다면, 자연스럽게 Overfitting을 막기 위해 별도의 규제 항을 추가하였던 것을 기억할 것입니다.

 Neural Network에서도 가중치를 제한하기 위해 L2 규제를 사용하거나, Sparse한(많은 가중치가 0인) 모델을 만들기 위해 L1 규제를 사용할 수 있습니다.

 다음은 규제 강도를 0.01을 사용하여 L2 규제를 적용하는 방법을 보여줍니다.

layer = keras.layers.Dense(100, activation="elu",
                           kernel_initializer="he_normal",
                           kernel_regularizer=keras.regularizers.l2(0.01))

 L2() 함수는 각 스텝마다 규제 Loss가 들어있는 객체를 반환하고, 이것은 최종 Loss에 반영됩니다. L1 규제를 사용하고 싶다면 keras.regularizaers.l1()을 사용하면 되고, L1, L2 두가지가 모두 필요하면 keras.regularizers.l1_l2()를 사용하면 됩니다.

 일반적으로 네트워크를 구성하는 Hidden Layer들에는 동일한 activation 함수, Initialization 전략을 사용하거나, 동일한 규제를 적용하여 동일한 파라미터 값을 반복하는 경우가 많습니다.

model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.Dense(300, activation="elu",
                       kernel_initializer="he_normal",
                       kernel_regularizer=keras.regularizers.l2(0.01)),
    keras.layers.Dense(100, activation="elu",
                       kernel_initializer="he_normal",
                       kernel_regularizer=keras.regularizers.l2(0.01)),
    keras.layers.Dense(10, activation="softmax",
                       kernel_regularizer=keras.regularizers.l2(0.01))
])

 위 코드는 보다시피 매 Layer마다 반복되는 파라미터가 존재합니다. 이 경우 매번 입력하는 대신 파이썬의 functools.partial() 함수를 사용하여 동일하게 사용하는 기본적인 매개변수 값을 사용하게 할 수 있습니다.

RegularizedDense = partial(keras.layers.Dense,
                           activation="elu",
                           kernel_initializer="he_normal",
                           kernel_regularizer=keras.regularizers.l2(0.01))

model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    RegularizedDense(300),
    RegularizedDense(100),
    RegularizedDense(10, activation="softmax")
])


Dropout

 드롭아웃은 Neural Network에서 가장 인기 있는 규제 기법중 하나입니다. 최고 성능을 내는 네트워크도 드롭아웃 적용 후 정확도를 1~2% 높였습니다. 이러한 1~2%의 상승은 오차율이 거의 40% 줄어드는 것을 의미합니다.

 드롭아웃의 알고리즘은 간단합니다. 매 Training 스텝에서 네트워크를 구성하는 각 뉴런은 임시적으로 드롭아웃될 확률 $p$를 가집니다.(입력 뉴런은 포함되고, 출력 뉴런은 제외됩니다.) 다시 말해서 드롭아웃된 뉴런은 완전히 없는 셈치고 학습을 진행하는 것입니다.

 다만 무시됐던 뉴런은 다음 훈련 스텝에서는 드롭아웃 확률에 따라 다시 활성화될 수 있습니다. 드롭아웃 확률 $p$는 하이퍼파라미터로 보통 10~30% 사이를 지정합니다.

 훈련이 끝난 후, Test set에서는 드롭아웃을 적용하지 않습니다. 그렇다면 이러한 드롭아웃이 성능을 높이는 이유는 무엇일까요?

 매 훈련 스텝마다 일정 드롭아웃 확률 $p$에 따라 각 뉴런들은 비활성화되거나 활성화됩니다. 다시 말해 매 훈련 스텝마다 네트워크의 모양은 다릅니다. 그러니까 우린 매 훈련 스텝마다 서로 다른 Neural Network를 사용한 셈이 되는 것입니다.

 그래서 예를들어 10000번의 훈련 스텝을 진행했다면 10000개의 서로 다른 Neural Network를 앙상블해서 훈련시킨 효과를 가지게 되는 것입니다.


 다만 한가지 사소하지만 유의해야할 사항이 있습니다. $p=50%$로 하면 Test시 하나의 뉴런은 훈련 때보다 평균적으로 두배 더 많은 입력 뉴런과 연결됩니다. 이런 점을 보상하기 위해 훈련 후 각 뉴런의 연결 가중치에 0.5를 곱하여 늘어난 입력 뉴런을 상쇄시켜야합니다.

 다시 말해 훈련이 끝나면 각 입력의 연결 가중치에 보존 확률$(1-p)$을 곱해줘야합니다.

 케라스의 keras.layers.Dropout은 훈련 동안 일부 Input을 랜덤하게 버립니다. 그리고 남은 입력을 보존 확률로 나눕니다. 우리가 착각하면 안될 것이 dropout이라든지, 보존 확률로 입력을 나눈다든지 이런 프로세싱은 훈련 단계에서 일어나는 일이지 Test 단계에서는 그냥 입력을 다음 층으로 전달합니다.

 다음은 드롭아웃 비율 0.2를 사용하여 구성한 model입니다.

model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.Dropout(rate=0.2),
    keras.layers.Dense(300, activation="elu", kernel_initializer="he_normal"),
    keras.layers.Dropout(rate=0.2),
    keras.layers.Dense(100, activation="elu", kernel_initializer="he_normal"),
    keras.layers.Dropout(rate=0.2),
    keras.layers.Dense(10, activation="softmax")
])

Max-Norm 규제

 마지막으로 우리가 살펴볼 규제는 Max-Norm 규제입니다. 이 방식은 각 뉴런에 대해 입력의 연결 가중치 $w$가 다음과 같도록 제한합니다.

 

 Max-Norm 규제는 전체 Loss 함수에 규제 항을 추가하지 않습니다. 대신 매 훈련 스텝이 끝날때마다 $w$의 norm을 계산하여 다음고 같이 스케일을 조정합니다.

 $r$은 하이퍼 파라미터이며,  r을 줄이면 줄일 수록 w에 더 작은 값이 곱해지니 가중치가 작아질 것이고 그렇게 되면 Overfitting을 감소시키는데 도움이 될 것입니다.

 다음은 keras에서 구현한 코드입니다.

layer = keras.layers.Dense(100, activation="selu", kernel_initializer="lecun_normal",
                           kernel_constraint=keras.constraints.max_norm(1.))

다음 포스팅에서는 텐서플로우에 대해 다뤄보겠습니다. 오늘도 읽어주셔서 감사합니다. 행복한 하루 보내세요 :)

반응형