如何在 Keras 中使用权重约束减少过拟合

权重约束提供了一种方法,用于减少深度学习神经网络模型在训练数据上的过拟合,并提高模型在新数据(如留存测试集)上的性能。

权重约束有多种类型,例如最大和单位向量范数,其中一些需要配置超参数。

在本教程中,您将了解 Keras API,用于向深度学习神经网络模型添加权重约束以减少过拟合。

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

  • 如何使用 Keras API 创建向量范数约束。
  • 如何使用 Keras API 将权重约束添加到 MLP、CNN 和 RNN 层。
  • 如何通过将权重约束添加到现有模型来减少过拟合。

用我的新书《更好的深度学习》来启动你的项目,书中包含分步教程和所有示例的 Python 源代码文件

让我们开始吧。

  • 更新于 2019 年 3 月:修复了在某些使用示例中将赋值误用为等号的拼写错误。
  • 2019 年 10 月更新:更新至 Keras 2.3 和 TensorFlow 2.0。
How to Reduce Overfitting in Deep Neural Networks With Weight Constraints in Keras

如何使用 Keras 中的权重约束减少深度神经网络中的过拟合
照片由 Ian Sane 拍摄,保留部分权利。

教程概述

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

  1. Keras 中的权重约束
  2. 层上的权重约束
  3. 权重约束案例研究

Keras 中的权重约束

Keras API 支持权重约束。

约束是按层指定的,但应用于层内的每个节点并强制执行。

使用约束通常涉及设置层上的 *kernel_constraint* 参数(用于输入权重)和 *bias_constraint* 参数(用于偏置权重)。

通常,权重约束不用于偏置权重。

一系列不同的向量范数可用作约束,在 keras.constraints 模块 中提供。它们是:

  • 最大范数(*max_norm*),强制权重具有等于或小于给定限制的幅度。
  • 非负范数(*non_neg*),强制权重具有正幅度。
  • 单位范数(*unit_norm*),强制权重具有 1.0 的幅度。
  • 最小-最大范数(*min_max_norm*),强制权重具有介于某个范围内的幅度。

例如,可以导入并实例化一个约束:

层上的权重约束

权重范数可用于 Keras 中的大多数层。

在本节中,我们将介绍一些常见的示例。

MLP 权重约束

下面的示例为 Dense 全连接层设置了最大范数权重约束。

CNN 权重约束

下面的示例为卷积层设置了最大范数权重约束。

RNN 权重约束

与其它层类型不同,循环神经网络允许您同时为输入权重和偏置以及循环输入权重设置权重约束。

循环权重的约束通过层的 *recurrent_constraint* 参数进行设置。

下面的示例为 LSTM 层设置了最大范数权重约束。

现在我们知道了如何使用权重约束 API,让我们来看一个实际示例。

想要通过深度学习获得更好的结果吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

权重约束案例研究

在本节中,我们将演示如何使用权重约束来减少 MLP 在一个简单的二分类问题上的过拟合。

此示例提供了一个模板,用于将权重约束应用于您自己的用于分类和回归问题的神经网络。

二分类问题

我们将使用一个标准的二分类问题,该问题定义了两个半圆形的观测点,每个半圆形代表一个类别。

每个观测值都有两个具有相同尺度的输入变量和一个类别输出值0或1。这个数据集被称为“moons”数据集,因为绘制时每个类别中的观测值的形状。

我们可以使用 make_moons() 函数 从这个问题中生成观测点。我们将向数据添加噪声并设置随机数生成器的种子,以便在每次运行时生成相同的样本。

我们可以绘制数据集,其中两个变量作为图上的x和y坐标,类别值作为观测值的颜色。

生成数据集并绘制它的完整示例如下所示。

运行示例将创建一个散点图,显示每个类别中观测值的半圆或月牙形。我们可以看到点分散中的噪声使得月牙形不那么明显。

Scatter Plot of Moons Dataset With Color Showing the Class Value of Each Sample

月牙形数据集的散点图,点颜色显示每个样本的类别值

这是一个很好的测试问题,因为这些类别不能用一条线分开,例如,它们不是线性可分的,需要一种非线性方法(如神经网络)来解决。

我们只生成了 100 个样本,对于神经网络来说太少了,这为过拟合训练数据集和在测试数据集上产生更高的误差提供了机会:这是使用正则化的一个好案例。此外,样本带有噪声,这使得模型有机会学习样本中不能泛化的方面。

过拟合多层感知器

我们可以开发一个MLP模型来解决这个二分类问题。

该模型将有一个隐藏层,其节点数可能超过解决此问题所需的数量,从而提供过拟合的机会。我们还将训练模型的时间延长到超过所需时间,以确保模型过拟合。

在定义模型之前,我们将数据集拆分为训练集和测试集,使用30个示例来训练模型,70个示例来评估拟合模型的性能。

接下来,我们可以定义模型。

隐藏层使用 500 个节点和 ReLU 激活函数。输出层使用 sigmoid 激活函数,以预测类别值为 0 或 1。

该模型使用二元交叉熵损失函数进行优化,适用于二元分类问题和梯度下降的有效 Adam 版本。

然后,将定义的模型在训练数据上拟合4,000个周期,并使用默认的批量大小32。

我们还将测试数据集用作验证数据集。

我们可以评估模型在测试数据集上的性能并报告结果。

最后,我们将绘制每个 epoch 模型在训练集和测试集上的性能。

如果模型确实过拟合了训练数据集,我们预计训练集上的准确度线图将继续增加,而测试集将先上升然后再次下降,因为模型学习了训练数据集中的统计噪声。

我们可以将所有这些部分结合起来;完整的示例如下所示。

运行示例会报告模型在训练数据集和测试数据集上的性能。

我们可以看到模型在训练数据集上的性能优于测试数据集,这可能是过拟合的一个迹象。

注意:您的结果可能会因算法或评估程序的随机性,或数值精度的差异而有所不同。考虑多次运行示例并比较平均结果。

由于模型过拟合,我们通常不期望在同一数据集上重复运行模型时,准确率有很大甚至任何差异。

创建了一个图,显示模型在训练集和测试集上的准确度线图。

我们可以看到一个过拟合模型的预期形状,其中测试准确度会增加到一个点,然后再次开始下降。

Line Plots of Accuracy on Train and Test Datasets While Training Showing an Overfit

训练期间训练集和测试集准确度线图,显示过拟合

带权重约束的过拟合 MLP

我们可以更新示例以使用权重约束。

有几种不同的权重约束可供选择。对于此模型,一个好的简单约束是简单地对权重进行归一化,使范数等于 1.0。

这种约束的效果是强制所有传入权重都很小。

我们可以通过在 Keras 中使用 *unit_norm* 来做到这一点。此约束可以像下面这样添加到第一个隐藏层:

我们也可以通过使用 *min_max_norm* 并将最小值和最大值设置为 1.0 来达到相同的结果,例如:

我们无法使用最大范数约束达到相同的结果,因为它允许范数等于或小于指定的限制;例如:

下面列出了包含单位范数约束的完整更新示例:

运行示例会报告模型在训练数据集和测试数据集上的性能。

注意:您的结果可能会因算法或评估程序的随机性,或数值精度的差异而有所不同。考虑多次运行示例并比较平均结果。

我们可以看到,对权重大小的严格约束确实在不影响训练集性能的情况下提高了模型在留存集上的性能。

回顾训练和测试准确率的折线图,我们可以看到模型不再像之前那样明显过拟合了训练数据集。

模型在训练集和测试集上的准确率都持续提高并达到平台期。

Line Plots of Accuracy on Train and Test Datasets While Training With Weight Constraints

训练期间使用权重约束时,训练集和测试数据集准确率的折线图

扩展

本节列出了一些您可能希望探索的扩展本教程的想法。

  • 报告权重范数。更新示例以计算网络权重的幅度,并演示约束确实减小了幅度。
  • 约束输出层。更新示例以将约束添加到模型的输出层并比较结果。
  • 约束偏置。更新示例以将约束添加到偏置权重并比较结果。
  • 重复评估。更新示例以多次拟合和评估模型,并报告模型性能的平均值和标准差。

如果您探索了这些扩展中的任何一个,我很想知道。

进一步阅读

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

文章

API

总结

在本教程中,您了解了 Keras API,用于向深度学习神经网络模型添加权重约束。

具体来说,你学到了:

  • 如何使用 Keras API 创建向量范数约束。
  • 如何使用 Keras API 将权重约束添加到 MLP、CNN 和 RNN 层。
  • 如何通过将权重约束添加到现有模型来减少过拟合。

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

今天就开发更好的深度学习模型!

Better Deep Learning

更快地训练,减少过拟合,以及集成方法

...只需几行python代码

在我的新电子书中探索如何实现
更好的深度学习

它提供关于以下主题的自学教程
权重衰减批量归一化dropout模型堆叠等等...

为你的项目带来更好的深度学习!

跳过学术理论。只看结果。

查看内容

34 条对*“如何在 Keras 中使用权重约束减少过拟合”*的回复

  1. Philippe 2018年11月26日 上午8:35 #

    梯度裁剪是否类似于权重约束?

    • Jason Brownlee 2018年11月26日 下午2:00 #

      很好的问题!

      不太对。

      权重约束应用于权重,是一种正则化技术。

      梯度裁剪应用于用于更新权重的误差梯度,用于避免梯度爆炸。

      • allen 2018年12月10日 上午12:59 #

        感谢分享,但为什么像正则化,因为没有惩罚?我认为权重约束更像归一化

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

          是的,就像每次更新后的权重归一化一样。

  2. diffusion 2018年11月26日 下午12:34 #

    很棒的文章。这有助于提高 Kaggle 竞赛“Don’t call me turkey!”的预测能力。

    祝好,

  3. Oren 2018年11月27日 上午7:04 #

    约束每层权重之和为一是否使模型更容易解释?

    • Jason Brownlee 2018年11月27日 下午2:07 #

      也许在输入层上,但在隐藏层上可能不行。

  4. Ruchit Dalwadi 2018年11月27日 上午9:06 #

    如果 kernel_constraint=max_norm(A)。我应该根据什么来设置“A”的值?

    • Jason Brownlee 2018年11月27日 下午2:10 #

      尝试一系列小的整数值,通常在 [1,4] 范围内。

  5. Ruchit Dalwadi 2018年11月27日 上午9:24 #

    应该将它应用于哪个层?因为 CNN 中的大多数网络都更深。有办法弄清楚吗?

  6. JG 2018年12月2日 下午10:46 #

    你好杰森

    好帖子!谢谢。

    我认为本教程旨在通过“权重约束”来帮助减少过拟合,它与另一个名为“如何使用权重正则化减少深度学习模型的过拟合”的教程密切相关,该教程使用“权重正则化”技术。因此,这两个教程(kernel_constraint vs kernel_regularizer 参数)具有相似的实现和结果。
    事实上,它们达到了相同的 94.3% 的测试准确率。

    在此意义上,我决定也实现网格搜索“Limiter”超参数分析(此处省略),作为前一篇帖子“Grid Regularizer”的复制,并定义一个 ALPHA 参数列表,其设置值为 = [0.3, 0.6, 0.9, 1., 1.3, 1.6],这些是用于 min_max_norm 等参数的值(ALPHA 对于 min 和 max 都是相同的值)。

    我的 Alpha 探索表明,除了参数 1.0(例如 unit_norm)之外,Alpha 参数值 0.9 和 1.3 也能达到相同的最大测试准确率(94.3%),但 Alpha 参数值更高或更低会降低准确率(测试数据为 92.9%)。

    谢谢

  7. mamina sahu 2018年12月14日 下午6:13 #

    不错的帖子

  8. Vineetha 2018年12月19日 下午8:41 #

    如何计算相等错误率?有公式吗?

  9. Vital 2019年3月11日 上午5:28 #

    嗨,Jason,

    我在 CNN 中尝试使用 bias_constraint==max_norm(3),但是 == 会导致错误
    SyntaxError: positional argument follows keyword argument

    我认为它应该只是 =

    • Jason Brownlee 2019年3月11日 上午6:55 #

      是的,使用单个 = 进行赋值。

      我已经修复了示例,谢谢。

  10. mustafa mohammed 2019年9月5日 上午4:56 #

    你好 Jason Brownlee
    手动将权重添加到 LSTM 的代码是什么?

  11. mustafa mohammed 2019年9月5日 下午10:07 #

    如何使用 model.set_weights() 与 LSTM(回归)?

    如何从 csv 文件添加权重?
    你能给我提供代码吗?
    非常感谢

    • Jason Brownlee 2019年9月6日 上午4:58 #

      抱歉,我没有能力为您准备示例。

      为什么你想从 CSV 文件设置模型权重?

  12. mustafa mohammed 2019年9月6日 上午5:38 #

    因为我从 PSO 算法生成权重,并且我想将它们放入 csv,然后尝试将它们加载到 LSTM 中。

    • Jason Brownlee 2019年9月6日 下午1:53 #

      我明白了。在最开始不使用 LSTM 结构的情况下,你如何评估权重?

  13. GB 2020年12月3日 下午9:52 #

    嗨,Jason,
    当使用 max_norm 等约束时,您是在处理权重向量 w 的范数,对吗?如果我也想对单个权重(即向量元素 w_i)施加约束,该怎么办?
    例如,我想让输入层的向量范数等于 1,但我也想让该层的所有单个权重都在 0 和 0.05 之间,比如。
    在只有一层输入、一层隐藏和一层输出的简单情况下,您将如何实现这一点?我是否遗漏了什么明显的东西?

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

      是的。

      听起来您在描述权重裁剪。

  14. Atis 2021 年 1 月 9 日 上午 12:50 #

    也许这篇博文中缺少的是对 max_norm() 规范中 axis= 参数的讨论。

    axis/axes 的不同选择会导致不同强度和含义的约束。在某些情况下,一些选择比其他选择更有说服力。

    https://tensorflowcn.cn/api_docs/python/tf/keras/constraints/MaxNorm

  15. tiffany 2021 年 1 月 12 日 下午 5:47 #

    权重约束是否只能用于输入权重,那卷积核权重呢?
    我想知道是否可以使用此约束来对训练后量化设置输入权重的最小值和最大值。

    • Jason Brownlee 2021 年 1 月 13 日 上午 6:11 #

      权重约束可以与网络中的任何权重一起使用。

      通常,它们是逐层指定的。

  16. Udit 2021 年 5 月 11 日 下午 8:07 #

    核约束可以应用于每个层(隐藏层),范数值是否应该成为前一层节点数的函数?
    例如,有两个隐藏层,分别是 500 和 10。如果对两者都应用单位范数,那么第一隐藏层的权重将远小于第二层。那么,是否建议改变范数值,使得权重在不同隐藏层之间保持相同的幅度?
    期待您的回复,我在任何地方都找不到答案。

留下回复

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