Dropout

 

Remarks

본 포스팅은 Hands-On Machine Learning with Scikit-Learn & TensorFlow (Auérlien Géron, 박해선(역), 한빛미디어), Srivastava, Nitish, et al. “Dropout: a simple way to prevent neural networks from overfitting.” The journal of machine learning research 15.1 (2014): 1929-1958. 등을 참고하여 작성되었습니다.


Dropout

  1. Training: Output neuron들을 제외한 모든 neuron들에 활성화되지 않을 확률($r$, dropout rate)을 할당
    $H = \sigma(XW) \quad → \quad H = \text{Bern}(\mathbf{r})⊗\sigma(XW)$
  2. Prediction: 모든 neuron을 활성화시키고 활성화되지 않은 neuron으로 인해 약화된 input 값으로 학습된 weight를 고려하여 weight에 $(1-r)$($p$, keep probability)을 곱하여 예측

{D1B527A0-7525-440D-8C5F-5C54FF5F1A3A} 1_UBPbfTBfcHfHK8kM3sGH0Q

1. Significance

  1. 특정 neuron에 학습이 집중되는 것을 방지
    → 일반화 성능 증가
  2. Training step 마다 새로운 network를 학습시키고, averaging ensemble model로 예측을 수행
    → 생성되는 model 간의 연관성이 높기 때문에 생성되는 model의 개수($2^\text{number of neurons}$)만큼의 효과는 없음

2. Practical Usage

  1. Dropout rate
    Overfitting 시, dropout rate를 증가시킴
    • MLP: 10~50%
    • CNN: 40~50%
    • RNN: 20~30%
  2. Position(?)
    • 마지막 hidden layer부터 3번째 layer까지 dropout을 적용 (일반적)
    • 마지막 hidden layer에만 dropout을 적용 (최근)

3. Monte-Carlo Dropout

3.1 Algorithm

  1. Train dropout network(dropout is applied for all layers)
  2. Get multiple predictions from model activating dropout
  3. Predict with mean of predictions

3.2 Significance

  1. Model의 uncertainty 측정가능
    자세한 내용은 What Uncertainty Do We Need in Bayesian Deep Learning for Computer Vision?과 해당 논문을 정리한 여기를 참고
  2. Model의 성능 증강

3.3 Etc

  1. 예측 시에도 강제로 학습 모드로 설정하기 때문에(training=True) 관련값에 영향을 받는 layer의 사용에 주의(BatchNormalization 등)

3.4 Code

3.4.1 training=True에 영향을 받는 layer가 있는 경우

keras.layers.BatchNormalization() 과 같은 layer는 학습과 예측에서 각각 다르게 작동하기 때문에 항상 dropout을 수행하도록 custom layer를 만들어줄 수 있다.

class MCDropout(keras.layers.Dropout):  # always training=True
    def call(self, inputs):
        return super().call(inputs, training=True)

model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]),
    keras.layers.BatchNormalization(),
    MCDropout(rate=0.2),

    keras.layers.Dense(300, kernel_initializer="he_normal"),
    keras.layers.BatchNormalization(),
    keras.layers.Activation('elu')
    MCDropout(rate=0.2),

    keras.layers.Dense(100, activation="elu", kernel_initializer="he_normal"),
    keras.layers.BatchNormalization(),
    MCDropout(rate=0.2),

    keras.layers.Dense(10, activation="softmax")
])
model.compile(..)
model.fit(..)

y_preds = [model.predict(X) for _ in range(N_MODELS)]
y_pred  = np.mean(y_preds, axis=0)

3.4.2 training=True에 영향을 받는 layer가 없는 경우

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")
])
model.compile(..)
model.fit(..)

y_preds = [model.predict(X, training=True) for _ in range(N_MODELS)]
y_pred  = np.mean(y_preds, axis=0)