处理深度学习模型中过拟合问题的辍学正则化

115 阅读10分钟

处理深度学习模型中过拟合问题的辍学正则化

过拟合和欠拟合是机器学习中常见的问题。当一个模型在训练中完美地学习,但在测试中表现不佳时,就会发生过拟合。该模型在训练数据集上会有较高的准确率,但在测试中的准确率却较低。

当模型既不能从训练数据中学习,也不能使用测试数据集进行预测时,就会发生欠拟合。这个模型在训练和测试中都表现不佳。这个模型太简单了,无法学习任何东西。

过度拟合问题比欠拟合问题更常见。我们有很多技术可以处理过拟合问题,如交叉验证数据增强特征选择早期停止和辍学正则化。我们将重点讨论辍学正则化技术。

在本教程中,我们将首先使用TensorFlow建立一个深度学习模型。然后我们将使用dropout正则化技术来处理过拟合问题。这将确保我们有一个在训练数据集和测试数据集上都有良好表现的模型。

前提条件

为了使读者能够轻松地学习本教程,他应该。

  • 知道如何建立[深度学习模型]。
  • 了解用于数据分析和操作的[Pandas]和[Numpy]。
  • 知道如何使用[TensorFlow]和Keras来构建神经网络。
  • 在构建神经网络模型时使用[谷歌Colab笔记本]。

开始使用Dropout正则化

Dropout正则化是一种技术,在模型训练过程中随机丢弃神经网络中的一些神经元。

这意味着被丢弃的神经元的贡献在时间上被移除,它们不会对模型的性能产生影响。

下面的图片显示了丢弃正则化的工作原理。

Dropout regularization

在上图中,左边的神经网络显示了一个原始的神经网络,所有的神经元都被激活并工作。

在右边,红色的神经元已经从神经网络中被移除。因此,在模型训练过程中,红色神经元将不被考虑。

我们将使用TensorFlow实际地实现这个概念。

Dropout将如何帮助解决过拟合的问题?

Dropout正则化将确保以下几点。

  • 神经元不能依赖一个输入,因为它可能被随机剔除。这减少了由于过度依赖一个输入而产生的偏差,偏差是过拟合的一个主要原因。
  • 神经元不会学习输入的冗余细节。这确保只有重要的信息被神经元存储。这使得神经网络能够获得有用的知识,并用来进行预测。

我们将从建立一个不应用辍学正则化的模型开始。在我们开始之前,让我们探索一下我们将用于建立模型的数据集。

探索数据集

使用的数据集是Sonar数据集。该数据集用于使用神经网络对声呐信号进行分类。该模型预测声纳信号是在金属表面还是在岩石表面被反弹。

为了加载数据集,我们使用Pandas和Numpy。这些是用于数据集操作和分析的有用的Python包。

import numpy as np
import pandas as pd

让我们加载数据集。

df = pd.read_csv("./sonar_dataset.csv", header=None)

要查看我们的数据集,请使用此代码。

print(df.sample(5))

5个数据样本的输出如下所示。

Dataset structure

从上面的图片来看,数据集总共有61列,标签为0 。前60列是模型的输入列,最后一列(第60列)是输出列。最后一列的标签是RM ,分别代表RockMetal

在我们的数据集中,我们必须创建一个X 变量和一个y 变量。X 变量代表输入列,而y 变量代表输出/目标列。我们创建我们的X 变量和y 变量如下。

X = df.drop(60, axis=1)
y = df[60]

从上面的代码来看,X 变量持有前60列的值,y 变量是最后一列(第60列)。

最后一列的标签是RM ,但我们需要将其转换为数字格式。它应该是01 。我们将用1 表示R ,用0 表示M

机器学习模型能很好地处理数字,而不像文本那样对这些模型来说是个大问题。为了将文本转换为数字,我们将使用get_dummies 方法,这是一种Pandas方法。

y = pd.get_dummies(y, drop_first=True)

要查看转换后的列,请运行此代码。

print(y.sample(5))

输出将给出5个数据样本,如下图所示。

Converted columns

下一步是分割我们的数据集。

数据集拆分

在这个阶段,我们把数据集分成两组。第一组将被用于训练,第二组将被用于测试。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=1)

从上面的代码中,我们已经导入了train_test_split ,用于数据集的分割。

我们使用test_size=0.25 来分割我们的数据集。这确保数据集的75% 将被用于训练,而25% 将被用于测试。

在拆分数据集后,下一步是首先建立没有剔除正则化的模型。在后面的章节中,我们将建立同样的模型,并使用放弃正则化。

不使用放弃正则化的模型

让我们导入我们将用于建立神经网络的重要库。

import tensorflow as tf
from tensorflow import keras

我们将使用TensorFlowKeras 来构建我们的神经网络。TensorFlow 将在训练神经网络时运行我们的后台。Keras 将创建我们神经网络的输入、隐藏和输出层。

在TensorFlow中,我们有两种类型的模型。

  1. 顺序性模型。
  2. 功能模型。

在顺序模型中,层是一个接一个地建立在彼此之上的,如下图所示。

Sequential model

功能性模型更加灵活,因为它们不按顺序连接各层。

这里,我们将建立一个顺序模型。

初始化顺序模型

我们初始化顺序模型,如下图所示。

model = keras.Sequential([
    keras.layers.Dense(60, input_dim=60, activation='relu'),
    keras.layers.Dense(30, activation='relu'),
    keras.layers.Dense(15, activation='relu'),
    keras.layers.Dense(1, activation='sigmoid')
])

从上面的代码来看,我们的模型将有四个层。这些层的情况如下。

第1层

第一层是我们神经网络的输入层。它有60 神经元。我们还添加了activation=relu 。我们使用relu ,因为我们的输出位于0和无限之间。

第2层

这是第一个隐藏层,包含30 神经元。我们还添加了activation=relu

第3层

这是第二个隐藏层,包含15 神经元。它也使用relu 作为激活函数。

第4层

第四层是输出层。它只有1 神经元,用来产生模型的预测结果。该层使用sigmoid 作为激活函数。

sigmoid 当输出值在 和 之间时,就使用激活函数。0 1

下一步是编译我们的模型。

编译模型

为了编译我们的模型,我们必须设置optimizerloss ,和metrics ,以便我们的模型使用。

优化器

这是用来在训练期间通过减少模型中存在的错误来提高模型的性能。我们使用adam 优化器。

衡量标准

这将被用来确定模型的性能,以便我们知道模型的学习效果如何。我们使用accuracy 来计算训练后模型的准确度得分。

损失

它计算训练期间的模型误差。我们使用binary_crossentropy 作为我们的损失,因为我们的输出是二进制形式的。输出可以是0 ,也可以是1

我们用下面的代码添加所有这些。

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

编译完这个模型后,下一步是将模型拟合到我们的数据集中。

模型拟合

在这个阶段,模型将从训练数据集中学习。

model.fit(X_train, y_train, epochs=100, batch_size=8)

我们将epochs 的数量设置为100 。该模型将在训练数据集中迭代100 次,并在每次迭代后输出准确率分数。这个过程显示在下面的图片中。

Training phase

从上面的图片来看,100 迭代后的训练得分是1.00 ,这代表100%

为了知道我们的模型是否过拟合,让我们使用测试数据集来计算准确率分数。

使用测试数据集的准确度得分

使用测试数据集来检查准确率得分,请使用以下代码。

model.evaluate(X_test, y_test)

准确率得分显示如下。

Testing phase

从上面的图片中,测试得分是0.7692 ,代表76.92% 。这表明训练准确率大于测试准确率。准确率从100% 急剧下降到76.92%

我们的模型在训练数据集上表现很好,但在测试数据集上表现很差。因此,我们的模型是过拟合的。我们现在需要实施dropout正则化来处理这种过拟合。

撤消正则化的模型

在dropout正则化中,我们将在我们的模型中添加dropout层。在模型训练期间,这些层将随机忽略神经网络中一定数量的神经元。

让我们用下面的代码来实现丢弃层。

modeld = keras.Sequential([
    keras.layers.Dense(60, input_dim=60, activation='relu'),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(30, activation='relu'),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(15, activation='relu'),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(1, activation='sigmoid')
])

注意:我们将带有dropout正则化的新模型命名为modeld

从上面的代码中,我们在每个Dense 层之后添加了一个Dropout 层。我们有3个丢弃层。

第1个滤波层

该层添加在输入层之后,我们将随机丢弃的神经元数量设置为0.5 。因此,一半的神经元将从输入层随机丢弃。

输入层有60 神经元,其中一半的神经元将被随机丢弃。

第2个剔除层

这个层是在第1个隐藏层之后添加的。我们将随机丢弃的神经元数量设置为0.5 。该隐藏层有30 神经元,这些神经元的一半将被随机丢弃。

第3个隐藏层

这一层是在第2个隐藏层之后添加的。我们设置随机丢弃的神经元数量为0.5 。这个隐藏层有15 神经元,这些神经元的一半将被随机丢弃。

在添加了丢弃层之后,我们现在可以编译,然后将我们的模型装入我们的数据集。这是用下面的代码完成的。

modeld.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
modeld.fit(X_train, y_train, epochs=100, batch_size=8)

这将训练我们的模型,如下图所示。

Dropout regularization

从上面的图片来看,100 迭代后的训练得分是0.9167 ,这代表91.67%

为了知道这个过程是否处理了过拟合,让我们使用测试数据集来计算准确率得分。

使用测试数据集

要计算使用测试数据集的准确度,请运行这段代码。

modeld.evaluate(X_test, y_test)

测试得分显示如下。

Testing score

从上面的图片中,我们的测试得分是0.8077 ,这代表80.77% 。你可以看到,通过使用dropout层,测试精度从76.92% 增加到80.77%

这是一个很好的改进,表明这个模型在训练和测试中都表现良好。因此,使用dropout正则化,我们已经处理了深度学习模型中的过拟合问题。

总结

在本教程中,我们已经了解了dropout正则化,以及如何使用它来处理深度学习模型中的过拟合。我们首先区分了机器学习中的过拟合和欠拟合。

然后,我们开始建立一个没有辍学正则化技术的模型。该模型在使用训练数据集时表现非常好,但在使用测试数据集时表现非常差。

最后,我们实施了dropout层。使用这些层,我们提高了测试准确率,从76.92% 增加到80.77% 。因此,我们成功地处理了过拟合问题。