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
- Training: Output neuron들을 제외한 모든 neuron들에 활성화되지 않을 확률($r$, dropout rate)을 할당
$H = \sigma(XW) \quad → \quad H = \text{Bern}(\mathbf{r})⊗\sigma(XW)$ - Prediction: 모든 neuron을 활성화시키고 활성화되지 않은 neuron으로 인해 약화된 input 값으로 학습된 weight를 고려하여 weight에 $(1-r)$($p$, keep probability)을 곱하여 예측
1. Significance
- 특정 neuron에 학습이 집중되는 것을 방지
→ 일반화 성능 증가 - Training step 마다 새로운 network를 학습시키고, averaging ensemble model로 예측을 수행
→ 생성되는 model 간의 연관성이 높기 때문에 생성되는 model의 개수($2^\text{number of neurons}$)만큼의 효과는 없음
2. Practical Usage
- Dropout rate
Overfitting 시, dropout rate를 증가시킴- MLP: 10~50%
- CNN: 40~50%
- RNN: 20~30%
- Position(?)
- 마지막 hidden layer부터 3번째 layer까지 dropout을 적용 (일반적)
- 마지막 hidden layer에만 dropout을 적용 (최근)
3. Monte-Carlo Dropout
3.1 Algorithm
- Train dropout network(dropout is applied for all layers)
- Get multiple predictions from model activating dropout
- Predict with mean of predictions
3.2 Significance
- Model의 uncertainty 측정가능
자세한 내용은 What Uncertainty Do We Need in Bayesian Deep Learning for Computer Vision?과 해당 논문을 정리한 여기를 참고 - Model의 성능 증강
3.3 Etc
- 예측 시에도 강제로 학습 모드로 설정하기 때문에(
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)
PREVIOUSEtc