人工神经网络

2025年3月17日 | 阅读 24 分钟

早期,传统计算机采用算法方法,即计算机遵循一组指令来解决问题,除非明确知道计算机需要遵循的特定步骤,否则计算机无法解决问题。因此,显然需要一个人来解决问题,或者提供指令给计算机,使其知道如何解决特定问题。这实际上将传统计算机解决问题的能力限制在我们已经理解并知道如何解决的问题上。

但是,那些答案不明确的问题该怎么办呢?这就是我们传统方法面临失败的地方,因此神经网络应运而生。神经网络以类似于人脑的方式处理信息,这些网络实际上是从示例中学习的,您无法对其进行编程以执行特定任务。它们只从过去的经验和示例中学习,这就是为什么您不需要提供有关任何特定任务的所有信息。所以,这是神经网络存在的主要原因。

人工神经网络在生物学上受到人脑的神经网络启发而构成。

神经网络是根据人脑建模的,以模仿其功能。人脑可以定义为由几个神经元组成的神经网络,同样,人工神经网络由许多感知器组成。

Artificial Neural Networks

神经网络由三个主要层组成,如下所示:

  • 输入层:输入层接受程序员提供的所有输入。
  • 隐藏层:在输入层和输出层之间,有一组隐藏层,在其上执行计算,从而产生输出。
  • 输出层:输入层经过一系列转换,穿过隐藏层后,产生由输出层输出的结果。

神经网络的动机

基本上,神经网络是基于神经元的,神经元就是脑细胞。一个生物神经元从其他来源接收输入,以某种方式将它们组合,然后对结果执行非线性操作,输出就是最终结果。

Artificial Neural Networks

树突将充当接收器,接收来自其他神经元的信号,然后将其传递给细胞体。细胞体将执行一些操作,可以是求和、乘法等。在对输入集执行操作后,它们将通过轴突传输到下一个神经元,轴突是神经元信号的发射器。

什么是人工神经网络?

人工神经网络是计算系统,旨在模拟人脑分析和处理信息的方式。人工神经网络具有自学习能力,使其能够随着更多数据的可用而产生更好的结果。因此,如果网络在更多数据上进行训练,它将更准确,因为这些神经网络从示例中学习。神经网络可以配置用于特定应用程序,如数据分类、模式识别等。

借助神经网络,我们实际上可以看到许多技术已经从将网页翻译成其他语言发展到拥有虚拟助手在线订购杂货。所有这些都归功于神经网络。因此,人工神经网络不过是各种人工神经元的网络。

神经网络的重要性

  • 没有神经网络:让我们看下面的例子。这里我们有一台机器,我们用四种猫来训练它,如下图所示。一旦训练完成,我们将向这台机器提供一张包含猫的随机图像。由于这只猫与我们训练系统所用的猫不相似,因此如果没有神经网络,我们的机器将无法识别图片中的猫。基本上,机器会混淆,不知道猫在哪里。

    Artificial Neural Networks
  • 有了神经网络:然而,当我们谈论有神经网络的情况时,即使我们没有用那只特定的猫训练我们的机器。但是,它仍然可以识别我们已经训练过的猫的某些特征,并且可以将这些特征与该特定图像中的猫进行匹配,并识别出猫。因此,通过这个例子,您可以清楚地看到神经网络概念的重要性。

人工神经网络的工作原理

我们不直接探讨人工神经网络的工作原理,而是先分解并尝试理解神经网络的基本单元,即感知器

因此,感知器可以定义为具有单层,对线性数据进行分类的神经网络。它进一步由以下四个主要组成部分构成:

  1. 输入
  2. 权重和偏差
  3. 求和函数
  4. 激活或转换函数
Artificial Neural Networks

感知器概念背后的主要逻辑如下:

输入 (x) 被送入输入层,经过与分配的权重 (w) 相乘,然后进行加法运算,形成加权和。然后,这些带相应权重的加权和输入在相关的激活函数上执行。

权重和偏差

当输入变量被送入网络时,会给该特定输入一个随机值作为权重,这样每个单独的权重代表该输入在对结果进行正确预测方面的重要性。

然而,偏差有助于调整激活函数的曲线,以实现精确的输出。

求和函数

给输入分配权重后,它会计算每个输入和权重的乘积。然后通过求和函数计算加权和,其中所有乘积都被相加。

激活函数

激活函数的主要目标是将加权和映射到输出。转换函数包括 tanh、ReLU、sigmoid 等激活函数。

激活函数分为两个主要部分

  1. 线性激活函数
  2. 非线性激活函数

线性激活函数

在线性激活函数中,函数的输出不受任何范围的限制。它的范围是从负无穷到正无穷。对于每个单独的神经元,输入乘以每个相应神经元的权重,这反过来导致产生与输入成比例的输出信号。如果所有输入层本质上都是线性的,那么最后一层的最终激活实际上将是初始层输入的线性函数。

Artificial Neural Networks

非线性函数

这些是最广泛使用的激活函数之一。它有助于模型推广和适应任何类型的数据,以便在输出之间进行正确的区分。它解决了线性激活函数面临的以下问题:

  • 由于非线性函数带有导数函数,因此与反向传播相关的问题已成功解决。
  • 为了创建深度神经网络,它允许堆叠多层神经元。
Artificial Neural Networks

非线性激活函数进一步分为以下几个部分:

  1. Sigmoid 或 Logistic 激活函数
    它通过防止输出值突然跳变来提供平滑的梯度。它的输出值范围在 0 和 1 之间,有助于规范化每个神经元的输出。对于 X,如果它的值大于 2 或小于 -2,那么 y 的值将更陡峭。简单来说,这意味着 X 的微小变化可以导致 Y 的巨大变化。
    它的值范围在 0 到 1 之间,因此二分类(结果为 0 或 1)非常喜欢它。
    Artificial Neural Networks
  2. Tanh 或双曲正切激活函数
    tanh 激活函数比 sigmoid 函数的效果好得多,或者简单地说,它是 sigmoid 激活函数的改进版本。由于其值范围在 -1 到 1 之间,因此它被神经网络中的隐藏层使用,并且由于这个原因,它使得学习过程变得更加容易。
    Artificial Neural Networks
  3. ReLU(修正线性单元)激活函数
    ReLU 是神经网络隐藏层最广泛使用的激活函数之一。它的值范围从 0 到无穷大。它明显有助于解决反向传播问题。它比 sigmoid 和 tanh 激活函数更昂贵。它只允许少数神经元在特定实例被激活,从而实现有效且更简单的计算。
    Artificial Neural Networks
  4. Softmax 函数
    它是一种 Sigmoid 函数,通过解决分类问题。它主要用于处理多个类别,为此它将每个类别的输出压缩到 0 到 1 之间,然后除以输出之和。这种函数主要由输出层中的分类器使用。

梯度下降算法

梯度下降是一种优化算法,用于最小化各种机器学习算法中使用的成本函数,从而更新学习模型的参数。在线性回归中,这些参数是系数,而在神经网络中,它们是权重。

过程

它始于系数的初始值或函数的系数,该值可能是 0.0 或任何小的任意值。

系数 = 0.0

为了估计系数的成本,它们被插入到有助于评估的函数中。

成本 = f(系数)
或者,成本 = 评估(f(系数))

接下来,将计算导数,它是微积分的一个概念,与函数在任何给定实例的斜率有关。为了知道系数的值将朝哪个方向移动,我们需要计算斜率,以便在下一次迭代中实现低成本。

delta = 导数(成本)

现在我们已经找到了下坡方向,它将进一步帮助更新系数的值。接下来,我们需要指定 alpha,它是一个学习率参数,因为它处理每个更新中系数所做的修改量。

系数 = 系数 - (alpha * delta)

直到系数的成本达到 0.0 或足够接近 0.0,整个过程将一遍又一遍地重复。

可以得出结论,梯度下降是一个非常简单明了的概念。它只需要您了解成本函数或您希望优化的函数的梯度。

批量梯度下降

对于梯度下降的每次重复,批梯度下降的主要目标是处理所有训练示例。如果我们有大量的训练示例,那么批梯度下降将变得昂贵且不太受欢迎。

批量梯度下降算法

m 为训练样本数,n 为特征数。

现在假设 hƟ 代表线性回归的假设, 计算从 i=1 到 m 的所有训练样本的总和。那么代价函数将由以下公式计算:

J训练 (Ɵ) = (1/2m) ∑ (hƟ(x(i)) - (y(i))2

重复 {

Ɵj = Ɵj - (学习率/m) * ∑ (hƟ(x(i)) - y(i)) xj(i)

对于每个 j = 0...n

}

这里 x(i) 表示第 ith 个训练样本的第 jth 个特征。如果 m 非常大,那么导数将无法收敛到 全局最小值

随机梯度下降

在单次重复中,随机梯度下降只处理一个训练示例,这意味着它要求所有参数在每个单次迭代处理一个训练示例后进行更新。它比批量梯度下降快得多,但是当我们有大量训练示例时,它也只处理一个示例,这可能导致系统进行大量重复。为了均匀地训练每种数据类型提供的参数,请正确打乱数据集。

随机梯度下降算法

假设 (x(i), y(i)) 是训练样本

成本 (Ɵ, (x(i), y(i))) = (1/2) ∑ (hƟ(x(i)) - (y(i))2

J训练 (Ɵ) = (1/m) ∑ 成本 (Ɵ, (x(i), y(i)))

重复 {

对于 i=1 到 m {

Ɵj = Ɵj - (学习率) * ∑ (hƟ(x(i)) - y(i)) xj(i)

对于每个 j=0...n

}

}

梯度下降不同变体的收敛趋势

批量梯度下降算法沿着直线路径向最小值收敛。如果成本函数是**凸函数**,则算法收敛到**全局最小值**;否则,如果成本函数不是凸函数,则收敛到**局部最小值**。这里学习率通常是常数。

然而,在随机梯度下降的情况下,算法在全球最小值附近波动而不是收敛。学习率会缓慢变化,以便它能够收敛。由于它在一次迭代中只处理一个示例,因此它往往会产生噪声。

反向传播

反向传播由一个神经元输入层、一个输出层和至少一个隐藏层组成。神经元对输入层执行加权求和,然后由激活函数(尤其是 sigmoid 激活函数)将其用作输入。它还利用监督学习来训练网络。它不断更新网络的权重,直到网络达到期望的输出。它包括以下影响网络训练和性能的因素:

  • 权重(初始)的随机值。
  • 训练周期数。
  • 隐藏神经元数量。
  • 训练集。
  • 教学参数值,例如学习率和动量。

反向传播的工作原理

请看下面的图表。

Artificial Neural Networks
  1. 预连接的路径传输输入 X
  2. 然后随机选择权重 W,用于对输入进行建模。
  3. 此后,计算每个神经元的输出,该输出从输入层传递到隐藏层,再到输出层。
  4. 最后,评估输出中的错误。误差B= 实际输出 - 期望输出
  5. 错误从输出层发送回隐藏层,以调整权重以减少错误。
  6. 直到达到所需结果,不断迭代所有过程。

反向传播的必要性

  • 由于它既快速又简单,因此非常容易实现。
  • 除了输入数量,它不包含任何其他参数来进行调整。
  • 因为它不需要任何先验知识,所以它往往更加灵活。
  • 这是一种效果良好的标准方法。

构建 ANN

在开始构建 ANN 模型之前,我们需要一个数据集,我们的模型将在这个数据集上运行。数据集是特定问题的数据集合,以 CSV 文件的形式存在。

CSV 代表逗号分隔值,它以表格格式保存数据。我们正在使用一个虚构的银行数据集。该银行数据集包含 10,000 名客户及其详细信息的数据。之所以进行这一切,是因为银行看到了一些异常的客户流失率,即客户以异常高的速度流失,他们想知道背后的原因,以便他们能够评估并解决这个问题。

在这里,我们将使用人工神经网络解决这个业务问题。我们要处理的问题是分类问题。我们有几个独立变量,例如信用评分、余额和产品数量,我们将根据这些变量预测哪些客户正在离开银行。基本上,我们将解决一个分类问题,而人工神经网络在进行此类预测方面可以做得非常出色。

因此,我们将从在 Anaconda Prompt 上安装 Keras 库、TensorFlow 库以及 Theano 库开始。为此,您需要以管理员身份打开它,然后按如下所示的顺序运行命令。

由于它已经安装,输出将如下所示。

Artificial Neural Networks

从下图中可以看出,TensorFlow 库已成功安装。

Artificial Neural Networks
pip install keras

Artificial Neural Networks

因此,我们也安装了 Keras 库。

现在我们已经完成了安装,下一步是将所有这些库更新到最新版本,这可以通过遵循给定的代码来完成。


Artificial Neural Networks

由于我们是第一次执行此操作,它会询问是否继续。用 y 确认并按 Enter。

Artificial Neural Networks

库成功更新后,我们将关闭 Anaconda 提示符并返回 Spyder IDE。

现在我们将分两部分开始构建我们的模型,其中在第一部分中,我们将进行数据预处理,而在第二部分中,我们将创建 ANN 模型

数据预处理对于正确准备数据以构建未来的深度学习模型非常必要。由于我们面临的是一个分类问题,所以我们有一些包含银行客户信息的独立变量,我们正在尝试预测因变量的二元结果,即如果客户离开银行则为 1,如果客户留在银行则为 0

第一部分:数据预处理

我们将从导入一些预定义的 Python 库开始,例如 NumPy、Matplotlib 和 Pandas,以执行数据预处理。所有这些库都执行某种特定的任务。

NumPy

NumPy 是一个 Python 库,代表 Numerical Python,允许对数组执行线性、数学和逻辑操作,以及傅里叶变换和操作形状的例程。

Matplotlib

它也是一个开源库,借助它可以在 Python 中绘制图表。这个库的唯一目的是可视化数据,为此它需要导入其 pyplot 子库。

Pandas

Pandas 也是一个开源库,提供高性能数据操作和分析工具。它主要用于处理数据和进行分析。

下面给出了一个输出图像,显示库已成功导入。

Artificial Neural Networks

接下来,我们将借助 Pandas 从当前工作目录导入数据文件。我们将使用 read.csv() 来读取本地和通过 URL 的 CSV 文件。

从上面给出的代码中,the dataset 是我们将保存数据的变量的名称。我们已将数据集的名称传递给 read.csv()。代码运行后,我们可以看到数据已成功上传。

通过单击“变量浏览器”并选择“数据集”,我们可以查看数据集,如下图所示。

Artificial Neural Networks

接下来,我们将创建特征矩阵,它就是自变量矩阵。由于我们不知道哪个自变量可能对因变量影响最大,所以这就是我们的人工神经网络通过查看相关性来发现的;它将对那些在神经网络中影响最大的自变量赋予更大的权重。

所以,我们将包含从信用评分到最后一个(即预期工资)的所有独立变量。

运行上述代码后,我们将看到我们已成功创建了特征矩阵 X。接下来,我们将创建一个因变量向量

通过点击 y,我们可以看到 y 包含所有 10,000 名银行客户的二元结果,即 0 或 1。

输出

Artificial Neural Networks

接下来,我们将数据集拆分为训练集和测试集。但在此之前,我们需要对特征矩阵进行编码,因为它包含分类数据。由于因变量也包含分类数据,但同时它也取数值,因此无需将文本编码为数字。但话又说回来,我们的自变量包含字符串类别,因此我们需要对分类自变量进行编码。

在拆分之前对分类数据进行编码的主要原因是,必须对 X 矩阵和因变量 y 进行编码。

所以,现在我们将通过查看控制台中的矩阵来编码我们的分类独立变量,为此我们只需在控制台中按下 X

输出

Artificial Neural Networks

从上面给出的图像中,我们可以看到我们只有两个分类独立变量,即包含三个国家(即法国、西班牙和德国)的国家变量,另一个是性别变量(即男性和女性)。所以,我们得到了这两个变量,我们将在我们的特征矩阵中对其进行编码。

因此,我们需要创建两个标签编码器对象,我们将首先创建名为 labelencoder_X_1 的第一个标签编码器对象,然后应用 fit_transform 方法来编码此变量,这将把这里的字符串法国、西班牙和德国转换为数字 0、1 和 2。

执行代码后,我们现在将查看 X 变量,只需像上一步一样在控制台中按 X。

输出

Artificial Neural Networks

所以,从上面给出的输出图像中,我们可以看到法国变成了 0,德国变成了 1,西班牙变成了 2。

现在,以类似的方式,我们将对另一个变量(即性别变量)执行相同的操作,但使用一个新对象。

输出

Artificial Neural Networks

我们可以清楚地看到女性变成了 0,男性变成了 1。由于我们的分类变量的类别之间没有关系顺序,所以我们需要为国家分类变量创建虚拟变量,因为它包含三个类别,不像性别变量只有两个类别,这就是为什么我们将删除一列以避免虚拟变量陷阱。为性别变量创建虚拟变量是无用的。我们将使用OneHotEncoder类创建虚拟变量。

输出

Artificial Neural Networks

通过查看 X,我们可以看到所有列现在都是相同类型的。此外,类型不再是对象,而是 float64。我们可以看到我们有十二个独立变量,因为我们有三个新的虚拟变量。

接下来,我们将删除一个虚拟变量,以避免陷入虚拟变量陷阱。我们将获取特征矩阵 X,并通过获取该矩阵的所有行和除第一列之外的所有列来更新它。

输出

Artificial Neural Networks

可以看到,我们只剩下两个虚拟变量,因此不再有虚拟变量陷阱。

现在我们已经准备好将数据集分成训练集和测试集。我们将测试集大小设置为0.2,用于在 8,000 个观测数据上训练 ANN,并在 2,000 个观测数据上测试其性能。

通过执行上述代码,我们将得到四个不同的变量,这些变量可以在变量浏览器部分下看到。

输出

Artificial Neural Networks

除了并行计算,我们还将进行高强度计算,并且我们不希望一个独立变量主导另一个,因此我们将应用特征缩放来简化所有计算。

执行上述代码后,我们可以快速查看 X_trainX_test,以检查所有自变量是否已正确缩放。

输出

X_train

Artificial Neural Networks

X_test

Artificial Neural Networks

现在我们的数据已经预处理完毕,我们将开始构建人工神经网络。

第二部分:构建 ANN

我们将从导入 Keras 库以及所需的包开始,因为它将基于 TensorFlow 构建神经网络


Artificial Neural Networks

导入 Keras 库后,我们现在将导入两个模块,即用于初始化神经网络的 Sequential 模块,以及用于构建 ANN 层的 Dense 模块。

接下来,我们将初始化 ANN,或者简单地说,我们将它定义为一系列层。深度学习模型可以通过两种方式初始化,要么通过定义层的序列,要么通过定义图。由于我们将通过连续的层构建 ANN,因此我们将通过将其定义为层的序列来初始化我们的深度学习模型。

这可以通过创建 Sequential 类的对象来完成,该对象取自顺序模型。我们要创建的对象就是模型本身,即一个神经网络,它将具有一排分类器,因为我们正在解决一个分类问题,我们需要预测一个类别,所以我们的神经网络模型将是一个分类器。由于在下一步中,我们将使用分类器名称预测测试集结果,因此我们将我们的模型称为分类器,它就是我们即将构建的未来人工神经网络。

由于此分类器是 Sequential 类的对象,因此我们将使用它,但不会传递任何参数,因为我们将逐步定义层,从输入层开始,然后添加一些隐藏层,最后是输出层。

此后,我们将开始添加输入层和第一个隐藏层。我们将使用在上一步中通过创建顺序类对象初始化的分类器,并使用 add() 方法在神经网络中添加不同的层。在 add() 中,我们将传递 layer 参数,由于我们将添加两个层,即输入层和第一个隐藏层,我们将借助上面提到的 Dense() 函数来完成。

Dense() 函数中,我们将传递以下参数:

  • units 是第一个参数,可以定义为我们希望在隐藏层中添加的节点数。
  • 第二个参数是 kernel_initializer,它将权重随机初始化为接近零的小数,以便它们可以随机地通过均匀函数初始化。这里我们有一个简单的均匀函数,它将根据均匀分布初始化权重。
  • 第三个参数是 activation,可以理解为我们希望在隐藏层中选择的函数。因此,我们将对隐藏层使用整流函数,对输出层使用sigmoid函数。由于我们处于隐藏层中,我们使用“relu”参数,因为它对应于整流函数。
  • 最后是 input_dim 参数,它指定输入层中的节点数,实际上就是独立变量的数量。添加该参数非常必要,因为到目前为止,我们只初始化了 ANN,还没有创建任何层,因此它不知道我们正在创建的这个隐藏层期望哪些节点作为输入。创建第一个隐藏层后,我们不需要为下一个隐藏层指定此参数。

接下来,我们将使用相同的 add 方法添加第二个隐藏层,然后传递相同的参数,即 Dense(),以及其中与上一步中相同的参数,除了 input_dim

添加两个隐藏层后,我们现在将添加最终输出层。这再次类似于上一步,只是我们将使用 units 参数,因为在输出层中我们只需要一个节点,因为我们的因变量是一个包含二元结果的分类变量,而且当存在二元结果时,在这种情况下,输出层中只有一个节点。因此,我们将 units 设置为 1,并且由于我们处于输出层,我们将把整流器函数替换为 sigmoid 激活函数。

完成 ANN 层的添加后,我们现在将通过应用随机梯度下降来编译整个人工神经网络。我们将从分类器对象开始,然后使用编译方法并向其中传递以下参数。

  • 第一个参数是优化器,它只是我们希望用来在神经网络中找到最优权重集的算法。我们将使用的算法就是随机梯度下降算法。由于有几种类型的随机下降算法,其中最有效的一种称为“adam”,它将作为此优化器参数的输入。
  • 第二个参数是损失,它是随机梯度下降算法中的一个损失函数,用于寻找最优权重。由于我们的因变量具有二元结果,因此我们将使用 binary_crossentropy 对数函数;当存在二元结果时,我们将采用 categorical_crossentropy
  • 最后一个参数是指标,它只是评估我们模型的标准,我们使用“准确度”。因此,当每次观测后权重更新时,算法会利用这种准确度来提高模型的性能。

接下来,我们将使 ANN 拟合训练集,为此我们将使用 fit 方法来使 ANN 拟合训练集。在 fit 方法中,我们将传递以下参数:

  • 第一个参数是我们想要训练分类器的数据集,即分为两个参数的训练集,如 X_train(包含训练集观测值的特征矩阵)和 y_train(包含训练集中所有观测值的因变量的实际结果)。
  • 下一个参数是 batch_size,即我们希望更新权重后的观测值数量。
  • 最后,是我们将应用于查看算法实际运行以及不同 epoch 中准确性改进的 epoch 数量。

输出

Artificial Neural Networks

从上面给出的输出图像中,您可以看到我们的模型已经准备就绪,并且达到了大约 84%准确度,这就是执行随机梯度下降算法的方式。

第三部分:进行预测和评估模型

既然我们已经完成了对训练集上的 ANN 训练,现在我们将在该集上进行预测。

输出

Artificial Neural Networks

从上面给出的输出图像中,我们可以看到测试集中 2,000 名客户离开银行的所有概率。例如,如果我们看一下第一个概率,即 21%,这意味着测试集中的第一个客户(索引为零)有 20% 的机会离开银行。

由于预测方法返回客户离开银行的概率,为了使用混淆矩阵,我们不需要这些概率,但我们需要以真或假形式表示的预测结果。因此,我们需要将这些概率转换为预测结果。

我们将选择一个阈值来决定预测结果何时为 1,何时为 0。因此,我们将高于阈值的预测结果设为 1,低于阈值的设为 0,同时我们将采用的自然阈值为 0.5,即 50%。如果 y_pred 较大,则返回 True,否则返回 False。

现在,如果我们查看 y_pred,我们会发现它已将结果更新为“False”或“True”形式。

输出

Artificial Neural Networks

因此,根据模型,测试集的前五位客户没有离开银行,而测试集中的第六位客户离开了银行。

接下来,我们将执行以下代码以获取混淆矩阵。

输出

Artificial Neural Networks

从上面给出的输出中,我们可以看到在 2000 个新观测值中;我们得到了 1542+141= 1683 个正确预测和 264+53= 317 个不正确预测。

所以,现在我们将在控制台上计算准确率,即正确预测数除以总预测数。

Artificial Neural Networks

所以,我们可以看到我们在没有训练我们的 ANN 的新观测值上获得了 84% 的准确率,即使这样也获得了很高的准确率。由于这与我们在训练集中获得的准确率相同,但在测试集中也获得了。

所以,最终我们可以验证我们的模型,现在银行可以利用它对客户进行排名,按他们离开银行的概率从高到低进行排名,即从离开银行概率最高的客户,到离开银行概率最低的客户。


下一主题卷积神经网络