Skip to content

Latest commit

 

History

History
570 lines (339 loc) · 33.1 KB

File metadata and controls

570 lines (339 loc) · 33.1 KB

八、神经网络算法

多种因素的组合使得人工神经网络人工神经网络)成为当今最重要的机器学习技术之一。这些因素包括解决日益复杂的问题的需要、数据的爆炸性增长,以及提供设计非常复杂算法所需的计算能力的技术的出现,如现成的廉价集群。

事实上,这是一个正在迅速发展的研究领域,是领先技术领域(如机器人技术、自然语言处理和自动驾驶汽车)所宣称的大部分重大进步的原因

从神经网络的结构来看,它的基本单元是神经元。人工神经网络的真正优势在于它能够利用多个神经元的能量,将它们组织成一个分层结构。人工神经网络通过将不同层次的神经元链接在一起,创建了一个分层结构。信号通过这些层,并在每个层中以不同的方式进行处理,直到生成最终所需的输出。正如我们将在本章中看到的,ANN 使用的隐藏层充当抽象层,支持深度学习,深度学习广泛用于实现强大的应用程序,如亚马逊的 Alexa、谷歌的图像搜索和谷歌照片。

本章首先介绍了典型神经网络的主要概念和组成部分。然后,介绍了各种类型的神经网络,并解释了这些神经网络中使用的不同类型的激活函数。然后,详细讨论了反向传播算法,它是训练神经网络最常用的算法。接下来,将解释迁移学习技术,该技术可用于大大简化和部分自动化模型的训练。最后,通过一个真实的示例应用程序,介绍了如何使用深度学习来标记欺诈文档。

以下是本章讨论的主要概念:

  • 理解人工神经网络
  • 人工神经网络的演化
  • 训练神经网络
  • 工具和框架
  • 迁移学习
  • 案例研究:利用深度学习进行欺诈检测

让我们从 ANN 的基础知识开始。

理解人工神经网络

受人脑神经元工作的启发,神经网络的概念由 Frank Rosenblatt 于 1957 年提出。为了全面理解这种结构,简要观察一下人脑中神经元的分层结构是很有帮助的。(参考下图,了解人脑中的神经元是如何连接在一起的。)

在人脑中,树突****充当检测信号的传感器。然后信号被传递到一个a****xon**,这是一个长而细的神经细胞投射物。轴突的功能是将此信号传递给肌肉、腺体和其他神经元。如下图所示,信号通过称为突触的互连组织传播在传递给其他神经元之前。请注意,通过这条有机管道,信号会一直传播,直到到达目标肌肉或腺体,在那里它会引起所需的动作。信号通过神经元链并到达目的地通常需要 7 到 8 毫秒:**

**

弗兰克·罗森布拉特(Frank Rosenblatt)受信号处理这一自然建筑杰作的启发,设计了一种技术,这意味着数字信息可以分层处理,以解决复杂的数学问题。他最初设计神经网络的尝试非常简单,看起来类似于线性回归模型。这个简单的神经网络没有任何隐藏层,被命名为感知器。下图对此进行了说明:

让我们尝试开发这个感知器的数学表示。在上图中,输入信号显示在左侧。它是输入的加权和,因为每个输入*(x1、x2..xn乘以相应的权重(w1、w2……wn*然后总结:

请注意,它是一个二进制分类器,因为该感知器的最终输出是真还是假取决于聚合器的输出(显示为 在图中)。如果聚合器能够从至少一个输入检测到有效信号,则聚合器将产生真实信号。

现在让我们来看看神经网络是如何随着时间的推移而进化的。

人工神经网络的演化

在前一节中,我们研究了一个没有任何层的简单神经网络,称为感知器。人们发现感知器有严重的局限性,1969 年,马文·明斯基(Marvin Minsky)和西摩·帕伯特(Seymour Papert)进行了研究,得出了感知器无法学习任何复杂逻辑的结论。

事实上,他们表明,即使是像 XOR 这样简单的逻辑函数,学习起来也很困难。这导致人们对机器学习的兴趣普遍下降,尤其是对神经网络的兴趣,并开启了一个被称为“人工智能冬季”的时代。全世界的研究人员都不会认真对待人工智能,认为它无法解决任何复杂的问题。

所谓 AI 冬天的主要原因之一是当时可用硬件能力的限制。要么缺乏必要的计算能力,要么成本过高。在 20 世纪 90 年代末,分布式计算的进步提供了易于使用且价格合理的基础设施,这导致了人工智能冬天的解冻。解冻为人工智能研究注入了活力。这最终导致将当前时代转变为一个可以称为人工智能之春的时代,在这个时代,人们对人工智能特别是神经网络非常感兴趣

对于更复杂的问题,研究人员开发了一种称为多层感知器的多层神经网络。多层神经网络有几个不同的层,如下图所示。这些层如下所示:

  • 输入层
  • 隐藏层
  • 输出层:

A deep neural network is a neural network with one or more hidden layers. Deep learning is the process of training an ANN. 

需要注意的一点是,神经元是这个网络的基本单元,一层的每个神经元都连接到下一层的所有神经元。对于复杂的网络,这些互连的数量激增,我们将探索在不牺牲太多质量的情况下减少这些互连的不同方法。

首先,让我们试着阐述一下我们试图解决的问题。

输入是一个维度为n的特征向量x

我们需要神经网络来预测数值。预测值用ý表示。

从数学上讲,我们希望在给定特定输入的情况下,确定交易具有欺诈性的概率。换句话说,给定一个特定的值x,那么y=1 的概率是多少?从数学上讲,我们可以表示如下:

注意,x 是一个nx维向量,其中nx是输入变量的个数。

这种神经网络有四层。输入和输出之间的层是隐藏层。第一隐藏层中的神经元数量用表示。不同节点之间的链路乘以称为权重的参数。训练神经网络就是为权重找到正确的值

让我们看看如何训练神经网络。

训练神经网络

使用给定数据集构建神经网络的过程称为训练神经网络*。*让我们看看典型神经网络的解剖结构。当我们谈论训练神经网络时,我们谈论的是计算权重的最佳值。通过以训练数据的形式使用一组示例迭代地完成训练。训练数据中的示例具有不同输入值组合的输出预期值。神经网络的训练过程不同于传统模型的训练方式(在第 7 章传统监督学习算法中讨论)。

理解神经网络的解剖结构

让我们看看神经网络由什么组成:

  • **层:**层是神经网络的核心构建块。每一层都是一个数据处理模块,充当过滤器。它接受一个或多个输入,以某种方式进行处理,然后产生一个或多个输出。每次数据通过一个层时,它都会经过一个处理阶段,并显示与我们试图回答的业务问题相关的模式。
  • **损失函数:**损失函数提供反馈信号,用于学习过程的各种迭代。损失函数提供单个示例的偏差。
  • **成本函数:**成本函数是一套完整示例上的损失函数。
  • **优化器:**优化器确定如何解释损失函数提供的反馈信号。
  • **输入数据:**输入数据是用于训练神经网络的数据。它指定目标变量。
  • **权重:**通过训练网络计算权重。权重大致对应于每个输入的重要性。例如,如果某个特定输入比其他输入更重要,则在训练后,它将被赋予更大的权重值,作为乘数。即使是重要输入的微弱信号,也会从较大的权重值(作为乘数)中收集强度。因此,权重最终根据每个输入的重要性进行调整
  • **激活函数:**将这些值乘以不同的权重,然后进行聚合。它们将如何聚合以及它们的值将如何解释将由所选激活函数的类型决定

现在让我们来看一下神经网络训练的一个非常重要的方面。

在训练神经网络的同时,我们将一个接一个地举每个例子。对于每一个示例,我们都使用欠训练模型生成输出。我们计算预期输出和预测输出之间的差异。对于每个单独的示例,这种差异称为损失。整体而言,整个训练数据集的损失称为成本。当我们继续训练模型时,我们的目标是找到将导致最小损失值的正确权重值。在整个训练过程中,我们不断调整权重值,直到找到一组权重值,从而使总成本尽可能低。一旦我们达到最低成本,我们将模型标记为已培训

定义梯度下降

训练神经网络模型的目的是找到正确的权重值。我们开始用随机或默认的权重值训练神经网络。然后,我们迭代地使用一个优化器算法,比如梯度下降法,来改变权重,从而改进我们的预测。

梯度下降算法的起点是在迭代算法时需要优化的权重的随机值。在随后的每一次迭代中,该算法通过以使成本最小化的方式改变权重值来进行

下图解释了梯度下降算法的逻辑:

在上图中,输入为特征向量X。目标变量的实际值为Y,目标变量的预测值为Y'。我们确定实际值与预测值的偏差。我们更新权重并重复这些步骤,直到成本最小化。

如何在算法的每次迭代中改变权重将取决于以下两个因素:

  • **方向:**取损失函数最小的方向
  • **学习率:**在我们选择的方向上,变化应该有多大

下图显示了一个简单的迭代过程:

该图显示了如何通过改变权重,梯度下降法试图找到最小成本。学习速度和选择的方向将决定图表上要探索的下一个点

Selecting the right value for the learning rate is important. If the learning rate is too small, the problem may take a lot of time to converge. If the learning rate is too high, the problem will not converge. In the preceding diagram, the dot representing our current solution will keep oscillating between the two opposite lines of the graph.

现在,让我们看看如何最小化梯度。仅考虑两个变量,即:T0 0,X,T1,1 和 2。xy的梯度计算如下:

为了最小化梯度,可以使用以下方法:

while(gradient!=0):
    if (gradient < 0); move right
    if (gradient > 0); move left

该算法也可用于寻找神经网络的最优或接近最优的权值

请注意,梯度下降的计算在整个网络中向后进行。我们首先计算最后一层的梯度,然后计算第二层到最后一层的梯度,然后计算之前的梯度,直到到达第一层。这被称为反向传播,由辛顿、威廉姆斯和鲁梅尔哈特于 1985 年引入

接下来,让我们看看激活函数

激活函数

激活函数规定了如何处理特定神经元的输入以产生输出。

如下图所示,神经网络中的每个神经元都有一个激活函数,用于确定如何处理输入:

在上图中,我们可以看到激活函数生成的结果被传递到输出。激活函数设置了如何解释输入值以生成输出的标准。

对于完全相同的输入值,不同的激活函数将产生不同的输出。在使用神经网络解决问题时,了解如何选择正确的激活函数非常重要。

现在让我们逐一研究这些激活函数。

阈值函数

最简单的激活函数是阈值函数。阈值函数的输出是二进制的:0 或 1。如果任何输入大于 1,它将生成 1 作为输出。这可以在下图中解释:

注意,一旦在输入的加权和中检测到任何生命迹象,输出(y就变为 1。这使得阈值激活功能非常敏感。由于小故障或某些噪音,它很容易被输入中最轻微的信号错误触发。

乙状结肠

sigmoid 函数可以看作是阈值函数的改进。在这里,我们可以控制激活函数的灵敏度:

乙状结肠功能y定义如下:

它可以用 Python 实现,如下所示:

def sigmoidFunction(z): 
      return 1/ (1+np.exp(-z))

请注意,通过降低激活函数的灵敏度,我们可以减少输入中的小故障造成的中断。注意,sigmoid 激活函数的输出仍然是二进制的,即 0 或 1。

校正线性单元(ReLU)

本章中介绍的前两个激活函数的输出是二进制的。这意味着它们将获取一组输入变量并将其转换为二进制输出。ReLU 是一种激活函数,它将一组输入变量作为输入,并将其转换为单个连续输出。在神经网络中,ReLU 是最常用的激活函数,通常用于隐藏层,我们不希望将连续变量转换为类别变量。

下图总结了 ReLU 激活功能:

注意当x≤ 0,表示y=0。这意味着来自输入的任何零或小于零的信号被转换为零输出:

用于

用于

x大于零时,即为x

ReLU 函数是神经网络中最常用的激活函数之一。它可以用 Python 实现,如下所示:

def ReLU(x): 
if x<0: 
    return 0 
else: 
    return x

现在让我们来看看泄漏的 ReLU,它是基于 ReLU 的。

漏泄雷卢

在 ReLU 中,x的负值导致y的零值。这意味着在培训过程中会丢失一些信息,这会延长培训周期,尤其是在培训开始时。泄漏的 ReLU 激活功能解决了这个问题。以下内容适用于泄漏的 ReLu:

;对于

用于

如下图所示:

这里,ß是一个值小于 1 的参数。

它可以用 Python 实现,如下所示:

def leakyReLU(x,beta=0.01):
    if x<0:
        return (beta*x)    
    else:        
        return x

有三种方法可以指定ß的值:

  • 我们可以指定默认值ß。
  • 我们可以在我们的神经网络中设置ß一个参数,我们可以让神经网络决定值(这称为参数 ReLU
  • 我们可以使ß成为一个随机值(这称为随机化 ReLU

双曲正切(tanh)

tanh 函数类似于 sigmoid 函数,但它也能给出负信号。下图说明了这一点:

y功能如下:

它可以通过以下 Python 代码实现:

def tanh(x): 
    numerator = 1-np.exp(-2*x) 
    denominator = 1+np.exp(-2*x) 
    return numerator/denominator

现在让我们看看 softmax 函数。

Softmax

有时,我们需要两个以上的级别来输出激活函数。Softmax 是一种激活功能,为我们提供两个以上的输出级别。它最适合于多类分类问题。假设我们有n类。我们有输入值。输入值映射类,如下所示:

x={x(1)、x(2)、.x(n)}

Softmax 以概率论为基础。softmax 的eth类的输出概率计算如下:

For binary classifiers, the activation function in the final layer will be sigmoid, and for multiclass classifiers it will be softmax.

工具和框架

在本节中,我们将详细介绍用于实现神经网络的框架和工具。

随着时间的推移,已经开发了许多不同的框架来实现神经网络。不同的框架各有优缺点。在本节中,我们将重点介绍带有 TensorFlow 后端的 Keras。

凯拉斯

Keras 是最流行且易于使用的神经网络库之一,是用 Python 编写的。它的编写考虑到了易用性,并提供了实现深度学习的最快方法。Keras 仅提供高级块,并在模型级别考虑

Keras 的后端引擎

Keras 需要一个深度较低的深度学习 lib 库来执行张量水平操作。这个较低级别的深度学习库被称为后端引擎。Keras 可能的后端引擎包括:

  • TensorFlowwww.TensorFlow.org):这是同类产品中最流行的框架,由谷歌开源。 *** Theonadeeplearning.net/software/theano):这是在蒙特勒尔大学 MILA 实验室开发的。* 微软认知工具包****CNTK:由微软开发。**

**此模块化深度学习技术堆栈的格式如下图所示:

这种模块化深度学习体系结构的优点是,可以在不重写任何代码的情况下更改 Keras 的后端。例如,如果我们发现 TensorFlow 比 Theona 更适合某个特定任务,我们可以简单地将后端更改为 TensorFlow,而无需重写任何代码

深度学习堆栈的底层

我们刚才提到的三个后端引擎都可以使用堆栈的底层在 CPU 和 GPU 上运行。对于 CPU,使用一个称为特征的低级张量运算库。对于 GPU,TensorFlow 使用 NVIDIA 的CUDA 深度神经网络cuDNN库。

定义超参数

第 6 章无监督机器学习算法所述,超参数是指在学习过程开始前选择其值的参数。我们从常识值开始,然后再尝试优化它们。对于神经网络,重要的超参数如下:

  • 激活函数
  • 学习率
  • 隐藏层的数量
  • 每个隐藏层中的神经元数量

让我们看看如何使用 Keras 定义模型。

定义 Keras 模型

定义完整的 Keras 模型涉及三个步骤:

  1. 定义层

我们可以通过两种可能的方式使用 Keras 构建模型:

  • 序列 API****允许我们为层的线性堆栈构建模型。它用于相对简单的模型,是建筑模型的常用选择:

**

注意,在这里,我们创建了三层–前两层具有 ReLU 激活功能,第三层具有 softmax 作为激活功能

  • **函数 API:**这允许我们为层的非循环图构建模型。可以使用函数 API 创建更复杂的模型。

请注意,我们可以使用顺序 API 和函数 API 定义相同的神经网络。从性能的角度来看,使用哪种方法来定义模型没有任何区别。

  1. 定义学习过程

在这一步中,我们定义了三件事:

  • 优化器
  • 损失函数
  • 量化模型质量的指标:

注意,我们使用model.compile函数来定义优化器、损失函数和度量。

  1. 培训车型。

一旦定义了架构,就应该培训模型:

请注意,batch_sizeepochs等参数是可配置的参数,使其成为超参数。

选择顺序模型还是函数模型

顺序模型将 ANN 创建为一个简单的层堆栈。顺序模型易于理解和实现,但其过于简单的体系结构也有一个主要限制。每一层连接到一个输入和输出张量。这意味着,如果我们的模型在输入或输出或任何隐藏层都有多个输入或多个输出,那么我们就不能使用顺序模型。在这种情况下,我们将不得不使用功能模型。

理解张量流

TensorFlow 是用于处理神经网络的最流行的库之一。在上一节中,我们了解了如何将其用作 Keras 的后端引擎。它是一个开源、高性能的库,实际上可以用于任何数值计算。如果我们查看堆栈,我们可以看到,我们可以用 Python 或 C++来编写一个高级语言,例如 TysFROW 分布式执行引擎。这使得它对开发人员非常有用,并且很受欢迎。

TensorFlow 的工作方式是创建一个有向图DG)来表示您的计算。连接节点的是数学运算的边、输入和输出。此外,它们还表示数据数组

介绍 TensorFlow 的基本概念

让我们简单地看看 TensorFlow 的概念,如标量、向量和矩阵。我们知道,一个简单的数字,如三或五,被称为一个在传统数学中的标量值。此外,在物理学中,向量是具有大小和方向的东西。对于张量流,我们使用向量来表示一维数组。扩展这个概念,二维数组是一个矩阵。对于三维阵列,我们使用术语3D 张量。我们使用术语来捕获数据结构的维度。因此,标量秩 0数据结构,向量秩****1数据结构,矩阵秩****2数据结构。这些多维结构称为张量,如下图所示:

正如我们在上图中所看到的,秩定义了张量的维数。

现在我们来看另一个参数,shapeshape是一个整数元组,指定每个维度中数组的长度。下图解释了shape的概念:

使用shape和秩,我们可以指定张量的细节。

理解张量数学

现在让我们看看使用张量的不同数学计算:

  • 让我们定义两个标量,并尝试使用 TensorFlow 将它们相加和相乘:

  • 我们可以将它们相加和相乘,并显示结果:

  • 我们还可以通过添加两个张量来创建新的标量张量:

  • 我们还可以执行复张量函数:

理解神经网络的类型

建立神经网络的方法不止一种。如果每一层中的每个神经元都与另一层中的每个神经元相连,那么我们称之为稠密或完全连接的神经网络。让我们看看其他形式的神经网络。

卷积神经网络

卷积神经网络CNN)通常用于分析多媒体数据。为了进一步了解 CNN 如何用于分析基于图像的数据,我们需要掌握以下过程:

  • 卷积
  • 汇集

让我们逐一探索。

卷积

卷积过程通过使用另一个称为过滤器(也称为内核)的较小图像对特定图像进行处理来强调感兴趣的模式。例如,如果我们想找到图像中对象的边缘,我们可以使用特定的过滤器对图像进行卷积以获得它们。边缘检测可以帮助我们在目标检测、目标分类等应用领域。所以,卷积的过程就是找到图像中的特征

查找模式的方法基于查找可在不同数据上重用的模式。可重用的模式称为过滤器或内核。

汇集

为机器学习目的处理多媒体数据的一个重要部分是对其进行下采样。这有两个好处:

  • 它降低了问题的总体维度,减少了主要方式训练模型所需的时间。
  • 通过聚合,我们将多媒体数据中不必要的细节提取出来,使其更通用,更能代表类似问题。

按如下方式执行下采样:

请注意,我们用一个像素替换了四个像素的每个块,选择四个像素中的最高值作为这一像素的值。这意味着我们已经减少了四倍的抽样。由于我们选择了每个块中的最大值,所以这个过程称为max****pooling。我们可以选择平均值;在这种情况下,这将是平均池。

递归神经网络

递归神经网络RNNs)是一种基于循环结构的特殊类型的神经网络。这就是为什么他们被称为复发。需要注意的重要一点是 RNN 具有内存。这意味着它们能够存储来自最近迭代的信息。它们用于分析句子结构以预测句子中的下一个单词等领域。

生成性对抗网络

生成性对抗网络GANs是一种生成合成数据的神经网络。它们由伊恩·古德费罗及其同事于 2014 年创建。它们可以用来生成从未存在过的人的照片。更重要的是,它们用于生成合成数据以扩充训练数据集。

在接下来的部分中,我们将看到什么是迁移学习。

迁移学习

多年来,开源社区中的许多组织、研究小组和个人已经完善了一些复杂的模型,这些模型使用大量的通用用例数据进行训练。在某些情况下,他们已投入数年的努力来优化这些模型。其中一些开源模型可用于以下应用程序:

  • 视频中的目标检测
  • 图像中的目标检测
  • 音频转录
  • 文本情感分析

每当我们开始训练一个新的机器学习模型时,我们都要问自己这样一个问题:与其从头开始,我们是否可以简单地为我们的目的定制一个经过良好训练的模型?换句话说,我们能否将现有模型的学习转移到我们的定制模型中,以便回答我们的业务问题?如果我们能够做到这一点,它将带来三个好处:

  • 我们的模型训练工作将有一个快速的开始。
  • 通过使用经过良好测试和完善的模型,我们模型的整体质量可能会提高。
  • 如果我们没有足够的数据来解决我们正在研究的问题,通过迁移学习使用预先训练的模型可能会有所帮助。

让我们看两个实际的例子,这将是有用的:

  • 在训练机器人时,我们可以首先使用模拟游戏来训练神经网络模型。在这个模拟中,我们可以创造出所有在现实世界中很难找到的罕见事件。一旦接受培训,我们就可以使用迁移学习;为真实世界训练模型。
  • 让我们假设我们想要训练一个模型,该模型可以从视频源中对苹果和 Windows 笔记本电脑进行分类。已经有成熟的对象检测模型作为开放源码提供,可以准确地对视频提要中的各种对象进行分类。我们可以使用这些模型作为起点,将对象识别为笔记本电脑。一旦我们将这些对象识别为笔记本电脑,我们就可以进一步训练模型来区分苹果和 Windows 笔记本电脑。

在下一节中,我们将应用本章中介绍的概念来构建欺诈文档分类神经网络。

案例研究——利用深度学习进行欺诈检测

使用机器学习ML技术)识别欺诈文件是一个活跃且具有挑战性的研究领域。研究人员正在调查神经网络的模式识别能力在多大程度上可以用于此目的。与手动属性提取器不同,原始像素可用于多种深入学习的体系结构

方法论

本节介绍的技术使用一种称为暹罗神经网络的神经网络结构,其特点是两个分支具有相同的结构和参数。使用暹罗神经网络标记欺诈文件如下图所示:

当需要验证特定文档的真实性时,我们首先根据其布局和类型对文档进行分类,然后将其与预期的模板和模式进行比较。如果偏离某个阈值,则标记为伪造文档;否则,它将被视为真实或真实的文件。对于关键用例,我们可以为算法无法最终将文档分类为真实或虚假的临界情况添加手动过程。

为了将文档与其预期模板进行比较,我们在暹罗体系结构中使用了两个相同的 CNN。CNN 具有学习最佳平移不变局部特征检测器的优势,并且可以构建对输入图像的几何失真具有鲁棒性的表示。这非常适合我们的问题,因为我们的目标是通过单个网络传递真实和测试文档,然后比较它们的结果的相似性。为了实现这一目标,我们实施以下步骤。

假设我们要测试一个文档。对于每一类文档,我们执行以下步骤:

  1. 获取真实文档的存储图像。我们称之为真实文档。测试文档应该看起来像真实文档。
  2. 真实文档通过神经网络层创建特征向量,这是真实文档模式的数学表示。我们称之为 F特征向量 1,如上图所示。
  3. 需要测试的文档称为测试文档。我们通过一个类似于为真实文档创建特征向量的神经网络来传递该文档。测试文档的特征向量称为 F特征向量 2
  4. 我们使用特征向量 1 和特征向量 2 之间的欧氏距离来计算真实文档和测试文档之间的相似性分数。该相似性得分称为相似性度量MOS。MOS 是一个介于 0 和 1 之间的数字。数字越大,表示文档之间的距离越小,文档相似的可能性越大。
  5. 如果神经网络计算的相似性分数低于预定义的阈值,我们将文档标记为欺诈。

让我们看看如何使用 Python 实现暹罗神经网络:

  1. 首先,让我们导入所需的 Python 包:
import random
import numpy as np
import tensorflow as tf
  1. 接下来,我们将定义用于处理暹罗网络每个分支的神经网络:
def createTemplate():
      return tf.keras.models.Sequential([
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(128, activation='relu'),
        tf.keras.layers.Dropout(0.15),
        tf.keras.layers.Dense(128, activation='relu'),
        tf.keras.layers.Dropout(0.15),
        tf.keras.layers.Dense(64, activation='relu'), 
        ])

请注意,为了减少过度装配,我们还规定了退出率0.15

  1. 为了实现暹罗网络,我们将使用 MNIST 图像。MNIST 图像非常适合测试我们方法的有效性。我们的方法需要以这样的方式准备数据:每个样本将有两个图像和一个二进制相似性标志。此标志表示它们来自同一类。现在我们来实现名为prepareData的函数,它可以为我们准备数据:
def prepareData(inputs: np.ndarray, labels: np.ndarray):
      classesNumbers = 10
      digitalIdx = [np.where(labels == i)[0] for i in range(classesNumbers)]
      pairs = list()
      labels = list()
      n = min([len(digitalIdx[d]) for d in range(classesNumbers)]) - 1
      for d in range(classesNumbers):
        for i in range(n):
            z1, z2 = digitalIdx[d][i], digitalIdx[d][i + 1]
            pairs += [[inputs[z1], inputs[z2]]]
            inc = random.randrange(1, classesNumbers)
            dn = (d + inc) % classesNumbers
            z1, z2 = digitalIdx[d][i], digitalIdx[dn][i]
            pairs += [[inputs[z1], inputs[z2]]]
            labels += [1, 0] 
      return np.array(pairs), np.array(labels, dtype=np.float32)

注意,prepareData()将导致所有数字的样本数相等。

  1. 我们现在将准备培训和测试数据集:
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train = x_train.astype(np.float32)
x_test = x_test.astype(np.float32)
x_train /= 255
x_test /= 255
input_shape = x_train.shape[1:]
train_pairs, tr_labels = prepareData(x_train, y_train)
test_pairs, test_labels = prepareData(x_test, y_test)
  1. 现在,让我们创建暹罗系统的两部分:
input_a = tf.keras.layers.Input(shape=input_shape)
enconder1 = base_network(input_a)
input_b = tf.keras.layers.Input(shape=input_shape)
enconder2 = base_network(input_b)
  1. 现在,我们将实施相似性度量MOS),它将量化我们想要比较的两个文档之间的距离:
distance = tf.keras.layers.Lambda( 
    lambda embeddings: tf.keras.backend.abs(embeddings[0] - embeddings[1])) ([enconder1, enconder2])
measureOfSimilarity = tf.keras.layers.Dense(1, activation='sigmoid') (distance)

现在,让我们来训练模型。我们将使用 10 个阶段来训练该模型:

请注意,我们使用 10 个纪元获得了 97.49%的准确率。增加纪元数将进一步提高准确度。

总结

在本章中,我们首先了解神经网络的细节。我们从研究神经网络多年来是如何进化的开始。我们研究了不同类型的神经网络。然后,我们研究了神经网络的各种构建模块。我们深入研究了用于训练神经网络的梯度下降算法。我们讨论了各种激活函数,并研究了激活函数在神经网络中的应用。我们还研究了迁移学习的概念。最后,我们看了一个实际例子,说明如何使用神经网络来训练机器学习模型,该模型可用于标记伪造或欺诈文档

展望未来,在下一章中,我们将探讨如何将这些算法用于自然语言处理。我们还将介绍 web 嵌入的概念,并将探讨使用递归网络进行自然语言处理。最后,我们还将探讨如何实施情绪分析。******