热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深度学习三人行(第3期)TensorFlow从DNN入手

我们已经学习了TensorFlow的一些基础知识,深度学习三人行(第1期)----TensorFlow爱之初体验深度学习三人行(第2期)----TensorFlow爱

我们已经学习了TensorFlow的一些基础知识,

深度学习三人行(第1期)---- TensorFlow爱之初体验

深度学习三人行(第2期)---- TensorFlow爱之再体验

该期我们将从DNN入手开始学习TensorFlow方面的相关知识。学习的路上,我们多多交流,共同进步。本期主要内容如下:

  • 从生物学到人工神经网络

  • 训练多层感知机

  • 训练DNN

文末附本期代码关键字,回复关键字即可下载。


一. 从生物学到人工神经网络

鸟类启发我们飞翔,牛蒡植物启发魔术贴,而大自然激发了许多其他发明。 那么,大脑的体系结构,是激发人工神经网络(ANN)的关键思想。人工神经网络是深度学习的核心。

1.1 从生物到人工神经元

在讨论人造神经元之前,让我们快速看一下生物神经元,如下图所示。它是一种看起来很奇特的细胞,主要存在于动物大脑皮层(例如,你的大脑)中,由含有细胞核和大部分细胞复杂成分的细胞体以及许多称为树突的分支延伸部分组成,还有一个非常长的延伸部分,称为轴突。轴突的长度可能比细胞体长几倍,或长达几万倍。靠近其末端的轴突分裂出成许多分支称为终树突,并且在这些分支的尖端是微小的结构,称为突触末端(或简称突触),其被连接到树突(或直接到细胞体)的其他神经元。生物神经元通过这些突触接收来自其他神经元的信号的短电脉冲。当一个神经元在几毫秒内接收到来自其他神经元的足够数量的信号时,它会触发自己的信号。

tf.assign()函数的作用是创建一个将新值赋给变量的一个节点,这里相当于执行如下迭代:

因此,单个生物神经似乎表现得相当简单,但它们组织在一个数十亿个神经元的庞大网络中,每个神经元通常与数千个其他神经元相连时情况就不同了。生物神经网络(BNN)的体系结构仍然是积极研究的主题,大脑的某些部分结构已经被打印出来,似乎神经元通常以连续的层次组织,如下图所示。


二. 训练多层感知机

Warren McCulloch和Walter Pitts提出了一个非常简单的生物神经元模型,该模型后来被称为人造神经元:它具有一个或多个二进制(开/关)输入和一个二进制输出。 当超过一定数量的输入有效时,人造神经元会简单地激活其输出。 McCulloch和Pitts表明,有了这样一个简化的模型,我们可以建立一个人造神经元网络,计算你想要的任何逻辑命题。 例如,假设神经元至少有两个输入有效时激活神经元,就可以构建一些执行各种逻辑运算的ANN,如下图所示。

感知机是Frank Rosenblatt于1957年发明的最简单的ANN架构之一。 它基于一个稍微不同的人造神经元(见下图),称为线性阈值单元(LTU):输入和输出现在是数字(而不是二进制开/关值),每个输入连接都与一个重量。 LTU计算其输入的加权和(z = w1 x1 + w2 x2 + ⋯ + wn xn = wT · x),然后对该和应用阶跃函数并输出结果:hw(x)= step(z) = step(wT·x)。

在感知机中使用的最常用的是Heaviside阶跃函数(见如下公式)。 有时使用符号函数代替。

单层感知器仅由单层LTU组成,每个神经元连接到所有输入,通常会添加一个额外的偏差特征(x0 = 1)。具有两个输入和三个输出的感知器如下图所示。 这个感知器可以将实例同时分为三个不同的二进制类,这使得它成为一个多输出分类器。

一个MLP由一个(直通)输入层,一个或多个LTU层组成,称为隐藏层,最后一层LTU称为输出层(如下图所示)。 除输出层以外的每一层都包含一个偏置神经元,并完全连接到下一层。 当ANN具有两个或更多个隐藏层时,它被称为深度神经网络(DNN)。

多年来,研究人员一直在努力寻找一种培训MLP的方法,但没有成功。但在1986年,D. E. Rumelhart 等人。发表了一篇突破性文章,介绍反向传播训练算法。对于每个训练实例,算法将其输入到网络并计算每个神经元的输出(这是正向传递,就像进行预测时一样)。 然后它计算网络的输出误差(即期望的输出和网络的实际输出之间的差异),并且它计算最后一个隐藏层中的每个神经元对每个输出神经元的误差有多大贡献。然后继续测量这些误差贡献中多少来自前一个隐藏层中的每个神经元 - 等等直到算法到达输入层。

为了使这个算法正常工作,作者对MLP的架构做了一个关键的改变:他们用logistic函数σ(z)= 1 /(1 + exp(-z))代替了阶跃函数。 这是很重要的,因为阶跃函数只包含平坦段,所以没有梯度可用(梯度下降不能在平坦表面上移动),而logistic函数在每个地方都有一个定义明确的非零导数,允许渐变下降 每一步都有进步。 反向传播算法可以与其他激活函数一起使用,而不是逻辑函数。 其他两种流行的激活功能是:

1.双曲正切函数tanh(z)=2σ(2z) - 1

它是S形的,连续的,可微分的,但是它的输出值范围从-1到1(而不是在逻辑函数中为0到1),这往往会使每一层的输出更大或训练开始时标准化程度较低(即以0为中心)。

2.ReLU功能

ReLU(z)= max(0,z)。 它是连续的,但不幸的是它在z = 0时不可微分(斜率突然变化,这可能导致梯度下降反弹)。实际上它运行得非常好,并且具有快速计算的优点。

这些流行的激活函数及其衍生物如图下图所示。

MLP通常用于分类,每个输出对应于不同的二进制类(例如,垃圾邮件/火腿,紧急/不紧急等等)。当这些类是排他性的(例如,数字图像分类的类0到9)时,输出层通常通过用共享的softmax函数代替单独的激活函数(见下图)。 softmax函数在机器学习系列中介绍过。每个神经元的输出对应于相应类的估计概率。 请注意,信号仅在一个方向上(从输入到输出)流动,所以此架构是前馈神经网络(FNN)的一个示例。

使用TensorFlow训练MLP的最简单方法是使用高级API TF.Learn,它与Scikit-Learn的API非常相似。 DNNClassifier类使得使用任意数量的隐藏层训练深层神经网络和softmax输出层来输出估计类别概率变得十分简单。 例如,下面的代码训练一个DNN用于分类两个隐藏层(一个具有300个神经元,另一个具有100个神经元)以及一个具有10个神经元的softmax输出层:

如果您在MNIST数据集上运行此代码(在对其进行缩放后(例如,通过使用ScikitLearn的StandardScaler),您可能会得到一个在测试集上的准确率超过98.2%的模型! 这比我们在机器学习系列文章的模型中训练的最佳模型要好:

代码过长,详细代码请移步公众号“智能算法”回复文末关键字下载。


三. 训练DNN

这里我们将实现Minibatch渐变下降以在MNIST数据集上进行训练。 第一步是构建阶段,构建TensorFlow图。 第二步是执行阶段,您可以在其中实际运行图来训练模型。

3.1 构建阶段

首先,我们需要导入tensorflow库。 然后,我们必须指定输入和输出的数量,并设置每层中隐藏的神经元的数量:

接下来,我们可以使用占位符节点来表示训练数据和目标。 X的形状只是部分定义的。 我们知道它将是一个二维张量(即矩阵),沿第一维的实例和沿第二维的特征,并且我们知道特征的数量将是28 x 28(每像素一个特征) ,但我们还不知道每个培训批次将包含多少个实例。 所以X的形状是(None,n_inputs)。 同样,我们知道y将是每个实例有一个入口的一维张量,但是在这一点上我们也不知道训练批量的大小,因此形状是(无)。

现在我们来创建实际的神经网络。 占位符X将充当输入层; 在执行阶段,它将一次替换为一个训练批次(请注意,训练批次中的所有实例都将由神经网络同时处理)。 现在你需要创建两个隐藏层和输出层。 这两个隐藏层几乎是相同的:它们的区别仅在于它们所连接的输入以及它们包含的神经元的数量。 输出层也非常相似,但它使用softmax激活功能而不是ReLU激活功能。 因此,让我们创建一个我们将用来一次创建一个图层的neuron_layer()函数。 它将需要参数来指定输入,神经元的数量,激活函数和图层的名称:

让我们一行一行地看看这段代码:

1.首先我们使用图层的名称创建一个名称范围:它将包含该神经元图层的所有计算节点。 这是可选的,但如果TensorBoard中的节点组织良好,该图形在TensorBoard中看起来会更好。

2.接下来,我们通过查询输入矩阵的形状并获得第二维的大小(第一维是实例)来获得输入的数量。

3.接下来的三行创建一个W变量,它将保存权重矩阵。 它将是一个二维张量,其中包含每个输入和每个神经元之间的所有连接权重; 因此,它的形状将是(n_inputs,n_neurons)。 它将被随机初始化,使用标准偏差为2 / ninputs的截断法线(高斯)分布。 使用这个特定的标准偏差有助于算法更快地收敛。 为所有隐藏层随机初始化连接权重非常重要,以避免梯度下降算法无法打破的任何对称性。

4.下一行为偏差创建一个b变量,初始化为0(在这种情况下不存在对称性问题),每个神经元具有一个偏置参数。

5.然后我们创建一个子图来计算z = X·W + b。 这种向量化的实现将有效地计算输入的加权和加上层中每个神经元的偏置项,对于批处理中的所有实例,只需一次。

6.最后,如果激活参数设置为“relu”,则代码返回relu(z)(即,max(0,z)),否则它只返回z。

好的,现在你有一个很好的功能来创建一个神经元层。 让我们用它来创建深度神经网络! 第一个隐藏层将X作为输入。 第二个将第一个隐藏层的输出作为输入。 最后,输出层将第二个隐藏层的输出作为输入。

请注意,为了清晰起见,我们再次使用名称范围。 还要注意,在通过softmax激活函数之前,logits是神经网络的输出:出于优化原因,我们稍后将处理softmax计算。

正如你所期望的那样,TensorFlow具有许多方便的功能来创建标准的神经网络图层,所以通常不需要像我们刚才那样定义自己的神经元层()函数。 例如,TensorFlow的dense()函数创建一个完全连接的层,其中所有输入连接到该层中的所有神经元。 只需导入该函数并用以下代码替换dnn构造部分:

现在我们已经准备好了神经网络模型,我们需要定义我们将用来训练它的代价函数。我们将使用交叉熵,交叉熵会惩罚估计目标类别的概率较低的模型。 TensorFlow提供了几个函数来计算交叉熵。 我们将使用sparse_softmax_cross_entropy_with_logits()。 这将给我们一个包含每个实例的交叉熵的一维张量。然后,我们可以使用TensorFlow的reduce_mean()函数来计算所有实例的平均交叉熵。

我们有神经网络模型,我们有代价函数,现在我们需要定义一个GradientDescentOptimizer来调整模型参数以最小化代价函数:

构造阶段的最后一个重要步骤是指定如何评估模型。我们可以使用in_top_k()函数。 这将返回一个布尔值为1D的张量,所以我们需要将这些布尔值转换为浮点数,然后计算平均值。 这会给我们网络的整体准确性。

我们需要创建一个节点来初始化所有变量,并且我们还将创建一个Saver以将我们训练好的模型参数保存到磁盘:

3.2 构建阶段

这部分更短,更简单。 首先,我们加载MNIST。 我们可以使用ScikitLearn,但TensorFlow提供了自己的帮助程序,它可以提取数据,对数据进行缩放(0到1之间),对其进行混洗,并提供一个简单的函数来一次加载一个小批量。 所以让我们用它来执行:

此代码打开TensorFlow会话,并运行初始化所有变量的init节点。 然后它运行主要的训练循环:在每个时代,代码迭代对应于训练集大小的许多小批量。 每个小批量都通过next_batch()方法获取,然后代码简单地运行训练操作,为其提供当前的最小批量输入数据和目标。 接下来,在每个迭代结束时,代码将在最后一个小批量和完整训练集上评估模型,并打印出结果。 最后,模型参数保存到磁盘。

3.3 使用神经网络

现在神经网络已经过训练,您可以使用它来进行预测。 要做到这一点,你可以重复使用相同的构造阶段,但像这样改变执行阶段:

首先代码从磁盘加载模型参数。 然后它加载一些你想分类的新图像。然后代码评估logits节点。 如果你想知道所有估计的类概率,你需要将softmax()函数应用于logits,但是如果你只是想预测一个类,你可以简单地选择具有最高logit值的类(使用 argmax()函数执行这个技巧)。


四. 本期小结

至此,我们了解了神经网络的由来,并且训练了多层感知机以及DNN神经网络。

(如需更好的了解相关知识,欢迎加入智能算法社区,在“智能算法”公众号发送“社区”,即可加入算法微信群和QQ群)

本文代码回复关键字:tfdnn


推荐阅读
  • 独家解析:深度学习泛化理论的破解之道与应用前景
    本文深入探讨了深度学习泛化理论的关键问题,通过分析现有研究和实践经验,揭示了泛化性能背后的核心机制。文章详细解析了泛化能力的影响因素,并提出了改进模型泛化性能的有效策略。此外,还展望了这些理论在实际应用中的广阔前景,为未来的研究和开发提供了宝贵的参考。 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 能够感知你情绪状态的智能机器人即将问世 | 科技前沿观察
    本周科技前沿报道了多项重要进展,包括美国多所高校在机器人技术和自动驾驶领域的最新研究成果,以及硅谷大型企业在智能硬件和深度学习技术上的突破性进展。特别值得一提的是,一款能够感知用户情绪状态的智能机器人即将问世,为未来的人机交互带来了全新的可能性。 ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 在2019中国国际智能产业博览会上,百度董事长兼CEO李彦宏强调,人工智能应务实推进其在各行业的应用。随后,在“ABC SUMMIT 2019百度云智峰会”上,百度展示了通过“云+AI”推动AI工业化和产业智能化的最新成果。 ... [详细]
  • 在机器学习领域,深入探讨了概率论与数理统计的基础知识,特别是这些理论在数据挖掘中的应用。文章重点分析了偏差(Bias)与方差(Variance)之间的平衡问题,强调了方差反映了不同训练模型之间的差异,例如在K折交叉验证中,不同模型之间的性能差异显著。此外,还讨论了如何通过优化模型选择和参数调整来有效控制这一平衡,以提高模型的泛化能力。 ... [详细]
  • 提升 Kubernetes 集群管理效率的七大专业工具
    Kubernetes 在云原生环境中的应用日益广泛,然而集群管理的复杂性也随之增加。为了提高管理效率,本文推荐了七款专业工具,这些工具不仅能够简化日常操作,还能提升系统的稳定性和安全性。从自动化部署到监控和故障排查,这些工具覆盖了集群管理的各个方面,帮助管理员更好地应对挑战。 ... [详细]
  • 自然语言处理(NLP)——LDA模型:对电商购物评论进行情感分析
    目录一、2020数学建模美赛C题简介需求评价内容提供数据二、解题思路三、LDA简介四、代码实现1.数据预处理1.1剔除无用信息1.1.1剔除掉不需要的列1.1.2找出无效评论并剔除 ... [详细]
  • 目录预备知识导包构建数据集神经网络结构训练测试精度可视化计算模型精度损失可视化输出网络结构信息训练神经网络定义参数载入数据载入神经网络结构、损失及优化训练及测试损失、精度可视化qu ... [详细]
  • 高端存储技术演进与趋势
    本文探讨了高端存储技术的发展趋势,包括松耦合架构、虚拟化、高性能、高安全性和智能化等方面。同时,分析了全闪存阵列和中端存储集群对高端存储市场的冲击,以及高端存储在不同应用场景中的发展趋势。 ... [详细]
  • 专业人士如何做自媒体 ... [详细]
  • 非计算机专业的朋友如何拿下多个Offer
    大家好,我是归辰。秋招结束后,我已顺利入职,并应公子龙的邀请,分享一些秋招面试的心得体会,希望能帮助到学弟学妹们,让他们在未来的面试中更加顺利。 ... [详细]
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
author-avatar
forsoz_627
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有