Python 深度学习 - 快速指南
Python 深度学习 - 简介
深度结构化学习或层次学习或简称深度学习是机器学习方法家族的一部分,机器学习方法本身是更广泛的人工智能领域的子集。
深度学习是一类机器学习算法,它使用多层非线性处理单元进行特征提取和转换。每个连续层都使用前一层的输出作为输入。
深度神经网络、深度信念网络和循环神经网络已应用于计算机视觉、语音识别、自然语言处理、音频识别、社交网络过滤、机器翻译和生物信息学等领域,在某些情况下它们产生的结果可与比人类专家更好。
深度学习算法和网络 -
基于多个级别的特征或数据表示的无监督学习。较高级别的特征源自较低级别的特征以形成层次表示。
使用某种形式的梯度下降进行训练。
Python 深度学习 - 环境
在本章中,我们将了解Python深度学习的环境设置。我们必须安装以下软件来制作深度学习算法。
- Python 2.7+
- Scipy 与 Numpy
- Matplotlib
- 西阿诺
- 喀拉斯
- TensorFlow
强烈建议通过 Anaconda 发行版安装 Python、NumPy、SciPy 和 Matplotlib。它附带所有这些软件包。
我们需要确保不同类型的软件安装正确。
让我们转到命令行程序并输入以下命令 -
$ python Python 3.6.3 |Anaconda custom (32-bit)| (default, Oct 13 2017, 14:21:34) [GCC 7.2.0] on linux
接下来,我们可以导入所需的库并打印它们的版本 -
import numpy print numpy.__version__
输出
1.14.2
安装 Theano、TensorFlow 和 Keras
在开始安装软件包 - Theano、TensorFlow 和 Keras 之前,我们需要确认pip是否已安装。Anaconda 中的包管理系统称为 pip。
要确认 pip 的安装,请在命令行中键入以下内容 -
$ pip
一旦确认安装了 pip,我们就可以通过执行以下命令来安装 TensorFlow 和 Keras -
$pip install theano $pip install tensorflow $pip install keras
通过执行以下代码行确认 Theano 的安装 -
$python –c “import theano: print (theano.__version__)”
输出
1.0.1
通过执行以下代码行确认 Tensorflow 的安装 -
$python –c “import tensorflow: print tensorflow.__version__”
输出
1.7.0
通过执行以下代码行确认 Keras 的安装 -
$python –c “import keras: print keras.__version__” Using TensorFlow backend
输出
2.1.5
Python 深度基础机器学习
人工智能 (AI) 是使计算机能够模仿人类认知Behave或智能的任何代码、算法或技术。机器学习 (ML) 是人工智能的一个子集,它使用统计方法使机器能够根据经验进行学习和改进。深度学习是机器学习的一个子集,它使得多层神经网络的计算变得可行。机器学习被视为浅层学习,而深度学习被视为具有抽象的分层学习。
机器学习涉及广泛的概念。下面列出了这些概念 -
- 监督的
- 无监督
- 强化学习
- 线性回归
- 成本函数
- 过拟合
- 欠拟合
- 超参数等
在监督学习中,我们学习从标记数据中预测值。一种有用的 ML 技术是分类,其中目标值是离散值;例如,猫和狗。机器学习中另一种可能有用的技术是回归。回归作用于目标值。目标值是连续值;例如,可以使用回归来分析股票市场数据。
在无监督学习中,我们根据未标记或结构化的输入数据进行推断。如果我们有一百万份医疗记录,并且我们必须理解它,找到底层结构、异常值或检测异常,我们使用聚类技术将数据划分为广泛的集群。
数据集分为训练集、测试集、验证集等。
2012 年的突破使深度学习的概念变得引人注目。使用 2 个 GPU 和大数据等最新技术,算法成功地将 100 万张图像分为 1000 个类别。
深度学习与传统机器学习的关系
传统机器学习模型遇到的主要挑战之一是称为特征提取的过程。程序员需要具体地告诉计算机需要注意的功能。这些功能将有助于做出决策。
将原始数据输入算法很少起作用,因此特征提取是传统机器学习工作流程的关键部分。
这给程序员带来了巨大的责任,而算法的效率在很大程度上取决于程序员的创造力。对于物体识别或手写识别等复杂问题来说,这是一个巨大的问题。
深度学习具有学习多层表示的能力,是帮助我们自动特征提取的少数方法之一。可以假设较低层正在执行自动特征提取,几乎不需要或不需要程序员的指导。
人工神经网络
人工神经网络,或者简称为神经网络,并不是一个新想法。它已经存在了大约 80 年。
直到 2011 年,深度神经网络随着新技术的使用、庞大的数据集可用性和强大的计算机而开始流行。
神经网络模仿神经元,神经元具有树突、细胞核、轴突和末端轴突。
对于网络,我们需要两个神经元。这些神经元通过一个神经元的树突和另一个神经元的末端轴突之间的突触传递信息。
人工神经元的可能模型如下所示 -
神经网络如下所示 -
圆圈是神经元或节点,它们对数据起作用,连接它们的线/边是传递的权重/信息。
每列都是一个层。数据的第一层是输入层。那么,输入层和输出层之间的所有层都是隐藏层。
如果你有一个或几个隐藏层,那么你就有一个浅层神经网络。如果你有很多隐藏层,那么你就有了一个深度神经网络。
在此模型中,您有输入数据,对其进行加权,然后将其传递给神经元中称为阈值函数或激活函数的函数。
基本上,它是与某个值进行比较后所有值的总和。如果您发射信号,则结果为 (1),或者没有发射任何信号,则结果为 (0)。然后对其进行加权并传递到下一个神经元,并运行相同类型的函数。
我们可以使用 s 型函数作为激活函数。
至于权重,它们只是随机开始的,并且每个节点/神经元的输入都是唯一的。
在典型的“前馈”(最基本的神经网络类型)中,您的信息直接通过您创建的网络,并将输出与您希望使用样本数据得到的输出进行比较。
从这里开始,您需要调整权重以帮助您获得与所需输出匹配的输出。
直接通过神经网络发送数据的Behave称为前馈神经网络。
我们的数据按顺序从输入到各层,然后到输出。
当我们向后退并开始调整权重以最小化损失/成本时,这称为反向传播。
这是一个优化问题。在实际应用中,使用神经网络,我们必须处理数十万、数百万甚至更多的变量。
第一个解决方案是使用随机梯度下降作为优化方法。现在,有 AdaGrad、Adam Optimizer 等选项。不管怎样,这都是一个巨大的计算操作。这就是为什么神经网络大部分被搁置了半个多世纪的原因。直到最近,我们的机器才具备了能力和架构来考虑执行这些操作,并匹配适当大小的数据集。
对于简单的分类任务,神经网络在性能上与 K 最近邻等其他简单算法相对接近。当我们拥有更大的数据和更复杂的问题时,神经网络的真正效用就会实现,而这两者都优于其他机器学习模型。
深度神经网络
深度神经网络 (DNN) 是一种在输入层和输出层之间具有多个隐藏层的 ANN。与浅层 ANN 类似,DNN 可以对复杂的非线性关系进行建模。
神经网络的主要目的是接收一组输入,对它们执行逐渐复杂的计算,并给出输出以解决现实世界的问题,例如分类。我们限制自己只能前馈神经网络。
我们在深度网络中有输入、输出和顺序数据流。
神经网络广泛应用于监督学习和强化学习问题。这些网络基于一组相互连接的层。
在深度学习中,隐藏层的数量(大部分是非线性的)可能很大;说大约1000层。
深度学习模型比普通的机器学习网络产生更好的结果。
我们主要使用梯度下降方法来优化网络并最小化损失函数。
我们可以使用Imagenet(一个包含数百万张数字图像的存储库)将数据集分类为猫和狗等类别。除了静态图像之外,DL 网络越来越多地用于动态图像以及时间序列和文本分析。
训练数据集是深度学习模型的重要组成部分。此外,反向传播是训练深度学习模型的主要算法。
深度学习用于训练具有复杂输入输出转换的大型神经网络。
深度学习的一个例子是将照片映射到照片中人物的姓名,就像在社交网络上所做的那样,用短语描述图片是深度学习的另一项最新应用。
神经网络是具有 x1、x2、x3 等输入的函数,这些输入在两个(浅层网络)或多个中间操作(也称为层(深层网络))中转换为 z1、z2、z3 等输出。
权重和偏差随层而变化。“w”和“v”是神经网络各层的权重或突触。
深度学习的最佳用例是监督学习问题。在这里,我们有大量的数据输入和一组所需的输出。
这里我们应用反向传播算法来获得正确的输出预测。
深度学习最基本的数据集是 MNIST,这是一个手写数字的数据集。
我们可以使用 Keras 深度训练卷积神经网络,以对该数据集中的手写数字图像进行分类。
神经网络分类器的触发或激活会产生一个分数。例如,为了将患者分为患病和健康,我们考虑身高、体重、体温、血压等参数。
高分意味着患者患病,低分意味着患者健康。
输出层和隐藏层中的每个节点都有自己的分类器。输入层接受输入并将其分数传递到下一个隐藏层以进一步激活,这样一直持续到达到输出。
这种从输入到输出从左到右向前的过程称为前向传播。
神经网络中的信用分配路径(CAP)是从输入到输出的一系列转换。CAP 详细阐述了输入和输出之间可能的因果关系。
给定前馈神经网络的 CAP 深度或 CAP 深度是隐藏层的数量加一(因为包含输出层)。对于循环神经网络,信号可能多次传播通过一层,CAP 深度可能是无限的。
深网和浅网
浅层学习和深度学习没有明确的深度界限;但大多数人认为,对于具有多个非线性层的深度学习,CAP 必须大于 2。
神经网络中的基本节点是模仿生物神经网络中神经元的感知。然后我们有多层感知或 MLP。每组输入都由一组权重和偏差进行修改;每条边都有独特的权重,每个节点都有独特的偏差。
神经网络的预测精度取决于其权重和偏差。
提高神经网络精度的过程称为训练。将前向支撑网的输出与已知正确的值进行比较。
成本函数或损失函数是生成的输出与实际输出之间的差值。
训练的目的是在数百万个训练样本中使训练成本尽可能小。为此,网络会调整权重和偏差,直到预测与正确的输出匹配。
一旦训练良好,神经网络就有可能每次都做出准确的预测。
当模式变得复杂并且您希望计算机识别它们时,您必须采用神经网络。在这种复杂的模式场景中,神经网络优于所有其他竞争算法。
现在的 GPU 可以比以往更快地训练它们。深度神经网络已经彻底改变了人工智能领域
事实证明,计算机擅长执行重复计算并遵循详细指令,但不擅长识别复杂模式。
如果存在简单模式识别的问题,支持向量机(SVM)或逻辑回归分类器可以很好地完成工作,但随着模式复杂性的增加,除了深度神经网络之外别无选择。
因此,对于像人脸这样的复杂图案,浅层神经网络会失败,别无选择,只能采用更多层的深层神经网络。深层网络能够通过将复杂的模式分解为更简单的模式来完成其工作。例如人脸;深网将使用边缘来检测嘴唇、鼻子、眼睛、耳朵等部位,然后将它们重新组合在一起形成人脸
正确预测的准确性已经变得如此准确,以至于最近在谷歌模式识别挑战赛上,深度网络击败了人类。
这种分层感知器网络的想法已经存在了一段时间。在这个领域,深度网络模仿人脑。但这样做的一个缺点是它们需要很长时间来训练,这是硬件限制
然而,最近的高性能 GPU 已经能够在一周内训练如此深的网络;而快速 CPU 可能需要数周甚至数月才能完成同样的任务。
选择深度网络
如何选择深网?我们必须决定是否要构建分类器,或者是否试图在数据中寻找模式,以及是否要使用无监督学习。为了从一组未标记的数据中提取模式,我们使用受限玻尔兹曼机或自动编码器。
选择深度网络时请考虑以下几点 -
对于文本处理、情感分析、解析和名称实体识别,我们使用循环网络或递归神经张量网络或 RNTN;
对于任何在字符级别运行的语言模型,我们使用循环网络。
对于图像识别,我们使用深度置信网络 DBN 或卷积网络。
对于物体识别,我们使用 RNTN 或卷积网络。
对于语音识别,我们使用循环网络。
一般来说,深度置信网络和具有修正线性单元或 RELU 的多层感知器都是分类的不错选择。
对于时间序列分析,始终建议使用循环网络。
神经网络已经存在 50 多年了;但直到现在他们才崭露头角。原因是它们很难训练;当我们尝试使用反向传播的方法训练它们时,我们会遇到梯度消失或爆炸的问题。当发生这种情况时,训练需要更长的时间,并且准确性会退居二线。在训练数据集时,我们不断计算成本函数,它是一组标记训练数据的预测输出与实际输出之间的差异。然后通过调整权重和偏差值直到最低值来最小化成本函数获得。训练过程使用梯度,即成本随着权重或偏差值的变化而变化的速率。
受限玻尔兹曼网络或自动编码器 - RBN
2006年,在解决梯度消失问题上取得了突破。Geoff Hinton 设计了一种新颖的策略,促进了受限玻尔兹曼机 - RBM(浅两层网络)的发展。
第一层是可见层,第二层是隐藏层。可见层中的每个节点都连接到隐藏层中的每个节点。该网络被称为受限网络,因为同一层内的任何两层都不允许共享连接。
自动编码器是将输入数据编码为向量的网络。它们创建原始数据的隐藏或压缩表示。这些向量可用于降维;该向量将原始数据压缩为较少数量的基本维度。自动编码器与解码器配对,允许基于其隐藏表示重建输入数据。
RBM 在数学上相当于双向转换器。前向传递接受输入并将其转换为一组对输入进行编码的数字。同时向后传递获取这组数字并将它们转换回重构的输入。训练有素的网络可以高精度地进行反向支撑。
在这两个步骤中,权重和偏差都起着关键作用。它们帮助 RBM 解码输入之间的相互关系,并确定哪些输入对于检测模式至关重要。通过前向和后向传递,RBM 被训练以使用不同的权重和偏差重新构造输入,直到输入和重建尽可能接近。RBM 的一个有趣的方面是数据不需要被标记。事实证明,这对于照片、视频、语音和传感器数据等现实世界的数据集非常重要,所有这些数据往往都是未标记的。RBM 不再由人类手动标记数据,而是自动对数据进行排序;通过适当调整权重和偏差,RBM 能够提取重要特征并重建输入。RBM 是特征提取器神经网络系列的一部分,旨在识别数据中的固有模式。这些也称为自动编码器,因为它们必须编码自己的结构。
深度信念网络 - DBN
深度信念网络(DBN)是通过结合 RBM 并引入巧妙的训练方法而形成的。我们有一个新模型最终解决了梯度消失的问题。Geoff Hinton 发明了 RBM 和 Deep Belief Nets 作为反向传播的替代方案。
DBN 在结构上与 MLP(多层感知器)相似,但在训练方面却截然不同。正是训练使 DBN 能够超越浅层网络
DBN 可以可视化为一堆 RBM,其中一个 RBM 的隐藏层是其上方 RBM 的可见层。第一个 RBM 经过训练以尽可能准确地重建其输入。
第一个 RBM 的隐藏层被视为第二个 RBM 的可见层,并且使用第一个 RBM 的输出来训练第二个 RBM。迭代这个过程直到网络中的每一层都被训练完毕。
在 DBN 中,每个 RBM 学习整个输入。DBN 通过连续微调整个输入来实现全局工作,模型会像相机镜头慢慢聚焦图片一样缓慢改进。一堆 RBM 的性能优于单个 RBM,就像多层感知器 MLP 优于单个感知器一样。
在此阶段,RBM 已检测到数据中的固有模式,但没有任何名称或标签。为了完成 DBN 的训练,我们必须向模式引入标签,并通过监督学习对网络进行微调。
我们需要一个非常小的标记样本集,以便特征和模式可以与名称相关联。这个小标签数据集用于训练。与原始数据集相比,这组标记数据可能非常小。
权重和偏差略有改变,导致网络对模式的感知发生微小变化,并且通常会导致总准确度略有增加。
与浅层网络相比,使用 GPU 也可以在合理的时间内完成训练,给出非常准确的结果,而且我们也看到了梯度消失问题的解决方案。
生成对抗网络 - GAN
生成对抗网络是由两个网络组成的深度神经网络,一个网络与另一个网络相互竞争,因此得名“对抗性”网络。
蒙特利尔大学研究人员在 2014 年发表的一篇论文中介绍了 GAN。Facebook 的人工智能专家 Yann LeCun 在提到 GAN 时称对抗性训练是“过去 10 年机器学习领域最有趣的想法”。
GAN 的潜力是巨大的,因为网络扫描可以学习模仿任何数据分布。GAN 可以被教导在任何领域创建与我们自己的世界惊人相似的平行世界:图像、音乐、演讲、散文。从某种程度上来说,他们是机器人艺术家,他们的作品令人印象深刻。
在 GAN 中,一个神经网络(称为生成器)生成新的数据实例,而另一个神经网络(称为判别器)则评估它们的真实性。
假设我们正在尝试生成手写数字,例如 MNIST 数据集中的数字,该数据取自现实世界。当显示来自真实 MNIST 数据集的实例时,鉴别器的工作是将它们识别为真实的。
现在考虑 GAN 的以下步骤 -
生成器网络以随机数形式获取输入并返回图像。
生成的图像与从实际数据集中获取的图像流一起作为鉴别器网络的输入。
鉴别器接收真实图像和假图像并返回概率,即 0 到 1 之间的数字,其中 1 代表真实性的预测,0 代表假性。
所以你有一个双重反馈循环 -
鉴别器处于与图像基本事实的反馈循环中,这是我们所知道的。
生成器与鉴别器处于反馈环路中。
递归神经网络 - RNN
RNN是一种数据可以在任何方向流动的神经网络。这些网络用于语言建模或自然语言处理 (NLP) 等应用。
RNN 的基本概念是利用顺序信息。在正常的神经网络中,假设所有输入和输出彼此独立。如果我们想预测句子中的下一个单词,我们必须知道它之前有哪些单词。
RNN 被称为循环神经网络,因为它们对序列的每个元素重复相同的任务,并且输出基于之前的计算。因此,RNN 可以说具有“记忆”,可以捕获有关先前计算内容的信息。理论上,RNN 可以使用很长序列中的信息,但实际上,它们只能回顾几个步骤。
长短期记忆网络 (LSTM) 是最常用的 RNN。
RNN 与卷积神经网络一起被用作模型的一部分来生成未标记图像的描述。令人惊奇的是,这似乎很有效。
卷积深度神经网络 - CNN
如果我们增加神经网络的层数以使其更深,则会增加网络的复杂性,并允许我们对更复杂的函数进行建模。然而,权重和偏差的数量将呈指数级增长。事实上,对于普通的神经网络来说,学习如此困难的问题是不可能的。这就产生了一个解决方案:卷积神经网络。
CNN 广泛应用于计算机视觉领域;也已应用于自动语音识别的声学建模中。
卷积神经网络背后的想法是穿过图像的“移动滤波器”的想法。这种移动滤波器或卷积适用于节点的某个邻域,例如可以是像素,其中应用的滤波器是 0.5 x 节点值 -
著名研究员 Yann LeCun 是卷积神经网络的先驱。Facebook 作为面部识别软件就使用了这些网络。CNN 一直是机器视觉项目的首选解决方案。卷积网络有很多层。2015 年,在 Imagenet 挑战赛中,机器在物体识别方面击败了人类。
简而言之,卷积神经网络(CNN)是多层神经网络。这些层有时多达 17 层或更多,并假设输入数据是图像。
CNN 大大减少了需要调整的参数数量。因此,CNN 可以有效地处理高维原始图像。
Python 深度学习 - 基础知识
在本章中,我们将研究 Python 深度学习的基础知识。
深度学习模型/算法
现在让我们了解不同的深度学习模型/算法。
深度学习中的一些流行模型如下 -
- 卷积神经网络
- 循环神经网络
- 深度信念网络
- 生成对抗网络
- 自动编码器等
输入和输出表示为向量或张量。例如,神经网络可能具有输入,其中图像中的各个像素 RGB 值表示为向量。
位于输入层和输出层之间的神经元层称为隐藏层。这是神经网络尝试解决问题时大部分工作发生的地方。仔细观察隐藏层可以揭示很多有关网络已经学会从数据中提取的特征的信息。
通过选择哪些神经元连接到下一层中的其他神经元来形成不同的神经网络架构。
用于计算输出的伪代码
以下是计算前向传播神经网络输出的伪代码-
- # node[] := 拓扑排序节点数组
- # 从a到b的边意味着a在b的左边
- # 如果神经网络有 R 个输入和 S 个输出,
- # 那么前 R 个节点是输入节点,最后 S 个节点是输出节点。
- #传入[x]:=连接到节点x的节点
- #weight[x] := 传入边到 x 的权重
对于每个神经元 x,从左到右 -
- if x <= R: 不执行任何操作 # 它是一个输入节点
- 输入 [x] = [输入 [x] 中的 i 的输出 [i]]
- Weighted_sum = dot_product(权重[x], 输入[x])
- 输出[x] = Activation_function(weighted_sum)
训练神经网络
我们现在将学习如何训练神经网络。我们还将学习Python深度学习中的反向传播算法和反向传递。
我们必须找到神经网络权重的最佳值才能获得所需的输出。为了训练神经网络,我们使用迭代梯度下降法。我们首先从权重的随机初始化开始。随机初始化后,我们通过前向传播过程对数据的某些子集进行预测,计算相应的成本函数 C,并按与 dC/dw 成比例的量更新每个权重 w,即成本函数相对于重量。比例常数称为学习率。
可以使用反向传播算法有效地计算梯度。反向传播或反向传播的关键观察是,由于微分的链式法则,神经网络中每个神经元的梯度可以使用神经元处的梯度来计算,它具有输出边缘。因此,我们向后计算梯度,即首先计算输出层的梯度,然后计算最顶层的隐藏层,然后是前面的隐藏层,依此类推,最后到输入层。
反向传播算法主要利用计算图的思想来实现,其中每个神经元扩展到计算图中的许多节点并执行简单的数学运算,如加法、乘法。计算图的边上没有任何权重;所有权重都分配给节点,因此权重成为它们自己的节点。然后在计算图上运行反向传播算法。计算完成后,只需要更新权重节点的梯度即可。其余的梯度可以被丢弃。
梯度下降优化技术
一种常用的优化函数根据权重引起的误差来调整权重,称为“梯度下降”。
梯度是斜率的另一个名称,在 xy 图表上,斜率表示两个变量如何相互关联:运行过程中的上升、距离随时间的变化等。在这种情况下,斜率是网络误差与单个权重之比;即,随着重量的变化,误差如何变化。
更准确地说,我们想要找到哪个权重产生的误差最小。我们希望找到正确表示输入数据中包含的信号的权重,并将其转换为正确的分类。
当神经网络学习时,它会慢慢调整许多权重,以便它们能够正确地将信号映射到含义。网络误差与每个权重之间的比率是导数 dE/dw,用于计算权重的微小变化导致误差微小变化的程度。
每个权重只是涉及许多变换的深层网络中的一个因素;权重信号经过多个层的激活和求和,因此我们使用微积分的链式法则来回溯网络激活和输出。这使我们得到了所讨论的权重及其与总体误差的关系。
给定两个变量(误差和权重),由第三个变量(激活)调节,权重通过该变量传递。我们可以通过首先计算激活的变化如何影响误差的变化,以及权重的变化如何影响激活的变化来计算权重的变化如何影响误差的变化。
深度学习的基本思想无非是:根据模型产生的误差来调整模型的权重,直到无法再减小误差为止。
如果梯度值较小,则深度网络训练缓慢;如果梯度值较高,则深度网络训练速度较快。训练中的任何不准确都会导致输出不准确。从输出到输入训练网络的过程称为反向传播或反向传播。我们知道前向传播从输入开始并向前传播。Back prop 执行反向/相反计算从右到左的渐变。
每次计算梯度时,我们都会使用到该点之前的所有梯度。
让我们从输出层的一个节点开始。边缘使用该节点处的梯度。当我们回到隐藏层时,它变得更加复杂。0 和 1 之间的两个数字的乘积会得到一个较小的数字。梯度值不断变小,因此后向支撑需要花费大量时间来训练,并且准确性会受到影响。
深度学习算法的挑战
浅层神经网络和深层神经网络都存在某些挑战,例如过度拟合和计算时间。DNN 会受到过度拟合的影响,因为使用了附加的抽象层,这使得它们能够对训练数据中罕见的依赖关系进行建模。
在训练过程中应用退出、早期停止、数据增强、迁移学习等正则化方法来对抗过度拟合。丢弃正则化在训练期间随机省略隐藏层中的单元,这有助于避免罕见的依赖关系。DNN 考虑多个训练参数,例如大小(即层数和每层单元数)、学习率和初始权重。由于时间和计算资源成本高昂,寻找最佳参数并不总是可行。批处理等一些技巧可以加快计算速度。GPU 的强大处理能力极大地帮助了训练过程,因为所需的矩阵和向量计算在 GPU 上得到了很好的执行。
辍学
Dropout 是一种流行的神经网络正则化技术。深度神经网络特别容易过度拟合。
现在让我们看看什么是 Dropout 以及它是如何工作的。
用深度学习先驱之一 Geoffrey Hinton 的话说,“如果你有一个深度神经网络并且它没有过度拟合,那么你可能应该使用更大的神经网络并使用 dropout”。
Dropout 是一种在每次梯度下降迭代期间,我们丢弃一组随机选择的节点的技术。这意味着我们随机忽略一些节点,就好像它们不存在一样。
每个神经元以 q 的概率保留,并以 1-q 的概率随机丢弃。对于神经网络中的每一层,q 值可能不同。隐藏层的值为 0.5,输入层的值为 0,适用于各种任务。
在评估和预测期间,不使用 dropout。每个神经元的输出乘以 q,以便下一层的输入具有相同的期望值。
Dropout 背后的想法如下:在没有 Dropout 正则化的神经网络中,神经元之间会产生相互依赖性,从而导致过度拟合。
实施技巧
在 TensorFlow、Pytorch 等库中,通过将随机选择的神经元的输出保持为 0 来实现 Dropout。也就是说,尽管神经元存在,但其输出会被覆盖为 0。
提前停止
我们使用称为梯度下降的迭代算法来训练神经网络。
提前停止背后的想法很直观。当误差开始增加时我们停止训练。这里,误差是指在验证数据上测量的误差,验证数据是用于调整超参数的训练数据的一部分。在这种情况下,超参数就是停止标准。
数据增强
我们增加现有数据量或通过使用现有数据并对其进行一些转换来扩充数据的过程。使用的确切转换取决于我们想要实现的任务。此外,有助于神经网络的转换取决于其架构。
例如,在许多计算机视觉任务(例如对象分类)中,有效的数据增强技术是添加新的数据点,这些数据点是原始数据的裁剪或翻译版本。
当计算机接受图像作为输入时,它会接收像素值数组。假设整个图像向左移动 15 个像素。我们在不同方向上应用许多不同的移位,从而产生了原始数据集大小的许多倍的增强数据集。
迁移学习
采用预先训练的模型并使用我们自己的数据集“微调”模型的过程称为迁移学习。有几种方法可以做到这一点。下面描述了几种方法 -
我们在大型数据集上训练预训练模型。然后,我们删除网络的最后一层,并将其替换为具有随机权重的新层。
然后我们冻结所有其他层的权重并正常训练网络。这里冻结层并不会改变梯度下降或优化期间的权重。
其背后的概念是预训练模型将充当特征提取器,并且只有最后一层将针对当前任务进行训练。
计算图
反向传播是通过使用计算图在 Tensorflow、Torch、Theano 等深度学习框架中实现的。更重要的是,理解计算图上的反向传播结合了几种不同的算法及其变体,例如随时间的反向传播和具有共享权重的反向传播。一旦所有内容都转换为计算图,它们仍然是相同的算法 - 只是计算图上的反向传播。
什么是计算图
计算图被定义为有向图,其中节点对应于数学运算。计算图是表达和评估数学表达式的一种方式。
例如,这是一个简单的数学方程 -
$$p = x+y$$
我们可以画出上述方程的计算图如下。
上面的计算图有一个加法节点(带“+”号的节点),有两个输入变量 x 和 y 以及一个输出 q。
让我们再举一个稍微复杂一点的例子。我们有以下等式。
$$g = \left (x+y \right ) \ast z $$
上述方程由以下计算图表示。
计算图和反向传播
计算图和反向传播都是深度学习训练神经网络的重要核心概念。
前向传球
前向传递是评估计算图表示的数学表达式的值的过程。进行前向传递意味着我们将变量的值从左侧(输入)向前传递到输出所在的右侧。
让我们考虑一个为所有输入赋予一些值的示例。假设为所有输入赋予以下值。
$$x=1,y=3,z=−3$$
通过将这些值赋予输入,我们可以执行前向传递并获得每个节点上的输出的以下值。
首先,我们使用 x = 1 和 y = 3 的值,得到 p = 4。
然后我们使用 p = 4 和 z = -3 得到 g = -12。我们从左到右,向前走。
向后传递的目标
在向后传递中,我们的目的是计算每个输入相对于最终输出的梯度。这些梯度对于使用梯度下降训练神经网络至关重要。
例如,我们想要以下梯度。
所需的梯度
$$\frac{\partial x}{\partial f}, \frac{\partial y}{\partial f}, \frac{\partial z}{\partial f}$$
向后传播(反向传播)
我们通过找到最终输出相对于最终输出(本身!)的导数来开始向后传递。因此,它将导致身份推导并且该值等于一。
$$\frac{\部分g}{\部分g} = 1$$
我们的计算图现在如下所示 -
接下来,我们将通过“*”操作进行向后传递。我们将计算 p 和 z 处的梯度。由于 g = p*z,我们知道 -
$$\frac{\部分g}{\部分z} = p$$
$$\frac{\部分g}{\部分p} = z$$
我们已经从前向传播中知道了 z 和 p 的值。因此,我们得到 -
$$\frac{\部分g}{\部分z} = p = 4$$
和
$$\frac{\部分g}{\部分p} = z = -3$$
我们想要计算 x 和 y 处的梯度 -
$$\frac{\部分g}{\部分x}, \frac{\部分g}{\部分y}$$
然而,我们希望有效地做到这一点(尽管 x 和 g 在此图中仅相距两跳,想象一下它们彼此相距甚远)。为了有效地计算这些值,我们将使用微分链式法则。根据链式法则,我们有 -
$$\frac{\部分g}{\部分x}=\frac{\部分g}{\部分p}\ast \frac{\部分p}{\部分x}$$
$$\frac{\部分g}{\部分y}=\frac{\部分g}{\部分p}\ast \frac{\部分p}{\部分y}$$
但我们已经知道 dg/dp = -3,dp/dx 和 dp/dy 很容易,因为 p 直接取决于 x 和 y。我们有 -
$$p=x+y\Rightarrow \frac{\partial x}{\partial p} = 1, \frac{\partial y}{\partial p} = 1$$
因此,我们得到 -
$$\frac{\partial g} {\partial f} = \frac{\partial g} {\partial p}\ast \frac{\partial p} {\partial x} = \left ( -3 \right ) .1 = -3$$
此外,对于输入 y -
$$\frac{\partial g} {\partial y} = \frac{\partial g} {\partial p}\ast \frac{\partial p} {\partial y} = \left ( -3 \right ) .1 = -3$$
向后执行此操作的主要原因是,当我们必须计算 x 处的梯度时,我们仅使用已经计算的值和 dq/dx (节点输出相对于同一节点输入的导数)。我们使用本地信息来计算全局值。
训练神经网络的步骤
按照以下步骤训练神经网络 -
对于数据集中的数据点x,我们以x作为输入进行前向传播,并计算成本c作为输出。
我们从 c 开始向后传递,并计算图中所有节点的梯度。这包括代表神经网络权重的节点。
然后我们通过 W = W - 学习率 * 梯度来更新权重。
我们重复此过程,直到满足停止标准。
Python 深度学习 - 应用
深度学习在计算机视觉、语言翻译、图像字幕、音频转录、分子生物学、语音识别、自然语言处理、自动驾驶汽车、脑肿瘤检测、实时语音翻译、音乐等一些应用中取得了良好的成果作文、自动游戏等。
深度学习是继机器学习之后的下一个重大飞跃,具有更先进的实现。目前,它正在成为一个行业标准,有望在处理原始非结构化数据时成为游戏规则改变者。
深度学习是目前解决广泛现实问题的最佳解决方案之一。开发人员正在构建人工智能程序,这些程序不使用先前给出的规则,而是从示例中学习来解决复杂的任务。随着许多数据科学家使用深度学习,更深层次的神经网络正在提供更加准确的结果。
这个想法是通过增加每个网络的训练层数来开发深度神经网络;机器会更多地了解数据,直到数据尽可能准确。开发者可以利用深度学习技术来实现复杂的机器学习任务,并训练AI网络具有高水平的感知识别能力。
深度学习在计算机视觉领域很受欢迎。这里实现的任务之一是图像分类,其中给定的输入图像被分类为猫、狗等,或者分类为最能描述图像的类或标签。作为人类,我们很早就学会了如何完成这项任务,并拥有快速识别模式、从先验知识中概括以及适应不同图像环境的技能。
库和框架
在本章中,我们将把深度学习与不同的库和框架联系起来。
深度学习和 Theano
如果我们想开始编写深度神经网络,我们最好了解 Theano、TensorFlow、Keras、PyTorch 等不同框架的工作原理。
Theano 是 python 库,它提供了一组用于构建深度网络的函数,这些函数可以在我们的机器上快速训练。
Theano 是在深网先驱 Yoshua Bengio 的领导下在加拿大蒙特利尔大学开发的。
Theano 让我们可以用向量和矩阵(数字的矩形数组)来定义和计算数学表达式。
从技术上讲,神经网络和输入数据都可以表示为矩阵,并且所有标准网络运算都可以重新定义为矩阵运算。这很重要,因为计算机可以非常快速地执行矩阵运算。
我们可以并行处理多个矩阵值,如果我们构建具有这种底层结构的神经网络,我们可以使用带有 GPU 的单台机器在合理的时间窗口内训练巨大的网络。
然而,如果我们使用 Theano,我们就必须从头开始构建深度网络。该库不提供创建特定类型深度网络的完整功能。
相反,我们必须对深层网络的各个方面进行编码,例如模型、层、激活、训练方法以及任何防止过度拟合的特殊方法。
然而好消息是,Theano 允许在矢量化函数之上构建我们的实现,为我们提供了高度优化的解决方案。
还有许多其他库可以扩展 Theano 的功能。TensorFlow 和 Keras 可以与 Theano 作为后端一起使用。
使用 TensorFlow 进行深度学习
Google 的 TensorFlow 是一个 Python 库。该库是构建商业级深度学习应用程序的绝佳选择。
TensorFlow 源自另一个库 DistBelief V2,它是 Google Brain 项目的一部分。该库旨在扩展机器学习的可移植性,以便研究模型可以应用于商业级应用程序。
与 Theano 库非常相似,TensorFlow 基于计算图,其中节点表示持久数据或数学运算,边表示节点之间的数据流,这是一个多维数组或张量;因此得名 TensorFlow
一个操作或一组操作的输出将作为下一个操作的输入。
尽管 TensorFlow 是为神经网络设计的,但它也适用于可以将计算建模为数据流图的其他网络。
TensorFlow 还使用了 Theano 的多项功能,例如公共和子表达式消除、自动微分、共享和符号变量。
可以使用 TensorFlow 构建不同类型的深度网络,如卷积网络、自动编码器、RNTN、RNN、RBM、DBM/MLP 等。
但是,TensorFlow 中不支持超参数配置。对于此功能,我们可以使用 Keras。
深度学习和 Keras
Keras 是一个功能强大且易于使用的 Python 库,用于开发和评估深度学习模型。
它具有极简的设计,允许我们逐层构建网络;训练它,然后运行它。
它封装了高效的数值计算库 Theano 和 TensorFlow,使我们能够用几行短代码定义和训练神经网络模型。
它是一个高级神经网络 API,有助于广泛使用深度学习和人工智能。它运行在许多较低级别的库之上,包括 TensorFlow、Theano 等。Keras 代码是可移植的;我们可以使用 Theano 或 TensorFlow 作为后端在 Keras 中实现神经网络,而无需更改任何代码。
Python 深度学习 - 实现
在深度学习的实施中,我们的目标是预测某家银行的客户流失或流失数据 - 哪些客户可能会离开该银行服务。使用的数据集相对较小,包含 10000 行 14 列。我们使用 Anaconda 发行版以及 Theano、TensorFlow 和 Keras 等框架。Keras 构建在 Tensorflow 和 Theano 之上,它们充当其后端。
# Artificial Neural Network # Installing Theano pip install --upgrade theano # Installing Tensorflow pip install –upgrade tensorflow # Installing Keras pip install --upgrade keras
步骤一:数据预处理
In[]: # Importing the libraries import numpy as np import matplotlib.pyplot as plt import pandas as pd # Importing the database dataset = pd.read_csv('Churn_Modelling.csv')
第2步
我们创建数据集特征和目标变量的矩阵,即第 14 列,标记为“Exited”。
数据的初始外观如下所示 -
In[]: X = dataset.iloc[:, 3:13].values Y = dataset.iloc[:, 13].values X
输出
步骤3
Y
输出
array([1, 0, 1, ..., 1, 1, 0], dtype = int64)
步骤4
我们通过对字符串变量进行编码来使分析变得更简单。我们使用 ScikitLearn 函数“LabelEncoder”自动对列中的不同标签进行编码,其值介于 0 到 n_classes-1 之间。
from sklearn.preprocessing import LabelEncoder, OneHotEncoder labelencoder_X_1 = LabelEncoder() X[:,1] = labelencoder_X_1.fit_transform(X[:,1]) labelencoder_X_2 = LabelEncoder() X[:, 2] = labelencoder_X_2.fit_transform(X[:, 2]) X
输出
在上面的输出中,国家名称被替换为0、1和2;而male和female则用0和1代替。
步骤5
标记编码数据
我们使用相同的ScikitLearn库和另一个名为OneHotEncoder 的函数来传递创建虚拟变量的列号。
onehotencoder = OneHotEncoder(categorical features = [1]) X = onehotencoder.fit_transform(X).toarray() X = X[:, 1:] X
现在,前 2 列代表国家/地区,第四列代表性别。
输出
我们总是将数据分为训练部分和测试部分;我们在训练数据上训练模型,然后在测试数据上检查模型的准确性,这有助于评估模型的效率。
步骤6
我们使用 ScikitLearn 的train_test_split函数将数据分为训练集和测试集。我们将训练与测试的分流比保持为 80:20。
#Splitting the dataset into the Training set and the Test Set from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)
有些变量的值以千为单位,而有些变量的值以十或个为单位。我们对数据进行缩放,使它们更具代表性。
步骤7
在此代码中,我们使用StandardScaler函数拟合和转换训练数据。我们对缩放进行标准化,以便使用相同的拟合方法来转换/缩放测试数据。
# Feature Scaling
fromsklearn.preprocessing import StandardScaler sc = StandardScaler() X_train = sc.fit_transform(X_train) X_test = sc.transform(X_test)
输出
数据现已正确缩放。最后,我们完成了数据预处理。现在,我们将从我们的模型开始。
步骤8
我们在这里导入所需的模块。我们需要顺序模块来初始化神经网络,并需要密集模块来添加隐藏层。
# Importing the Keras libraries and packages import keras from keras.models import Sequential from keras.layers import Dense
步骤9
我们将该模型命名为分类器,因为我们的目标是对客户流失进行分类。然后我们使用Sequential模块进行初始化。
#Initializing Neural Network classifier = Sequential()
步骤10
我们使用密集函数一层一层地添加隐藏层。在下面的代码中,我们将看到许多参数。
我们的第一个参数是output_dim。它是我们添加到该层的节点数。init是随机梯度下降的初始化。在神经网络中,我们为每个节点分配权重。初始化时,权重应接近于零,我们使用统一函数随机初始化权重。仅第一层需要input_dim参数,因为模型不知道输入变量的数量。这里输入变量的总数为 11。在第二层中,模型自动知道来自第一个隐藏层的输入变量的数量。
执行以下代码行添加输入层和第一个隐藏层 -
classifier.add(Dense(units = 6, kernel_initializer = 'uniform', activation = 'relu', input_dim = 11))
执行以下代码行添加第二个隐藏层 -
classifier.add(Dense(units = 6, kernel_initializer = 'uniform', activation = 'relu'))
执行以下代码行添加输出层 -
classifier.add(Dense(units = 1, kernel_initializer = 'uniform', activation = 'sigmoid'))
第11步
编译人工神经网络
到目前为止,我们已经向分类器添加了多个层。我们现在将使用compile方法来编译它们。最终编译控制中添加的参数完成了神经网络。所以,我们在这一步需要小心。
以下是对论点的简要解释。
第一个参数是Optimizer。这是一种用于查找最佳权重集的算法。该算法称为随机梯度下降(SGD)。在这里,我们使用多种类型中的一种,称为“Adam 优化器”。SGD 取决于损失,因此我们的第二个参数是损失。如果我们的因变量是二元的,我们使用名为'binary_crossentropy'的对数损失函数,如果我们的因变量在输出中具有两个以上类别,那么我们使用'categorical_crossentropy'。我们希望基于准确度来提高神经网络的性能,因此我们添加了准确度指标。
# Compiling Neural Network classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
步骤12
这一步需要执行很多代码。
将 ANN 拟合到训练集
我们现在根据训练数据训练我们的模型。我们使用fit方法来拟合我们的模型。我们还优化权重以提高模型效率。为此,我们必须更新权重。批量大小是我们更新权重后的观察次数。Epoch是迭代的总数。批量大小和历元的值通过试错法选择。
classifier.fit(X_train, y_train, batch_size = 10, epochs = 50)
做出预测并评估模型
# Predicting the Test set results y_pred = classifier.predict(X_test) y_pred = (y_pred > 0.5)
预测单个新观察结果
# Predicting a single new observation """Our goal is to predict if the customer with the following data will leave the bank: Geography: Spain Credit Score: 500 Gender: Female Age: 40 Tenure: 3 Balance: 50000 Number of Products: 2 Has Credit Card: Yes Is Active Member: Yes
步骤13
预测测试集结果
预测结果将为您提供客户离开公司的概率。我们将该概率转换为二进制 0 和 1。
# Predicting the Test set results y_pred = classifier.predict(X_test) y_pred = (y_pred > 0.5)
new_prediction = classifier.predict(sc.transform (np.array([[0.0, 0, 500, 1, 40, 3, 50000, 2, 1, 1, 40000]]))) new_prediction = (new_prediction > 0.5)
第14步
这是我们评估模型性能的最后一步。我们已经有了原始结果,因此我们可以构建混淆矩阵来检查模型的准确性。
制作混淆矩阵
from sklearn.metrics import confusion_matrix cm = confusion_matrix(y_test, y_pred) print (cm)
输出
loss: 0.3384 acc: 0.8605 [ [1541 54] [230 175] ]
根据混淆矩阵,我们模型的准确性可以计算为 -
Accuracy = 1541+175/2000=0.858
我们达到了 85.8% 的准确率,这很好。
前向传播算法
在本节中,我们将学习如何编写代码来为简单的神经网络进行前向传播(预测) -
每个数据点都是一个客户。第一个输入是他们有多少个帐户,第二个输入是他们有多少个孩子。该模型将预测用户明年进行的交易量。
输入数据被预加载为输入数据,权重位于称为权重的字典中。隐藏层中第一个节点的权重数组位于权重 ['node_0'] 中,隐藏层中第二个节点的权重数组位于权重 ['node_1'] 中。
馈送到输出节点的权重在权重中可用。
修正线性激活函数
“激活函数”是在每个节点上工作的函数。它将节点的输入转换为某些输出。
修正线性激活函数(称为ReLU)广泛应用于高性能网络中。该函数将单个数字作为输入,如果输入为负,则返回 0;如果输入为正,则将输入作为输出。
这里有一些例子 -
- 雷卢(4) = 4
- 雷卢(-2)= 0
我们填写 relu() 函数的定义−
- 我们使用 max() 函数来计算 relu() 的输出值。
- 我们将relu()函数应用于node_0_input来计算node_0_output。
- 我们将relu()函数应用于node_1_input来计算node_1_output。
import numpy as np input_data = np.array([-1, 2]) weights = { 'node_0': np.array([3, 3]), 'node_1': np.array([1, 5]), 'output': np.array([2, -1]) } node_0_input = (input_data * weights['node_0']).sum() node_0_output = np.tanh(node_0_input) node_1_input = (input_data * weights['node_1']).sum() node_1_output = np.tanh(node_1_input) hidden_layer_output = np.array(node_0_output, node_1_output) output =(hidden_layer_output * weights['output']).sum() print(output) def relu(input): '''Define your relu activation function here''' # Calculate the value for the output of the relu function: output output = max(input,0) # Return the value just calculated return(output) # Calculate node 0 value: node_0_output node_0_input = (input_data * weights['node_0']).sum() node_0_output = relu(node_0_input) # Calculate node 1 value: node_1_output node_1_input = (input_data * weights['node_1']).sum() node_1_output = relu(node_1_input) # Put node values into array: hidden_layer_outputs hidden_layer_outputs = np.array([node_0_output, node_1_output]) # Calculate model output (do not apply relu) odel_output = (hidden_layer_outputs * weights['output']).sum() print(model_output)# Print model output
输出
0.9950547536867305 -3
将网络应用于许多观察/数据行
在本节中,我们将学习如何定义函数