在 Python 中将 Keras 深度学习模型与 Scikit-Learn 结合使用

Keras是Python中最受欢迎的深度学习库之一,因其简洁和易用性而广泛应用于研究和开发。

Scikit-learn库是Python中最流行的通用机器学习库。

在这篇文章中,您将了解如何将Keras的深度学习模型与Python中的scikit-learn库一起使用。

这将使您能够利用scikit-learn库的强大功能来执行诸如模型评估和模型超参数优化之类的任务。

开始您的项目,阅读我的新书《Python深度学习》,其中包括分步教程和所有示例的Python源代码文件。

让我们开始吧。

  • 2016年5月:原始帖子
  • 2016年10月更新:为Keras 1.1.0和scikit-learn v0.18更新了示例。
  • 2017年1月更新:修复了网格搜索结果打印中的一个错误。
  • 2017 年 3 月更新:针对 Keras 2.0.2、TensorFlow 1.0.1 和 Theano 0.9.0 更新了示例。
  • **2018 年 3 月更新**:添加了下载数据集的备用链接,因为原始链接似乎已被删除。
  • 2022年6月更新:为TensorFlow 2.x和SciKeras更新了代码。
Use Keras Deep Learning Models with Scikit-Learn in Python

在Python中使用Keras深度学习模型与scikit-learn
照片作者:Alan Levine,保留部分权利。

概述

Keras是Python中流行的深度学习库,但该库的重点是深度学习模型。事实上,它力求简洁,只关注您快速、简单地定义和构建深度学习模型所需的内容。

Python中的scikit-learn库建立在SciPy堆栈之上,用于高效的数值计算。它是一个功能齐全的通用机器学习库,并在开发深度学习模型方面提供了许多有用的实用程序。其中最重要的是

  • 使用重采样方法(如k折交叉验证)评估模型
  • 模型超参数的高效搜索和评估

曾经有一个TensorFlow/Keras库中的包装器,可以将深度学习模型用作scikit-learn中的分类或回归估计器。但最近,这个包装器被移出,成为一个独立的Python模块。

在接下来的部分中,您将通过示例学习如何使用KerasClassifier包装器来处理在Keras中创建并在scikit-learn库中使用的分类神经网络。

测试问题是Pima印第安人糖尿病发病分类数据集。这是一个小数据集,所有属性都是数值型的,易于处理。下载数据集并将其放在当前工作目录中,文件名为pima-indians-diabetes.csv (更新:从此处下载)。

以下示例假定您已成功安装TensorFlow 2.x、SciKeras和scikit-learn。如果您使用pip系统来管理Python模块,则可以使用以下命令安装它们:

Python 深度学习需要帮助吗?

参加我的免费为期两周的电子邮件课程,发现 MLP、CNN 和 LSTM(附代码)。

立即点击注册,还将免费获得本课程的 PDF 电子书版本。

使用交叉验证评估深度学习模型

SciKeras中的KerasClassifier和KerasRegressor类接受一个名为model的参数,该参数是要调用的用于获取模型的函数名称。

您必须定义一个函数(名称随意),该函数定义模型、编译模型并返回模型。

在下面的示例中,您将定义一个名为create_model()的函数,该函数为问题创建一个简单的多层神经网络。

您通过model参数将此函数名称传递给KerasClassifier类。您还传递了额外的参数nb_epoch=150batch_size=10。这些参数会自动打包并传递给fit()函数,该函数由KerasClassifier类在内部调用。

在此示例中,您将使用scikit-learn的StratifiedKFold执行10折分层交叉验证。这是一种重采样技术,可以提供对机器学习模型在未见过数据上性能的稳健估计。

接下来,使用scikit-learn函数cross_val_score()通过交叉验证方案评估您的模型并打印结果。

注意:您的结果可能有所不同,这取决于算法或评估程序的随机性,或者数值精度的差异。请尝试运行示例几次,并比较平均结果。

运行该示例将显示模型每个时期的性能。总共创建和评估了10个模型,并显示了最终的平均准确率。

相比之下,以下是使用scikit-learn中的神经网络模型的等效实现:

KerasClassifier的作用是作为一个适配器,使Keras模型能够像scikit-learn的MLPClassifier对象一样工作。

网格搜索深度学习模型参数

前面的示例展示了如何轻松地包装Keras的深度学习模型并在scikit-learn库的函数中使用它。

在这个例子中,您将更进一步。您在创建KerasClassifier包装器时传递给model参数的函数可以接受参数。您可以使用这些参数来进一步定制模型的构建。此外,您知道可以向fit()函数提供参数。

在这个例子中,您将使用网格搜索来评估您的神经网络模型的不同配置,并报告能提供最佳估计性能的组合。

create_model()函数被定义为接受两个参数:optimizerinit,两者都必须有默认值。这将允许您评估使用不同的优化算法和权重初始化方案对网络的影响。

在创建模型之后,定义您希望搜索的参数值的数组,特别是:

  • 用于搜索不同权重值的优化器
  • 用于使用不同方案准备网络权重的初始化器
  • 用于在不同数量的训练数据集暴露下训练模型的时期数
  • 用于在权重更新之前改变样本数量的批次大小

选项被指定在一个字典中,并传递给GridSearchCV scikit-learn类的配置。该类将评估您的神经网络模型的一个版本,针对每个参数组合(优化器、初始化、时期和批次的组合为2 x 3 x 3 x 3)。然后,使用默认的3折分层交叉验证来评估每个组合。

这涉及到大量的模型和大量的计算。由于所需时间,您不应该轻易使用这种方案。对于您来说,设计小规模的实验,使用较小的数据子集,以便在合理的时间内完成,可能会很有用。在这种情况下,这是合理的,因为网络和数据集都比较小(不到1000个实例和九个属性)。

最后,将显示最佳模型的性能和配置组合,然后是所有参数组合的性能。

请注意,在字典param_grid中,model__init被用作我们create_model()函数的init参数的键。前缀model__对于SciKeras中的KerasClassifier模型是必需的,以便提供自定义参数。

在CPU(而不是GPU)上执行时,这可能需要大约5分钟才能在您的工作站上完成。运行该示例显示了下面的结果。

注意:您的结果可能有所不同,这取决于算法或评估程序的随机性,或者数值精度的差异。请尝试运行示例几次,并比较平均结果。

您可以看到,网格搜索发现,使用均匀初始化方案、rmsprop优化器、150个时期和10个批次大小,在此问题上实现了最佳交叉验证分数,约为77%。

有关使用Keras进行超参数调优的更完整示例,请参阅教程

总结

在这篇文章中,您学习了如何包装Keras深度学习模型并在scikit-learn通用机器学习库中使用它们。

您可以看到,使用scikit-learn执行模型评估和模型超参数优化等标准机器学习操作,可以比自己实现这些方案节省大量时间。

包装您的模型使您能够利用scikit-learn的强大工具,将深度学习模型融入到您的通用机器学习流程中。

您对在scikit-learn中使用Keras模型或对本文有任何疑问吗?请在评论中提出您的问题,我将尽力回答。

254条对在Python中使用Keras深度学习模型与Scikit-Learn的回复

  1. Shruthi 2016年6月2日 上午6:38 #

    首先,这非常有帮助。非常感谢。

    我是keras的新手,我一直在尝试优化其他参数,如dropout和隐藏单元的数量。网格搜索可以处理您示例中列出的参数。但是,当我尝试优化dropout时,代码会报错,说它不是一个合法的参数名。我原以为指定create_model()函数中的名称就足够了;显然,我错了。

    简而言之:如果我必须使用GridSearchCV来优化dropout,那么修改您的代码会是什么样子?

    如果我的问题很愚蠢,请原谅,我正在同时学习keras、python和深度学习。谢谢!

    Shruthi

    • Jason Brownlee 2016年6月23日 上午10:20 #

      很好的问题。

      正如您所说,您只需向create_model()函数添加一个名为dropout_rate的新参数,然后在创建dropout层时使用该参数。

      下面是一个在Keras中网格搜索dropout值的示例:

      运行示例会产生以下输出:

      希望这有帮助

  2. Rish 2016年6月22日晚上10:01 #

    嗨,Jason,

    感谢您的帖子,这太棒了。我发现网格搜索非常有帮助。

    一个快速的问题:有没有办法将提前停止纳入网格搜索?对于我正在玩的一个特定模型,我发现它经常会过度拟合,因此我的验证损失会受到影响。虽然我可以在我的示例中包含一系列 epoch 参数(如您的示例),但如果它仅仅在少量 epoch 中停止而验证准确性增加,似乎更有效。除非您有更好的想法?

    再次感谢!

    • Jason Brownlee 2016年6月23日早上5:30 #

      Rish,很棒的评论,而且是个很好的想法。

      我不认为 scikit-learn 支持在其参数搜索中提前停止。您需要自己进行参数搜索并添加提前停止子句,或者考虑修改 sklearn 本身。

      我还想知道您是否可以挂钩 Keras 的检查点功能,并将最佳参数组合捕获到文件中(检查点回调),并允许您随时停止搜索。

      • Rish 2016年7月19日中午12:06 #

        感谢您的回复!🙂 我也这么想!

        • Vadim 2017年3月13日早上8:16 #

          嗨,Jason,

          很棒的文章。您是否偶然发现将回调函数挂钩到网格搜索的方法?在这种情况下,Tensorboard 可以聚合和可视化网格搜索结果。

          • Thanin Wangveerathananon 2019年10月25日晚上7:37 #

            这将是理想用例。是否有关于此用例的任何示例?

  3. Rishabh 2016年8月17日凌晨3:13 #

    嗨,Jason,

    很棒的文章。谢谢。

    我一直面临的一个问题是深度学习模型的训练(即使在 H2O 中也是如此),那就是预测概率分布总是平坦的(即跨样本的概率变化非常小)。任何其他 ML 模型,例如 RF/GBM,都更容易调整,并且在大多数情况下都能取得良好的结果。所以我的疑问是双重的

    1. 除了例如图像数据 CNN 可能是一个不错的选择外,在什么情况下我们应该尝试拟合深度学习模型。
    2. 我认为我遇到的深度学习模型问题通常是由于欠拟合。您能否提供一些关于如何调整深度学习模型(其他 ML 模型更容易调整)的技巧?

    谢谢

    • Jason Brownlee 2016年8月17日早上9:53 #

      深度学习非常适合原始数据,如图像、文本、音频和类似数据。它可以处理复杂的表格数据,但在实践中,特征工程加上 xgboost 通常效果更好。

      继续添加层/神经元(容量)并训练更长时间,直到性能趋于平稳。

      • Rishabh 2016年8月17日晚上7:51 #

        谢谢。我会尝试添加更多层并添加一些正则化参数。

        • Jason Brownlee 2016年8月18日早上7:16 #

          祝你好运 Rishabh,让我知道你的进展。

          • Rishabh 2016年9月10日晚上11:26 #

            Jason,得益于您的帖子,我能够调整模型,尽管 GBM 的拟合效果更好。我包含了 prelu 层,这改善了拟合。

            一个问题是,是否有最佳方法来查找隐藏神经元数量和隐藏层数量,还是网格搜索是唯一的选择?

          • Jason Brownlee 2016年9月12日早上8:27 #

            Rishabh,调整(网格/随机)是我所知道的最佳选项。

          • Rishabh 2016年9月12日晚上5:03 #

            谢谢。网格搜索对我的 16GB 笔记本电脑来说负担太重了,因此我正在寻找一种最佳方法。

          • Jason Brownlee 2016年9月13日早上8:10 #

            这确实很痛苦。小的网格对内存更友好。

          • Kouame 2025年2月10日早上9:41 #

            pip install pandas numpy tensorflow scikit-learn matplotlibimport pandas as pd
            import numpy as np
            import tensorflow as tf
            from tensorflow.keras.models import Sequential
            from tensorflow.keras.layers import LSTM, Dense, Dropout
            from sklearn.preprocessing import MinMaxScaler
            from datetime import datetime, timedelta
            import matplotlib.pyplot as plt

            # 加载数据(替换为真实 CSV 文件)
            data = pd.read_csv(“lucky_jet_data.csv”)

            # 将时间列转换为 datetime
            data[“time”] = pd.to_datetime(data[“time”])

            # 将时间转换为自开始以来的经过秒数
            start_time = data[“time”].min()
            data[“seconds_since_start”] = (data[“time”] – start_time).dt.total_seconds()

            # 数据归一化
            缩放器 = MinMaxScaler()
            data_scaled = scaler.fit_transform(data[[“previous_crash”, “crash_value”, “seconds_since_start”]])

            # 为 LSTM 创建序列(使用前 10 个部分预测下一个)
            sequence_length = 10
            X, y_crash, y_time = [], [], []

            for i in range(len(data_scaled) – sequence_length)
            X.append(data_scaled[i:i+sequence_length, :]) # 最后 10 个输入
            y_crash.append(data_scaled[i + sequence_length, 1]) # 目标崩溃值
            y_time.append(data_scaled[i + sequence_length, 2]) # 目标时间

            X, y_crash, y_time = np.array(X), np.array(y_crash), np.array(y_time)

            # 将数据分为训练/测试集
            split = int(0.8 * len(X))
            X_train, X_test = X[:split], X[split:]
            y_train_crash, y_test_crash = y_crash[:split], y_crash[split:]
            y_train_time, y_test_time = y_time[:split], y_time[split:]# 定义 LSTM 模型
            模型 = 序列([
            LSTM(50, return_sequences=True, input_shape=(sequence_length, 3)),
            Dropout(0.2),
            LSTM(50, return_sequences=False),
            Dropout(0.2),
            Dense(25, activation=’relu’),
            Dense(2) # 预测两个值:[崩溃值, 时间]
            ])

            # 编译模型
            model.compile(optimizer=”adam”, loss=”mse”)
            model.summary()

            # 训练模型
            history = model.fit(X_train, np.column_stack((y_train_crash, y_train_time)), epochs=50, batch_size=32, validation_data=(X_test, np.column_stack((y_test_crash, y_test_time))))# 使用模型进行预测
            prediction_scaled = model.predict(X_test)

            # 将归一化值转换回实际值
            pred_crash = scaler.inverse_transform(np.column_stack((np.zeros(len(prediction_scaled)), prediction_scaled[:, 0], prediction_scaled[:, 1])))[:, 1]
            pred_time = scaler.inverse_transform(np.column_stack((np.zeros(len(prediction_scaled)), prediction_scaled[:, 0], prediction_scaled[:, 1])))[:, 2]

            # 将秒转换为可读时间
            predicted_time = [start_time + timedelta(seconds=s) for s in pred_time]

            # 显示一个随机预测
            index = np.random.randint(0, len(pred_crash))
            print(f”📌 下一个崩溃值预测: {pred_crash[index]:.2f}”)
            print(f”🕒 预计出现时间: {predicted_time[index].strftime(‘%H:%M:%S’)}”)

          • James Carmichael 2025年2月11日早上8:52 #

            你好 Kouame…你对内容有什么疑问吗?

  4. xiao 2016年9月17日晚上10:59 #

    嗨,Jason,
    感谢您的帖子。我是 Keras 的初学者,最近在使用 Keras 和 sk-learn 时遇到了一些问题。如果方便的话,您能帮我个忙吗?

    详情见此
    http://stackoverflow.com/questions/39467496/error-when-using-keras-sk-learn-api

    谢谢!!!

    • Jason Brownlee 2016年9月18日早上8:01 #

      唉。Xiao,抱歉,我没什么头绪。

      我会通过将其缩减到产生问题的最简单的网络/代码,然后找到导致问题的行,并以此为基础进行调试。

      如果您需要快速得出结果,我会使用相同的分解方法来快速找到解决方法。

      告诉我进展如何。

      • xiao 2016年9月18日早上10:43 #

        非常感谢,Jason。
        如果可能,我需要快速得出结果。

      • xiao 2016年9月21日中午12:22 #

        Jason,您有什么想法吗?

        • Jason Brownlee 2016年9月22日早上8:06 #

          是的,我在前面的评论 Xiao 中给出了您调试问题的方法。

          抱歉,我不知道更多了。

          • xiao 2016年9月22日晚上4:52 #

            谢谢,我会试试的。

  5. Josh 2016年9月22日凌晨12:12 #

    Jason,感谢您的教程,它为我节省了很多时间。我正在从 shell 文件在远程服务器上运行大量数据。模型的输出被写入另一个 shell 文件,以防出现错误。但是,当我按照您上面介绍的方法运行代码时,它会输出训练状态,即每个网格搜索模型的 epoch 号和准确性。有没有办法抑制此输出?我尝试将“verbose=0”作为附加参数传递给“fit”调用(这会产生一个错误)和 GridsearchCV(什么都没做)。

    谢谢

    • Jason Brownlee 2016年9月22日早上8:17 #

      好问题 Josh。

      将 verbose=0 传递给分类器的构造函数

  6. Tom 2016年10月5日晚上9:09 #

    你好 Jason,
    首先,非常感谢您的 Keras 和深度学习的指南和示例!请继续!🙂
    问题 1
    是否有可能使用网格保存最佳训练模型并设置一些回调(例如提前停止)?我想通过这样做来实现保存最佳模型
    checkpoint=ModelCheckpoint(filepath, monitor=’val_acc’, verbose=0, save_best_only=True, mode=’max’)
    grid_result = grid.fit(X, Y, callbacks=[checkpoint])
    但 TypeError: fit() got an unexpected keyword argument ‘callbacks’
    问题 2
    有没有办法可视化训练好的权重并真正看到创建的网络?我想让神经网络更实用,而不仅仅是分类。我知道您可以绘制模型:plot(model, to_file=’model.png’),但我想将我的数据集成到这个模型中。
    提前感谢,
    汤姆

    • Jason Brownlee 2016年10月6日早上9:37 #

      你好 Tom,我很高兴您觉得我的材料有价值。

      抱歉,我对网格搜索中的回调函数不太了解。听起来它可能会造成很大的混乱(即,不是为此设计的)。

      我不知道有内置的可视化权重的方法。我个人喜欢查看生产模型的权重,看看是否有任何疯狂的事情发生——但只是原始数字。

      • David 2017年8月22日下午4:46 #

        嗨,Jason,
        感谢这篇写得非常好的文章!非常清晰易懂。
        我有一个回调函数,可以进行不同类型的学习率退火。它有四个参数我想优化。
        根据您上面的评论,我猜 SciKit 包装器无法用于优化此参数?
        您知道我该如何做到这一点吗?
        非常感谢您的帮助。
        大卫

        • Jason Brownlee 2017年8月23日早上6:41 #

          您可能需要自己写一个 for 循环 David。事实上,我推荐这样做,以获得经验和控制。

  7. Soren Pallesen 2016年10月18日下午5:08 #

    你好,感谢您的所有启发。在运行上面的示例时,我得到的结果略有不同

    最佳:0.751302 使用 {‘optimizer’: ‘rmsprop’, ‘batch_size’: 5, ‘init’: ‘normal’, ‘nb_epoch’: 150}

    即 init:normal 而不是您示例中的 uniform。

    这些变化是正常的吗?

    • Jason Brownlee 2016年10月19日早上9:16 #

      你好 Soren,

      结果可能因初始化方法而异。很难预测它们在给定问题上的变化程度。

  8. Saddam 2016年12月15日晚上9:20 #

    嘿,我遇到了一个错误“ValueError: init is not a legal parameter”。
    代码如下。
    init = [‘glorot_uniform’, ‘normal’, ‘uniform’]
    batches = numpy.array([50, 100, 150])
    param_grid = dict(init=init)
    print(str(self.model_comp.get_params()))
    grid = GridSearchCV(estimator=self.model_comp, param_grid=param_grid)
    grid_result = grid.fit(X_train, Y_train)

    我找不到我哪里做错了。请帮帮我。

    • Jason Brownlee 2016年12月16日早上5:41 #

      抱歉 Saddam,原因并不明显。

      也许可以发布更多错误消息,或者考虑在 stack overflow 上发布问题?

      • Palash Goyal 2017年1月15日晚上11:36 #

        Hi Saddam and Jason,

        错误是由于 init 参数 ‘glorot_uniform’ 引起的。
        看来它已经被弃用或有什么原因,一旦您将其从可能的值中删除(即 init=[‘uniform’,’normal’]),您的代码就会运行。

        谢谢

    • Fareed 2018年2月8日晚上11:27 #

      检查您是否已将“init”定义为函数中的参数。如果尚未将其定义为参数,请在函数中定义它。完成后,当您创建 KerasClassifier 实例并在 GRidSearchCV() 中调用它时,它不会抛出错误。

  9. Tameru 2016年12月21日早上9:44 #

    嗨,Jason,

    最近,我尝试对图像分类问题使用 K-fold 交叉验证,并遇到了以下错误

    训练图像 X 形状 = (2041,64,64)
    标签 y 形状 = (2041,2)

    代码

    model = KerasClassifier(build_fn=creat_model, nb_epoch=15, batch_size=10, verbose=0)

    # 使用 6 折交叉验证进行评估

    kfold = StratifiedKFold(n_splits=6, shuffle=False, random_state=seed)

    results = cross_val_score(model, x, y, cv=kfold)

    print results

    print ‘Mean=’,

    print(results.mean())

    一个错误

    IndexError Traceback (最近一次调用)
    in ()
    2 # 使用 6 折交叉验证进行评估
    3 kfold = StratifiedKFold(n_splits=6, shuffle=False, random_state=seed)
    —-> 4 results = cross_val_score(model, x, y, cv=kfold)
    5 print results
    6 print ‘Mean=’,

    IndexError: 数组索引过多

    我不明白这里哪里出错了?
    谢谢,

    • Jason Brownlee 2016年12月22日早上6:29 #

      抱歉 Tameru,我以前没见过这个错误。也许试试 stack overflow?

    • coyan 2017年1月5日晚上6:50 #

      嗨,我遇到了同样的问题。您有什么简单的解决方法吗?

      谢谢!

      • Jason Brownlee 2017年1月6日早上9:07 #

        听起来可能是一个数据问题。

        也许您的数据在每个类别中的观测值不足以分成 6 组?

        想法
        – 尝试不同的 k 值。
        – 尝试使用 KFold 而不是 StratifiedKFild
        – 尝试训练/测试拆分

        • Tameru 2017年1月8日早上7:04 #

          @ Coyan,我仍在尝试解决它。我们试试 Jason 的建议。谢谢,Jason。

    • JiaMingLin 2017年1月20日晚上8:47 #

      我也遇到了这个问题,我猜 scikit-learn 的 k-fold 函数不接受“one hot”向量。您可能可以尝试 StratifiedShuffleSplit 和“one hot”向量列表。

      这意味着您只能在二元分类问题中评估 Keras 模型。

  10. Ali 2017年1月15日晚上7:52 #

    亲爱的布朗利博士,

    您的结果约为 75%。我用我的数据进行的实验结果约为 85%。这算是好结果吗?

    因为 DNN 和 RNN 以其出色的性能而闻名。我想知道这是否正常以及如何改进结果。

    此致,

  11. Miriam 2017年2月3日凌晨1:01 #

    嗨,Jason,

    我无法告诉您我的教程在节省我理解 Keras 的时间方面有多么棒,

    但是,我在训练、验证和测试方面遇到了概念上的障碍。我最初的理解是,将 Keras 封装在 Gridsearch 中有助于我调整超参数。因此,使用 GridsearchCV,没有单独的训练集和验证集。我可以接受这一点,因为任何 CV 都是如此。

    但是,我想使用 Keras 来预测优化超参数的模型上的结果。我看到的每个模型.fit/model.evaluate 的示例都使用 validation_data(或 validation_split)参数,我理解我们正在使用测试集作为验证集——这是一个真正的禁忌。

    请参阅 https://github.com/fchollet/keras/issues/1753 了解对此的讨论以及我不是唯一一个感到困惑的证明。

    所以我的问题是:在完成您那些很棒的菜谱(新手指南)后,当我找到了所有超参数后,我该如何运行我的测试数据?

    如果我使用 model.fit,测试数据是否会被非法用于重新训练?validation_data 或 _split 参数在 Keras 的 model.fit 中到底发生了什么???

    • Jason Brownlee 2017年2月3日早上10:05 #

      你好 Miriam,

      通常,您可以保留一个单独的验证集来评估最终模型和一组参数。这是推荐的做法。

      可以使用合适的重采样方法(带有重复的 k-fold 交叉验证)在相同的测试集上执行模型选择和调优。理想情况下,应为算法选择和参数选择使用不同的数据集,但这通常成本太高(在可用数据方面)。

  12. wenger 2017年3月6日下午5:12 #

    我遵循了步骤,但出现了错误

    ValueError: optimizer is not a legal parameter

    我不知道如何处理它。

    • Jason Brownlee 2017年3月7日早上9:35 #

      抱歉听到这个 wenger。也许可以确认您安装了最新版本的 Keras 和 sklearn?

      • Pedro Cadahia 2018年2月5日晚上9:19 #

        嗨 wenger,这个错误是由下面所示示例中的编码错误引起的。您应该更改函数并为其传递一个名为 optimizer 的参数,如下所示 create_model(optimizer),并且在同一个函数中,您必须编辑模型编译并更改固定的优化器,如果您想进行网格搜索,这是错误的……因此一个好的解决方案是更改 ‘adam’ 并再次写入 ‘optimizer=optimizer’,通过这样做,您将能够再次运行代码并找到最佳的求解器。

        祝您深度学习愉快!

    • Xian Jing 2018年2月2日凌晨12:11 #

      我遇到了你的问题,我发现你可能没有将优化器传递给模型函数。

  13. myk 2017年3月31日晚上9:25 #

    你好,如何使用 scikit 库和 Keras 实现 SVM 机器学习算法?

    • Jason Brownlee 2017年4月1日 上午5:54 #

      Keras 用于深度学习,而不是 SVM。你只需要 sklearn。

  14. Ronen 2017年4月3日 下午10:02 #

    嗨,Jason,

    一如既往,信息丰富且文笔娴熟的帖子。

    面对极度不平衡的数据集,如何在上面的示例中进行管道下采样预处理步骤?

    谢谢!

  15. Jens 2017年4月16日 上午6:54 #

    嗨,Jason,

    我为我的项目试用了你的代码,遇到一个问题,在使用管道(即使没有标准化)时,我得到了不同的结果。
    我也在 crossvalidated 上发布了这个问题
    https://stats.stackexchange.com/questions/273911/different-results-for-keras-sklearn-wrapper-with-and-without-use-of-pipline

    你能帮我解决这个问题吗?
    谢谢你

  16. Carlton banks 2017年4月30日 上午11:15 #

    你能提供一个使用数据生成器和 fit_generator 的示例吗?

  17. Anni 2017年5月3日 下午7:59 #

    嗨,Jason,

    感谢这篇帖子,太棒了。但我遇到了

    ValueError: Can’t handle mix of multilabel-indicator and binary

    当我将 scoring 函数设置为 precision、recall 或 f1 进行交叉验证时。但如果我不设置 scoring 函数,就像你做的那样,它就能正常工作。你有什么简单的解决方法吗?

    非常感谢!

    这是代码:
    scores2=cross_val_score(model, X_train.as_matrix(), y_train, cv=10, scoring=’precision’)

    • Jason Brownlee 2017年5月4日 上午8:06 #

      这是否发生在本次教程中使用的数据集上?

      • Anni 2017年5月5日 上午4:57 #

        不,实际上是发生在 UCI 机器学习的乳腺癌数据集上。我使用 train_test_split 将数据分成训练集和测试集。但当我尝试拟合模型时,我得到了

        IndexError: indices are out-of-bounds.

        所以我尝试修改 y_train,使用了以下代码:

        y_train = np_utils.to_categorical(y_train)

        你有什么想法吗?我尝试了一周都无法解决这个问题。

        • Jason Brownlee 2017年5月5日 上午7:34 #

          我相信该数据集中的所有变量都是分类变量。

          我预计您需要对每个变量使用整数编码和独热编码。

          • Anni 2017年5月5日 下午10:24 #

            好的,我会尝试您的建议。感谢您的回复 🙂

    • cass 2018年7月30日 上午8:01 #

      嘿 Anni,

      你解决了吗?我有点困惑,因为神经网络的输出是概率,它不能直接得到像精确率和召回率这样的指标……

  18. Edward 2017年5月12日 上午7:24 #

    Jason,深度学习中有类似 xgboost 的 feature_importance 吗?
    对于图像来说,这没有意义,但在这种情况下它可能很重要。

    • Jason Brownlee 2017年5月12日 上午7:52 #

      可能有,但我不知道。

      你可以在 RFE(递归特征消除)过程中使用神经网络。

      • Edward 2017年5月12日 上午7:59 #

        感谢您的回复,Jason!您的博客是黄金!:)

  19. Adrian 2017年5月26日 上午12:04 #

    您知道如何将超参数与 TensorBoard 回调一起保存吗?

  20. Anisa 2017年5月28日 下午6:12 #

    嗨,Jason!

    我正在使用自定义的 scoring 函数进行网格搜索,但我需要从训练模型中获取准确率和召回率等结果。所以,我使用 cross_val_score 与网格搜索得到的最优参数。但是 cross_val_score 产生的与网格搜索得到的最优分数不同的结果。你有什么想法可以解决我的问题吗?

    谢谢,

  21. Shabran 2017年5月30日 下午3:41 #

    嗨,Jason!

    我正在使用自定义函数作为 scoring 函数进行网格搜索,但我需要从网格搜索得到的最优参数中报告其他指标。所以,我正在使用最优参数进行交叉验证。但问题是交叉验证产生的结果与网格搜索的最优分数不同。差异非常显著。你有什么想法可以解决这个问题吗?

    谢谢。

  22. Szymon 2017年6月6日 上午6:52 #

    我们如何使用 Keras 进行集成,例如投票?当基础模型来自 sklearn 库时,一切正常,但使用 Keras 时,我得到“TypeError: cannot create ‘sys.flags’ instances”。你知道有什么解决方法吗?

    • Jason Brownlee 2017年6月6日 上午10:09 #

      您可以手动对每个子模型的预测列表执行投票。

  23. Kirana 2017年6月14日 下午3:12 #

    我正在评估三种算法(SVM-RBF、XGBoost 和 MLP)在小型数据集上的表现。SVM 和 XGBoost 适用于小型数据集,而深度学习需要“相对”大量的数据才能表现良好,这种说法是真的吗?你能解释一下吗?

    非常感谢。

    • Jason Brownlee 2017年6月15日 上午8:42 #

      也许,让结果和硬数据来指导您的模型选择。

  24. James 2017年6月17日 上午2:55 #

    很棒的文章。这似乎与我目前正在学习的内容相似。我正在使用 Keras 的 sklearn 包装器,特别是 KerasClassifier 和 sklearn 的 `cross_val_score()`。我遇到了 `cross_val_score` 的 `n_jobs` 参数的问题。我想利用我 Windows 10 机器上的 GPU,但当 `n_jobs = -1` 或任何大于 1 的值时,我遇到了 `Blas GEMM launch failed`。另外,从 shell 提示符运行与从 python 解释器运行得到的结果不同。你有什么想法可以让我解决这个问题吗?

    Windows 10
    Geforce 1080 Ti
    Tensorflow GPU
    Python 3.6 (通过 Anaconda)
    Keras 2.0.5

    • Jason Brownlee 2017年6月17日 上午7:33 #

      抱歉 James,我没有关于在 Windows 上为 Keras 设置 GPU 的好建议。

      也许你可以在 stackoverflow 上发帖?

  25. Anastasios Selalmazidis 2017年6月18日 上午2:17 #

    你好 Jason,

    当我运行您的第一个示例,即使用 StratifiedKFold 的那个,对于我的多类别数据集,我得到了一个错误。StratifiedKFold 不能用于多类别吗?当我尝试运行带有 StritifiedKFold 的 GridSearch 时,我也遇到了同样的问题:“IndexError: too many indices for array”。

  26. Sean 2017年6月27日 下午5:24 #

    嗨,Jason,
    我按照您的步骤操作,程序运行了 40 多分钟。所以我中途放弃了等待。您知道有什么方法可以加快 GridSearchCV 的速度吗?或者在 2013 年的 Mac 上运行此代码等待 40 多分钟是否正常?谢谢。

    • Jason Brownlee 2017年6月28日 上午6:18 #

      您可以减少正在搜索的参数数量。

      我经常在 AWS 上运行需要数周才能完成的网格搜索。

  27. Clarence Wong 2017年6月27日 下午8:31 #

    嗨,Jason,

    如何在我将 Keras Classifier 包装在 Scikit 的 GridSearchCV 中时保存模型?

    我应该将其视为一个 scikit 对象并使用 pickle/joblib,还是使用 Keras 原生的 model.save 方法?

    • Jason Brownlee 2017年6月28日 上午6:23 #

      抱歉,我没有尝试过。它可能不支持开箱即用。

  28. Karthik 2017年7月15日 上午11:39 #

    嗨,Jason,

    我想执行分层 K-fold 交叉验证,模型预测的是距离而不是二元标签。是否可以向 scikit-learn 的交叉验证方法提供距离阈值(或有其他方法),即距离 < 0.5 被视为正面标签(y=1),否则为负面标签(y=0)?

    • Jason Brownlee 2017年7月16日 上午7:56 #

      分层需要一个类别值。

      也许您可以将您的问题构建成这样,使结果距离被阈值为类别标签。

      注意,这是关于如何构建您的预测问题和准备您的数据的问题,而不是关于 sklearn 库。

  29. Merco 2017年7月15日 下午11:12 #

    非常酷!!您也可以通过这种方式使用 scikit 的 Recursive Feature Elimination 函数吗?

  30. ambika 2017年7月19日 下午4:33 #

    请问您能否告诉我 ReLU 函数的公式,我需要它用于回归。

  31. ds 2017年7月21日 下午7:34 #

    您的代码是否可以用于更复杂的模型架构?我有 3 个不同的输入和分支(带有 ConvLayers),它们在最后被连接起来形成一个密集层。
    我尝试按如下方式调用 grid.fit() 函数:
    grid_result = grid.fit({‘input_1’: train_input_1, ‘input_2’: train_input_2, ‘input_3’: train_input_3}, {‘main_output’: lebels_train})

    我收到一个错误:
    “ValueError: found input variables with inconsistent numbers of samples: [3, 1]”

    您有这方面的经验吗?

    • Jason Brownlee 2017年7月22日 上午8:32 #

      抱歉,我不知道。

      我建议使用原生的 Keras。

  32. Nas 2017年10月10日 下午4:23 #

    来自 keras.models import Sequential
    from keras.layers import Dense
    来自 keras.wrappers.scikit_learn 的 KerasClassifier
    从 sklearn.model_selection 导入 StratifiedKFold
    from sklearn.model_selection import cross_val_score
    import numpy

    def create_model()
    # 创建模型
    model = Sequential()
    model.add(Dense(12, input_dim=8, activation=’relu’))
    model.add(Dense(8, activation='relu'))
    model.add(Dense(1, activation=’sigmoid’))
    # 编译模型
    model.compile(loss=’binary_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])
    return model

    seed = 7
    numpy.random.seed(seed)
    dataset = numpy.loadtxt(“/home/nasrin/nslkdd/NSL_KDD-master/KDDTrain+.csv”, delimiter=”,”)
    X = dataset[:,0:41]
    Y = dataset[:,41]

    model = KerasClassifier(build_fn=create_model, epochs=150, batch_size=10, verbose=0)
    kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)
    results = cross_val_score(model, X, Y, cv=kfold)
    print(results.mean())

    使用 TensorFlow 后端。
    回溯(最近一次调用)
    File “nsl2.py”, line 20, in
    dataset = numpy.loadtxt(“/home/nasrin/nslkdd/NSL_KDD-master/KDDTrain+.csv”, delimiter=”,”)
    File “/home/nasrin/.local/lib/python3.5/site-packages/numpy/lib/npyio.py”, line 1024, in loadtxt
    items = [conv(val) for (conv, val) in zip(converters, vals)]
    File “/home/nasrin/.local/lib/python3.5/site-packages/numpy/lib/npyio.py”, line 1024, in
    items = [conv(val) for (conv, val) in zip(converters, vals)]
    File “/home/nasrin/.local/lib/python3.5/site-packages/numpy/lib/npyio.py”, line 725, in floatconv
    return float(x)
    ValueError: could not convert string to float: b’tcp’
    抱歉打扰您,我在这里遗漏了什么步骤。

  33. Piotr 2017年10月12日 下午10:33 #

    您知道如何在 cross_val_score() 中、在 fold 之间执行 K.clear_session() 吗?

    我有很多大型 CNN 网络,但它们只在进行一次训练时适合我的内存。问题是,当我使用 sci-kit learn 和 cross_val_score 函数进行交叉验证时。我看到内存随着每个 fold 的增加而增加。你知道如何改变它吗?毕竟,在每个 fold 之后,我们只需要记住结果,而不是带有所有权重的庞大模型。

    我尝试使用 keras 的 on_train_end 回调,但这不起作用,因为模型在评估之前就被清除了。所以你知道是否存在其他解决方案?不幸的是,我在 cross_val_score 函数中看不到任何回调……

    非常感谢您的帮助!

  34. Sanaz 2017年10月25日 下午10:17 #

    非常感谢如此有用的代码!我遇到了一个问题,尽管我像您在这里定义的那样在模型和字典中都定义了 init,但我还是收到一个错误:

    ‘{} is not a legal parameter’.format(params_name))

    ValueError: init is not a legal parameter

    您能帮我解决这个问题吗?

  35. Ab 2017年11月9日 下午9:31 #

    你好,
    感谢您的精彩论文。
    我尝试使用 AdaBoostClassifier( model, n_estimators=2, learning_rate=1.5, algorithm=”SAMME”)
    并将 CNN 用作“model”。但是,我得到了以下错误:

    File “”, line 1, in
    runfile(‘/home/aboozar/Sphere_FE/adaboost/adaboost_CNN3.py’, wdir=’~/adaboost’)

    File “/usr/local/lib/python2.7/dist-packages/spyder/utils/site/sitecustomize.py”, line 688, in runfile
    execfile(filename, namespace)

    File “/usr/local/lib/python2.7/dist-packages/spyder/utils/site/sitecustomize.py”, line 93, in execfile
    builtins.execfile(filename, *where)

    File “/~/adaboost_CNN3.py”, line 234, in
    bdt_discrete.fit(X_train, y_train)

    File “/usr/local/lib/python2.7/dist-packages/sklearn/ensemble/weight_boosting.py”, line 413, in fit
    return super(AdaBoostClassifier, self).fit(X, y, sample_weight)

    File “/usr/local/lib/python2.7/dist-packages/sklearn/ensemble/weight_boosting.py”, line 130, in fit
    self._validate_estimator()

    File “/usr/local/lib/python2.7/dist-packages/sklearn/ensemble/weight_boosting.py”, line 431, in _validate_estimator
    % self.base_estimator_.__class__.__name__)

    ValueError: KerasClassifier doesn’t support sample_weight.

    您有什么建议吗?

  36. Arooj 2017年12月15日 下午5:14 #

    你好,
    我是 Keras 的新手。我刚刚复制了上面的代码并执行了网格搜索,但得到了这个错误:

    “ValueError: init is not a legal parameter”

    感谢您的指导。

    • Jason Brownlee 2017年12月16日 上午5:24 #

      仔细检查您是否复制了所有代码,并保持了相同的缩进。

      同时仔细检查您是否安装了最新版本的 Keras 和 sklearn。

  37. michele 2017年12月18日 下午10:20 #

    嗨,很棒的教程,非常感谢!

    我有一个问题:如果我想在网格搜索场景或类似场景中使用 KerasClassifier 和我自己的 score 函数,比如最大化 F1,而不是准确率。
    我该怎么办?

    谢谢!

    • Jason Brownlee 2017年12月19日 上午5:19 #

      您可以通过“scoring”属性指定 sklearn 在使用 CV 或其他方法评估模型时使用的 scoring 函数。

      • michele 2017年12月20日 上午12:50 #

        谢谢你的回答。但是,如果我理解正确的话,kerasclassifier 的 score 函数必须是可微分的,因为它也用作损失函数,而 F1 不是。

        • Jason Brownlee 2017年12月20日 上午5:46 #

          不,那是 Keras 模型本身的损失函数,与 sklearn 对模型预测的评估是不同的。

  38. Ankur Singh 2017年12月19日 下午3:24 #

    嗨 Jason,您的博客很棒。我也拥有您的深度学习书籍。

    我有一个问题:我不想在我的代码中使用分层 KFold。我有自己的验证数据。我能在一个给定的数据集上训练我的模型,并使用 Grid Search 在不同的验证数据上检查最佳分数吗?

  39. Claudio 2018年1月3日 上午2:11 #

    嗨 Jason…
    非常感谢您提供的这一系列关于 Keras 的文章!我认为这简直太棒了

    我有一个关于如何在 Spark 集群上运行 Grid Search Deep Learning Model Parameters 的最佳方法的疑问。它只是一个将代码无更改地移植到那里的问题,优化就会神奇地启用(在不同的节点上并行运行测试的任何参数组合)……还是我们应该导入其他库或进行一些更改来启用它?

    提前感谢!

    • Jason Brownlee 2018年1月3日 上午5:39 #

      抱歉,我无法为您提供关于使用 Spark 调优 Keras 模型的良好建议。

  40. vikram singh 2018年1月4日 下午11:29 #

    当有多标签分类问题时,如何进行交叉验证?
    每当我传递 Y_train 时,我都会得到 'IndexError: too many indices for array',如何解决这个问题?

  41. Sam Miller 2018年1月5日上午6:56 #

    嗨,Jason,
    使用KerasClassifier和k-folds时,如何从模型中获得精确率和召回率分数?应用cross_val_score后是否有生成sklearn.metrics分类报告的方法?
    我需要这些值,因为我的数据集是不平衡的,并且我想通过生成混淆矩阵、ROC曲线和精确率-召回率曲线来比较过采样(undersampling)数据前后得到的结果。

    • Jason Brownlee 2018年1月5日上午11:35 #

      是的,将“scoring”参数更改为一个或多个要报告的指标。

  42. yerra 2018年1月8日上午2:47 #

    你好 Brownlee,

    感谢您提供的精彩的机器学习和深度学习材料。按照您的建议,我有一个已经分割为训练集和测试集的数据集。使用Keras,如何训练模型,然后在测试数据上进行预测?

  43. Reed Guo 2018年1月21日上午1:13 #

    嗨,Jason

    如何找到隐藏层和神经元的最佳数量?

    可以发布Python代码吗?我在Google上找不到任何有用的帖子。

    非常感谢。

    • Jason Brownlee 2018年1月21日上午9:12 #

      很好的问题。

      您必须通过试错法来为您的特定模型和特定数据找到答案。

  44. Reed Guo 2018年1月21日下午7:23 #

    嗨,Jason

    谢谢你的回复。

    我还是感到困惑。我不知道该怎么做?(使用网格搜索还是反复尝试?)

    可以为本课程中的示例提供一段Python代码吗?

  45. Reed Guo 2018年1月23日下午12:19 #

    嗨,Jason

    非常非常感谢。

  46. Magesh Rathnam 2018年2月2日上午3:48 #

    Jason你好 - 感谢您的帖子。我不知道有这个包装器。是否有类似的回归器包装器?我刚开始接触机器学习,我曾尝试做一个房屋价格预测问题。我看到可以使用scikit的随机森林回归器来完成。但我想看看是否也可以用keras来完成,因为我从keras开始,觉得它稍微容易一些。我尝试了一个简单的顺序模型,带有多个层,但它没有起作用。您能告诉我如何为我的问题实现keras吗?

    谢谢。

  47. Atefeh 2018年2月6日上午12:28 #

    你好

    我遇到了一个错误。

    问题是什么?

  48. Atefeh 2018年2月6日下午5:35 #

    你好

    导入Kerasclassifier后,对于Kfold,我应该导入什么?

    来自 keras.wrappers.scikit_learn 的 KerasClassifier
    def create_model()
    model=Sequential()

    model.compile(…)
    return model
    model=KerasClassifier(build_fn=create_model, epochs=150, batch_size=10)
    kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)

    NameError Traceback (最近一次调用)
    in ()
    6 return model
    7 model=KerasClassifier(build_fn=create_model, epochs=150, batch_size=10)
    —-> 8 kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)

    NameError: name ‘StratifiedKFold’ is not defined

    谢谢你

    • Jason Brownlee 2018年2月7日上午9:22 #

      看起来你仍然缺少一些导入。

      考虑使用博客文章中的现有代码作为起点?

  49. K V Subrahmanyam 2018年2月13日下午8:41 #

    感谢这篇精彩的文章。我有一个问题。为什么我们不将epochs和batches作为参数传递给create_model函数?你能帮助我理解这一点吗?

    此致
    Subbu

    • Jason Brownlee 2018年2月14日上午8:18 #

      因为我们在拟合模型时传递它们。该函数仅用于定义模型,而不用于拟合它。

  50. Janina 2018年2月18日上午9:27 #

    Jason你好,虽然你的帖子看起来非常直接,但我仍然在努力实现这个网格搜索方法。它没有给我任何错误消息,但它只是不停地运行,没有任何输出。我故意尝试使用非常少的epochs和非常少的超参数进行搜索。没有网格搜索,一个epoch运行得非常快,所以我不认为我只需要给它更多时间。它根本什么都不做。

    我的代码

    非常感谢您的帮助!!

    • Jason Brownlee 2018年2月19日上午8:59 #

      也许可以尝试使用更小的数据样本?

      也许手动进行网格搜索,用您自己的for循环?或者分布式到多台机器上?

      • starsini 2020年1月12日下午1:57 #

        将verbose设置为verbose=9怎么样?

        model = KerasClassifier(build_fn=create_model, verbose=9)

  51. Rishab Verma 2018年3月2日下午5:33 #

    查看您对其他人问题的答复,比这更受赞赏的莫过于此了。

    我也遇到一个问题。我想在已保存的ResNet的具有全连接层的模型的权重上训练一个SVM分类器。如何为SVM分类器填充值?
    任何指导都值得赞赏。

    • Jason Brownlee 2018年3月3日上午8:07 #

      抱歉,我不知道如何将神经网络权重加载到SVM中。

  52. Choi 2018年3月6日下午2:09 #

    嗨,Jason,
    感谢您的教程。
    除了使用‘KerasClassifier’来拟合模型之外,还有其他方法吗?
    因为我想用增强数据来训练模型,这是通过使用‘ImageDataGenerator’来实现的。

    更具体地说,

    如以下所示,您可以通过“fit()”函数更改参数X_train和Y_train。

    history = model.fit(X_train, Y_train, nb_epoch=nb_epoch, batch_size=batch_size, shuffle=True, verbose=1)

    但是,您不能像下面这样使用“KerasClassifier”函数来更改参数X_train和Y_train,因为此函数中没有输入数据的参数。

    model = KerasClassifier(build_fn=create_model, epochs=50, batch_size=1, verbose=0)

    提前感谢!

  53. Elena Markova 2018年4月19日上午1:42 #

    嗨,Jason,

    感谢您的文章。
    您能解释一下,在使用Keras拟合模型时,使用scikit的kfold交叉验证示例与仅使用keras中的validation split = 1/k有何不同吗?抱歉,我是机器学习新手。唯一的区别是keras中的validation split选项永远不会改变或打乱其验证数据吗?

    提前感谢!

    • Jason Brownlee 2018年4月19日上午6:36 #

      验证分割是一次数据分割。一个模型在一个数据集上进行评估。

      k折交叉验证创建k个模型,在k个不相交的测试集上进行评估。

      这可以更好地估计在给定大小的随机数据样本上训练的模型的能力。但计算成本很高,特别是对于深度学习模型,训练起来非常慢。

  54. Saber 2018年5月27日上午12:45 #

    我读过一些地方说k折交叉验证在深度学习模型中不太常见,因为它们计算量很大。但是k折交叉验证也用于在达到所需的FPR、FNR等之前,为深度学习模型选择一个“最佳”决策/分类阈值。您对如何进行“阈值优化”有什么建议吗?k折交叉验证是唯一的选择吗?

    谢谢!

    • Jason Brownlee 2018年5月27日上午6:46 #

      有道理。

      是的,每个分割都可以根据训练数据估计阈值,并在保留的折上进行测试。

  55. Sazid 2018年5月27日下午8:59 #

    哪一个能给我带来更好的结果,keras scikit learn 包装类还是像KNN、SVM、决策树、随机森林树这样的通用机器学习算法?
    请帮助我。我感到困惑。

  56. Mik 2018年6月2日上午1:12 #

    嗨,Jason,

    我关注您的博客一段时间了,我发现您在机器学习方面的帖子非常有用,因为它填补了许多文档站点留下的空白。例如,您关于Keras的帖子在清晰度方面远远领先于Keras自己的文档。所以,请继续保持出色的工作,伙计。

    在使用Keras时,我遇到一个周期性问题。并非每次都会发生,但偶尔(我估计大约1/10次),代码会因以下错误而失败:

    忽略的异常: <bound method BaseSession.__del__ of >
    回溯(最近一次调用)
    File “/home/mede/virtualenv/lib/python3.5/site-packages/tensorflow/python/client/session.py”, line 707, in __del__

    我相信这是这些StackOverflow帖子中描述的相同错误:https://stackoverflow.com/questions/40560795/tensorflow-attributeerror-nonetype-object-has-no-attribute-tf-deletestatushttps://github.com/tensorflow/tensorflow/issues/3388 当然,我已经尝试应用这些帖子中建议的修复程序。但是,由于(在我看来)错误发生在执行网格搜索的循环中,所以我无法在每次运行之间删除Tensorflow会话。您知道是否有,或者您能想到一种解决方法吗?

    提前感谢!

    • Jason Brownlee 2018年6月2日上午6:35 #

      抱歉,我从未见过这个。

      也许请确保所有库和依赖库都已更新?
      也许迁移到Py 3.6?

  57. Mik 2018年6月4日上午7:27 #

    好的,我试试看,谢谢。

  58. Chase 2018年7月11日上午6:33 #

    感谢您的精彩内容!

    我正在寻找一些关于如何构建学习曲线的指导,这些曲线专门显示了随着训练样本的增加,顺序Keras模型的训练和测试误差。我已经构建了一些代码,并遇到了一个错误,这让我重新考虑我的方法。任何建议都将不胜感激。

    供参考,这是当前的错误。

    TypeError: Cannot clone object ” (type ): it does not seem to be a scikit-learn estimator as it does not implement a ‘get_params’ methods.

  59. cass 2018年7月30日上午7:58 #

    嗨 Jason

    使用KerasClassifier进行交叉验证的第一个示例仅用于准确性。有没有办法获得f1分数或召回率?

    神经网络总是返回概率。那么对于二元分类,cross_val_score是如何工作的(我试过了,但它不起作用)?

  60. Huda 2018年8月31日下午7:48 #

    嗨,Jason,

    如果我有多个在相同数据上训练的模型怎么办?您能否举例说明如何使用VotingClassifier和Keras模型?

    谢谢!

  61. tequila rifa 2018年9月5日下午9:47 #

    嗨,Jason,

    我在您的网站和书籍中学到了很多东西。我非常感谢您的帮助。

    我注意到,在查看电子书《Python深度学习》以及您的其他书籍时。

    大多数/几乎所有的章节+代码都可以在您的网站上作为单独的博客文章找到,

    那么对于购买这本书的人有什么额外的好处呢?

  62. reaky 2018年12月20日凌晨12:27 #

    嗨,Jason,
    回溯(最近一次调用)
    File “H:/pycharm_workspace/try_process/model1.py”, line 61, in
    model_change.fit(X_train,Y_train)
    File “J:\python_3.6\lib\site-packages\keras\wrappers\scikit_learn.py”, line 210, in fit
    return super(KerasClassifier, self).fit(x, y, **kwargs)
    File “J:\python_3.6\lib\site-packages\keras\wrappers\scikit_learn.py”, line 139, in fit
    **self.filter_sk_params(self.build_fn.__call__))
    TypeError: __call__() missing 1 required positional argument: ‘inputs’
    错误是什么意思?

  63. bileesh 2019年1月10日 下午6:08 #

    嗨,Jason,

    有可能将 scikit 的 SVM 分类器包装在一个 Keras CNN 特征提取模块中吗?

    • Jason Brownlee 2019年1月11日 上午7:42 #

      CNN 的输出(特征)可以馈送到 SVM。

      • bileesh 2019年1月11日 下午4:36 #

        谢谢,Jason。

        与其通过 CNN 提取特征然后使用 SVM 进行分类,是否可以将 CNN 的全连接层替换为 scikit-learn 中可用的 SVM 模块并进行端到端训练?

        • Jason Brownlee 2019年1月12日 上午5:37 #

          直接这样操作?也许可以,我没试过。

  64. jessy 2019年2月1日 上午9:03 #

    先生,
    执行网格搜索超参数的最佳 Anaconda 提示是什么……才能做到最好并快速执行?

  65. wybiu 2019年2月23日 下午1:59 #

    先生:我使用 keras API 将 adaboost LSTM 集成到 scikit-learn 中。但我遇到了一些错误。
    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    from keras.layers.core import Dense, Activation, Dropout
    来自 keras.models import Sequential
    import time
    import math
    from keras.layers import LSTM
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.metrics import mean_squared_error
    from keras import optimizers
    import os
    from matplotlib import pyplot
    from keras.wrappers.scikit_learn import KerasRegressor
    from sklearn import ensemble
    from sklearn.tree import DecisionTreeRegressor

    def create_dataset(dataset, look_back)
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back)
    a = dataset[i:(i+look_back), 0]
    dataX.append(a)
    dataY.append(dataset[i + look_back, 0])
    return np.array(dataX), np.array(dataY)

    def create_train_test_data(dataset,look_back )
    scaler = MinMaxScaler(feature_range=(0, 1))
    数据集 = scaler.fit_transform(数据集)
    datasetX, datasetY = create_dataset(dataset, look_back)
    train_size = int(len(datasetX) * 0.90)
    trainX, trainY, testX, testY = datasetX[0:train_size,:],datasetY[0:train_size],datasetX[train_size:len(datasetX),:],datasetY[train_size:len(datasetX)]
    trainXrp = trainX.reshape (trainX.shape[0],look_back,1)
    testXrp = testX.reshape(testX.shape[0], look_back,1)
    return scaler,trainXrp,trainY,testXrp,testY,trainX,testX

    def build_model(): #layers [1,50,100,1]
    model = Sequential()

    model.add(LSTM(10,return_sequences=True))
    model.add(Dropout(0.5))
    model.add(LSTM(100,return_sequences=False))
    model.add(Dropout(0.2))
    #model.add(LSTM(layers[3],return_sequences=False))
    #model.add(LSTM(layers[4],return_sequences=False))
    #model.add(Dropout(0.5))
    model.add(Dense(units=1, activation=’tanh’))

    start = time.time()
    #adagrad=optimizers.adagrad(lr=1)
    rmsprop = optimizers.rmsprop(lr=0.001)
    #model.compile(loss=”mse”, optimizer=rmsprop)
    #model.compile(loss=”mse”, optimizer=”adagrad”)
    model.compile(loss=”mse”, optimizer=”rmsprop”)
    print(“编译时间 : “, time.time() – start)
    return model

    if __name__==’__main__’
    global_start_time = time.time()
    print(‘> 正在加载数据… ‘)
    dataframe = pd.read_csv(‘xxxx.csv’, usecols=[0])
    dataset = dataframe.values
    dataset = dataset.astype(‘float32’)
    scaler,trainXrp,trainY,testXrp,testY,trainX,testX = create_train_test_data(dataset,seq_len)
    LSTM_estimator = KerasRegressor(build_fn=build_model, nb_epoch=2)
    boosted_LSTM = ensemble.AdaBoostRegressor(base_estimator=LSTM_estimator,n_estimators=100, random_state=None,learning_rate=0.1)
    trainXrp = [np.concatenate(i) for i in trainXrp]
    boosted_LSTM.fit(trainXrp, trainY)
    trainPredict=boosted_LSTM.predict(testXrp)

    ————————————————————————————————————————
    —————————————————————————
    ValueError 回溯 (最近一次调用)
    in
    102 trainZ = trainX.reshape (trainX.shape[0],1)
    103 print(‘Xrp_train 形状:’,trainZ.shape)
    --> 104 boosted_LSTM.fit(trainZ, trainY.ravel())
    105 trainPredict=boosted_LSTM.predict(trainX)

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/sklearn/ensemble/weight_boosting.py in fit(self, X, y, sample_weight)
    958
    959 # Fit
    --> 960 return super(AdaBoostRegressor, self).fit(X, y, sample_weight)
    961
    962 def _validate_estimator(self)

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/sklearn/ensemble/weight_boosting.py in fit(self, X, y, sample_weight)
    141 X, y,
    sample_weight,
    --> 143 random_state)
    144
    145 # Early termination

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/sklearn/ensemble/weight_boosting.py in _boost(self, iboost, X, y, sample_weight, random_state)
    1017 # Fit on the bootstrapped sample and obtain a prediction
    # for all samples in the training set
    -> 1019 estimator.fit(X[bootstrap_idx], y[bootstrap_idx])
    1020 y_predict = estimator.predict(X)
    1021

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/keras/wrappers/scikit_learn.py in fit(self, x, y, **kwargs)
    150 fit_args.update(kwargs)
    151
    -> 152 history = self.model.fit(x, y, **fit_args)
    153
    154 return history

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
    950 sample_weight=sample_weight,
    951 class_weight=class_weight,
    –> 952 batch_size=batch_size)
    953 # Prepare validation data.
    954 do_validation = False

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
    675 # to match the value shapes.
    676 if not self.inputs
    -> 677 self._set_inputs(x)
    678
    679 if y is not None

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/keras/engine/training.py in _set_inputs(self, inputs, outputs, training)
    587 assert len(inputs) == 1
    588 inputs = inputs[0]
    -> 589 self.build(input_shape=(None,) + inputs.shape[1:])
    590 return
    591

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/keras/engine/sequential.py in build(self, input_shape)
    219 self.inputs = [x]
    220 for layer in self._layers
    -> 221 x = layer(x)
    222 self.outputs = [x]
    223 self._build_input_shape = input_shape

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/keras/layers/recurrent.py in __call__(self, inputs, initial_state, constants, **kwargs)
    530
    531 if initial_state is None and constants is None
    -> 532 return super(RNN, self).__call__(inputs, **kwargs)
    533
    534 # If any of initial_state or constants are specified and are Keras

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/keras/engine/base_layer.py in __call__(self, inputs, **kwargs)
    412 # Raise exceptions in case the input is not compatible
    # with the input_spec specified in the layer constructor.
    -> 414 self.assert_input_compatibility(inputs)
    415
    416 # Collect input shapes to build layer.

    /usr/local/miniconda3/envs/dl/lib/python3.6/site-packages/keras/engine/base_layer.py in assert_input_compatibility(self, inputs)
    309 self.name + ‘: expected ndim=’ +
    str(spec.ndim) + ‘, found ndim=’ +
    -> 311 str(K.ndim(x)))
    312 if spec.max_ndim is not None
    ndim = K.ndim(x)

    ValueError: Input 0 is incompatible with layer lstm_13: expected ndim=3, found ndim=2

    • Jason Brownlee 2019年2月24日 上午9:04 #

      抱歉,我没有能力调试您的代码。

      也许在 stackoverflow 上发帖?

    • Carolina 2021年6月9日 下午9:14 #

      嗨!

      你找到解决方案了吗?我遇到了同样的情况。

      谢谢你。

  66. danielprasaja 2019年3月8日 下午7:51 #

    你好 Jason,我刚读了几篇你的文章,但它们都使用了简单的 keras 模型。我想知道是否可以对像 CNN 这样的复杂模型运行交叉验证?

  67. abhijit 2019年4月20日 上午12:16 #

    你好 Jason,

    这里有一个问题,我正在尝试使用 keras 模型进行网格搜索来查找最佳参数,但我的评分是 auc,我该如何做到,因为 keras 分类器只允许准确率作为评分?

      • abhijit 2019年4月20日 下午4:40 #

        我想要使用网格搜索和 AUC 作为评分的最佳模型,我尝试了这段代码但它不起作用,您能否审阅并帮助我指出哪里出错了。

        来自 keras.wrappers.scikit_learn 的 KerasClassifier
        from sklearn.model_selection import GridSearchCV
        来自 keras.models import Sequential
        from keras.layers import Dense
        from sklearn.metrics import roc_auc_score
        import tensorflow as tf
        from keras.utils import np_utils
        from keras.callbacks import Callback, EarlyStopping

        # 定义 roc_callback,受 https://github.com/keras-team/keras/issues/6050#issuecomment-329996505 启发
        def auc_roc(y_true, y_pred)
        # 任何 tensorflow 指标
        value, update_op = tf.contrib.metrics.streaming_auc(y_pred, y_true)

        # 查找为此指标创建的所有变量
        metric_vars = [i for i in tf.local_variables() if ‘auc_roc’ in i.name.split(‘/’)[1]]

        # 将指标变量添加到 GLOBAL_VARIABLES 集合。
        # 它们将被初始化为新会话。
        for v in metric_vars
        tf.add_to_collection(tf.GraphKeys.GLOBAL_VARIABLES, v)

        # 强制更新指标值
        with tf.control_dependencies([update_op])
        value = tf.identity(value)
        return value

        def build_classifier(optimzer,kernel_initializer)
        classifier = Sequential()
        classifier.add(Dense(6, input_dim = 11, kernel_initializer = kernel_initializer, activation = ‘relu’ ))
        classifier.add(Dense(6, kernel_initializer = kernel_initializer, activation = ‘relu’ ))
        classifier.add(Dense(1, kernel_initializer = kernel_initializer, activation = ‘sigmoid’ ))
        classifier.compile(optimizer = optimzer, loss = ‘binary_crossentropy’, metrics = [auc_roc])
        return classifier

        classifier = KerasClassifier(build_fn = build_classifier)
        my_callbacks = [EarlyStopping(monitor= auc_roc, patience=300, verbose=1, mode=’max’)]
        parameters = {‘batch_size’: [25, 32],
        ‘nb_epoch’: [100, 300],
        ‘optimzer’: [‘adam’, ‘rmsprop’] ,
        ‘kernel_initializer’:[‘random_uniform’,’random_normal’]}
        grid_search = GridSearchCV(estimator = classifier,
        param_grid = parameters,
        scoring = auc_roc,
        cv = 5)
        grid_search = grid_search.fit(X_train, y_train,callbacks=my_callbacks)
        best_parameters = grid_search.best_params_
        best_accuracy = grid_search.best_score_

  68. Mustafa 2019年5月24日 上午3:49 #

    谢谢,Jason 博士。

    我想知道如何将 LSTM 与 SVM 结合到 Keras 的顺序模型中,如果可能的话,请提供一个简单的示例,无需执行。提前谢谢您,Jason 博士。

  69. John 2019年6月21日 下午4:28 #

    我正在构建一个估计器,其中一些参数是可调用的。有些可调用对象有自己的参数。使用上面的示例,估计器有一个 EarlyStop 可调用对象作为参数。EarlyStop 可调用对象接受一个 patience 参数。patience 参数不是估计器的参数。

    如果有人想对 patience 参数的各种值进行 GridsearchCV,scikit-learn 是否能够将可调用对象及其参数报告为‘best_parameters_’?

    • Jason Brownlee 2019年6月22日 上午6:33 #

      我认为您需要实现自己的 for 循环来进行搜索。

  70. Emi 2019年8月30日 上午10:34 #

    嗨,Jason,

    首先,感谢您的精彩教程。

    我有一个大约 1000 个节点的包含 4 个时间序列的数据集。每个时间序列的长度正好是 6。标签是 0 或 1(即二元分类)。

    更具体地说,我的数据集如下所示。

    节点,时间序列1,时间序列2,时间序列_3,时间序列4,标签
    n1, [1.2, 2.5, 3.7, 4.2, 5.6, 8.8], [6.2, 5.5, 4.7, 3.2, 2.6, 1.8], …, 1
    n2, [5.2, 4.5, 3.7, 2.2, 1.6, 0.8], [8.2, 7.5, 6.7, 5.2, 4.6, 1.8], …, 0
    等等。

    我正在使用以下 LSTM 模型。

    model = Sequential()
    model.add(LSTM(10, input_shape=(6,4)))
    model.add(Dense(32))
    model.add(Dense(1, activation=’sigmoid’))
    model.compile(loss=’binary_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])

    由于我的数据集很小,我想执行 10 折交叉验证,正如您在本教程中所建议的。

    然而,我不太清楚 KerasClassifier 的 batch_size 是什么意思。

    您能否告诉我 batch_size 是什么,您推荐我使用多大的 batch_size?

    此致,Emi

    • Jason Brownlee 2019年8月30日 下午2:15 #

      如果它们是时间序列,那么交叉验证将无效,相反,您必须使用前向验证。

      你可以在这篇帖子中了解更多信息
      https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/

      您可以在这里开始使用 LSTM 进行时间序列预测
      https://machinelearning.org.cn/start-here/#deep_learning_time_series

      • Emi 2019年8月30日 下午3:02 #

        嗨 Jason,非常感谢您的回复。我看了您的“backtest-machine-learning-models-time-series-forecasting”教程。然而,由于我的问题不是时间序列预测,我不太清楚如何将这些技术应用于我的问题。

        更具体地说,我有一个二进制分类问题,旨在检测未来可能的趋势商品。为此,我计算了以下四个特征:
        – 时间序列 1:每个商品的度中心性从 2010-2016 年如何变化
        – 时间序列 2:每个商品的介数中心性从 2010-2016 年如何变化
        – 时间序列 3:每个商品的紧密度中心性从 2010-2016 年如何变化
        – 时间序列 4:每个商品的特征向量中心性从 2010-2016 年如何变化

        标签值(0 或 1)基于 2017-2018 年的趋势商品。如果商品是趋势商品,则标记为 1,否则为 0。

        所以,我假设我的问题更像是序列分类。在这种情况下,我可以使用 10 折交叉验证吗?

        期待您的回复。

        此致 -Emi

        • Jason Brownlee 2019年8月31日 上午6:02 #

          是的,这听起来像时间序列分类,前向验证的概念同样适用。也就是说,您只能在过去拟合数据并在未来预测,切勿打乱样本。

          我在这里提供了时间序列分类前向验证的示例
          https://machinelearning.org.cn/start-here/#deep_learning_time_series

          • Emi 2019年8月31日 下午10:14 #

            嗨 Jason,我仔细思考了您说的话。

            然而,我觉得我的问题设置中的数据在交叉验证中是按点分割的,而不是按时间分割。

            即(按点分割)

            第一个折训练
            item_1, item2, …….., item_799, item_800

            第一个折测试
            item 801, …….., item_1000
            而不是(按时间分割)

            第一个折训练
            2010, 2011, …….., 2015

            第一个折测试
            2016, …….., 2018

            因此,我不太清楚如何使用前向验证。

            也许我给您的关于我的问题设置的描述有点少。所以,我扩展了我的问题设置并在 Stackoverflow 上发布了一个问题:https://stackoverflow.com/questions/57734955/how-to-use-lstm-for-sequence-classification-using-kerasclassifier/57737501#57737501

            我希望我的问题在 stackoverflow 问题中得到了清晰的描述。

            请告诉我您的想法。我仍然是这方面的新手。所以,我很乐意获得您的反馈来改进我的解决方案。期待您的回复。

            非常感谢

            🙂

            此致 -Emi

          • Jason Brownlee 2019年9月1日 上午5:44 #

            嗯,您是您问题的专家,而不是我,所以如果您觉得安全,那就去吧!

            告诉我进展如何。

          • Emi 2019年8月31日 下午10:16 #

            抱歉,指向 stackoverfow 问题的链接应该是:https://stackoverflow.com/questions/57734955/how-to-use-lstm-for-sequence-classification-using-kerasclassifier

      • Minesh Jethva 2020年5月22日 下午3:41 #

        谢谢

  71. Suyash 2019年8月31日 下午9:12 #

    请帮帮我,CNN 提取的特征如何馈送到 SVM?是否有代码?如果有,请告诉我。

  72. Ulises García 2019年9月28日 上午8:28 #

    嗨 Jason,问候,好文章
    你能帮我吗?

    如何使用 .predict 计算 F1 分数(加权)或如何计算 F1 分数(加权)

  73. Dima 2020年1月26日 上午1:32 #

    嗨,Jason,
    感谢您的辛勤工作。我想知道您是否有关于将用于图像识别的 CNN 与普通特征结合的内容?您能帮忙吗?

  74. Mehreen Tariq 2020年3月27日 下午7:46 #

    我实现了相同的代码,但准确率只有 32%。
    import numpy
    import pandas
    来自 keras.models import Sequential
    from keras.layers import Dense
    来自 keras.wrappers.scikit_learn 的 KerasClassifier
    from keras.utils import np_utils
    from sklearn.model_selection import cross_val_score
    from sklearn.model_selection import KFold
    from sklearn.preprocessing import LabelEncoder
    from sklearn.pipeline import Pipeline
    # 设置随机种子以保证结果可复现
    seed = 7
    numpy.random.seed(seed)
    # 加载数据集
    dataframe = pandas.read_csv(“iris.csv”, header=None)
    dataset = dataframe.values
    X = dataset[:,0:4].astype(float)
    Y = dataset[:,4]
    # 将类别值编码为整数
    encoder = LabelEncoder()
    encoder.fit(Y)
    encoded_Y = encoder.transform(Y)
    # 将整数转换为虚拟变量(即独热编码)
    dummy_y = np_utils.to_categorical(encoded_Y)
    # 定义基线模型
    def baseline_model()
    # 创建模型
    model = Sequential()
    model.add(Dense(4, input_dim=4, kernel_initializer=’normal’ , activation= ‘relu’ ))
    model.add(Dense(3, kernel_initializer=’normal’ , activation= ‘sigmoid’ ))
    # 编译模型
    model.compile(loss= ‘categorical_crossentropy’ , optimizer= ‘adam’ , metrics=[ ‘accuracy’ ])
    return model
    estimator = KerasClassifier(build_fn=baseline_model, nb_epoch=200, batch_size=5, verbose=0)
    kfold = KFold(n_splits=10, shuffle=True, random_state=seed)
    results = cross_val_score(estimator, X, dummy_y, cv=kfold)
    print(“Accuracy: %.2f%% (%.2f%%)” % (results.mean()*100, results.std()*100))

  75. jr 2020年4月3日 下午8:08 #

    嗨,感谢您的教程!它们非常有帮助。
    但我遇到了麻烦……
    我处理的是回归问题,在这种情况下,准确率指标不是最佳选择。
    相反,我想在网格搜索(使用 sci-kit)中将均方误差作为指标。
    但我找不到在哪里指定它
    我的猜测是 KerasClassifier 或 GridSearchCV 的定义?
    非常感谢!

    • Jason Brownlee 2020年4月4日 上午6:18 #

      好问题。

      keras 的 compile() 函数将指定‘mse’作为损失。

      scikit-learn 库将指定‘neg_mean_squared_error’。

  76. lavanya 2020年6月1日 下午10:49 #

    先生,请告知将神经网络和回归结合起来的优缺点

    创建的模型将是神经网络模型、回归模型还是深度网络模型?

    • Jason Brownlee 2020年6月2日 上午6:14 #

      神经网络在回归方面可能很有效,因为它们可以学习输入和目标之间复杂、不连续和非线性关系,作为连续函数。

  77. Basma 2020年7月15日 上午8:52 #

    嗨,Jason,
    非常感谢您的帖子。我执行时遇到了一个错误。

    RuntimeError: 无法克隆对象,因为构造函数未设置或修改参数 nb_epoch

    详情见此
    https://stackoverflow.com/questions/62874851/cannot-clone-object-keras-wrappers-scikit-learn-kerasclassifier-object-at-0x7f9

    • Jason Brownlee 2020年7月15日 下午1:58 #

      很遗憾听到这个消息,也许可以尝试直接使用 Keras API。

  78. amjass 2020年8月15日 上午2:47 #

    感谢您持续的文章,它们非常有帮助!

    一个快速的问题:在使用 scikit learn 进行 KFold 交叉验证时,并在 keras 中使用 model.fit 方法,是否可以使用验证数据集(KFold 分割中的测试集)进行早停,并用于 KFold 指标中的模型性能?我看到一些人没有在 model.fit 中添加任何验证集,有些人则将相同的测试集用于验证和模型性能。那么下面的做法是否可以接受?由于验证仅用于早停,并且每个折叠都有不同的验证样本,因此这没有理由是错误的?

    inputs=np.array(alldata)
    targets=trainingtargets

    K-fold 交叉验证器
    kfold = KFold(n_splits=num_folds, shuffle=True, random_state=42)

    #早停
    early stopping 等…

    fold_no = 1
    for train, test in kfold.split(inputs, targets)

    # model

    model=tf.keras.models.Sequential()
    model.add(tf.keras.layers.Dense(units=800, input_dim=500, activation=”relu”))
    model.add(tf.keras.layers.Dense(units=900, activation=”relu”))
    model.add(tf.keras.layers.Dense(units=700, activation=”relu”))
    model.add(tf.keras.layers.Dense(units=19, activation=”sigmoid”))

    # Compile the model
    model.compile(loss=”binary_crossentropy”, optimizer=optimizer, metrics=[‘accuracy’])

    # 生成一个打印
    print(‘————————————————————————‘)
    print(f’正在为折叠 {fold_no} 进行训练 …’)

    # 拟合数据到模型
    history=model.fit(inputs[train], targets[train],
    epochs=200,
    batch_size=32,
    verbose=1,
    validation_data=(inputs[test], targets[test]),
    callbacks=[earlystop], shuffle=True)

    # 生成泛化指标
    scores = model.evaluate(inputs[test], targets[test], verbose=0)

    使用 validation_data(inputs[test])进行早停和生成折叠分数是否可以,不一定必须是独立的保留集?样本数量通常有限,所以没有数百万的数据可以玩!

    谢谢你!

    • Jason Brownlee 2020年8月15日 上午6:34 #

      好问题,通常是可以的,但我没有例子。这会有帮助
      https://machinelearning.org.cn/faq/single-faq/how-do-i-use-early-stopping-with-k-fold-cross-validation-or-grid-search

      • amjass 2020年8月15日 上午7:25 #

        非常感谢!!这确实有帮助!我能接着问两个具体的问题吗?

        1. (我看过您提供的链接),但我想知道关于在KFold交叉验证期间使用提前停止(early stopping)的普遍观点是什么?它是否被推荐?如果我的模型通常在约30个epoch收敛,让它运行150个epoch将无法很好地衡量KFold试图预测的实际世界性能?

        2. 回到我最初的问题,使用测试数据作为模型性能的预测指标是否会因为在model.fit()调用中的validation_split参数中也使用了它作为验证数据而产生偏差?

        再次感谢!

        • Jason Brownlee 2020年8月15日 下午1:25 #

          一般来说,这很困难/一团糟。

          将epoch数量作为超参数进行调整,或者将提前停止视为“模型的一部分”要简单得多。我认为这是仅有的两种可行方法。

          是的,不应该使用测试数据,您应该再次拆分训练集,并使用一部分作为验证集。
          https://machinelearning.org.cn/difference-test-validation-datasets/

          • amjass 2020年8月15日 下午6:36 #

            非常感谢!

          • Jason Brownlee 2020年8月16日 上午5:49 #

            不客气。

  79. Rex 2020年8月19日 上午5:39 #

    嗨,Jason,

    非常感谢您的帖子!我有一个关于在不同优化器中调整学习率的问题。假设我想在SGD和Adam之间进行选择,并且我有一系列学习率(例如[0.001, 0.01, 0.1])。在这种情况下,我应该如何设置网格搜索?

    非常感谢。

    • Jason Brownlee 2020年8月19日 上午6:06 #

      不客气!

      如果您调整学习率,则必须使用SGD。

  80. EOE 2020年9月2日 下午6:55 #

    你好先生,

    根据您的教程,我尝试在KerasClassifier中使用LSTM模型。但是我遇到了一个问题。

    LSTM需要3D形状的输入,但是sklearn的model.fit()需要2D形状的输入。

    有没有办法解决这个问题?

    • Jason Brownlee 2020年9月3日 上午6:05 #

      我不建议将LSTM与kerasclassifier一起使用。

      我建议直接通过Keras API使用LSTM。

      • EOE 2020年9月3日 下午7:16 #

        好的,谢谢您,先生。

  81. Faria Zarin Subah 2020年9月7日 下午2:28 #

    嗨,Jason。根据您的书《Python深度学习》,我尝试使用KerasClassifier。但我遇到了一个问题。当我使用KerasClassifier并执行kfold交叉验证时,准确率约为53%。但是,当我直接通过Keras API实现相同的模型时,准确率完全不同,为23%。为什么?这是我的代码链接
    https://stackoverflow.com/questions/63763714/why-am-i-having-different-accuracy-results-for-the-same-network-configuration-wh

    • Jason Brownlee 2020年9月8日 上午6:45 #

      听到这个消息我很难过。

      也许您使用的模型方差很高。尝试用更小的学习率训练更长时间?

  82. Ravit 2020年9月19日 下午9:35 #

    嗨,Jason,

    非常感谢您提供的这个精彩教程。我正尝试在我的项目中使用此代码。我使用的是tensorflow-gpu keras。
    我遇到了这个错误,但找不出如何解决


    回溯(最近一次调用)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\IPython\core\interactiveshell.py”, line 3417, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
    File “”, line 1, in
    runfile(‘C:\\Users\\ravit\\PycharmProjects\\Barak_BGU\\Decoder-ANN.py’, wdir=’C:/Users/ravit/PycharmProjects/Barak_BGU’)
    File “C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\plugins\python-ce\helpers\pydev\_pydev_bundle\pydev_umd.py”, line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
    File “C:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\plugins\python-ce\helpers\pydev\_pydev_imps\_pydev_execfile.py”, line 18, in execfile
    exec(compile(contents+”\n”, file, ‘exec’), glob, loc)
    File “C:\Users\ravit\PycharmProjects\Barak_BGU\Decoder-ANN.py”, line 281, in
    best_grid_results = dec.check_for_best_params(dec_model, new_train, y_train)
    File “C:\Users\ravit\PycharmProjects\Barak_BGU\Decoder-ANN.py”, line 184, in check_for_best_params
    grid_result = grid.fit(X[:-500,:,:], y[:-500], X_val=X[500:,:,:], y_val=y[500:])
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\sklearn\utils\validation.py”, line 72, in inner_f
    return f(**kwargs)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\sklearn\model_selection\_search.py”, line 681, in fit
    base_estimator = clone(self.estimator)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\sklearn\utils\validation.py”, line 72, in inner_f
    return f(**kwargs)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\sklearn\base.py”, line 87, in clone
    new_object_params[name] = clone(param, safe=False)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\sklearn\utils\validation.py”, line 72, in inner_f
    return f(**kwargs)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\sklearn\base.py”, line 71, in clone
    return copy.deepcopy(estimator)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 281, in _reconstruct
    state = deepcopy(state, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 241, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 216, in _deepcopy_list
    append(deepcopy(a, memo))
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 281, in _reconstruct
    state = deepcopy(state, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 241, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 216, in _deepcopy_list
    append(deepcopy(a, memo))
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 281, in _reconstruct
    state = deepcopy(state, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 241, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 216, in _deepcopy_list
    append(deepcopy(a, memo))
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 281, in _reconstruct
    state = deepcopy(state, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 241, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 281, in _reconstruct
    state = deepcopy(state, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 241, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 180, in deepcopy
    y = _reconstruct(x, memo, *rv)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 281, in _reconstruct
    state = deepcopy(state, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 150, in deepcopy
    y = copier(x, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 241, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
    File “C:\ProgramData\Anaconda3\envs\tf-gpu\lib\copy.py”, line 169, in deepcopy
    rv = reductor(4)
    TypeError: can’t pickle _thread.RLock objects”

    您有什么想法如何解决这个问题吗?

  83. Jenny Li 2020年9月28日 下午7:27 #

    嗨,Jason,
    我想知道如何显示KerasClassifier的混淆矩阵。

  84. Ömer 2020年10月12日 下午5:38 #

    你好 Jason,
    感谢您提供这个网站,我从您的帖子和例子中学到了很多。
    我只有一件事要问:我想保存模型和权重,并在最后拥有一个模型池以供我的项目进行比较。我知道我通常可以保存模型
    ‘model.save()’
    但在使用scikit-learn包装器时,我不知道如何访问包装器内的模型并保存它。
    包装器方法可以更轻松地生成许多模型,所以我想使用它,但我需要帮助。
    您能给我一个解决这个问题的提示或解释一下吗?其他人可能也有类似的情况。
    谢谢!

    • Jason Brownlee 2020年10月13日 上午6:32 #

      您必须直接使用Keras API才能保存模型。您不能使用包装器。

      • Ömer 2020年10月19日 上午5:09 #

        谢谢您的关注和回答,Jason。
        我已解决我的问题。我写下这个,因为它可能对其他人有帮助。
        我想在不只是保存最好的模型的情况下保存我的模型,同时使用scikit-learn包装器,因为我的项目需要它们,用于未来的比较、保存权重等。这主要是研究和实验。

        在“tensorflow.keras.wrappers.scikit_learn”中,有“KerasClassifier”和“KerasRegressor”类,它们继承自第三个类“BaseWrapper”。

        如果您添加
        self.model.save(“name_of_your_model.h5”)在“BaseWrapper”类中的fit()方法里,您可以保存所有拟合的模型、权重、神经网络架构。
        我不知道这在正常使用中有多大用处,但在我的项目中,我需要拥有一个神经网络池用于未来的比较和诊断,所以我需要它们。
        谢谢你。

        • Jason Brownlee 2020年10月19日 上午6:41 #

          感谢分享。

        • Soumili 2022年2月19日 上午1:05 #

          嘿,您能详细告诉我吗?这真的很紧急。

  85. bhat 2020年12月6日 上午2:00 #

    亲爱的Jason,这是一个非常棒的教程。
    谢谢您。

    我有一个小警告,每次运行Keras分类器代码时都会出现。

    WARNING:tensorflow:5 out of the last 13 calls to <function Model.make_test_function..test_function at 0x7fd0eb1fd378> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has experimental_relax_shapes=True option that relaxes argument shapes that can avoid unnecessary retracing. For (3), please refer to https://tensorflowcn.cn/tutorials/customization/performance#python_or_tensor_args and https://tensorflowcn.cn/api_docs/python/tf/function for more details.

    我尝试在网上查找解决方案,但不太理解。
    我很乐意听到您对此问题的答复。
    请告诉我。
    谢谢你

    • Jason Brownlee 2020年12月6日 上午7:04 #

      暂时忽略它吧。

      • Alex 2021年1月15日 下午10:40 #

        我遇到了同样的问题,有什么消息吗?
        谢谢

  86. Lilo 2021年2月4日 上午12:50 #

    亲爱的 Jason,

    感谢您的教程。

    我想对具有多个输入的Keras模型执行交叉验证。当使用具有多个输入的cross_val_score时,似乎不起作用,并且我遇到了这个错误:“ValueError: Found input variables with inconsistent numbers of samples: [2, 500]”。

    这是代码

    accuracies = cross_val_score(keras_classifier, [X1, X2], y, cv=cv, scoring=’f1_weighted’).

    我知道问题出在输入上,我想问问您如何解决?

    • Jason Brownlee 2021年2月4日 上午6:21 #

      您可能需要手动枚举折叠(fold),并在每个循环中手动拟合/评估模型。

  87. Gus Diamantis 2021年3月24日 上午8:34 #

    你好,Jason!

    如果我想绘制每个epoch的val_acc,以及我运行的每个案例的val_acc,这些数据是否会存储?

    提前感谢!

    • Jason Brownlee 2021年3月25日 上午4:35 #

      我建议直接使用keras API,然后绘制调用fit()返回的history,例如:
      https://machinelearning.org.cn/display-deep-learning-model-training-history-in-keras/

      • Vijay Anaparthi 2021年4月18日 下午3:02 #

        但在这种情况下,它不会打印val_accuaracy,对吗?因为这里我们没有分割训练/验证集,而是使用了k-fold cv,如下所示。

        model = KerasClassifier(build_fn=create_model, epochs=150, batch_size=10, verbose=0)
        results = cross_val_score(model, X, Y, cv=kfold)

        在这里,我如何在训练模型时打印每个epoch的val_accuarcay?

        • Jason Brownlee 2021年4月19日 上午5:49 #

          您必须手动逐个epoch训练模型,在一个for循环中。

          或者,直接使用keras API并使用回调功能。

  88. Andrei 2021年4月6日 下午4:04 #

    你好 Jason,
    我想说,我非常感谢您在制作网站帖子方面付出的时间和精力。我从教程中学到了很多,并觉得自己很幸运能找到这个资源。

    说了这些,当我按照您的教程尝试在项目中实现交叉验证时,我遇到了一些问题。
    我也在StackOverflow上发布了我的问题。
    https://stackoverflow.com/questions/66963373/scikit-learn-cross-val-score-throws-valueerror-the-first-argument-to-layer-cal

    在仔细遵循了所有步骤后,我得到的结果是一个包含NaN的数组
    array([nan, nan, nan, nan, nan])

    我将error_score=”raise”传递给了cross_val_score,现在我得到了
    ValueError: The first argument to Layer.call must always be passed.

    您能帮我解决这个问题吗?

  89. ENAS KHALIL 2021年4月30日 上午8:29 #

    亲爱的Jason,非常感谢您提供这些有价值的教程,我每天都在学习!
    我正在尝试将网格搜索与我的LSTM模型一起使用,但我遇到了一个问题,fit()需要二维数组,而LSTM需要三维数组。我的代码是

    # 创建模型的功能,KerasClassifier 所必需
    def create_model(learn_rate, dropout_rate)

    # 创建模型
    model = Sequential()
    model.add(Dense(300, activation=’relu’))

    model.add(Bidirectional(LSTM(300, activation=’relu’, return_sequences=True)))
    model.add(Dropout(drop_out2))
    model.add(Dropout(dropout_rate))
    model.add(Bidirectional(LSTM(100, activation=’relu’, return_sequences=True)))
    model.add(Dropout(dropout_rate))
    model.add(Bidirectional(LSTM(50, activation=’relu’, return_sequences=True)))
    model.add(Dropout(dropout_rate))
    model.add(TimeDistributed(Dense(11,activation=”sigmoid”)))
    # Compile the model
    adam = Adam(lr=learn_rate)
    model.compile(loss=’mse’, optimizer=adam, metrics=[‘accuracy’])
    return model

    # 扩展我的数据维度
    X_all = np.expand_dims(X_all, 1)
    Y_all = np.expand_dims(Y_all, 1)
    # ###################

    # 创建模型
    model = KerasClassifier(build_fn=create_model, verbose=10)
    # 定义您希望在网格搜索中使用的参数以及您希望尝试的值列表
    # 以及您希望尝试的值列表

    learn_rate = [0.001, 0.02]
    dropout_rate = [0.0, 0.2, 0.5]
    batch_size = [10,20,30]

    epochs = [5,10,20]

    # 设置随机种子以保证结果可复现
    seed = 30

    scoring = {‘F1_score’: ‘f1_micro’,’precision_micro’: ‘precision_micro’,’Accuracy’: ‘jaccard’}
    # 创建网格搜索参数字典
    param_grid =dict(learn_rate=learn_rate, dropout_rate=dropout_rate, batch_size=batch_size, epochs=epochs )

    # 构建并拟合GridSearchCV
    grid = GridSearchCV(estimator=model, param_grid=param_grid,scoring=scoring,refit=’Accuracy’,
    cv=5, verbose=10)

    grid_results = grid.fit(X_all, Y_all)

    # 以可读的格式总结结果
    print(“Best: {0}, using {1}”.format(grid_results.best_score_, grid_results.best_params_))

    means = grid_results.cv_results_[‘mean_test_score’]
    stds = grid_results.cv_results_[‘std_test_score’]
    params = grid_results.cv_results_[‘params’]

    for mean, stdev, param in zip(means, stds, params)
    print(‘{0} ({1}) with: {2}’.format(mean, stdev, param))

    ———————————————————————————————-
    我的任务是多标签分类任务——情感分析

    ————————————————————————————————————————————————————

    当我运行时,我得到以下信息

    回溯(最近一次调用)

    File “D:\code in thesis\new experiment 6-4-2021\grid search4.py”, line 215, in
    grid_results = grid.fit(X_all, Y_all)

    File “C:\Users\Admin\anaconda3\lib\site-packages\sklearn\utils\validation.py”, line 72, in inner_f
    return f(**kwargs)

    File “C:\Users\Admin\anaconda3\lib\site-packages\sklearn\model_selection\_search.py”, line 765, in fit
    self.best_estimator_.fit(X, y, **fit_params)

    File “C:\Users\Admin\anaconda3\lib\site-packages\tensorflow\python\keras\wrappers\scikit_learn.py”, line 222, in fit
    raise ValueError(‘Invalid shape for y: ‘ + str(y.shape))

    ValueError: Invalid shape for y: (4381, 1, 11)

    =————————————————————————————————————————————-
    我该如何解决这个问题?
    另外,如果我没有在GridSearchCV中指定分数,那么输出的默认分数应该是什么?

    非常感谢您的鼎力支持。

  90. George 2021年8月18日 下午2:42 #

    嗨,Jason,
    在运行create_model函数时,使用

    param_grid = dict(dropout_rate=dropout_rate)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, cv=5)
    grid_result = grid.fit(X, Y)

    我收到了一个UserWarning

    UserWarning:
    model.predict_classes() is deprecated and will be removed after 2021-01-01. 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).
    warnings.warn('
    model.predict_classes() is deprecated and '

    请问如何解决这个问题?
    谢谢

    • George 2021年8月18日 下午3:07 #

      实际上,当使用验证集拟合grid时,例如

      grid_result = grid.fit(X_train, Y_train, validation_data=(X_valid, y_valid))


      我收到了上述UserWarning。

      • George 2021年8月18日 下午3:10 #

        在grid.fit上使用验证集是否正确?

        • Adrian Tam
          Adrian Tam 2021年8月19日 上午3:45 #

          您上面的代码是正确的。用训练集拟合,用验证集验证。

      • Adrian Tam
        Adrian Tam 2021年8月19日 上午3:44 #

        这个被弃用的警告没关系。它只是意味着语法在未来会有问题。这通常是当您的底层库比高层库更新时发生的。将来,当高层库有新版本时,它可能会消失。

        • George 2021年8月19日 上午9:53 #

          非常感谢您,@Adrian。

          • Adrian Tam
            Adrian Tam 2021年8月20日 上午1:02 #

            不客气。

  91. Siva Kumar Prasad Chebiyyam 2023年5月9日 上午4:20 #

    非常感谢您的分享……。

    • James Carmichael 2023年5月9日 上午9:40 #

      嗨,Siva……不客气!

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。