使用手动KFold-交叉验证与KerasClassifier-KFold交叉验证时的不同结果

问题描述 投票:0回答:1

我一直在努力理解为什么两个类似的Kfold-cross验证会产生两个不同的平均值。

当我使用手动的KFold方法(使用Tensorflow和Keras)时

cvscores = []
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=3)
for train, test in kfold.split(X, y):
  model = create_baseline()
  model.fit(X[train], y[train], epochs=50, batch_size=32, verbose=0)
  scores = model.evaluate(X[test], y[test], verbose=0)
  #print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
  cvscores.append(scores[1] * 100)

print("%.2f%% (+/- %.2f%%)" % (np.mean(cvscores), np.std(cvscores)))

我得到

65.89% (+/- 3.77%)

当我使用scikit中的KerasClassifier包装器时

estimator = KerasClassifier(build_fn=create_baseline, epochs=50, batch_size=32, verbose=0)
kfold = StratifiedKFold(n_splits=10,shuffle=True, random_state=3)
results = cross_val_score(estimator, X, y, cv=kfold, scoring='accuracy')
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))

我得到

63.82% (5.37%)

此外,当使用KerasClassifier时,出现以下警告

WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/wrappers/scikit_learn.py:241: Sequential.predict_classes (from tensorflow.python.keras.engine.sequential) is deprecated and will be removed after 2021-01-01.
Instructions for updating:
Please use instead:* `np.argmax(model.predict(x), axis=-1)`,   if your model does multi-class classification   (e.g. if it uses a `softmax` last-layer activation).* `(model.predict(x) > 0.5).astype("int32")`,   if your model does binary classification   (e.g. if it uses a `sigmoid` last-layer activation).

是否因为KerasClassifier使用了 预测类() 而手动的TensorflowKeras方法只用了 预测()? 如果是,哪种方法更合理?

我的模型是这样的

def create_baseline():
model = tf.keras.models.Sequential()
model.add(Dense(8, activation='relu', input_shape=(12,)))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
tensorflow keras scikit-learn neural-network cross-validation
1个回答
0
投票

两个CV结果看起来没有太大区别,它们都在彼此的标准差范围内。

您固定了种子的 StratifiedKFold 类,这很好。然而还有一个额外的随机性需要你去控制,那就是来自于 权重初始化. 确保你为每次 CV 运行用不同的权重来初始化你的模型,但对交叉验证、手动和自动使用相同的 10 个初始化。您可以通过一个 初始化器 到每一层,他们有一个 seed 参数也是如此。一般来说,你应该固定所有可能的种子 (np.random.seed(3), tf.set_random_seed(3)).

如果你运行 cross_val_score() 或你的手动版两次?你得到的结果数字一样吗?

© www.soinside.com 2019 - 2024. All rights reserved.