keras batchnorm 的测试性能很差
keras batchnorm has awful test performance
在对训练数据进行交叉验证时,batchnorm 的使用显着提高了性能。但是(在对整个训练集进行再训练之后)batchnorm 层的存在完全破坏了模型对 holdout 集的泛化。这有点令人惊讶,我想知道我是否错误地实施了测试预测。
泛化 w/o 存在的 batchnorm 层很好(对于我的项目目标来说不够高,但对于这样一个简单的网络来说是合理的)。
我无法分享我的数据,但有人看到明显的实施错误吗?是否有应设置为测试模式的标志?我在文档中找不到答案,dropout(也应该有不同的 train/test 行为)按预期工作。谢谢!
代码:
from keras.callbacks import EarlyStopping
early_stopping = EarlyStopping(monitor='val_loss', patience=10)
from keras.callbacks import ModelCheckpoint
filepath="L1_batch1_weights.best.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True, mode='auto')
init = 'he_normal'
act = 'relu'
neurons1 = 80
dropout_rate = 0.5
model = Sequential()
model.add(Dropout(0.2, input_shape=(5000,)))
model.add(Dense(neurons1))
model.add(BatchNormalization())
model.add(Activation(act))
model.add(Dropout(dropout_rate))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer="adam", metrics=["accuracy"])
my_model = model.fit(X_train, y_train, batch_size=128, nb_epoch=150, validation_data =(X_test, y_test),callbacks=[early_stopping, checkpoint])
model.load_weights("L1_batch1_weights.best.hdf5")
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print("Created model and loaded weights from file")
probs = model.predict_proba(X_test,batch_size=2925)
fpr, tpr, thresholds = roc_curve(y_test, probs)
来自 docs:"During training we use per-batch statistics to normalize the data, and during testing we use running averages computed during the training phase."
在我的案例中,训练批量大小为 128。在测试时,我手动将批量大小设置为完整测试集的大小 (2925)。
用于一个批次大小的统计数据显然与明显不同的批次大小无关。
将测试批量大小更改为训练批量大小 (128) 会产生更稳定的结果。我玩了 w/prediction 批量大小来观察效果:对于任何批量大小 +/- 3 倍的训练批量大小,预测结果都是稳定的,超出该性能会恶化。
此处讨论了与 load_weights() 一起使用时测试批量大小以及使用 batchnorm 的影响:
https://github.com/fchollet/keras/issues/3423
在对训练数据进行交叉验证时,batchnorm 的使用显着提高了性能。但是(在对整个训练集进行再训练之后)batchnorm 层的存在完全破坏了模型对 holdout 集的泛化。这有点令人惊讶,我想知道我是否错误地实施了测试预测。
泛化 w/o 存在的 batchnorm 层很好(对于我的项目目标来说不够高,但对于这样一个简单的网络来说是合理的)。
我无法分享我的数据,但有人看到明显的实施错误吗?是否有应设置为测试模式的标志?我在文档中找不到答案,dropout(也应该有不同的 train/test 行为)按预期工作。谢谢!
代码:
from keras.callbacks import EarlyStopping
early_stopping = EarlyStopping(monitor='val_loss', patience=10)
from keras.callbacks import ModelCheckpoint
filepath="L1_batch1_weights.best.hdf5"
checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True, mode='auto')
init = 'he_normal'
act = 'relu'
neurons1 = 80
dropout_rate = 0.5
model = Sequential()
model.add(Dropout(0.2, input_shape=(5000,)))
model.add(Dense(neurons1))
model.add(BatchNormalization())
model.add(Activation(act))
model.add(Dropout(dropout_rate))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer="adam", metrics=["accuracy"])
my_model = model.fit(X_train, y_train, batch_size=128, nb_epoch=150, validation_data =(X_test, y_test),callbacks=[early_stopping, checkpoint])
model.load_weights("L1_batch1_weights.best.hdf5")
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print("Created model and loaded weights from file")
probs = model.predict_proba(X_test,batch_size=2925)
fpr, tpr, thresholds = roc_curve(y_test, probs)
来自 docs:"During training we use per-batch statistics to normalize the data, and during testing we use running averages computed during the training phase."
在我的案例中,训练批量大小为 128。在测试时,我手动将批量大小设置为完整测试集的大小 (2925)。
用于一个批次大小的统计数据显然与明显不同的批次大小无关。
将测试批量大小更改为训练批量大小 (128) 会产生更稳定的结果。我玩了 w/prediction 批量大小来观察效果:对于任何批量大小 +/- 3 倍的训练批量大小,预测结果都是稳定的,超出该性能会恶化。
此处讨论了与 load_weights() 一起使用时测试批量大小以及使用 batchnorm 的影响: https://github.com/fchollet/keras/issues/3423