Keras的交叉验证

Ali*_*asi 10 machine-learning neural-network scikit-learn cross-validation keras

我正在Keras中实现一个多层感知器并使用scikit-learn来执行交叉验证.为此,我受到了Keras交叉验证问题中的代码的启发

from sklearn.cross_validation import StratifiedKFold

def load_data():
    # load your data using this function

def create model():
    # create your model using this function

def train_and_evaluate__model(model, data[train], labels[train], data[test], labels[test)):
    # fit and evaluate here.

if __name__ == "__main__":
    X, Y = load_model()
    kFold = StratifiedKFold(n_splits=10)
    for train, test in kFold.split(X, Y):
        model = None
        model = create_model()
        train_evaluate(model, X[train], Y[train], X[test], Y[test])
Run Code Online (Sandbox Code Playgroud)

在我对神经网络的研究中,我了解到神经网络的知识表示是在突触权重和网络跟踪过程中,更新的权重,从而降低网络错误率并改善其性能.(就我而言,我正在使用监督学习)

为了更好地训练和评估神经网络性能,一种常用的方法是交叉验证,它返回数据集的分区,用于训练和评估模型.

我怀疑是......

在此代码段中:

for train, test in kFold.split(X, Y):
    model = None
    model = create_model()
    train_evaluate(model, X[train], Y[train], X[test], Y[test])
Run Code Online (Sandbox Code Playgroud)

我们为每个生成的分区定义,训练和评估一个新的神经网络?

如果我的目标是为整个数据集微调网络,为什么定义单个神经网络并使用生成的分区对其进行训练是不正确的?

也就是说,为什么这段代码是这样的?

for train, test in kFold.split(X, Y):
    model = None
    model = create_model()
    train_evaluate(model, X[train], Y[train], X[test], Y[test])
Run Code Online (Sandbox Code Playgroud)

而不是这样?

model = None
model = create_model()
for train, test in kFold.split(X, Y):
    train_evaluate(model, X[train], Y[train], X[test], Y[test])
Run Code Online (Sandbox Code Playgroud)

我对代码如何工作错误的理解是什么?还是我的理论?

谢谢!

des*_*aut 9

如果我的目标是为整个数据集微调网络

目前尚不清楚您所说的“微调”是什么意思,甚至不清楚您执行交叉验证(CV)的目的是什么;通常,简历具有以下目的之一:

  • 模型选择(选择超参数的值)
  • 模型评估

由于您没有在代码中为超参数选择定义任何搜索网格,因此您似乎在使用CV来获得模型的预期性能(误差,准确性等)。

无论如何,无论出于何种原因使用CV,第一个代码段都是正确的。你的第二个片段

model = None
model = create_model()
for train, test in kFold.split(X, Y):
    train_evaluate(model, X[train], Y[train], X[test], Y[test])
Run Code Online (Sandbox Code Playgroud)

将在不同的分区上依次训练您的模型(即在分区#1上训练,然后在分区#2上继续训练,依此类推),这实际上只是对您的整个数据集进行训练,并且肯定不是交叉验证...

就是说,通常仅隐含在CV 之后的最后一步(通常是初学者经常遗漏的)是,对CV程序给出的选择的超参数和/或模型性能满意后,您可以返回并再次训练您的模型,这次包含所有可用数据。


Meg*_*ron 6

您可以将 Scikit-Learn API 的包装器与 Keras 模型结合使用。

给定输入xy,这是一个重复 5 折交叉验证的示例:

from sklearn.model_selection import RepeatedKFold, cross_val_score
from tensorflow.keras.models import * 
from tensorflow.keras.layers import * 
from tensorflow.keras.wrappers.scikit_learn import KerasRegressor

def buildmodel():
    model= Sequential([
        Dense(10, activation="relu"),
        Dense(5, activation="relu"),
        Dense(1)
    ])
    model.compile(optimizer='adam', loss='mse', metrics=['mse'])
    return(model)

estimator= KerasRegressor(build_fn=buildmodel, epochs=100, batch_size=10, verbose=0)
kfold= RepeatedKFold(n_splits=5, n_repeats=100)
results= cross_val_score(estimator, x, y, cv=kfold, n_jobs=2)  # 2 cpus
results.mean()  # Mean MSE
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。我用“KerasClassifier”“准确性”替换。已投赞成票。 (2认同)
  • KerasRegressor 已弃用。它建议改用 Sci-Keras (https://github.com/adriangb/scikeras)。 (2认同)

小智 5

我认为如果您阅读有关嵌套交叉验证的内容,您的许多问题都会得到解答。这是“微调”模型超参数的好方法。这里有一个线程:

https://stats.stackexchange.com/questions/65128/nested-cross-validation-for-model-selection

要注意的最大问题是“偷看”或循环逻辑。本质上 - 您希望确保在训练期间看不到用于评估模型准确性的任何数据

这可能会出现问题的一个例子是,如果您正在运行 PCA 或 ICA 之类的工具来进行特征提取。如果执行此类操作,您必须确保在训练集上运行 PCA,然后将训练集的转换矩阵应用到测试集。