如何使用 Keras 函数式 API 进行深度学习

Keras Python 库使创建深度学习模型快速而简单。

顺序式 API 允许您为大多数问题逐层创建模型。它的局限性在于不允许您创建共享层或具有多个输入或输出的模型。

Keras 中的函数式 API 是创建模型的另一种方式,它提供了更大的灵活性,包括创建更复杂的模型。

在本教程中,您将学习如何使用 Keras 中更灵活的函数式 API 来定义深度学习模型。

完成本教程后,您将了解:

  • 顺序式 API 和函数式 API 之间的区别。
  • 如何使用函数式 API 定义简单的多层感知器、卷积神经网络和循环神经网络模型。
  • 如何定义具有共享层和多个输入和输出的更复杂模型。

通过我的新书《使用 Python 进行深度学习启动您的项目,其中包括逐步教程和所有示例的 Python 源代码文件。

让我们开始吧。

  • 2017 年 11 月更新:添加了关于输入层悬空维度的说明。
  • 2018 年 11 月更新:添加了 CNN 缺少展平层,感谢 Konstantin。
  • 2018 年 11 月更新:添加了函数式 API Python 语法的描述。

教程概述

本教程分为7个部分;它们是:

  1. Keras 顺序模型
  2. Keras 函数式模型
  3. 标准网络模型
  4. 共享层模型
  5. 多输入多输出模型
  6. 最佳实践
  7. 新功能:关于函数式 API Python 语法的说明

1. Keras 顺序模型

回顾一下,Keras 提供了一个顺序模型 API。

如果您是Keras或深度学习的新手,请参阅此分步Keras教程。

顺序模型 API 是一种创建深度学习模型的方式,其中创建了 Sequential 类的实例,并向其添加模型层。

例如,可以定义层并将其作为数组传递给 Sequential

层也可以分段添加

顺序模型 API 在大多数情况下非常适合开发深度学习模型,但它也有一些局限性。

例如,定义可能具有多个不同输入源、产生多个输出目的地或重用层的模型并不简单。

2. Keras 函数式模型

Keras 函数式 API 提供了一种更灵活的模型定义方式。

它特别允许您定义多输入或多输出模型以及共享层的模型。更重要的是,它允许您定义特设的非循环网络图。

模型通过创建层实例并将其成对直接连接,然后定义一个 Model 来指定作为模型输入和输出的层来定义。

我们依次看看 Keras 函数式 API 的三个独特方面

1. 定义输入

与顺序模型不同,您必须创建并定义一个独立的输入层,该层指定输入数据的形状。

输入层接受一个形状参数,它是一个元组,指示输入数据的维度。

当输入数据是一维时(例如多层感知器),形状必须明确为训练网络时用于拆分数据的 mini-batch 大小留出空间。因此,当输入是一维时(例如 (2,)),形状元组总是定义为悬空的最后一个维度。

2. 连接层

模型中的层成对连接。

这是通过在定义每个新层时指定输入来源来完成的。使用括号表示法,即在创建层之后,指定当前层的输入来自哪个层。

让我们通过一个简短的例子来阐明这一点。我们可以像上面那样创建输入层,然后创建一个隐藏层作为 Dense 层,它只接收来自输入层的输入。

请注意在创建 Dense 层之后 (visible) 将输入层输出作为 Dense 隐藏层的输入进行连接。

正是这种逐层连接的方式赋予了函数式 API 灵活性。例如,您可以看到开始定义即时层图是多么容易。

3. 创建模型

创建所有模型层并将它们连接在一起后,您必须定义模型。

与顺序式 API 一样,模型是您可以总结、拟合、评估和用于进行预测的东西。

Keras 提供了一个 Model 类,您可以使用它从您创建的层创建模型。它要求您只指定输入和输出层。例如:

现在我们已经了解了 Keras 函数式 API 的所有关键部分,让我们尝试定义一系列不同的模型并进行一些实践。

每个示例都是可执行的,并打印结构并创建图的图表。我建议您为自己的模型执行此操作,以明确您究竟定义了什么。

我希望这些示例能为您将来使用函数式 API 定义自己的模型提供模板。

3. 标准网络模型

刚开始使用函数式 API 时,最好看看一些标准神经网络模型是如何定义的。

在本节中,我们将介绍如何定义简单的多层感知器、卷积神经网络和循环神经网络。

这些示例将为理解后面更复杂的示例奠定基础。

多层感知器

在本节中,我们为二元分类定义一个多层感知器模型。

该模型有 10 个输入,3 个隐藏层,分别有 10、20 和 10 个神经元,以及一个有 1 个输出的输出层。每个隐藏层使用修正线性激活函数,输出层使用 sigmoid 激活函数进行二元分类。

运行示例会打印网络的结构。

模型图的绘图也已创建并保存到文件中。

Multilayer Perceptron Network Graph

多层感知器网络图

卷积神经网络

在本节中,我们将定义一个用于图像分类的卷积神经网络。

该模型接收黑白 64×64 图像作为输入,然后包含两个卷积和 池化层 的序列作为特征提取器,随后是一个全连接层来解释特征,以及一个带有 sigmoid 激活的输出层用于两类预测。

运行示例会总结模型层。

模型图的绘图也已创建并保存到文件中。

Convolutional Neural Network Graph

卷积神经网络图

循环神经网络

在本节中,我们将定义一个长短期记忆循环神经网络用于序列分类。

该模型期望 100 个时间步长,每个时间步长具有一个特征作为输入。该模型有一个单个 LSTM 隐藏层来从序列中提取特征,然后是一个全连接层来解释 LSTM 输出,再然后是一个输出层用于进行二元预测。

运行示例会总结模型层。

模型图的绘图也已创建并保存到文件中。

Recurrent Neural Network Graph

循环神经网络图

4. 共享层模型

多个层可以共享一个层的输出。

例如,一个输入可能存在多个不同的特征提取层,或者多个层用于解释特征提取层的输出。

我们来看这两个例子。

共享输入层

在本节中,我们定义了多个具有不同大小内核的卷积层来解释图像输入。

该模型接收大小为 64x64 像素的黑白图像。有两个 CNN 特征提取子模型共享此输入;第一个的内核大小为 4,第二个的内核大小为 8。这些特征提取子模型的输出被展平为向量并连接成一个长向量,然后传递给一个全连接层进行解释,最后由一个输出层进行二元分类。

运行示例会总结模型层。

模型图的绘图也已创建并保存到文件中。

Neural Network Graph With Shared Inputs

具有共享输入的神经网络图

共享特征提取层

在本节中,我们将使用两个并行子模型来解释 LSTM 特征提取器的输出,用于序列分类。

模型的输入是 100 个时间步长,每个时间步长具有 1 个特征。一个具有 10 个记忆单元的 LSTM 层解释此序列。第一个解释模型是一个浅层单全连接层,第二个是一个深度 3 层模型。两个解释模型的输出被连接成一个长向量,该向量传递给用于进行二元预测的输出层。

运行示例会总结模型层。

模型图的绘图也已创建并保存到文件中。

Neural Network Graph With Shared Feature Extraction Layer

带共享特征提取层的神经网络图

5. 多输入多输出模型

函数式 API 也可用于开发具有多输入(可能具有不同模态)的更复杂模型。它还可用于开发生成多输出的模型。

我们将在本节中分别介绍这些示例。

多输入模型

我们将开发一个图像分类模型,它以两个不同尺寸的图像版本作为输入。具体来说,一个是黑白 64×64 版本,另一个是彩色 32×32 版本。独立的特征提取 CNN 模型分别对每个版本进行操作,然后将两个模型的结果连接起来进行解释和最终预测。

请注意,在创建 Model() 实例时,我们将两个输入层定义为一个数组。具体如下:

完整的示例如下所示。

运行示例会总结模型层。

模型图的绘图也已创建并保存到文件中。

Neural Network Graph With Multiple Inputs

带多个输入的神经网络图

多输出模型

在本节中,我们将开发一个模型,该模型能够进行两种不同类型的预测。给定一个包含 100 个时间步长的一个特征的输入序列,该模型将同时对序列进行分类,并输出一个长度相同的新序列。

一个 LSTM 层解释输入序列并返回每个时间步长的隐藏状态。第一个输出模型创建一个堆叠的 LSTM,解释特征,并进行二元预测。第二个输出模型使用相同的输出层对每个输入时间步长进行实值预测。

运行示例会总结模型层。

模型图的绘图也已创建并保存到文件中。

Neural Network Graph With Multiple Outputs

带多个输出的神经网络图

6. 最佳实践

在本节中,我将为您提供一些技巧,帮助您在定义自己的模型时最大限度地利用函数式 API。

  • 一致的变量名。对输入层(visible)和输出层(output)使用相同的变量名,甚至可以对隐藏层(hidden1、hidden2)也使用相同的变量名。这将有助于正确地连接各个部分。
  • 审查层摘要。始终打印模型摘要并审查层输出,以确保模型按照您的预期连接在一起。
  • 审查图表。始终创建模型图表并审查它,以确保所有部分都按照您的意图组合在一起。
  • 命名层。您可以为层分配名称,这些名称将在审查模型图的摘要和图表时使用。例如:Dense(1, name='hidden1')。
  • 分离子模型。考虑分离子模型的开发,并在最后将子模型组合在一起。

在使用函数式 API 时,您有什么自己的最佳实践技巧吗?
请在评论中告诉我。

7. 函数式 API Python 语法说明

如果您是 Python 新手或刚接触 Python,函数式 API 中使用的语法可能会让您感到困惑。

例如,给定

双括号语法有什么作用?

这意味着什么?

它看起来令人困惑,但它不是一个特殊的 Python 特性,只是一行代码做了两件事。

第一个括号“(32)”通过类构造函数创建层,第二个括号“(input)”是一个通过 __call__() 函数实现的无名函数,当调用时将连接层。

__call__() 函数是所有 Python 对象上的默认函数,可以被重写,用于“调用”一个实例化对象。就像 __init__() 函数是所有对象上的默认函数,在实例化对象后立即调用以初始化它一样。

我们可以在两行代码中完成同样的事情

我想我们也可以显式地调用对象的 __call__() 函数,尽管我从未尝试过

进一步阅读

如果您想深入了解此主题,本节提供了更多资源。

总结

在本教程中,您学习了如何使用 Keras 中的函数式 API 来定义简单和复杂的深度学习模型。

具体来说,你学到了:

  • 顺序式 API 和函数式 API 之间的区别。
  • 如何使用函数式 API 定义简单的多层感知器、卷积神经网络和循环神经网络模型。
  • 如何定义具有共享层和多个输入和输出的更复杂模型。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

对《如何使用 Keras 函数式 API 进行深度学习》的 314 条回复

  1. Salameh 2017 年 10 月 27 日上午 5:36 #

    谢谢你
    我一直在等待这个教程

    • Jason Brownlee 2017 年 10 月 27 日下午 2:52 #

      谢谢,希望它有所帮助!

      • Fathi 2019 年 1 月 7 日上午 3:22 #

        我正在使用 keras API,我正在使用带有 2 个输入和 1 个输出的共享层,并且在 fit 模型方面遇到了问题

        model.fit([train_images1, train_images2],
        batch_size=batch_size,
        epochs=epochs,
        validation_data=([test_images1, test_images2]))

        我收到此错误

        ValueError: 检查模型输入时出错:您传递给模型的 Numpy 数组列表的大小不是模型预期的大小。预期看到 2 个数组,但却得到了以下包含 1 个数组的列表:[array([[[[0.2 , 0.5019608 , 0.8862745 , …, 0.5686275 ,
        0.5137255 , 0.59607846],
        [0.24705882, 0.3529412 , 0.31764707, …, 0.5803922 ,
        0.57254905, 0.6 ],

        • Jason Brownlee 2019 年 1 月 7 日上午 6:37 #

          也许可以仔细检查数据是否具有每个模型头部预期的形状。

        • Camilo 2021 年 2 月 4 日下午 2:49 #

          你修好了吗?

        • Arbaz 2021 年 8 月 22 日上午 2:38 #

          您没有在 fit 方法中提供输出,这就是它要求 2 个 numpy 数组的原因。

        • Ahmad 2021 年 8 月 22 日下午 7:23 #

          Fathi,你修好了吗??

  2. Thabet Ali 2017 年 10 月 27 日上午 7:21 #

    Jason 你太棒了!

    我迫不及待地想看到你在这个精彩的博客上发表更多内容,你把所有这些都藏在哪里了 😉
    你能写一本书,在书中实现更多函数式 API 吗?
    我确信这本书会大获成功

    此致
    Thabet

    • Tom 2017 年 10 月 27 日下午 12:18 #

      我同意 Thabet Ali 的观点,需要一本关于高级函数式 API 部分的书。

      • Jason Brownlee 2017 年 10 月 27 日下午 2:57 #

        Tom,函数式 API 的哪些方面你需要更多帮助?

    • Jason Brownlee 2017 年 10 月 27 日下午 2:54 #

      谢谢!

      函数式 API 给你带来了什么问题?

      • Thabet 2017 年 10 月 27 日下午 7:00 #

        我想了解更多关于如何使用函数式 API 在多输入时间序列信号上实现自动编码器,并进行单输出分类。

      • Franco 2018 年 4 月 19 日上午 5:34 #

        嗨,Jason,你是在征求心愿单吗? 🙂
        – 使用 Keras API 进行自动编码器 / 异常检测

        谢谢!

    • Franco 2018 年 4 月 19 日上午 5:32 #

      是的,完全同意。

  3. Alexander 2017 年 10 月 27 日下午 6:50 #

    Jason,感谢您非常有趣的博客。一篇美丽的帖子,可以打开新的大门。

  4. Leon 2017 年 10 月 28 日下午 5:28 #

    Brownlee 博士,
    你是如何学习这么多算法背后的数学知识的?
    致敬
    Leon

  5. Alex 2017 年 11 月 4 日上午 5:32 #

    我能否将 LSTM 层的 initial_state 视为架构的输入分支?假设对于每个数据,我有一个序列 s1、s2、s3 和一个上下文特征 X。我定义了一个具有 128 个神经元的 LSTM,对于每个批次,我想通过 Dense(128) 层将 X 映射到 128 维特征,并为该批次训练设置 initial_state,同时将序列 s1、s2、s3 作为输入序列馈送到 LSTM。

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

      抱歉 Alex,我不太明白。如果你有什么想法,也许可以设计一个实验来测试它们?

  6. Jithu R Jacob 2017 年 11 月 6 日下午 8:38 #

    感谢您精彩的教程。

    对于任何想要直接在 Jupyter Notebook 中可视化的人,请使用以下行。

    from IPython.display import SVG
    from keras.utils.vis_utils import model_to_dot

    SVG(model_to_dot(model).create(prog=’dot’, format=’svg’))

  7. Luis 2017 年 11 月 7 日上午 2:09 #

    感谢这个博客。它真的很有帮助,而且解释得很清楚。

    • Jason Brownlee 2017 年 11 月 7 日上午 9:51 #

      谢谢 Luis,很高兴听到这个消息。感谢您的支持!

  8. Cal Almodovar 2017 年 11 月 11 日上午 8:52 #

    嗨,Jason – 我想知道代码是否应该是

    visible = Input(image_file, shape=( height, width, color channels))

    如果不是,我想知道代码如何引用问题中的图像……

    很惊讶没有人问这个……

    JASON 你真棒!

  9. joe 2017 年 11 月 25 日上午 5:32 #

    在第 1 节中,您写道“形状元组总是定义一个悬空的最后一个维度”,但是当您定义卷积网络时,您将其定义为

    visible = Input(shape=(64,64,1))

    没有任何悬空的最后一个维度。我是不是漏掉了什么?

    • Jason Brownlee 2017 年 11 月 25 日上午 10:23 #

      是的,我错了。这只适用于一维输入。我已经更新了帖子,谢谢。

      • Gerhard Lemmer 2019 年 10 月 14 日下午 6:57 #

        你还是错了。即使是一维输入,也没有“悬空的最后一个维度”。这是一个 Python 用来区分 0 元组或 1 元组与括号的“尾随逗号”。

  10. Franek 2017 年 12 月 1 日下午 9:14 #

    Jason,我读 Keras 和 AI 已经有一段时间了,我总是觉得你的文章比网上的其他内容更清晰、更直接 🙂
    谢谢!

  11. Franek 2017 年 12 月 1 日下午 9:17 #

    Jason,出于某种原因,我需要知道模型中层的输出张量。我尝试按照 Keras 文档尝试使用 layer.get_output、get_output_et 等,但我总是无法得到任何合理的结果。

    我试图在您的博客上寻找这个主题,但没有找到任何内容。您打算写一篇关于这个的帖子吗? 🙂 那真的很有帮助!

  12. Nicola 2017 年 12 月 2 日上午 12:32 #

    嗨,Jason,又一篇很棒的帖子。
    我使用您过去的一篇文章创建了一个 LSTM,它使用多个时间序列,预测特定时间序列的多个步骤。目前我有这个结构

    其中
    – x_tr 的维度为 (440, 7, 6)(440 个样本,7 个过去时间步,6 个变量/时间序列)
    – y_tr 的维度为 (440, 21),即 440 个样本和 21 个提前预测值。

    现在,我想扩展我的网络,使其预测两个时间序列的(多步提前)值。我尝试了以下代码:

    其中 y1 和 y2 的维度均为 (440, 21),但我遇到了这个错误:

    “检查目标时出错:预期 dense_4 具有 3 个维度,但得到的数组形状为 (440, 21)”。

    我应该如何重塑 y1 和 y2 以使其适应网络?

    • Jason Brownlee 2017 年 12 月 2 日上午 9:03 #

      抱歉,我无法为您调试代码,或许您可以发布到 Stack Overflow 上?

      • Owolabi 2020 年 6 月 15 日下午 3:58 #

        查看关于 LSTM 的文章,这将有很大帮助。输出序列的维度必须为 n,2,21;即 n 个数据,2 个时间步和 21 个变量。
        Y.reshape( (440/2),2,21)

    • Owolabi 2020 年 6 月 15 日下午 3:47 #

      x 维度已经就位,将 y 维度更改为 3 个维度。样本数、时间步、变量

  13. Davor 2017 年 12 月 22 日上午 3:12 #

    很棒的教程,它真的帮助我更好地理解了 Model API!谢谢!

  14. Debarati Bhattacharjee 2018 年 1 月 5 日上午 2:27 #

    嗨 Jason,这是一篇很棒的帖子,特别适合初学者学习函数式 API。您介意写一篇帖子,一步一步地为初学者解释图像分割问题的代码吗?

  15. Harminder 2018 年 1 月 6 日晚上 10:10 #

    嗨 Jason,感谢您如此精彩的帖子。它极大地帮助我理解了 Keras 中的函数式 API。
    您能否解释一下在多输出情况下,每个子模型都有不同的目标函数时,我们如何定义 model.compile 语句。例如,一个输出可能是回归,另一个是分类,就像您在这篇帖子中提到的那样。

    • Jason Brownlee 2018 年 1 月 7 日上午 5:06 #

      我相信您必须为整个模型设置一个目标函数。

  16. Harry Garrison 2018 年 1 月 23 日晚上 7:57 #

    一如既往的精彩教程!

    您认为将来可以制作关于 Siamese 神经网络的教程吗?特别有趣的是,如何在 Keras 中创建三元组损失模型,例如识别面部。函数式 API 肯定是可行的方法,但我无法想象层应该如何连接。

  17. Akhtar Ali 2018 年 1 月 27 日晚上 8:20 #

    不错的教程
    非常感谢

  18. Paul the Student 2018 年 2 月 2 日上午 2:49 #

    非常感谢您的教程!它帮助了我很多!

    我有一个关于成本函数的问题。我有一个请求和几个文档:1 个相关的和 4 个不相关的。我想要一个既最大化 SCORE(Q, D+) 又最小化 SCORE(Q, D-) 的成本函数。所以,我可以有 Delta = SUM{ Score(Q,D+) – Score(Q,Di-) },其中 i 属于 (1..4)
    使用铰链损失成本函数,我有 L = max(0, 4 – Delta)

    我想知道,取出这 4 个文档,用 NN 计算它们的得分,然后将所有内容发送到成本函数中,这是一种好的做法吗?

  19. Joseph 2018 年 2 月 15 日上午 3:42 #

    我好奇是否有可能将两个独立的层作为输入层,而不是将它们连接成一个新层,然后让连接层投射到输出层。如果 Keras 无法做到这一点,您能推荐一个允许这样做的库吗?我刚接触神经网络,所以更喜欢适合初学者的库。

    • Jason Brownlee 2018 年 2 月 15 日上午 8:50 #

      除了连接层,还有许多合并层可供选择。

      这有帮助吗?

  20. vinayakumar r 2018 年 2 月 16 日上午 12:16 #

    我有两张图片,第一张图片及其标签是好的,第二张图片及其标签是坏的。我想一次将两张图片传递给深度学习模型进行训练。在测试时,我将有两张(未标记的)图片,我想检测哪张是好的,哪张是坏的。您能告诉我怎么做吗?

    • Jason Brownlee 2018 年 2 月 16 日上午 8:34 #

      您将需要一个带有两个输入的模型,每个图像一个。

  21. vinayakumar r 2018 年 2 月 24 日下午 5:57 #

    您有没有给模型提供两个输入的例子?

  22. John 2018 年 2 月 25 日上午 7:28 #

    非常感谢您的教程!非常感谢。

    我困惑的是多输入多输出的模型。简单来说,假设我们有两个输入层,一些共享层和两个输出层。我能够在 Keras 中构建这个模型并获得预期的模型输出,但是当我尝试拟合模型时,Keras 抱怨道:ValueError:所有输入数组 (x) 应该具有相同的样本数。

    是否无法输入不同大小的输入?

    • Jason Brownlee 2018 年 2 月 25 日上午 7:47 #

      正确。输入必须填充到相同的长度。

  23. saira 2018 年 3 月 8 日上午 6:54 #

    你好,

    在帖子的开头,您谈到了悬挂维度以容纳小批量大小。您能稍微解释一下吗?
    我的特征矩阵是一个 numpy N 维数组,采用 one-hot 编码形式:(6000,200),我的批次大小 = 150。

    这是否意味着我应该提供 shape=(200,)?

    • saira 2018 年 3 月 8 日上午 6:55 #

      * 批次大小 = 50。

      谢谢!

    • Jason Brownlee 2018 年 3 月 8 日下午 2:53 #

      抱歉,这意味着一个 numpy 数组,其中实际上只有 1D 数据,第二个维度未指定。

      例如

      结果是

      它是 1D 的,但对于初学者来说看起来很混乱。

      • saira 2018 年 3 月 8 日下午 5:09 #

        这意味着我应该使用 shape(200,)。

        非常感谢您的及时回复!!!

  24. H Hua 2018 年 3 月 9 日上午 1:32 #

    如何处理多输入多输出的情况

    • Jason Brownlee 2018 年 3 月 9 日上午 6:24 #

      只需将此帖子中的一些示例组合起来即可。

  25. Kieu My 2018 年 3 月 9 日上午 5:18 #

    嗨,Jason,
    非常感谢您的博客,通过一些示例很容易理解,我认识到从一些示例中学习是学习新事物的快速方法之一。
    在您的文章中,我有点困惑,在多输入的情况下。如果您有一个图像,但您想为每个 Conv 分支获取 RGB 32x32x3 版本和 64x64x1 灰度版本。网络如何知道这一点。因为当我们定义网络时,我们只说了 input_shape,我们没有说我们想要将哪种图像导入到分支 1 或分支 2 中的 Conv?在 fit 方法中,我们还必须说输入和输出,而不是给出详细信息。如果我想要灰度版本是:32x32x3(3 因为我想要通道方向,三重灰度版本)。网络如何识别第一个分支是用于灰度。如果我不知道有什么简单的事情,请原谅我的问题。再次感谢您的文章。我一直在关注您的文章。

    • Jason Brownlee 2018 年 3 月 9 日上午 6:28 #

      您可以将所有图像通过一个输入运行,并将较小的图像填充到较大图像的维度。或者您可以使用多输入模型并定义两个独立的输入形状。

  26. saira 2018 年 3 月 9 日下午 5:32 #

    你好,

    当我在模型中运行此函数式 API 进行 K 折交叉验证时,在每次折叠的返回拟合模型中,命名密集层中的数字都在增加。
    例如,在第一折中是“dense_2_acc”,然后在第二折中是“dense_5_acc”。

    我的模型摘要显示我的模型是正确的。您能否告诉我为什么拟合模型“历史”对象中每次折叠的名称会发生变化?

    此致,

  27. Jane 2018 年 3 月 16 日下午 4:33 #

    这是一个非常棒且简洁的初学者教程,用于使用 Keras 构建神经网络。做得好!

  28. HARISANKAR HARIDAS 2018 年 3 月 19 日晚上 10:44 #

    谢谢您的教程。

    “当输入数据是一维的,例如多层感知器时,形状必须明确为训练网络时用于分割数据的迷你批次大小的形状留出空间。

    因此,当输入是一维时,形状元组总是定义为悬挂的最后一个维度 (2,)。”


    visible = Input(shape=(2,))

    我一开始读这两句话有点困惑。

    关于末尾逗号:当元组只有一个元素时,总是需要一个末尾逗号。否则 (2) 只返回值 2,而不是包含值 2 的元组。 https://docs.pythonlang.cn/3/reference/expressions.html#expression-lists

    由于 Input 的 shape 参数应该是一个元组(https://keras.org.cn/layers/core/#input),当我们有一个要传递的单个元素时,除了添加逗号之外,我们别无选择。

    所以,我无法理解“形状必须明确为迷你批次大小的形状留出空间……因此,形状元组总是定义为悬挂的最后一个维度”所隐含的含义

  29. Jeremy 2018 年 3 月 27 日上午 2:50 #

    嗨,Jason,

    非常感谢这篇精彩的帖子。

    所以,在您共享输入层的情况下,您有相同的 CNN 模型用于特征提取,并且输出可以连接,因为两个特征都产生了二元分类结果。

    但是,如果我们有单独的分类模型(用于序列分类)和回归模型(用于时间序列),它们依赖于相同的输入数据。那么,是否可以将分类模型(产生两个以上的类别)与回归模型连接起来,并且模型连接后的最终结果是二元分类?

    在这种情况下,非常感谢您的意见。

    谢谢你。

    • Jason Brownlee 2018 年 3 月 27 日上午 6:39 #

      我不确定我是否理解。也许可以尝试一下,并尽可能多地尝试各种变体,然后看看效果如何。

  30. Dhruv 2018 年 5 月 2 日下午 1:59 #

    嗨 Jason,谢谢您这篇简洁的帖子。

  31. Wayne Satz 2018 年 5 月 5 日上午 8:11 #

    谢谢 Jason,非常棒且有帮助的帖子
    您能详细介绍一下如何使用函数式 API 组合宽深模型吗?

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

      感谢您的建议。

      您对这种方法有什么具体问题或疑虑吗?

  32. Ankush Chandna 2018 年 5 月 15 日晚上 11:31 #

    谢谢 Jason,

    您的文章是最好的,文章之间的一致性令人钦佩。

    您能否也用函数式 API 解释一下残差网络。

    谢谢

  33. mina 2018 年 5 月 25 日晚上 7:17 #

    非常感谢您的精彩文章。
    尽管我有一个问题,我使用多输入多输出模型和相同的网络作为我的输入。我希望在它们之间共享权重,您能指出我应该如何处理这个问题吗?

    • Jason Brownlee 2018 年 5 月 26 日上午 5:53 #

      在层之间复制它们,或使用一个允许您重用层的包装器,例如 timeDistributed。

  34. Ahmed Sahlol 2018 年 6 月 11 日上午 1:55 #

    您的所有帖子都很棒。上帝保佑您 🙂

  35. Ahmed Sahlol 2018 年 6 月 11 日上午 9:32 #

    真的,很棒的教程。
    你为什么不用测试步骤“预测”来完成它呢?
    再次感谢 🙂

  36. Ahmed Sahlol 2018 年 6 月 12 日上午 1:24 #

    “共享输入层”非常有趣。我想知道这两个卷积结构是否可以替换为两个预训练模型(比如 VGG16 和 Inception)。您怎么看?

  37. Shardul Singh 2018 年 6 月 12 日下午 7:22 #

    这个问题是关于您之前关于“使用窗口方法的多层感知器”的帖子:https://machinelearning.org.cn/time-series-prediction-with-deep-learning-in-python-with-keras/

    在您的代码中,您成功地使用多维数组输入创建了一个模型,而无需将其展平。
    使用 Keras 函数式 API 也能做到这一点吗?我找到的每个解决方案似乎都需要展平数据,但我正在尝试进行时间序列分析,展平会导致信息丢失。

  38. Joshna 2018 年 6 月 14 日下午 3:09 #

    嗨,
    感谢这篇博客。我想知道如何从 Alexnet 模型的中间层提取特征。我正在使用函数式 API。

  39. joost zeeuw 2018 年 6 月 15 日下午 6:13 #

    嗨,Jason!

    再次感谢您的精彩博客。我有一个关于当前多输入模型研究的问题。

    我正在构建一个结合文本序列和患者特征的模型。为此,我正在使用一个 LSTM“分支”,我将其与神经网络中的一个普通“分支”连接起来。我很好奇您是否遇到过一些深入探讨此类架构的精彩论文/文章,可能会给我一些关于如何优化此模型并彻底理解它的见解。

    此致,
    Joost Zeeuw

    • Jason Brownlee 2018 年 6 月 16 日上午 7:25 #

      手头没有。我建议你对架构进行大量实验,看看什么最适合你的数据集。

      我很想听听你的进展。

  40. Isaac 2018 年 7 月 3 日上午 6:27 #

    嗨 Jason!博客写得真好!

    我的问题是:如何使用生成器为这种模型提供数据?实际上是两个生成器,一个用于测试,一个用于训练。顺便说一下,我正在尝试进行音素分类

    我尝试了类似这样的代码:

    #模型
    input_data = Input(name='the_input', shape=(None, self.n_feats))

    x = Bidirectional(LSTM(20, return_sequences=False, dropout=0.3), merge_mode='sum')(input_data)
    y_pred = Dense(39, activation="softmax"), name="out")(x)

    labels = Input(name='the_labels', shape=[39], dtype='int32') # 不确定这个,但否则如何比较标签呢??
    self.model = Model(inputs=[input_data, labels], outputs=y_pred)
    ...
    # 为了简化,我将省略优化和编译步骤

    我的生成器会产生类似这样的东西

    return ({'the_input':data_x, 'the_labels':labels},{'out':np.zeros([batch_size, np.max(seq_lens), num_classes])})


    另外,只是为了确定,对于序列分类(多对一),我应该在循环层中使用 return_sequences=False,而不是 TimeDistributed rigth?

    谢谢!
    艾萨克

  41. priya 2018 年 7 月 11 日上午 3:22 #

    嗨,Jason,

    感谢这篇博客。它非常有趣。读完你的博客后,我有一个疑问,如果你能帮助我解决这个问题——如果一个人想从一个经过微调的 Siamese 网络中的中间层提取特征,该网络已经用前馈多层感知器进行了预训练,该怎么办?

    您能提供任何线索吗?这将对我非常有帮助。

    • Jason Brownlee 2018 年 7 月 11 日上午 6:01 #

      您可以通过 layer.get_weights() 获取网络的权重。

  42. Hee 2018 年 7 月 16 日下午 5:06 #

    你好,感谢你的文章。
    我有一个问题。
    结合离散和连续特征层更有效的方法是什么?

    • Jason Brownlee 2018 年 7 月 17 日上午 6:12 #

      通常,整数编码、独热编码或嵌入层对分类变量是有效的。

  43. Vivek 2018 年 7 月 17 日上午 7:03 #

    嗨,Jason,您的博客非常好。我想在 Keras 中添加自定义层。您能解释一下我该怎么做吗?

    • Jason Brownlee 2018 年 7 月 17 日下午 2:30 #

      谢谢。

      我希望将来能涵盖这个话题。

  44. Matt 2018年7月20日 下午3:48 #

    嗨,Jason,

    感谢这篇精彩的文章。我尝试实现一个1个隐藏层(2个神经元)后接一个输出层,都使用带有Sigmoid激活的密集层,用于训练XOR输入——这是一个经典问题,当然有解决方案。然而,在没有指定特定初始化的情况下,我无法训练这个最小神经元网络以找到解决方案(使用足够多的神经元时,我认为它独立于初始化而工作)。您能否提供这样一个简单的示例,作为Keras机制的测试用例,并就损失函数存在多个临界点时可能遇到的陷阱进行评论?

    祝好,
    Matt

    • Jason Brownlee 2018年7月21日 上午6:30 #

      感谢您的建议。

      XOR无论如何都只是一个学术练习,也许可以关注一些真实数据集?

  45. Sola 2018年7月22日 上午10:40 #

    感谢您出色的教程。我正在尝试将Keras函数式API用于我的问题。我有两组不同的输入,我正在尝试使用一个双输入-单输出模型。
    我的模型看起来像您的“多输入模型”示例,正如您所提到的,我正在做同样的事情,比如
    model = Model(inputs=[visible1, visible2], outputs=output)
    我正在使用这段代码拟合模型
    model.fit([XTrain1, XTrain2], [YTrain1, YTrain2], validation_split=0.33, epochs=100, batch_size=150, verbose=2),但我收到了关于大小不匹配的错误。
    输出TensorShape的维度为3,而YTrain1和YTrain2的形状也为(–, 3)。您对如何解决此错误有什么建议吗?我将不胜感激。

    • Jason Brownlee 2018年7月23日 上午6:04 #

      如果模型只有一个输出,您只需要指定一个yTrain。

      • Sola 2018年8月10日 上午5:11 #

        谢谢你的回复。
        我还有另一个问题,如果您能帮助我,我将不胜感激。
        在您的多层感知器示例中,输入数据是一维的,如果我在Dense4的末尾添加一个reshape模块,将输出重塑为二维对象,那么是否可以将这个二维特征空间视为图像?
        有没有绘制这个二维张量对象的语法?
        谢谢

        • Jason Brownlee 2018年8月10日 上午6:21 #

          如果您在图像上拟合MLP,图像像素必须在作为输入提供之前被展平为1D。

  46. tuan anh 2018年7月25日 下午5:45 #

    谢谢,Jason
    您能给我一个Conv1D => BiLSTM => Dense组合的例子吗?
    我尝试过,但不知道如何将它们组合起来

    • Jason Brownlee 2018年7月26日 上午7:37 #

      这将有所帮助,作为一个开始
      https://machinelearning.org.cn/cnn-long-short-term-memory-networks/

      • tuan anh 2018年7月26日 下午12:24 #

        非常感谢您的快速回复,Jason,我读了这篇文章,非常有用!

        但当我应用时,我发现它有一个非常奇怪的事情,我不知道为什么

        看我的程序,它运行正常,但val_acc,我不知道为什么它总是 .] – ETA: 0s – loss: 0.2195 – acc: 0.8978
        Epoch 00046: loss improved from 0.22164 to 0.21951,

        40420/40420 [==============================] – 386s – loss: 0.2195 – acc: 0.8978 – val_loss: 5.2004 – val_acc: 0.2399
        Epoch 48/100
        40416/40420 [============================>.] – ETA: 0s – loss: 0.2161 – acc: 0.9010
        Epoch 00047: loss improved from 0.21951 to 0.21610,

        40420/40420 [==============================] – 390s – loss: 0.2161 – acc: 0.9010 – val_loss: 5.0661 – val_acc: 0.2369
        Epoch 49/100
        40416/40420 [============================>.] – ETA: 0s – loss: 0.2274 – acc: 0.8965
        Epoch 00048: loss did not improve
        40420/40420 [==============================] – 393s – loss: 0.2276 – acc: 0.8964 – val_loss: 5.1333 – val_acc: 0.2412
        Epoch 50/100
        40416/40420 [============================>.] – ETA: 0s – loss: 0.2145 – acc: 0.9028
        Epoch 00049: loss improved from 0.21610 to 0.21455,

        40420/40420 [==============================] – 395s – loss: 0.2146 – acc: 0.9027 – val_loss: 5.3898 – val_acc: 0.2344
        Epoch 51/100
        40416/40420 [============================>.] – ETA: 0s – loss: 0.2100 – acc: 0.9051
        Epoch 00050: loss improved from 0.21455 to 0.20999,

        • Jason Brownlee 2018年7月26日 下午2:25 #

          您可能需要根据您的问题调整网络。

          • tuan anh 2018年7月26日 下午3:28 #

            我尝试了很多次,但即使它过拟合了所有数据库,val_acc仍然很低。
            我知道它过拟合了所有数据,因为我使用预测程序预测了所有数据库,准确率与训练准确率一样高。
            谢谢你

          • Jason Brownlee 2018年7月27日 上午5:45 #

            也许可以尝试添加一些正则化,例如Dropout?

            也许可以获取更多数据?

            也许可以尝试减少训练的epochs数量?

            也许可以尝试减小模型的大小?

  47. tuan anh 2018年7月30日 下午12:29 #

    谢谢你,Jason,
    ——我正在尝试通过添加一些 dropout 层进行测试,
    ——训练时的 epoch 数量不需要减少,因为我自己经常观察到这一点,
    ——关于模型的大小,我正在并行训练 4 个程序来检查它。
    ——最后一点,获取更多数据,如果以上所有方法都获得更好的结果,我才会这样做

  48. sahand 2018年9月1日 下午10:27 #

    嗨 Jason 感谢这篇很棒的文章
    真的很有帮助

    当我运行这段代码时

    l_input = Input(shape=(336, 25))
    adense = GRU(256)(l_input)
    bdense = Dense(64, activation=’relu’)(adense)
    .
    .
    .

    我会收到这个错误

    ValueError: Invalid reduction dimension 2 for input with 2 dimensions. for ‘model_1/gru_1/Sum’ (op: ‘Sum’) with input shapes: [?,336], [2] and with computed input tensors: input[1] = .

    我真的筋疲力尽了,我在任何地方都找不到答案。
    我该怎么办?
    我感谢您的帮助

    • Jason Brownlee 2018年9月2日 上午5:31 #

      听起来数据和模型预期不符。也许可以改变数据或模型?

  49. Bradley Elfman 2018年9月15日 上午5:33 #

    这是一个特别有用的教程,但我没有数据源就无法开始使用。

  50. Bradley Elfman 2018年9月15日 上午6:00 #

    我之前留过一个关于需要数据源的回复,我看到其他读者没有这个问题,但我似乎仍然处于不知道输入什么数据或如何为这些示例进行预处理的阶段。我也很困惑,因为看起来PNG是一种常见的源。

    我对一个能接收文本和问题并返回答案的示例特别感兴趣——我在哪里可以找到这样的输入以及如何将其适配到您的代码中?

  51. Bradley Elfman 2018年9月15日 下午10:46 #

    Jason,您的github数据集中哪个数据集适合这个LSTM教程?或者您能推荐一个在线数据集吗?我对用于文本处理(非IMDB)的LSTM和Keras函数式API都感兴趣。

  52. Mark 2018年10月2日 下午5:44 #

    有没有可能用一些真实/虚拟数据作为载体来制作一个关于这个的教程?

  53. rim 2018年10月4日 下午9:25 #

    谢谢您,Jason先生,

    您能帮我使用卡尔曼滤波器预测太阳辐射吗?

    您有关于卡尔曼滤波器预测太阳辐射的matlab代码吗?

    此致

    • Jason Brownlee 2018年10月5日 上午5:36 #

      抱歉,我没有matlab示例,也没有卡尔曼滤波器的示例。

  54. Gledson 2018年10月7日 上午3:08 #

    你好吗?抱歉打扰了。我正在关注您关于Keras使用神经网络和卷积神经网络的解释。我正在尝试使用一组具有三个通道的图像和另一组具有一个通道的图像进行卷积。当我使用Keras为每种类型的图像运行CNN时,我得到了一个结果。所以我有两个输入和一个输出。输入是X_train1,大小为(24484,227,227,1),X_train2,大小为(24484,227,227,3)。所以我分别为每个输入进行卷积,然后使用KERAS的“merge”命令,然后将“merge”应用于CNN。但是,我收到了以下错误
    ValueError: could not broadcast input array from shape (24484,227,227,1) into shape (24484,227,227)。

    我已经尝试删除数字1,所以形状变为(24484,227,227)。这样看起来是对的。但是错误又发生在X_train2上,并带有以下警告
    ValueError: could not broadcast input array from shape (24484,227,227,3) into shape (24484,227,227)。
    但是,我无法删除数字“3”。

    您能帮我消除这个错误吗?

    我的代码是

    X_train1:形状为(24484,227,227,1)
    X_train2:形状为(24484,227,227,3)
    X_val1:形状为(2000,227,227,1)
    X_val2:形状为(2000,227,227,3)

    batch_size=64
    num_epochs=30
    DROPOUT = 0.5

    model_input1 = Input(shape = (img_width, img_height, 1))
    DM = Convolution2D(filters = 64, kernel_size = (1,1), strides = (1,1), activation = “relu”)(model_input1)
    DM = Convolution2D(filters = 64, kernel_size = (1,1), strides = (1,1), activation = “relu”)(DM)

    model_input2 = Input(shape = (img_width, img_height, 3))
    RGB = Convolution2D(filters = 64, kernel_size = (1,1), strides = (1,1), activation = “relu”)(model_input2)
    RGB = Convolution2D(filters = 64, kernel_size = (1,1), strides = (1,1), activation = “relu”)(RGB)

    merge = concatenate([DM, RGB])

    # 第一个卷积层
    z = Convolution2D(filters = 96, kernel_size = (11,11), strides = (4,4), activation = “relu”)(merge)
    z = BatchNormalization()(z)
    z = MaxPooling2D(pool_size = (3,3), strides=(2,2))(z)

    # 第二个卷积层
    z = ZeroPadding2D(padding = (2,2))(z)
    z = Convolution2D(filters = 256, kernel_size = (5,5), strides = (1,1), activation = “relu”)(z)
    z = BatchNormalization()(z)
    z = MaxPooling2D(pool_size = (3,3), strides=(2,2))(z)

    # 剩余的3个卷积层
    z = ZeroPadding2D(padding = (1,1))(z)
    z = Convolution2D(filters = 384, kernel_size = (3,3), strides = (1,1), activation = “relu”)(z)

    z = ZeroPadding2D(padding = (1,1))(z)
    z = Convolution2D(filters = 384, kernel_size = (3,3), strides = (1,1), activation = “relu”)(z)

    z = ZeroPadding2D(padding = (1,1))(z)
    z = Convolution2D(filters = 256, kernel_size = (3,3), strides = (1,1), activation = “relu”)(z)

    z = MaxPooling2D(pool_size = (3,3), strides=(2,2))(z)
    z = Flatten()(z)

    z = Dense(4096, activation=”relu”)(z)
    z = Dropout(DROPOUT)(z)

    z = Dense(4096, activation=”relu”)(z)
    z = Dropout(DROPOUT)(z)

    model_output = Dense(num_classes, activation=’softmax’)(z)
    model = Model([model_input1,model_input2], model_output)
    model.summary()

    sgd = SGD(lr=0.001, decay=1e-6, momentum=0.9, nesterov=True)
    model.compile(loss='categorical_crossentropy',
    optimizer=sgd,
    metrics=['accuracy'])

    print(‘RGB_D’)

    datagen_train = ImageDataGenerator(rescale=1./255)
    datagen_val = ImageDataGenerator(rescale=1./255)

    print(“fit_generator”)
    # 使用训练集训练模型…
    Results_Train = model.fit_generator(datagen_train.flow([X_train1,X_train2], [Y_train1,Y_train2], batch_size = batch_size),
    steps_per_epoch = nb_train_samples//batch_size,
    epochs = num_epochs,
    validation_data = datagen_val.flow([X_val1,X_val1], [Y_val1,Y_val2],batch_size = batch_size),
    shuffle=True,
    verbose=1)

    print(Results_Train.history)

    • Jason Brownlee 2018年10月7日 上午7:26 #

      看起来您的数据和模型不匹配。您可以重塑数据或更改模型的预期。

    • Fathi 2019年1月7日 上午4:46 #

      感谢您提供的所有信息。

      您是否有使用Keras API共享层(2个输入和1个输出)的示例?

      我想知道如何使用每个输入来获取其:Xtrain, Ytrain 和 Xtest, Ytest,

      我想,用一个例子会更简单。

      谢谢你。

  55. Leeor 2018年10月9日 上午12:43 #

    你好,Jason。
    您知道如何将每个模型与不同的损失函数结合起来吗?

    Leeor。

    • Jason Brownlee 2018年10月9日 上午8:44 #

      是的,在它们训练之后,可以作为集成模型。

  56. Konstantin 2018年11月1日 下午11:34 #

    嗨,Jason,
    感谢您精彩的教程!

    我只是想知道“卷积神经网络”的例子。max_pooling2d_2 和 dense_1 之间是不是少了一个 Flatten 层?

    像这样
    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
    flatt = Flatten()(pool2)
    hidden1 = Dense(10, activation=’relu’)(flatt)

    此致

  57. Nada 2018年11月6日 下午3:31 #

    嗨 Jason

    在多输入模型中,您是如何命名图层的?

    ____________________________________________________________________________________________________
    层(类型)输出形状参数 # 连接到
    ====================================================================================================
    input_1 (InputLayer) (None, 64, 64, 1) 0
    ____________________________________________________________________________________________________
    conv2d_1 (Conv2D) (None, 61, 61, 32) 544 input_1[0][0]
    ____________________________________________________________________________________________________
    conv2d_2 (Conv2D) (None, 57, 57, 16) 1040 input_1[0][0]
    ____________________________________________________________________________________________________
    max_pooling2d_1 (MaxPooling2D) (None, 30, 30, 32) 0 conv2d_1[0][0]
    ____________________________________________________________________________________________________
    max_pooling2d_2 (MaxPooling2D) (None, 28, 28, 16) 0 conv2d_2[0][0]
    ____________________________________________________________________________________________________
    flatten_1 (Flatten) (None, 28800) 0 max_pooling2d_1[0][0]
    ____________________________________________________________________________________________________
    flatten_2 (Flatten) (None, 12544) 0 max_pooling2d_2[0][0]
    ____________________________________________________________________________________________________
    concatenate_1 (Concatenate) (None, 41344) 0 flatten_1[0][0]
    flatten_2[0][0]
    ____________________________________________________________________________________________________
    dense_1 (Dense) (None, 10) 413450 concatenate_1[0][0]
    ____________________________________________________________________________________________________
    dense_2 (Dense) (None, 1) 11 dense_1[0][0]
    ====================================================================================================
    总参数:415,045
    可训练参数:415,045
    不可训练参数: 0
    ____________________________________________________________________________________________________

    • Jason Brownlee 2018年11月7日 上午5:57 #

      如果模型一次性构建完成,默认名称即可。

      如果模型是在不同时间构建的,我会给每个头部一个任意名称,例如:name = ‘head_1_’ + name

  58. Or Bennatan 2018年11月6日 下午10:29 #

    对Keras的见解非常深刻。
    我还阅读了您的 Deep_Learning_Time_Series_Forcasting,非常有帮助。

    • Jason Brownlee 2018年11月7日 上午6:02 #

      谢谢。

      正是您的邮件促使我更新这篇文章,增加了Python语法解释!

  59. Jonathan Roy 2018年11月8日 上午2:01 #

    哇,非常感谢您所有的帖子,您为我的学习和原型设计经验节省了大量时间!

    我使用了一个LSTM层,并想使用其输出来馈送一个Dense层以获得第一个预测值,然后将这个新值插入到第一个LSTM输出中,并馈送一个新的LSTM层。我卡在了维度问题上…

    main_inputs = Input(shape=(train_X.shape[1], train_X.shape[2]), name=’main_inputs’)

    ly1 = LSTM(100, return_sequences=False)(main_inputs)
    auxiliary_output = Dense(1, activation=’softmax’, name=’aux_output’)(ly1)

    merged_input = concatenate([main_inputs, auxiliary_output])

    ly2 = LSTM(100, return_sequences=True)(merged_input)
    main_output = Dense(1, activation= ‘softmax’, name=’main_output’)(ly2)

    任何建议都欢迎

    • Jason Brownlee 2018年11月8日 上午6:12 #

      具体是什么问题?

      我没有能力调试您的代码,也许可以发到stackoverflow上?

  60. Alaya 2018年11月11日 上午5:25 #

    谢谢Jason的帖子🙂

    在多输入CNN模型示例中,两张图片是否以相同的索引同时输入到模型中?

    两张图片是否以相同的类别同时输入到模型中?

    在训练中,每张黑白图片是多次(与所有彩色图片一起)输入到模型中,还是每张黑白图片只输入一次(与仅一张彩色图片一起)?

    谢谢..

    • Jason Brownlee 2018年11月11日 上午6:12 #

      两张图片同时提供给模型。

      • Alaya 2018年11月11日 上午8:18 #

        两张图片是否以相同的类别同时输入到模型中?

      • bit_scientist 2020年2月11日 下午5:13 #

        嗨,Jason,我一直在寻找评论,希望有人会问类似的问题。

        我有一些图像及其对应的数值。如果我构建一个用于图像的微调VGG模型和一个用于数值的MLP(或任何其他模型),并像您在这篇文章中那样将它们连接起来,我需要如何保持它们之间的对应关系?

        通过某种标准(例如图像名称)将图像(和数值)输入到模型中是否实际可行?因为我的图像名称和数值数据集中的一列保存着样本的名称。

        非常感谢。

        • Jason Brownlee 2020年2月12日 上午5:42 #

          您可以使用多输入模型,一个用于图像的输入,一个用于数字的输入。

          训练数据集将是两个数组,一个图像数组,一个数字数组。行将对应。

          这有帮助吗?

  61. Meiling 2018年11月14日 上午2:46 #

    你好,现在我想使用一维数据(例如 wave.shape=(360,))作为输入,以及三维数据(例如 velocity.shape=(560,7986,3))作为输出。我想问一下,这个问题是否可以通过多层感知器来训练这些数据解决?我尝试过,但形状问题没有解决,它显示“ValueError: Error when checking target: expected dense_3 to have 2 dimensions, but got array with shape (560, 7986, 3)”

    • Jason Brownlee 2018年11月14日 上午7:35 #

      也许吧,这真的取决于数据代表什么。

  62. CHYOO 2018年12月2日 上午12:33 #

    您好,感谢分享内容🙂
    “多输出”情况与“多任务深度学习”是否相同?

    我正在尝试构建多任务深度学习模型,并在这里找到了。
    再次感谢您。

  63. Antonio 2018年12月7日 下午11:06 #

    Jason,目前我有一个非常微小的贡献。只是一个错别字。在,

    ……共享特征提取层
    在本节中,我们将两个并行子模型来解释输出…

    这句话看起来像缺少一个动词或什么,听起来很奇怪。
    如果对你来说没问题,就忽略吧,肯定是我太累了。

    我希望将来能更实质性地支持这个非凡的网站。

    (你不需要发布这条评论)

    此致
    安东尼奥

    • Jason Brownlee 2018年12月8日 上午7:10 #

      谢谢,已修复!

      (我喜欢保留这些评论,以表明一切都在进步中,并且在逐步改进)

  64. Liu 2018年12月14日 上午2:16 #

    Jason,非常感谢您的教程,它非常有帮助!我有一个问题,ModelCheckpoint回调如何与多个输出一起工作?如果我设置 save_best_only = True 会保存什么?是保存对两个输出都产生最佳总体结果的模型,还是会保存两个模型?

  65. Rojin 2018年12月15日 上午10:41 #

    您能发一篇关于如何在Keras中制作部分连接层的帖子吗?带有预定义的神经元连接(上一层到下一层)。

  66. alija 2019年1月2日 上午2:49 #

    嗨,Jason,

    如果我们想将预测结果写入单独的txt文件,需要在代码末尾添加什么?

    谢谢。

    • Jason Brownlee 2019年1月2日 上午6:41 #

      您可以使用savetext()函数直接将numpy数组保存到csv文件中。

  67. Ritesh 2019年1月11日 晚上8:17 #

    嗨,Jason,我非常喜欢这篇文章。我有一个应用程序,数据以CSV文件形式存在,其中包含四列文本数据,我将前三列作为输入数据来预测第四列数据作为我的输出。我需要将前三列作为输入,因为数据是相关的。您能指导我如何使用glove训练模型吗?
    谢谢

  68. Kaiche 2019年1月31日 晚上7:41 #

    嗨 Jason

    再次感谢您的精彩教程,我想知道将两层作为特征提取进行连接时的区别。您使用了 merge = concatenate([interp1, interp13])

    其他人使用 merge = concatenate([interp1, interp13], axis = -1)。我想知道这两者之间是否有区别,以及区别有多大

  69. majed 2019年2月3日 晚上7:55 #

    嗨 Jason

    感谢您的精彩教程,我想使用带 fit generator 的多输入模型

    model.fit_generator(generator=fit_generator,
    steps_per_epoch=steps_per_epoch_fit,
    epochs=epochs,
    verbose=1,
    validation_data=val_generator,
    validation_steps=steps_per_epoch_val)

    但我收到 ValueError: Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 2 array(s), but instead got the following list of 1 arrays

    keras 代码

    input1 = Input(shape=(145,53,63,40))
    input2 = Input(shape=(145,133560))
    #特征 1
    conv1 = Conv3D(16, (3,3,3),data_format =’channels_last’)(input1)
    pool1 = MaxPooling3D(pool_size=(2, 2,2))(conv1)
    batch1 = BatchNormalization()(pool1)
    ac1=Activation(‘relu’)(batch1)
    …….

    ac3=Activation(‘relu’)(batch3)

    flat1 = Flatten()(ac3)
    #特征 2

    gr1=GRU(8,return_sequences=True)(input2)
    batch4 = BatchNormalization()(gr1)
    ac4=Activation (‘relu’)(batch4)

    flat2= Flatten()(ac4)

    # 合并特征提取器

    merge = concatenate([flat1, flat2])

    output = Dense(2)(merge)
    out=BatchNormalization()(output)
    out1=Activation(‘softmax’)(out)

    # 预测输出

    model = Model(inputs=[input1,input2], outputs=out1)

    opt2 = optimizers.Adam(lr=learn_rate, decay=decay)

    model.compile(loss=’categorical_crossentropy’, optimizer=opt2,
    metrics=['accuracy'])

  70. sanker 2019年2月22日 下午4:28 #

    我尝试了给定部分(5. 多输入和输出模型)
    请帮我拟合数据。我收到了错误
    AttributeError: ‘NoneType’ object has no attribute ‘shape’
    我的输入

  71. Teja 2019年3月1日 早上4:29 #

    我是机器学习新手。使用函数式 API 拟合模型后,我得到了训练准确率和损失。但我不知道如何使用 Keras 函数式 API 找到测试准确率。

    • Jason Brownlee 2019年3月1日 早上6:26 #

      您可以通过调用 model.evaluate() 在测试数据集上评估模型。

  72. David 2019年3月6日 晚上7:40 #

    我想构建 CNN + convLSTM 模型,
    但是,在最后一行出现了维度错误…我该如何调整形状
    :输入 0 与层 conv_lst_m2d_27 不兼容:期望 ndim=5,找到 ndim=4
    input = Input(shape=(30,30,3), dtype=’float32”)

    conv1 = Convolution2D(kernel_size=1, filters=32, strides=(1,1), activation=”selu”)(input)
    conv2 = Convolution2D(kernel_size=2, filters=64, strides=(2,2), activation=”selu”)(conv1)
    conv3 = Convolution2D(kernel_size=2, filters=128, strides=(2,2), activation=”selu”)(conv2)
    conv4 = Convolution2D(kernel_size=2, filters=256, strides=(2,2), activation=’selu’)(conv3)

    ConvLSTM_1 = ConvLSTM2D(32, 2, strides=(1,1) )(conv1)

    • Jason Brownlee 2019年3月7日 早上6:46 #

      也许改变输入形状以匹配模型的预期,或者改变模型以匹配数据形状的预期?

  73. Xu Zhang 2019年3月12日 早上5:54 #

    非常感谢您的精彩文章。

    如果我的问题是这样的,我应该如何使用 API 设置我的模型
    首先,分类化学品是否有毒,如果它们有毒,它们的毒性分数是多少。我可以分别创建两个模型。但是将它们结合在一起是一种很好的正则化,一些论文说。我认为这是一个多输入和多输出问题。我有一个数据集,其输入形状相同,组合输出将是 y1 = 0 或 1,如果 y1=1,则 y2 = 数值分数。

    我不知道在哪里以及如何将 if 语句放入组合模型中。

    任何建议都将不胜感激。

    • Jason Brownlee 2019年3月12日 早上7:00 #

      也许从这里开始
      https://machinelearning.org.cn/start-here/#deeplearning

      • Xu Zhang 2019年3月12日 早上8:56 #

        也许我没有清楚地解释我的问题。

        我可以使用 Keras 分别构建分类和回归模型,没有任何问题。我的问题是如何将这两个模型与“IF 语句”组合成一个多输入、多输出模型。从您提供的链接中,我找不到解决方案。您能详细说明一下吗?非常感谢。

        • Jason Brownlee 2019年3月12日 下午2:30 #

          输入和输出具体是什么?

          • Xu Zhang 2019年3月13日 早上9:39 #

            就像这样

            例如 x1 x2 x3 x4 y1 y2
            1 0.1 0.5 0.7 0.4 1 0.3
            2 0.5 0.2 0.4 0.1 0
            3 0.7 0.6 0.3 0.2 0
            4 0.12 0.33 0.05 0.77 1 0.55
            .. .. .. .. .. .. ..

            只有当 y1 = 1 时,y2 才有一个值

            以上不是真实数据集。

          • Jason Brownlee 2019年3月13日 下午2:08 #

            解决这个问题可能有很多方法。

            也许您可以设置模型始终预测一些东西,并且只在 y1 具有特定值时才关注 y2?

          • Xu Zhang 2019年3月14日 早上3:56 #

            首先,非常感谢您的快速回复。
            我还是不明白。您说有很多方法可以解决,但我不知道其中任何一种。有两个数据集(X1,y1),(X2,y2)。所以我认为这是一个多输入和多输出问题。两个数据集之间的样本数量应该相等吗?

          • Jason Brownlee 2019年3月14日 早上9:28 #

            是的。

  74. Helina 2019年4月21日 晚上8:33 #

    谢谢你,Jason,又一个很棒的教程!你是一位非常有才华的老师!

  75. Zabit 2019年5月22日 晚上7:55 #

    嗨 Jason,我一直关注您的博客和书籍(线性代数用于机器学习),它们非常有帮助。您是否有关于 LSTM 层后接 2D CNN/Maxpool 的帖子?如果您已有帖子,请提供链接。

    实际上,按照这篇帖子中给出的方向操作后,我遇到了一些维度问题。
    https://stackoverflow.com/questions/53904688/using-keras-to-build-a-lstmconv2d-model/56253458#56253458

    但这并没有解决我的问题。如果您能在这方面提供帮助,那就太好了。

    谢谢你

    • Jason Brownlee 2019年5月23日 早上5:58 #

      我不认为我有 LSTM 连接到 CNN,我认为这没有意义。

      你为什么要这样做?

  76. Mostafa Shahriari 2019年6月5日 凌晨1:00 #

    你好,
    首先非常感谢您的出色网页。从我开始进行深度学习的第一天起,它就提供了很大的帮助。不过我有一个问题。您在“多输入模型”小节中提到的具有多个输入和一个输出的模型的相应损失函数是什么?我想知道,如果您的输入是 X1 和 X2,输出是 Y,那么损失函数的数学表达式会是什么。我想做同样的事情。但是,我不确定我将最小化什么。

    另一个问题是关于损失权重。例如,如果我有两个输出和它们各自的两个损失函数,如果我将第一个损失权重设置为零,它会停用与第一个输出相关的训练过程吗?

    提前非常感谢您的帮助。

    此致,

    • Jason Brownlee 2019年6月5日 早上8:47 #

      该模型将为每个输出设置一个损失函数。

      Y 只有一个输出,一个具有两个输入 X1 和 X2 的单输出模型。

      如果输出是向量,则只有一个损失函数,对向量输出中的每个项取平均值。

      在非平凡问题中,除非您过度拟合训练数据,否则您永远不会达到零损失。

      • Mostafa Shahriari 2019年6月7日 凌晨12:48 #

        非常感谢您的回复。但是,您误解了我关于多输出的问题。不过,我已经解决了那个问题。但是我关于包含两个输入(X1 和 X2)和一个输出的网络的问题仍然没有得到解答。我知道它只有一个损失,但我不确定损失是什么。它可以是以下任何一种

        1. [ F1(x1)+F2(x2) – Y ]

        2. [ F(x1,x2) – Y ]

        我不确定这里会是哪一个损失。如果您能帮助我,我将不胜感激。非常感谢。

        • Jason Brownlee 2019年6月7日 早上8:04 #

          多输入中的输入是聚合的,因此损失是两个输入的函数。

  77. Balaji 2019年6月5日 下午3:19 #

    很棒的博客!
    您能帮我们提供一个不使用密集层的示例代码架构吗?
    发现很难理解最后一部分如何摆脱密集层。

    谢谢

    • Jason Brownlee 2019年6月6日 早上6:19 #

      您可以使用任何您想要的输出层。

      你为什么要去掉密集层?

  78. Karthik S 2019年6月21日 早上9:06 #

    太棒了。非常感谢分享。真的很有帮助!你是个巫师……

  79. Wesly Vazkez 2019年6月28日 凌晨12:05 #

    精彩的帖子!它既易于理解,又足够复杂,可以推广多种类型的网络。它对我帮助很大!谢谢!!

  80. Jake 2019年7月23日 凌晨2:38 #

    嗨,Jason,

    你帮了我很多,但我又碰壁了。

    我想构建一个多输出多输入线性回归模型,但在网上找不到任何相关信息。我尝试使用不同的关键词,如使用 keras 的多目标线性回归、多依赖变量、多元。我找不到任何东西。

    您有这方面的资料吗?

    • Jason Brownlee 2019年7月23日 早上8:11 #

      您可以将目标数量指定为输出层中的节点数量。

      是的,我有很多时间序列的例子,你可以从这里开始
      https://machinelearning.org.cn/start-here/#deep_learning_time_series

      还有这个。
      https://machinelearning.org.cn/faq/single-faq/how-do-you-use-lstms-for-multi-step-time-series-forecasting

      这有帮助吗?

      • Jake 2019年7月23日 晚上11:00 #

        嗨,Jason,
        非常感谢您提供的两个链接,我不知道您的资料组织得如此有条理。

        我是机器学习新手,我想我有点困惑。
        假设我有一堆数据,它们都是时间序列数据的平均值。
        我真的需要使用时间序列吗?我有 10 列输入和 5 列输出。但是,我将处理此数据集的时间序列版本。

        另外,时间序列的定义是:“在描述性建模或时间序列分析中,时间序列被建模以确定其在季节模式、趋势、与外部因素关系等方面的组成部分。……相比之下,时间序列预测使用时间序列中的信息(可能带有附加信息)来预测该序列的未来值。”——摘自您的博客

        如果我的数据没有趋势或模式怎么办?比如我的数据是工业数据,例如发动机的数据?我想预测它在特定时间如何运行或类似的事情。

        我还记得您曾发帖说 LSTM 不太适合时间序列预测。我可以使用哪些不同的方法?我没有图像,所以不能使用 CNN。

        RNN 好吗?

        抱歉写了这么长。

  81. luka 2019年8月5日 早上5:23 #

    一如既往的精彩帖子!!谢谢 Jason。

    我有两个关于展平的问题

    我们可以用 Bi-LSTM 替换展平吗?

    如果我想在 Embedding 之后使用 Bi-LSTM,我应该在进入 Bi-Lstm 之前展平 Embedding 的输出吗?

    谢谢。

  82. priyanshu Khullar 2019年8月26日 凌晨1:12 #

    太棒了

  83. Hamed 2019年9月7日 凌晨3:58 #

    一如既往的棒!但您介意告诉我如何在MIMO情况下处理损失函数吗?我猜它应该为每个输入/输出单独计算。谢谢!

    • Jason Brownlee 2019年9月7日 凌晨5:37 #

      没有不同,如果多个输出是数字,均方误差是一个很好的开始。

  84. Rekha 2019年9月18日 下午3:31 #

    函数模型可以应用于预测股市吗?

  85. Abdul Damodu 2019年9月23日 晚上9:08 #

    非常感谢这篇富有洞察力的文章。我正在寻找一种结合RNN(LSTM)和HMM的方法,根据两种范式的综合优势来预测股票价格,以期获得比普通RNN(LSTM)更好的结果。谢谢。

    • Jason Brownlee 2019年9月24日 早上7:42 #

      听起来是个有趣的项目,告诉我进展如何。

  86. Abdul Damodu 2019年9月24日 早上9:10 #

    谢谢您的回复。但我需要您在这方面的见解。谢谢。

    • Jason Brownlee 2019年9月24日 下午1:05 #

      抱歉,我没有任何使用HMM或将其与LSTM集成的例子。

      我建议开发一些原型以发现什么有效。

  87. haider jafri 2020年2月5日 凌晨6:36 #

    我创建了一个双输出LSTM模型来预测角速度和线速度,角速度的损失较低,但线速度的损失较高。请告诉我如何减少损失。

    第 9/10 纪元
    – 18秒 – 损失:0.4790 – A_输出_损失:0.0826 – L_输出_损失:0.3964 – A_输出_准确率:0.6077 – L_输出_准确率:0.4952 – 验证_损失:0.6638 – 验证_A_输出_损失:0.0958 – 验证_L_输出_损失:0.5680 – 验证_A_输出_准确率:0.6059 – 验证_L_输出_准确率:0.3166
    第 10/10 纪元
    – 18秒 – 损失:0.4752 – A_输出_损失:0.0821 – L_输出_损失:0.3931 – A_输出_准确率:0.6084 – L_输出_准确率:0.4996 – 验证_损失:0.6503 – 验证_A_输出_损失:0.0970 – 验证_L_输出_损失:0.5533 – 验证_A_输出_准确率:0.6052 – 验证_L_输出_准确率:0.3176

  88. Sam 2020年2月16日 晚上8:06 #

    在共享层CNN示例中,为什么形状从64变为61,我理解核大小是4,但64/4没有余数。另外,您知道mxnet是否有类似的方法或教程吗?

  89. Hilbert van Pelt 2020年2月19日 下午2:29 #

    嗨,Jason,

    感谢您的精彩网站和您的精彩书籍(我们拥有大部分)。

    我有一个问题,希望您能帮助我。

    在上面的文章中,您描述了许多可以实现的不同网络结构。有没有什么经验法则可以描述哪种网络结构最适合哪种问题?我在时间序列预测方面做了一些工作,我读过的所有内容都告诉我只尝试不同的结构,但考虑到不同结构的数量,这很不切实际。

    例如,如果您有多个数据输入源,您是将它们连接成MLP的单个输入,还是使用多输入模型?

    我很想听听您的想法。

  90. saipavankumar 2020年3月10日 晚上8:40 #

    嗨 Jason,自从我开始大学项目以来,我一直在关注您的博客,我在这页上卡住了,我的问题是我有一个生物反应器(发酵过程)的数据集,它有100批数据,每批有1000个时间步和200个参数(变量)。
    所以是 100 * 1000 = 100,000 个时间步,每个时间步有 200 个变量。我想开发一个“Y”形架构(就像您帖子中的 MIMO),因此“Y”的一侧输入是“观测变量”,另一侧是“受控变量”。我想通过 LSTM 层传递观测变量,但在输入维度上我很困惑,另一个是如何使用这个模型?
    1. 我会根据当前批次预测下一个批次吗?
    2. 我会根据 t 预测下一个时间步 (t+1) 吗?
    3. 当我们想要进行预测时,是否需要传递整个批次大小,因为我们构建模型时使用了 dim(1000 * timesteps * 200)?

    我的目标是:给定当前过程状态(3 或 4 或“n”个时间步),我希望我的模型能够预测 n+1 或 n+10 个时间步,同时提供“Y”另一侧的受控变量。

  91. lamiaa ali 2020年4月8日 早上11:42 #

    请 Jason 博士
    我不明白 None 的意思以及它是如何从 Flatten 层处理到 Dense 层的
    正如我所读到的,它是(并行处理的批次数量,特征数量)
    我还想知道如何编写 Python 代码来可视化这个展平输出(包括批次和特征)

    非常感谢

    • Jason Brownlee 2020年4月8日 下午1:20 #

      None 意味着未指定,因此它将处理提供的任何数字。

  92. Zaidur Rahman 2020年5月5日 早上8:41 #

    非常感谢!整篇文章都很有帮助!!特别是最后关于函数式 API Python 语法的说明。没有人会费心将这个添加到他们的深度学习教程中!

  93. Ricardo 2020年5月5日 下午2:33 #

    先生,您的教程很棒。非常感谢。

  94. Mostafa 2020年5月12日 晚上6:09 #

    感谢您的信息丰富的教程。

    我有两个目录包含RGB图像。我将使用两个数据生成器来读取它们,然后将这两个生成器馈送到CNN中。

    问题1
    我应该如何组合这两个数据生成器,更重要的是,如何将“fit_generator”函数用于多个生成器,以便网络可以在所有样本(两个目录)上进行训练?

    问题2
    如果我手动合并这两个数据集(将所有文件从一个目录复制到另一个目录)以形成一个单独的数据集,然后使用一个单独的数据生成器读取它们并将其馈送到CNN中。
    与方法1(问题1中提及)相比,它对输出有影响吗?这意味着它会增加或减少准确性、损失或其他指标吗?

    谢谢。

    • Jason Brownlee 2020年5月13日 早上6:31 #

      每个目录都使用一个单独的生成器。

      可能。试试看。

      • nkm 2020年5月29日 凌晨4:13 #

        Jason 先生,您好!

        我也有同样的疑问。如果您能 kindly 分享任何参考代码,读者将不胜感激。

        谢谢并致以问候

  95. James Kajdasz 2020年6月1日 下午3:12 #

    这是我目前找到的关于函数式 API 的最佳解释。

  96. Negar 2020年6月4日 晚上8:34 #

    嗨,Jason,
    感谢您写出如此精彩的博客,您提供的进一步阅读链接无法使用。请问您能更新它们吗?再次感谢!

  97. S.Gowri pooja 2020年6月9日 早上11:40 #

    你好,Jason。我有一个疑问。为什么 Keras 被称为 Keras API?它是一个库,它是如何变成 API 的?

  98. hoan 2020年6月16日 晚上9:44 #

    太棒了。非常感谢您发表这篇文章。

  99. Sina 2020年7月4日 早上7:44 #

    谢谢你,杰森,

    这是一篇非常有用的文章。对于多输入多输出的情况,似乎每个输入中的示例/样本数量应该与训练数据相同。我有一个单一模式,具有两组不同的输入,它们产生两组不同的输出。对每个输出应用不同的损失(每个输出一个损失,总共2个)。

    然而,我收到此错误:“所有输入数组 (x) 的样本数量应相同。”

    这似乎是一个常见问题,但没有人有解决方案。您有什么想法吗?

    ==========================================================
    #输入/输出1和2的示例数量不同
    model = Model(inputs= [input1, input2], outputs=[outputs1, outputs2])

    model.compile(loss=[loss1,loss2], optimizer=opt, metrics=[‘accuracy’])

    model.fit({‘inputs1’:input_data_array1, ‘inputs2′:input_data_array2},
    {outputs1′:y_arrray1,outputs2’:y_arrray2,
    , epochs=100)

    • Jason Brownlee 2020年7月5日 早上6:47 #

      是的,输入样本的数量必须与输出样本的数量匹配,例如,对于两个目标。

  100. David 2020年7月21日 早上7:46 #

    我将提名杰森·布朗利为年度澳大利亚人!

  101. Febin 2020年8月4日 晚上10:55 #

    你好 Jaison,

    感谢您的博客。我是机器学习的新手,我有以下问题。

    我创建了多个输入(CNN、LSTM)和一个单一输出模型。由于模型同时接受图像输入和文本输入,我该如何添加图像增强?

    model.fit([image_train,text_train], label_train, batch_size=BATCH_SIZE,
    epochs=40, verbose=1, callbacks=callbacks, validation_data=([image_test,text_test], label_test))

    • Jason Brownlee 2020年8月5日 早上6:14 #

      您可以创建带有文本副本(未增强)的增强图像。为此,您可能需要一个自定义数据生成器。

  102. Jim 2020年8月13日 晚上7:41 #

    嗨,Jason,

    感谢博客。

    由于我是Python初学者,这可能是一个与Python语法而非Keras相关的问题。

    对于 Keras 函数式 API 示例

    from keras.layers import Input
    from keras.layers import Dense
    visible = Input(shape=(2,))
    hidden = Dense(2)(visible)

    最后的语法类似于 Java 中的类型转换,它在 Python 中叫什么,有什么作用?

    • Jason Brownlee 2020年8月14日 早上6:02 #

      不,不是类型转换。

      它是在从构造函数返回的对象上调用一个函数,而这个函数恰好是将对象的输入连接到作为参数传递的另一个层的输出的函数。

      很难阅读——我知道,但很容易编写。

      • Jim 2020年8月14日 下午3:03 #

        所以根据你的解释,我可以这样写吗?

        hidden = visible(Dense(2))

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

          不。它会有不同的效果,例如,visible 将 Dense(2) 的输出作为输入,而 Dense(2) 的引用现在不可用。

  103. Xu Zhang 2020年9月3日 下午5:22 #

    非常感谢您的精彩文章。

    如果我有两个输入但样本数量不同,是否可以使用多输入、多输出 API 来构建和训练模型?

    我的问题是,如果我给你一张图片,首先,我想知道图片中是否有人。如果是,我想知道他/她多大。所以我必须准备两个数据集。例如,一个数据集包含10,000张图片,其中5,000张有人,5,000张没有人。另一个数据集包含1,000张有人且标注了年龄的图片。这两个数据集的样本数量不同,有些图片可能出现在两个数据集中。

    对于这个问题,它是一个多输入、多输出问题,但两个输入的样本数量不同,我可以使用 Keras 的 API 来构建模型吗?如果不能,您有什么其他方法可以建议吗?非常感谢

    • Jason Brownlee 2020年9月4日 早上6:21 #

      不客气。

      不,我认为每个输入的样本数量必须相同。

      • Xu Zhang 2020年9月4日 早上8:06 #

        谢谢您的回复。如果每个输入的样本数量相同,那么当我准备这两个输入时,我需要将它们配对吗?我的意思是数据集1和数据集2的特征必须代表相同的样本。就像我举的例子,数据集1中的第1张图片必须是数据集2中的第1张图片,依此类推。

        • Jason Brownlee 2020年9月4日 下午1:34 #

          是的,输入需要配对。

          • Xu Zhang 2020年9月5日 早上7:56 #

            非常感谢!

          • Jason Brownlee 2020年9月5日 早上8:07 #

            不客气。

  104. Sai 2020年9月28日 晚上9:41 #

    嗨,好帖子!对函数式 API 进行了快速而清晰的介绍。

  105. saeed 2020年10月21日 晚上10:30 #

    嗨,Jason,

    感谢博客。
    我正在将图像分成块。您对提取特征以区分隐写图像和原始图像有什么建议?

    • Jason Brownlee 2020年10月22日 早上6:44 #

      不客气。

      “隐写图像和原始图像”是什么意思?

  106. Helene 2020年10月23日 凌晨1:14 #

    嗨,Jason,

    非常感谢这篇精彩的教程!

    我正在尝试使用您的示例“多输入模型”来实现一个具有多个输入层的模型。在调用 fit 函数时,我在输入数据的形状方面遇到了一些问题。您能提供一个如何在您的示例上调用 fit 函数的示例吗?

    • Jason Brownlee 2020年10月23日 早上6:13 #

      像往常一样调用 fit(),并提供一个输入列表,其中列表中的每个元素对应模型中的每个输入。

      我在博客上提供了许多多输入模型的示例。也许可以尝试搜索一下。

  107. Jyothsna 2020年11月5日 下午2:48 #

    非常感谢您清晰的解释。我想知道如何在其中添加 BatchNormalization 和 Relu。实际上,我正在尝试使用函数式 API 编写 dncnn 代码。

    顺序 API 代码
    model=Sequential()
    model.add(Conv2D(64,(3,3),padding=”same”,input_shape=(None,None,1)))
    model.add(Activation('relu'))
    for layers in range(2,16+1)
    model.add(Conv2D(64,(3,3),padding=”same”))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    model.add(Conv2D(1,(3,3),padding=”same”))

    我想知道如何使用函数式 API 实现

    • Jason Brownlee 2020年11月6日 凌晨5:52 #

      您可以通过函数式 API 添加批归一化层,就像添加任何其他层(例如密集层)一样。不需要特殊的语法。

  108. Sarasa Jyothsna Kamireddi 2021年3月16日 下午4:18 #

    先生,这个解释非常好。我想知道如何实现以下目标:
    1. 创建并训练一个模型。(我已经明白了)
    2. 将这个模型及其训练好的权重作为另一层用于其他模型中。
    如果您能提供这方面的信息,将非常有帮助。

  109. Grace 2021年3月30日 晚上9:51 #

    你好,Jason。
    您能给我解释一下理论吗?输入数据是如何转换为第一个 LSTM 层的张量的。例如,如果输入是 (None, 1, 10),并且 LSTM 的第一层有 64 个神经元,即 (None, 64)。这里是不是发生了一些矩阵乘法?

  110. Shashank Gurnalkar 2021年5月27日 下午4:13 #

    感谢这个很棒的教程。它真的很有帮助。

  111. Maqsood 2021年6月3日 凌晨12:26 #

    你好,Jason。

    万分感谢。您简直是天才。

    我有一个关于多输入层(CNN)的问题。我什么都明白了,但我不知道如果我有两张图像作为输入,该如何训练这个模型?您能指导一下吗?

    通常我们这样调用拟合模型,使用单个 x 和 y,但我对两个输入感到困惑。
    例如
    model.fit(trainImages, trainPrices, validation_data=(testImages, testPrices),epochs=300, batch_size=batchSize)

    如果您能帮助我,我将不胜感激。谢谢

    • Jason Brownlee 2021年6月3日 凌晨5:37 #

      您需要为模型的每个输入提供一个输入数据集,在调用fit时以列表形式提供,例如 model.fit([trainX1, trainX2], …)

      我的博客上有很多例子。

      • Maqsood 2021年6月4日下午7:37 #

        谢谢你,Jason Brownlee,

        我明白了,并且成功了。愿上帝保佑你,祝你在生活中取得更大的成功。

  112. Atheer 2021年6月21日上午6:11 #

    你好,杰森
    非常感谢你的辛勤工作
    这几个月我一直在看你的教程,它们真的很有帮助
    我能问一下你有没有关于深度学习模型有两个输入(比如文本和二进制特征)的例子,或者读过这样的例子吗?谢谢。

    • Jason Brownlee 2021年6月22日上午6:26 #

      是的,你可以使用多输入模型,为每种数据类型/流设置一个输入。我有一些例子,例如照片字幕教程可能会给你一些想法。

  113. Lidya 2021年6月25日下午3:00 #

    你好,我能问一下如何进行自动编码器特征选择并将其放入深度神经网络模型中吗?
    谢谢您

  114. Pankaj 2021年7月15日上午12:51 #

    很棒的帖子 @Jason Brownlee

    有没有关于如何使用深度学习进行聚类的例子?

  115. Reza 2021年7月16日上午12:26 #

    谢谢,这是我读过最好的解释🙂

  116. Akilu Muhammad 2021年8月4日上午2:09 #

    有趣而复杂的内容被简洁地表达出来。我真希望我能更早看到这篇帖子。非常感谢Jason。

  117. nkm 2021年8月16日上午3:25 #

    谢谢,Jason博士,这个很棒的博客。

    另外,我想问如何连接CNN(使用图像)和LSTM(使用时间序列)模型,其中CNN是使用Keras的flow_from_directory和生成器进行训练的。

    任何示例或指导都将有助于实际实现。

    谢谢和问候

  118. liedji 2021年8月19日上午2:19 #

    谢谢。这篇帖子很容易理解。我很喜欢!

    • Adrian Tam
      Adrian Tam 2021年8月19日上午4:10 #

      谢谢你。希望你喜欢。

  119. Alexandrea Marks 2021年10月13日上午1:47 #

    有趣而复杂的内容被简洁地表达出来。我真希望我能更早看到这篇帖子。非常感谢Jason。

    • Adrian Tam
      Adrian Tam 2021年10月13日上午7:34 #

      谢谢。很高兴你喜欢。

  120. Vaishnavi 2022年3月26日上午1:23 #

    感谢这篇博客。
    我想问一下,如果我想在最后一个隐藏层神经元上使用包含三角函数的函数。那么,我如何将张量中的输入分开并对它们应用函数,然后将输出提供给输出层呢?

    • Vaishnavi 2022年3月26日下午7:53 #

      我定义了一个自定义层,其输入类型是张量。然后我使用了 tf.split() 函数,我以为它会将前一个隐藏层的输入分成5个输入。然后,我对这5个输入使用了6个函数并将它们保存在一个列表中。最后,我使用 tf.convert_to_tensor() 函数将列表转换为张量。最终,自定义层将返回这个张量。我遇到了一个错误。
      真的可以将一个张量分成5个变量吗?另外,批处理大小会影响分割吗?

  121. Jaydeep 2022年6月12日下午2:22 #

    我的数据集有以下列:

    year, w_1_1, w_1_2,…., w_1_52, w_2_1, w_2_2,…,w_2_52, w_3_1,…, w_3_52, w_4_1,.., w_4_52, w_5_1,…, w_5_52, w_6_1,…, w_6_52, yield

    其中 yield 是我希望模型预测的单个值。

    我想创建6个1D CNN模型来训练数据的不同部分,第一个模型在 w_1_1 到 w_1_52 上训练,第二个模型在 w_2_1 到 w_2_52 上训练,第三个模型在 w_3_1 到 w_3_52 上训练,以此类推,直到第六个模型在 w_6_1 到 w_6_52 上训练,最后将它们的输出连接起来。

    但我不知道如何为1D卷积调整数据的不同部分的大小。

  122. Zack 2022年8月4日下午6:03 #

    你好,James,谢谢你的教程,非常有帮助。

    你有没有使用Keras函数式API的任何教程或完整实现?例如,使用Keras函数式API编译和拟合一个多输入多输出模型,并使用ImageDataGenerator函数。

    谢谢。

  123. efuye 2022年10月9日上午6:06 #

    我正在尝试使用 Python 连接多类别两特征(HOG 和 CNN)的 CNN,你能帮我吗?

    • James Carmichael 2022年10月10日上午9:53 #

      嗨 efuye……请详细说明您已经做了什么以及可能遇到的问题,以便我们更好地帮助您。

  124. Henriko 2023年8月23日上午8:29 #

    嘿,Jason,感谢你的精彩博客文章!

    在这种情况下,你将如何指定 layer_input 形状:我有一个三维的平衡月度面板数据集,每个月有2500个独立的横截面观测值,每个横截面有134个特征,时间段从2006-01到2019-12(168个月),所以是 2500 x 134 x 168。
    因此,数据集有 2500*168 = 420000 行和 134 列。
    正如你所说,批次大小(时间维度)被省略了,所以我在输入层中指定了 'shape = c(2500, 134)'。然而,我收到了错误 'ValueError: Input 0 of layer “model_6” is incompatible with the layer: expected shape=(None, 2537, 132), found shape=(None, 132)'

    在这种三维面板数据的情况下,你能告诉我如何正确指定输入层的形状吗?

  125. Rahul Gulia 2024年1月26日上午4:22 #

    我正在尝试为我的数据集使用“多输入,多输出模型”。

    # 合并输入模型
    merge = concatenate([flat1, flat2])

    我想知道这两个输入数据集是应该对整个数据集进行拼接,还是应该分别对训练和测试数据进行拼接。

    期待任何建议。谢谢。

  126. Rahul Gulia 2024年1月26日上午4:27 #

    我正在尝试为我的数据集使用 “5. 多输入和输出模型”。

    在这行代码中,

    # 合并输入模型
    merge = concatenate([flat1, flat2])

    我应该分别拼接训练和测试数据集,还是应该一次性对整个数据集进行拼接?

  127. Rahul Gulia 2024年1月26日上午4:28 #

    期待任何建议。

  128. Murilo Souza 2024年5月30日下午8:56 #

    文献中通常有什么术语来指代“多输入模型”架构吗?在我看来它不像是一个多头网络。

发表评论

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