如何使用 Keras 构建多层感知器神经网络模型

用于深度学习的 Keras Python 库专注于将模型创建为一系列层。

在本教程中,您将使用 Keras 和 TensorFlow 来发现可用于创建神经网络和简单深度学习模型的简单组件。

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

让我们开始吧。

  • 2016 年 5 月:初版
  • 2017 年 3 月更新:针对 Keras 2.0.2、TensorFlow 1.0.1 和 Theano 0.9.0 更新了示例。
  • 更新于 2022 年 6 月:代码已更新为 TensorFlow 2.x。外部链接已更新。
How To Build Multi-Layer Perceptron Neural Network Models with Keras

如何使用 Keras 构建多层感知器神经网络模型
照片来源:George Rex,部分权利保留。

Keras 中的神经网络模型

Keras 库的重点是模型。

最简单的模型在 Sequential 类中定义,它是一个线性堆叠的层。

您可以创建 Sequential 模型并在构造函数中定义所有层;例如:

一个更实用的方法是创建一个 Sequential 模型,并按照您希望执行的计算顺序添加您的层;例如:

模型输入

模型中的第一层必须指定输入的形状。

这是由 input_shape 参数定义的输入属性的数量。此参数期望一个元组。

例如,您可以如下为 Dense 类型层定义 8 个输入:

模型层

不同类型的层有一些共同的属性,特别是它们的权重初始化方法和激活函数。

权重初始化

用于层初始化的类型在 kernel_initializer 参数中指定。

一些常见的层初始化类型包括:

  • random_uniform:权重被初始化为介于 -0.05 和 0.05 之间的小均匀随机值。
  • random_normal:权重被初始化为小的、均值为零、标准差为 0.05 的高斯随机值。
  • zeros:所有权重都被设置为零值。

您可以在 初始化用法 页面上找到支持的初始化技术的完整列表。

激活函数

Keras 支持一系列标准的神经元激活函数,例如 softmax、ReLU(整流线性单元)、tanh 和 sigmoid。

您通常在 activation 参数中指定层使用的激活函数的类型,该参数接受一个字符串值。

您可以在 激活用法 页面上找到 Keras 支持的激活函数的完整列表。

有趣的是,您还可以创建一个 Activation 对象并将其直接添加到模型中,在您的层之后应用该激活函数。

层类型

对于标准神经网络,有大量的核心层类型。

您可以从一些常见且有用的层类型中进行选择:

  • Dense:全连接层,是多层感知器模型中最常用的层类型
  • Dropout:将 dropout 应用于模型,将一部分输入设置为零,以减少过拟合
  • Concatenate:将多个层的输出组合起来作为单个层的输入

您可以在 核心层 页面上了解 Keras 核心层的所有完整列表。

模型编译

一旦您定义了模型,就需要对其进行编译。

这会创建 TensorFlow 用于在训练期间高效执行模型的有效结构。具体来说,TensorFlow 会将您的模型转换为图,以便可以高效地进行训练。

您可以使用 compile() 函数来编译您的模型,它接受三个重要属性:

  1. 模型优化器
  2. 损失函数
  3. 度量标准

1. 模型优化器

优化器是用于更新模型权重的搜索技术。

您可以创建一个优化器对象,并通过 optimizer 参数将其传递给 compile 函数。这允许您使用自己的参数(如学习率)来配置优化过程。例如:

您还可以通过将优化器的名称指定给 optimizer 参数来使用优化器的默认参数。例如:

您可能想要选择的一些流行的梯度下降优化器包括:

  • SGD:随机梯度下降,支持动量
  • RMSprop:Geoff Hinton 提出的自适应学习率优化方法
  • Adam:自适应矩估计(Adam),也使用自适应学习率

您可以在 优化器用法 页面上了解 Keras 支持的所有优化器。

您可以在 Sebastian Ruder 的文章 梯度下降优化算法概述 的“梯度下降优化算法”部分了解更多关于不同梯度下降方法的信息。

2. 模型损失函数

损失函数,也称为目标函数,是优化器用来导航权重空间的模型评估。

您可以通过 loss 参数在 compile 函数中使用要使用的损失函数的名称。一些常见示例包括:

  • mse‘:均方误差
  • binary_crossentropy‘:二元对数损失 (logloss)
  • categorical_crossentropy‘:多类对数损失 (logloss)

您可以在 损失 页面上了解 Keras 支持的损失函数的更多信息。

3. 模型度量标准

在训练期间,模型会评估度量标准。

目前仅支持一个度量标准,即准确度。

模型训练

模型在 NumPy 数组上使用 fit() 函数进行训练;例如:

训练同时指定了训练的 epoch 数量和批次大小。

  • Epochs (epochs) 指的是模型暴露于训练数据集的次数。
  • Batch Size (batch_size) 是在执行权重更新之前显示给模型的训练实例的数量。

fit 函数还允许在训练期间对模型进行一些基本评估。您可以设置 validation_split 值,从训练数据集中保留一部分用于在每个 epoch 中进行验证评估,或者提供一个 validation_data 元组 (X, y) 来进行评估。

拟合模型会返回一个 history 对象,其中包含模型在每个 epoch 中计算的详细信息和度量标准。这可用于绘制模型性能图。

模型预测

训练完模型后,您可以使用它来预测测试数据或新数据。

您可以从训练好的模型中计算出多种不同的输出类型,每种类型都可以通过模型对象上的不同函数调用来计算。例如:

  • model.evaluate():计算输入数据的损失值
  • model.predict():为输入数据生成网络输出

例如,如果您提供了数据批次 X 和期望的输出 y,您可以使用 evaluate() 来计算损失度量(在 compile() 中定义的那个)。但是,对于新数据批次 X,您可以使用 predict() 来获取网络输出。它可能不是您想要的输出,但它将是您网络的输出。例如,分类问题可能会为每个样本输出一个 softmax 向量。您需要使用 numpy.argmax() 将 softmax 向量转换为类别标签。

Python 深度学习需要帮助吗?

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

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

总结模型

一旦您对模型满意,就可以对其进行最终确定。

您可能希望输出模型的摘要。例如,您可以调用 summary 函数来显示模型的摘要:

您还可以使用 get_config() 函数检索模型配置的摘要:

最后,您可以直接创建模型结构的图像:

资源

您可以使用以下资源了解如何使用 Keras 创建简单的神经网络和深度学习模型:

总结

在本教程中,您发现了 Keras API,可用于创建人工神经网络和深度学习模型。

具体来说,您了解了 Keras 模型的生命周期,包括:

  • 构建模型
  • 创建和添加层,包括权重初始化和激活
  • 编译模型,包括优化方法、损失函数和度量标准
  • 拟合模型,包括 epoch 和批次大小
  • 模型预测
  • 总结模型

如果您对 Keras 深度学习或本教程有任何疑问,请在评论区提问,我将尽力回答。

27 条回复:如何使用 Keras 构建多层感知器神经网络模型

  1. Chong Wang 2016 年 10 月 8 日凌晨 2:35 #

    你好,Jason。

    对于 merge 层,您知道如何使用 mode=’dot’ 吗?我想通过点乘合并两个 embedding 层的输出。

    具体问题在此:http://stackoverflow.com/questions/39919549/how-to-get-dot-product-of-the-outputs-of-two-embedding-layers-in-keras

    谢谢。

    • Chong Wang 2016 年 10 月 8 日凌晨 3:29 #

      哦,我刚发现我应该使用 'mul',而不是 'dot'。

      您认为 'mul' 也能像 SVD 中的 'dot' 那样捕捉两个 embedding 的交互吗?('mul' 的输出将输入到后续的 LSTM 层中。)

      • Jason Brownlee 2016 年 10 月 8 日上午 10:43 #

        好问题 Chong,抱歉我还没有尝试过 merge 层。

        • john woo 2017 年 1 月 13 日下午 4:03 #

          有人知道输入到 merge 层的顺序有意义吗?假设合并层直接连接到一个 dense 层?

          • Jason Brownlee 2017 年 1 月 15 日上午 5:17 #

            目前不知道,您可以发邮件到谷歌群组、使用受控实验进行试错,或者查阅源代码来弄清楚。

  2. Keshav 2017 年 9 月 9 日凌晨 4:16 #

    嗨,Jason,
    感谢本教程以及您博客中的所有其他文章——它们非常有用且令人赞叹!
    我有一个问题:一个隐藏(Dense)层推荐的隐藏单元数量是多少?对于 MLP,它不应该少于输入层中的特征数量吗?(input_dim 参数)那么上面示例中单元的数量应该小于 8 对吗?那么 16 是如何工作的呢?引用这段代码:‘ Dense(16, input_dim=8) ‘

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

      我们无法通过分析来配置神经网络,您必须通过试错来发现什么适用于您的特定数据集。

  3. Shabnam 2017 年 12 月 16 日下午 6:29 #

    非常感谢这篇精彩的文章。
    我尝试运行了您提供的示例。我注意到我需要使用“from keras.utils.vis_utils import plot_model”而不是“from keras.utils.visualize_util import plot”。我认为如果对其他人有用,那么我会在这里分享。

    • Jason Brownlee 2017 年 12 月 17 日上午 8:51 #

      谢谢,已修正。

      • Shabnam 2017 年 12 月 18 日上午 7:30 #

        没关系,我想下一行也应该是 plot_model。

  4. Shabnam 2017 年 12 月 18 日上午 7:53 #

    如果我们有多个隐藏层,我们如何探索激活函数的最佳组合?例如,对于二元分类,我会考虑输出层使用 sigmoid 函数。但是,我不知道隐藏层使用 sigmoid 是否更好,还是需要尝试不同的函数来查看哪个最适合我的数据。

    • Jason Brownlee 2017 年 12 月 18 日下午 3:23 #

      您必须设计实验来测试不同的配置,以查看哪种最适合您的特定数据。

  5. Michael Lange 2018 年 5 月 24 日凌晨 3:52 #

    感谢 Jason 的这篇文章!写得很好。我是 Keras 的忠实粉丝。

    “我们无法通过分析来配置神经网络,您必须通过试错来发现什么适用于您的特定数据集。”

    只是 FYI,给所有阅读这篇文章的人,试错很麻烦。但却是学习“动物园”的好方法。我必须这么说。

    但是,这里有一些代码可能对您有用。一个简单的 GA,用于优化 scikit-learn 的学习流程。 https://github.com/mikewlange/KETTLE – 最初由 Computational Genetics Lab 称为 TPot http://epistasis.org/ 开发 – 它仅限于 scikit-learn 的分类和回归流程。但我正在构建 Keras 支持——总有一天!哈哈。

    祝好,
    Mike

  6. Arya 2018 年 10 月 26 日下午 6:54 #

    有人认为用所有零权重初始化 MLP 是个坏主意。为什么?

  7. MAK 2019 年 1 月 1 日上午 8:32 #

    你好 Jason 博士
    很棒的博客……
    我想预测我的所有系统特征,提前一步,数据是时间的。
    我使用 100 个特征作为输入,100 个特征作为输出(预测提前一步的所有特征)。
    我构建了一个 LSTM 模型,其中包含 10 个隐藏层来预测下一步。
    每个隐藏层包含 200 个神经元,在每个层中我的激活函数是 relu,
    输出层的激活函数是线性的。
    优化器损失函数是 mae
    在训练阶段,我注意到一些奇怪的问题
    1.我收到了较低的损失值,同时准确率也很低?你能解释一下怎么会这样吗?
    2.在训练过程中,我插入了不同的数据集,但具有相同的特征,我突然收到了非常高的损失值(从 0.01 变为 2909090),您有什么想法为什么吗?
    3.每层的神经元数量是否合适?对于选择神经元数量与输入层相比,您有什么经验法则吗?
    谢谢

  8. Walid 2019 年 2 月 6 日凌晨 1:05 #

    我认为没有人能写出比这更好的介绍了。

  9. olufemi george 2019 年 9 月 18 日凌晨 1:58 #

    很棒的教程!我如何在一个 MLP 模型中创建多个输出?您所有的示例都只显示一个输出。

    谢谢

    • Jason Brownlee 2019 年 9 月 18 日上午 6:15 #

      将输出层的节点数更改为所需的输出数量。就是这样。

  10. vasanth kumar 2020 年 4 月 8 日凌晨 5:28 #

    感谢您的教程。我的 jupyter notebook 中无法使用 sequential()。我知道这不是最合适的平台,但请帮助我。错误消息是“正在使用 TensorFlow 后端……未找到模块 ‘tensorflow’”。. 然后我安装了 tensorflow。即使这样问题仍然存在。

    如果有人建议其他可以轻松安装深度学习包的 python 工具,我将感到高兴。

留下回复

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