版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第四章
深度学习学习目标
了解深度学习产生的原因。
了解深度学习的训练过程。
了解卷积神经网络LeNet-5的结构。
了解传统循环神经网络和LSTM神经网络的结构。
能够利用TensorFlow进行全连接神经网络、卷积神经网络、循环神经网络的案例编程。5.1深度学习简介5.2深度学习经典网络及深度学习开源框架5.3深度学习编程案例5.1深度学习简介5.1.1深度学习概念
深度学习是一种基于深度神经网络对数据进行表征学习的方法,是一种能够模拟人脑的神经结构的机器学习算法。深度学习是一种无监督学习算法,可以视为机器学习的一个分支。
深度学习通过组合低层特征形成更加抽象的高层表示属性类别或特征,以发现数据的分布式特征表示。深度学习的理论基础源于人工神经网络。深度学习具有广阔的应用前景,在计算机视觉、图像处理、自然语言处理等领域取得了显著成果,其效果优于传统机器学习。
深度学习本质上是构建含有多隐藏层的神经网络,通过输入大规模数据进行训练,得到大量更具代表性的特征信息,从而对样本进行分类和预测。训练样本的特征不再需要人工提取,而是通过网络自动获得。5.1.1深度学习概念
深度神经网络的特点有以下两点。(1)深度神经网络在结构上含有更多的隐藏层,更具有“深度”。深度神经网络包含的隐藏层的层数通常在5层以上。(2)通过逐层特征提取,将数据样本在原空间的特征变换到新的特征空间,这种表示方法使得深度神经网络更容易解决分类或预测问题。和人工设计的特征提取方法相比,利用深度神经网络学习到的数据特征更能代表数据的丰富内在信息。5.1.2深度学习产生的原因
为什么会产生深度学习?
常用的BP神经网络、Hopfield神经网络等浅层神经网络通常只有一层隐藏层。在训练样本和计算单元数量受限情况下,这类网络对复杂函数的表示能力有限,其处理复杂分类问题的泛化能力受到制约。那么人们设想能不能为浅层神经网络(比如BP神经网络)添加几层隐藏层让其变成深层神经网络,来增强网络的性能呢?答案是不能。因为深层神经网络存在一些利用传统神经网络训练方法无法有效解决的问题。1.局部最优解问题
在线性模型当中,从任意一个点出发进行搜索最优解,最终必然会处于全局最优解附近。而深层神经网络属于非线性模型,随着层数增多,优化算法(比如梯度下降算法)会越来越容易陷入局部最优解,导致模型仅仅得到了局部最优解却未达到全局最优解,而训练过程就停止了,使深层神经网络的性能还不如浅层神经网络的。5.1.2深度学习产生的原因2.梯度消失问题
梯度消失问题是指在深层神经网络的训练过程中,误差在从输出层向输入层反向传播的过程中,梯度渐渐变小甚至趋近于零,导致网络中的输入层和靠近输入层的参数无法得到有效更新,从而影响模型的训练效果。该问题实际上是激活函数选取不当引起的,如果深层神经网络使用S型函数作为激活函数,会使得误差从输出层到输入层传播过程中会衰减。假设信号的初始梯度1,在BP神经网络反向传播梯度时,每传递一层,梯度会衰减为原来的25%。如果网络层数较多(如多于4层),梯度值会呈指数级衰减,最终导致靠近输入层的神经元几乎接收不到有效的训练信号,从而无法正常更新参数。5.1.2深度学习产生的原因3.过拟合问题
过拟合是指训练时模型的误差很低,而预测时模型的误差很高。这是什么原因导致的呢?假设一个BP神经网络有5层,由于梯度消失问题,网络结构中靠近输入层神经元无法接收误差,难以得到有效训练,而较高层神经元仍可以进行训练。这些未充分训练的神经元会将原始输入数据(或错误处理的数据)传输给较高层神经元,导致较高层神经元对输入数据直接进行拟合,最终导致模型记住了训练数据的细节(包括噪声),未能学到真正的规律,即训练时误差很低,预测时误差很高。5.1.2深度学习产生的原因4.特征选取和标签问题
在图像处理中,一张图片对应的特征向量往往有几万个特征,如何从几万个特征中选取合适的特征用于训练模型是一个问题。如果基于BP神经网络来构建深度神经网络,由于BP神经网络的训练过程属于监督学习,需要事先明确每个训练数据的标签,但实际情况下训练数据可能没有标签或不方便打标签。
5.1.3深度学习的训练过程
深度学习算法打破了传统神经网络对层数的限制,可根据设计需要选择网络层数。深度学习训练方法不同于传统神经网络训练方法。传统训练方法是对所有层同时进行训练,时间复杂度较高。如果改为逐层训练,由于深度神经网络的神经元和参数太多,偏差会逐层累积,产生欠拟合现象,增加训练误差。
深度学习在训练过程中采用贪婪无监督逐层训练方法。首先,使用无监督学习算法对深度神经网络的底层进行训练,生成深度神经网络的初始参数值。然后,当前一层训练完后,后一层将前一层的输出作为输入并编码以用于训练,同样使用无监督学习算法对该层参数进行初始化。最后,当所有层参数完成训练后,利用监督学习算法对参数进行微调。这样能够解决传统神经网络训练算法在深层神经网络中的问题(比如局部最优解、梯度消失、过拟合等问题)。5.1.3深度学习的训练过程
深度学习的训练过程主要分为两步。1.自下向上的无监督学习(特征学习)
这一步和传统神经网络训练方法区别较大,进行的学习过程称为特征学习(FeatureLearning)。具体学习过程如下:先使用无标签数据(也可以使用有标签数据)训练第一层神经元,先学习第一层神经元的参数(该一层可以看作是一个三层神经网络中的隐藏层,该隐藏层使得3层神经网络的输出和输入差别最小),然后将该层的输出作为下一层神经元的输入,用于训练,逐层训练,最终得到各层神经元的参数。2.自上向下的监督学习(微调)
这一步是基于学习到的特征,通过有标签数据进行训练,误差自上向下传输,对网络进行微调。当所有层完成训练后,基于所得到的各层参数进一步微调整个网络的模型参数,整个过程属于监督学习。微调模型参数时使用wake-sleep算法,主要目的是学习原始数据特征并能正确恢复原始数据。神经网络的训练通常有两个阶段:从下向上认知原始数据的特征表达和从上向下以最大概率或最小误差生成原始数据。这两个阶段分别对应wake-sleep算法的wake阶段和sleep阶段。从仿生学角度来看,这种学习过程更类似于人类大脑的学习过程。5.1.3深度学习的训练过程wake阶段:认知过程,通过外界的特征和层间的上行权重(认知权重)产生每一层的抽象表示(节点状态),并且使用梯度下降法修改层间的下行权重(生成权重)。比如我们认识现实世界中某个事物,学习事物的特征,同时不断更新头脑中对事物的认知,从而使头脑中所想象(生成)的事物和现实的事物尽可能一致。sleep阶段:生成过程,通过顶层表示(醒时学得的概念)和层间的下行权重,生成底层的状态,同时修改层间的上行权重。比如我们在头脑中想象(生成)的事物如果和真实的事物存在差异,就不断地调整认知,使两者尽量一致,从而减少生成过程的误差。
传统神经网络训练的第一步大都是随机初始化参数,而深度学习训练的第一步是通过学习输入数据的结构初始化参数,这样参数的值更接近全局最优解,提升了深度学习的性能。5.2深度学习经典网络及深度学习开源框架5.2.1卷积神经网络
深度神经网络由多层神经网络组成,每一层神经元都要和上下两层的神经元两两互连形成全连接结构,这会使得参数(权值和偏置)数量急剧增加。如果想要训练这么多的参数,必须要有大量的样本。但这会导致计算量暴增,尤其是在图像处理方面。
比如,处理一张10像素×10像素的RGB三通道图像。假设隐藏层的节点数为1000个,则全连接网络的参数有10×10×3×1000=300000个,这还没有包括偏置项。而10像素×10像素的图片是非常小的,当图片更大时,从参数数量会急剧增加,普通的计算机难以完成对这么多参数的运算。因此,要使深度神经网络从理论走向实际运用,在连接方式上需要做出改变,参数必须要减少。在这种需求下,卷积神经网络诞生了。
卷积神经网络是一类包含卷积计算且具有深度结构的前馈神经网络,是深度学习中经典的网络。为了减少网络参数,卷积神经网络采用了局部连接和权值共享的设计思想。5.2.1卷积神经网络
处理一张4像素×4像素图片的过程。假设网络中有4个神经元,若采用全连接,则一个神经元需要建立16个连接,而每个连接的权值不同,所以权值参数为16×4=64个。如果采用局部连接,把像素点分组,每4个像素点分为一组连接一个神经元,则一个神经元只需要建立4个连接,权值不变,则权值参数为4×4=16个。局部连接来源于动物视觉皮层的结构,动物视觉皮层的神经元在感知外界景物的过程中只有一部分在起作用,但是它们能够感知外界的所有景物,而不会遗漏。
但是如果图片很大,像素点很多,即使采用局部连接,权值还是很多,这时候就可以使用权值共享假设一个神经元有4个权值,为了减少权值个数,其他神经元也使用这4个权值(共享的权值称为卷积核),则权值参数进一步减少为4个。和之前64个权值参数相比,局部连接和权值共享使权值参数大大减少。5.2.1卷积神经网络
在图片处理中,一般采用多个卷积核提取图片的不同特征,但使用的图片一般不会是原图,因为原图除了包含需要的有效特征外,还包含很多无用信息(如背景)。在进行图片处理时只需要获得图像的有效特征,而无用信息需要被过滤掉。对此,卷积神经网络采用池化对图像进行降维处理,即压缩图像。这进一步降低了计算复杂度,过滤了无用信息,保留了有效特征。比如,将包含一只猫的图片压缩为原来的一半,仍然可以从图中看出这是一只猫,这是由于图片虽然过滤了很多无关特征,但是猫的有效特征都被保留了。
至此,卷积神经网络的三大特征(局部连接、权值共享和池化)都已出现。5.2.1卷积神经网络
卷积神经网络一般包含输入层、卷积层(可为多层)、池化层(可为多层)、全连接层(可为多层)、输出层。其中,输入层的神经元数量取输入图像的像素数量(图像高度*图像宽度*通道数),卷积层卷积核的大小一般为3×3,池化层滑动窗口一般为2×2,一次降维相当于将图片的大小压缩为之前的一半。卷积层用于提取图像特征,池化层用于降维卷积结果。多层卷积层、池化层的目的是利用卷积层提取图像的有效特征,然后利用池化层对卷积结果进行降维,过滤无效特征,放大有效特征。不断重复这一过程,就能尽可能多地得到图片的有效特征,提升训练效果。
5.2.1卷积神经网络
卷积神经网络的代表——LeNet-5的网络结构。5.2.1卷积神经网络LeNet-5是杨立昆(YannLeCun)在1998年提出的、用于手写体字符识别的卷积神经网络,其输入为32像素×32像素的手写体字符图片。LeNet-5共有7层(不包含输入层),分别是卷积层C1、S2、C3、池化层S4、卷积层C5、全连接层F6、输出层。其中,C5采用全连接形式。每层都包含不同数量的可训练参数,每层都包含多个特征图(FeatureMap),每个特征图通过卷积滤波器提取输入的一种特征。(1)卷积层C1
卷积层的功能是提取特征。C1采用大小为5×5的卷积核提取特征。卷积核的卷积过程如下:5×5卷积核从输入图片左上角5×5的区域开始进行卷积计算[5×5卷积核与输入图片5×5的区域对应相乘,然后把相乘结果相加,再加上偏置(本例中偏置为0,把相加结果输入激活函数(如Sigmoid函数)进行计算,激活函数的输出结果为下一层的输入了。5.2.1卷积神经网络
一次卷积完毕后,卷积核滑动一个像素(为保证特征提取的局部连接和平滑,卷积核每次移动的步长应小于自身长度,即两次卷积的区域之间有重叠),再对图片下一个5×5的区域进行卷积计算,直到整个图片被扫描完毕,即一个卷积核提取特征完毕。
(2)池化层S2
池化层又叫下采样层,其作用是压缩数据,降低数据维度。池化有两种方式:最大值池化和平均值池化。5.2.1卷积神经网络LeNet-5的池化输入大小一般为2×2,各个输入之间不重叠,即4个输入数据池化后变成一个输出结果。池化方式选择平均值池化,将4个输入数据求和取平均值,再乘权值,然后加上偏置值。将池化结果输入激活函数,激活函数再输出结果给下一层。
(3)卷积层C3C3也是卷积层,但它的卷积比较复杂,为什么呢?因为C3有16个卷积核,会形成16个特征图,而S2的特征图只有6个。那么两层的特征图是如何对应的呢?C3层特征图与S2的特征图的对应关系如下。把C3层特征图编号为0,1,2,…,15,把S2层特征图编号为0,1,2,3,4,5。横向的数字表示C3的16个特征图,纵向的数字表示S2的6个特征图。5.2.1卷积神经网络C3层编号为0~5的6个特征图,每个特征图对S2的3个相邻的特征图进行卷积。C3层编号为6~11的6个特征图,每个特征图对S2层4个相邻的特征图进行卷积。C3层编号为12~14的3个特征图,每个特征图对S2层4个不相邻的特征图进行卷积。C3层编号为15的特征图每个特征图对S2层所有特征图进行卷积。
(4)池化层S4
这一层和S2一样,使用的池化输入大小为2×2,C3的特征图大小为10×10,则池化后得到大小为5×5的特征图,每个特征图又缩小了4倍。神经元数量为16×5×5=400。S4有16个特征图,每个特征图有两个参数,分别是权值和偏置,所以权值参数数量为2×16=32。连接数量为16×(2×2+1)×5×5=2000。这一层的池化结果将输入激活函数,激活函数再输出结果给下一层。
(5)卷积层C5C5有120个卷积核,卷积核大小为5×5,输入样本为S4的16个大小为5×5的特征图,卷积核的大小和特征图的大小正好匹配,则输出的特征图大小为(5-5+1)×(5-5+1)=1×1,即只有一个神经元。由于C5的每个特征图和S4的所有神经元连接,同时C5的每个特征图只有一个神经元,因此可以得出C5的每个神经元和S4的所有神经元连接,这种情况称为全连接。因此,C5的连接数量为120×(5×5×16+1)=48120,由于全连接,这一层的权值参数数量和连接数量一样,都是48120。5.2.1卷积神经网络
(6)全连接层F6F6为全连接层,其作用就是汇总卷积层和池化层提取的特征。F6有84个神经元(84个神经元是为了和输出层相对应),对应一个7×12的位图,-1表示白色,1表示黑色,这样每个符号的位图可以表示成编码的形式。每一个神经元都和C5的120个神经元相连接,因为是全连接,所以可以计算出连接数量为(120+1)×84=10164,而权值参数数量也是10164。F6计算输入向量和权重向量之间的点积,将点积结果加上偏置,然后将相加结果通过激活函数输出。
(7)输出层
输出层也是全连接层,共有10个节点,分别代表数字0~9,输出层采用的是RBF作为网络连接方式。假设x是F6的输出(7×12的位图的编码),y是RBF的输出,则RBF输出的计算公式是:
。其中,
表示F6的84个神经元的输出,j取值为0~83。
的值由i的位图编码确定,i的位图编码像素为7×12,这就解释了为什么F6有84个神经元,因为要比较所有像素点和i的位图编码像素点的差别,差别越接近于0,则网络输入越接近于i。该层权值参数数量和连接数量为84×10=840。5.2.2循环神经网络
为什么会出现循环神经网络呢?
这是因为无论是卷积神经网络还是全连接深度神经网络,其输出都只考虑前一时刻输入的影响而没有考虑其他时刻输入的影响。虽然对于处理和识别静态的图片有比较好的效果。但在处理一些与序列数据有关的问题(比如对视频内物体运动轨迹的预测、上下文理解、语音识别等)时,这些算法的表现就不尽如人意了。为了解决上述问题,循环神经网络应运而生。
循环神经网络是一类以序列数据为输入,按序列的演进方向进行递归且所有节点(循环单元)链式连接的递归神经网络。循环神经网络是根据“人的认知是基于过往的经验和记忆”这一观点提出的。它不仅考虑前一时刻的输入,而且拥有对前面其他时刻的输入的“记忆”。“循环”二字表现为网络当前输出与前面多个时刻的输入有关,会记忆前面的信息。网络中各个隐藏层之间的神经元不再仅仅和前后层神经元相连,还和其他各层的神经元相连,而且隐藏层的输入不仅包括输入层的输出,还包括上一时刻隐藏层的输出。5.2.2循环神经网络
循环神经网络结构分为3部分:输入层、隐藏层、输出层。其中隐藏层有一个箭头,表示网络的数据是循环更新的,从而实现记忆功能。5.2.2循环神经网络
展开的循环神经网络隐藏层。假设有3个时刻t-1、t、t+1。x表示输入数据,表示输入数据在t时刻的状态。因为每个循环单元当前时刻的状态由该当前时刻的输入和前一时刻的状态决定,所以有以下公式:
。其中,W表示前一时刻的输入状态权值,U表示当前时刻的输入数据权值,f为前一时刻反馈的激活函数(一般为tanh、ReLU、Sigmoid等),v为输出权值。在实际情况中,权值U、V、W不可能固定,而是需要训练和优化。循环神经网络优化权值的方式类似于BP神经网络的BP算法,只不过反向传播时还需要考虑之前的若干时刻的状态。5.2.2循环神经网络
改进型循环神经网络——LSTM神经网络
循环神经网络具备记忆功能,但是这种记忆是短期的,并不具有长期性。比如,当前时刻t=10,则t=1或t=2时的状态对的影响就会变得很小,几乎可以忽略不计,而t=8或t=9时的状态对的影响较大。这种现象类似于梯度消失问题,不同之处在于梯度消失发生在时间维度上,即在误差反向传播时,t时刻的梯度在时间轴上向前传播几个时刻之后就消失了,使训练效果变差。对于一些简单的场景,这种影响不明显,但是如果场景比较复杂,由于隐藏层太多,循环神经网络的性能就会下降得很快。
针对这种情况,人们提出了一种改进型循环神经网络LSTM神经网络。目前,LSTM神经网络主要被用于处理时间序列类的问题(比如自主语音识别)。5.2.2循环神经网络LSTM神经网络通过引入一种叫“门”(Gate)的结构来调整神经元当前状态。门能够判断前面时刻的神经元状态是否重要,如果重要则记住,否则就丢弃。这样就实现了对前面时刻的神经元状态的过滤。一种实现方法是在求的同时输出一个0~1的概率值,表示前面时刻的神经元状态有百分之多少需要被记忆。如果为0则表示都不记忆,如果为1表示全部记忆。那么前面梯度比较大的(比较重要的)记忆会被保留,梯度比较小(比较不重要的)的记忆会消失,从而解决梯度消失问题。5.2.3深度学习开源框架和平台1.TensorFlowTensorFlow是谷歌在2015年发布的深度学习开源框架,它利用数据流图进行数值计算。Tensor的意思是张量,Flow的意思是流。TensorFlow的计算过程就是使张量从图的一端流动到另一端的过程。2.CaffeCaffe(ConvolutionalArchitectureforFastFeatureEmbedding)是一个深度学习开源框架,由加利福尼亚大学伯克利分校的贾扬清博士创建。Caffe的内核是用C++编写的,但它提供Python和MATLAB相关的接口。3.KerasKeras是一个用Python编写的深度学习开源框架,它可以作为TensorFlow、MicrosoftCNTK和Theano的高阶API,用于深度学习模型的设计、调试、评估、应用和可视化。4.PyTorch2017年1月,Facebook发布了PyTorch深度学习框架。与TensorFlow相比,PyTorch更易于使用。即使没有扎实的数学或机器学习基础知识的用户,也可以理解PyTorch建立的模型的结构。5.2.3深度学习开源框架和平台5.PaddlePaddlePaddlePaddle(飞桨)是百度推出的深度学习平台。作为一个全面开源、技术领先、功能完备的深度学习平台,PaddlePaddle集合了深度学习核心框架、基础模型库、端到端开发套件、工具组件和服务平台等多种模块。5.3深度学习编程案例5.3.1深度学习环境搭建
在第4章搭建的环境基础上继续安装TensorFlow。TensorFlow有CPU版本和GPU版本,这里安装选择CPU版本,版本号为2.0.0。打开虚拟机,在命令行终端输入命令pip3install-i/simpletensorflow==2.0.0,安装TensorFlow。5.3.1深度学习环境搭建
测试TensorFlow是否安装成功,在命令行终端中执行命令python3。然后执行代码importtensorflow导入TensorFlow,如果没有出现任何报错信息,则安装成功。
最后,安装TensorFlow自带的数据集,因为后续的编程需要用到其中的Fashion-MNIST数据集。在命令行终端执行命令pip3installtensorflow-datasets。5.3.2全连接神经网络识别案例
使用TensorFlow建立神经网络实现图像识别的步骤如下。(1)加载数据集,并对数据进行归一化处理,然后把数据集分割成训练集和测试集。(2)构建模型,并选择激活函数。(3)编译模型,设置优化器,定义损失函数,指定评估指标。(4)训练模型,设置训练轮数。(5)并评估误差。(6)使用模型预测并展现结果。5.3.2全连接神经网络识别案例
使用Fashion-MNIST数据集,包含大小为28px×28px灰度图片,总计70000张。其中,设置训练集60000张图片,测试集10000张图片。所有数据可分为10个不同的类型,每一类型对应不同的标签。
Fashion-MNIST数据集类型标签标签描述0T恤(T-shirt/top)1裤子(Trouser)2套头衫(Pullover)3连衣裙(Dress)4外套(Coat)5凉鞋(Sandal)6衬衫(Shirt)7运动鞋(Sneaker)8包(Bag)9靴子(Ankleboot)5.3.2全连接神经网络识别案例
首先建立全连接神经网络,对Fashion-MNIST数据集的60000个训练样本进行训练,然后利用训练好的网络对Fashion-MNIST数据集的10000个测试样本进行预测。针对训练样本,一次训练32个,因此需要训练1875次,训练轮数设为1轮。针对测试样本,每次测试32个,需要测试313次。代码如下。5.3.2全连接神经网络识别案例importtensorflowastfimporttensorflow_datasetsastfdsimportmathimportnumpyasnpimportmatplotlib.pyplotaspltimporttqdmimporttqdm.auto
#数据标准化函数:将像素值从[0,255]归一化到[0,1]defnormalize(images,labels):
images=tf.cast(images,tf.float32)
#转换为浮点数
images/=255
#数据归一化
returnimages,labels#绘制图像和预测结果的函数defplot_image(i,predictions_array,true_labels,images):predictions_array,true_label,img=predictions_array[i],true_labels[i],images[i]plt.grid(False) #关闭网格plt.xticks([]) #关闭x轴刻度plt.yticks([]) #关闭y轴刻度plt.imshow(img[...,0],cmap=plt.cm.binary) #显示灰度图predicted_label=np.argmax(predictions_array) #获取预测标签ifpredicted_label==true_label:#预测正确显示为蓝色,错误显示为红色color='blue'else:color='red'plt.xlabel("{}{:2.0f}%({})".format(class_names[predicted_label],100*np.max(predictions_array),class_names[true_label]),color=color)5.3.2全连接神经网络识别案例#绘制预测概率条形图的函数defplot_value_array(i,predictions_array,true_label):predictions_array,true_label=predictions_array[i],true_label[i]plt.grid(False) #关闭网格plt.xticks([]) #关闭x轴刻度plt.yticks([]) #关闭y轴刻度thisplot=plt.bar(range(10),predictions_array,color="#777777")#绘制条形图plt.ylim([0,1]) #设置y轴范围predicted_label=np.argmax(predictions_array) #获取预测标签thisplot[predicted_label].set_color('red') #预测标签为红色thisplot[true_label].set_color('blue') #真实标签为蓝色#加载FashionMNIST数据集dataset,metadata=tfds.load('fashion_mnist',as_supervised=True,with_info=True)train_dataset,test_dataset=dataset['train'],dataset['test']num_train_examples=metadata.splits['train'].num_examples #训练集样本数num_test_examples=metadata.splits['test'].num_examples #测试集样本数print("Numberoftrainingexamples:{}".format(num_train_examples))print("Numberoftestexamples:{}".format(num_test_examples))#定义类别标签class_names=['T-shirt/top','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankleboot']#对训练集和测试集进行标准化train_dataset=train_dataset.map(normalize)test_dataset=test_dataset.map(normalize)5.3.2全连接神经网络识别案例#打印前10张图片myfiguretop=plt.figure(figsize=(10,10))i=0for(image,label)intrain_dataset.take(10):image=image.numpy().reshape((28,28)) #将图片形状设置为28x28plt.subplot(5,5,i+1) #子图布局plt.xticks([]) #关闭x轴刻度plt.yticks([]) #关闭y轴刻度plt.grid(False) #关闭网格plt.imshow(image,cmap=plt.cm.binary) #显示灰度图plt.xlabel(class_names[label]) #显示类别标签i+=1myfiguretop.subplots_adjust(hspace=0.41) #调整子图间距plt.show()#创建全连接神经网络模型model=tf.keras.Sequential([#输入层:将28x28的图片展平为784维向量tf.keras.layers.Flatten(input_shape=(28,28,1)),#隐藏层:128个神经元,激活函数为ReLUtf.keras.layers.Dense(128,activation=tf.nn.relu),#输出层:10个神经元,激活函数为Softmax(用于多分类)tf.keras.layers.Dense(10,activation=tf.nn.softmax)])#编译模型:设置优化器、损失函数和评估指标pile(optimizer='adam', #使用Adam优化器loss='sparse_categorical_crossentropy',#多分类损失函数metrics=['accuracy']) #评估指标为准确率5.3.2全连接神经网络识别案例#设置训练参数BATCH_SIZE=32#每次训练的批量大小train_dataset=train_dataset.repeat().shuffle(num_train_examples).batch(BATCH_SIZE)#打乱数据并分批次test_dataset=test_dataset.batch(BATCH_SIZE)#测试集分批次#训练模型print('trainstart')model.fit(train_dataset,epochs=1,#训练轮数steps_per_epoch=math.ceil(num_train_examples/BATCH_SIZE))#每轮训练步数print('trainok')#在测试集上评估模型test_loss,test_accuracy=model.evaluate(test_dataset,steps=math.ceil(num_test_examples/BATCH_SIZE))print('Accuracyontestdataset:',test_accuracy)#对测试集进行预测fortest_images,test_labelsintest_dataset.take(1):test_images=test_images.numpy()test_labels=test_labels.numpy()predictions=model.predict(test_images)#获取预测结果5.3.2全连接神经网络识别案例#绘制预测结果num_rows=5num_cols=3num_images=num_rows*num_colsmyfigure=plt.figure(figsize=(2*2*num_cols,2*num_rows))print('plotmapstart')foriinrange(num_images):plt.subplot(num_rows,2*num_cols,2*i+1)#显示图像plot_image(i,predictions,test_labels,test_images)plt.subplot(num_rows,2*num_cols,2*i+2) #显示预测概率plot_value_array(i,predictions,test_labels)myfigure.subplots_adjust(hspace=0.41) #调整子图间距plt.show()
运行时首先会下载Fashion-MNIST数据集,下载完毕执行程序代码,输出标准化后的10张原始图像。然后开始训练。5.3.2全连接神经网络识别案例
最终结果为,网络训练准确度为82.53%,测试准确度为84.89%。5.3.2全连接神经网络识别案例
输出前15个测试样本检查测试效果,被正确预测的测试样本用蓝色表示,被错误预测的测试样本用红色表示。可以看到除了第二排第一个测试样本被预测错误之外,其余测试样本都被正确预测了。5.3.3卷积神经网络识别案例
要实现卷积神经网络只需要在全连接神经网络的基础上增加两层卷积层和两层池化层即可。model=tf.keras.Sequential([
tf.keras.layers.Conv2D(32,(3,3),padding='same',activation=tf.nn.relu,input_shape=(28,28,1)),
tf.keras.layers.MaxPooling2D((2,2),strides=2),
tf.keras.layers.Conv2D(64,(3,3),padding='same',activation=tf.nn.relu),
tf.keras.layers.MaxPooling2D((2,2),strides=2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128,activation=tf.nn.relu),
tf.keras.layers.Dense(10,
activation=tf.nn.softmax)])5.3.3卷积神经网络识别案例
完整代码:#导入必要的库importtensorflowastfimporttensorflow_datasetsastfds
importmathimportnumpyasnpimportmatplotlib.pyplotasplt
#绘图库importtqdmimporttqdm.auto
#数据标准化函数:将图像像素值从0~255归一化到0~1范围defnormalize(images,labels):
images=tf.cast(images,tf.float32)
#转换为float32类型
images/=255
#归一化
returnimages,labels
#绘制单张图像及其预测结果的函数defplot_image(i,predictions_array,true_labels,images):
predictions_array,true_label,img=predictions_array[i],true_labels[i],images[i]
plt.grid(False)
#不显示网格
plt.xticks([])
#不显示x轴刻度
plt.yticks([])
#不显示y轴刻度
#显示灰度图像(FashionMNIST是单通道图像)
plt.imshow(img[...,0],cmap=plt.cm.binary)
#获取预测结果中概率最大的类别
predicted_label=np.argmax(predictions_array)
#根据预测是否正确设置标签颜色(正确为蓝色,错误为红色)
ifpredicted_label==true_label:
color='blue'
else:
color='red'
5.3.3卷积神经网络识别案例#设置图像标题,显示预测结果和真实标签plt.xlabel("{}{:2.0f}%({})".format(class_names[predicted_label],100*np.max(predictions_array),#预测置信度百分比class_names[true_label]),color=color)#绘制预测概率分布柱状图的函数defplot_value_array(i,predictions_array,true_label):predictions_array,true_label=predictions_array[i],true_label[i]plt.grid(False)#不显示网格plt.xticks([])#不显示x轴刻度plt.yticks([])#不显示y轴刻度
#绘制10个类别的概率分布柱状图thisplot=plt.bar(range(10),predictions_array,color="#777777")plt.ylim([0,1])#设置y轴范围
predicted_label=np.argmax(predictions_array)#获取预测类别
#设置柱状图颜色(预测类别为红色,真实类别为蓝色)thisplot[predicted_label].set_color('red')thisplot[true_label].set_color('blue')
#加载FashionMNIST数据集#as_supervised=True表示返回(image,label)形式的数据#with_info=True表示同时返回数据集元信息dataset,metadata=tfds.load('fashion_mnist',as_supervised=True,with_info=True)#分割训练集和测试集train_dataset,test_dataset=dataset['train'],dataset['test']5.3.3卷积神经网络识别案例#获取训练集和测试集的样本数量num_train_examples=metadata.splits['train'].num_examplesnum_test_examples=metadata.splits['test'].num_examplesprint("训练集样本数量:{}".format(num_train_examples))print("测试集样本数量:{}".format(num_test_examples))#定义FashionMNIST的10个类别名称class_names=['T-shirt/top','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankleboot']#对训练集和测试集进行标准化处理train_dataset=train_dataset.map(normalize)test_dataset=test_dataset.map(normalize)#可视化前10个训练样本myfiguretop=plt.figure(figsize=(10,10))#创建10x10英寸的画布i=0for(image,label)intrain_dataset.take(10):#取前10个样本image=image.numpy().reshape((28,28))#将图像重塑为28x28形状plt.subplot(5,5,i+1)#创建子图(5行5列)plt.xticks([])#不显示x轴刻度plt.yticks([])#不显示y轴刻度plt.grid(False)#不显示网格plt.imshow(image,cmap=plt.cm.binary)#显示灰度图像plt.xlabel(class_names[label])#显示类别标签i+=1myfiguretop.subplots_adjust(hspace=0.41)#调整子图间距plt.show()#显示图像5.3.3卷积神经网络识别案例#创建卷积神经网络(CNN)模型model=tf.keras.Sequential([#第一卷积层:32个3x3的卷积核,使用ReLU激活函数,保持输入尺寸不变(padding='same')tf.keras.layers.Conv2D(32,(3,3),padding='same',activation=tf.nn.relu,input_shape=(28,28,1)),
#最大池化层:2x2池化窗口,步长为2tf.keras.layers.MaxPooling2D((2,2),strides=2),
#第二卷积层:64个3x3的卷积核,使用ReLU激活函数tf.keras.layers.Conv2D(64,(3,3),padding='same',activation=tf.nn.relu),
#最大池化层:2x2池化窗口,步长为2tf.keras.layers.MaxPooling2D((2,2),strides=2),
#将多维数据展平为一维,供全连接层使用tf.keras.layers.Flatten(),
#全连接层:128个神经元,使用ReLU激活函数tf.keras.layers.Dense(128,activation=tf.nn.relu),
#输出层:10个神经元对应10个类别,使用Softmax激活函数输出概率分布tf.keras.layers.Dense(10,activation=tf.nn.softmax)])#编译模型pile(optimizer='adam',#使用Adam优化器loss='sparse_categorical_crossentropy',#稀疏分类交叉熵损失函数metrics=['accuracy']#评估指标为准确率)5.3.3卷积神经网络识别案例#设置训练参数BATCH_SIZE=32#每个批次的样本数量#准备训练数据:重复数据集、打乱顺序、分批train_dataset=train_dataset.repeat().shuffle(num_train_examples).batch(BATCH_SIZE)#准备测试数据:分批test_dataset=test_dataset.batch(BATCH_SIZE)#训练模型print('trainstart.')model.fit(train_dataset,epochs=1,#训练轮数steps_per_epoch=math.ceil(num_train_examples/BATCH_SIZE)#每轮的训练步数)print('trainok')#评估模型在测试集上的表现test_loss,test_accuracy=model.evaluate(test_dataset,steps=math.ceil(num_test_examples/BATCH_SIZE))print('Accuracyontestdataset:',test_accuracy)#进行预测fortest_images,test_labelsintest_dataset.take(1):#取一个批次(32个)测试样本test_images=test_images.numpy()#转换为numpy数组test_labels=test_labels.numpy()#转换为numpy数组predictions=model.predict(test_images)#进行预测#获取第一个样本的预测结果和真实标签np.argmax(predictions[0]),test_labels[0]5.3.3卷积神经网络识别案例#获取第一个样本的预测结果和真实标签np.argmax(predictions[0]),test_labels[0]#可视化预测结果num_rows=5#行数num_cols=3#列数num_images=num_rows*num_cols#总共显示的图像数量#创建画布myfigure=plt.figure(figsize=(2*2*num_cols,2*num_rows))print('开始绘制预测结果...')#绘制预测结果foriinrange(num_images):#左侧显示图像和预测标签plt.subplot(num_rows,2*num_cols,2*i+1)plot_image(i,predictions,test_labels,test_images)
#右侧显示预测概率分布plt.subplot(num_rows,2*num_cols,2*i+2)plot_value_array(i,predictions,test_labels)#调整子图间距myfigure.subplots_adjust(hspace=0.41)plt.show()#显示图像5.3.3卷积神经网络识别案例
最终结果为,网络训练准确度为85.43%,测试准确度为87.94%。5.3.3卷积神经网络识别案例
输出前15个测试样本检查测试效果。其中被正确预测的测试样本用蓝色表示,被错误预测的测试样本用红色表示。可以看到所有测试样本都被正确预测了。5.3.4循环神经网络识别案例
循环神经网络需要在全连接神经网络的基础上做以下两点改变。
(1)在全连接神经网络的基础上新增循环神经网络。下面用较为简单的循环神经网络SimpleRNN来实现,在网络结构中新增两层SimpleRNN。
(2)对输入数据进行重构。因为循环神经网络要求输入向量是3维的,而原始输入数据是4维的,因此需要重新构建输入数据,model=tf.keras.Sequential([
tf.keras.layers.SimpleRNN(
input_shape=(28,28),
units=128,unroll=True,return_sequences=True),
tf.keras.layers.SimpleRNN(
units=64,return_sequences=True),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128,activation=tf.nn.relu),
tf.keras.layers.Dense(10,
activation=tf.nn.softmax)])defnormalizereshape(images,labels):
images=tf.cast(images,tf.float32)
images=images/255
images=tf.reshape(images,(28,28))
returnimages,labels5.3.4循环神经网络识别案例
完整代码如下。importtensorflowastfimporttensorflow_datasetsastfdsimportmathimportnumpyasnpimportmatplotlib.pyplotaspltimporttqdmimporttqdm.auto#定义数据标准化和形状调整函数defnormalizereshape(images,labels):images=tf.cast(images,tf.float32)#转换数据类型为float32images=images/255#像素值归一化images=tf.reshape(images,(28,28))#调整图像形状为28x28returnimages,labels#返回处理后的图像和标签#定义单张图像可视化函数defplot_image(i,predictions_array,true_labels,images):predictions_array,true_label,img=predictions_array[i],true_labels[i],images[i]#获取当前索引的数据plt.grid(False)#关闭网格显示plt.xticks([])#隐藏x轴刻度plt.yticks([])#隐藏y轴刻度plt.imshow(img[...,0],cmap=plt.cm.binary)#显示单通道灰度图像predicted_label=np.argmax(predictions_array)#获取预测概率最大的类别
#根据预测是否正确设置标签颜色ifpredicted_label==true_label:color='blue'#正确预测显示蓝色else:color='red'#错误预测显示红色
5.3.4循环神经网络识别案例#设置图像标题:预测类别+置信度+真实类别plt.xlabel("{}{:2.0f}%({})".format(class_names[predicted_label],100*np.max(predictions_array),class_names[true_label]),color=color)#定义预测概率分布可视化函数defplot_value_array(i,predictions_array,true_label):predictions_array,true_label=predictions_array[i],true_label[i]#获取当前索引的数据plt.grid(False)#关闭网格显示plt.xticks([])#隐藏x轴刻度plt.yticks([])#隐藏y轴刻度
#绘制10个类别的概率分布柱状图thisplot=plt.bar(range(10),predictions_array,color="#777777")plt.ylim([0,1])#设置y轴范围为0-1predicted_label=np.argmax(predictions_array)#获取预测概率最大的类别
#设置柱状图颜色:预测类别红色,真实类别蓝色thisplot[predicted_label].set_color('red')thisplot[true_label].set_color('blue')#加载FashionMNIST数据集dataset,metadata=tfds.load('fashion_mnist',as_supervised=True,with_info=True)#分割数据集为训练集和测试集train_dataset,test_dataset=dataset['train'],dataset['test']#获取训练集和测试集的样本数量num_train_examples=metadata.splits['train'].num_examplesnum_test_examples=metadata.splits['test'].num_examples5.3.4循环神经网络识别案例#打印数据集信息print("训练集样本数量:{}".format(num_train_examples))print("测试集样本数量:{}".format(num_test_examples))#定义FashionMNIST的10个类别名称class_names=['T-shirt/top','Trouser','Pullover','Dress','Coat','Sandal','Shirt','Sneaker','Bag','Ankleboot']#对训练集和测试集应用标准化和形状调整处理train_datasetreshape=train_dataset.map(normalizereshape)test_datasetreshape=test_dataset.map(normalizereshape)#创建图像显示画布myfiguretop=plt.figure(figsize=(10,10))i=0#初始化计数器#可视化训练集前10个样本for(image,label)intrain_dataset.take(10):image=image.numpy().reshape((28,28))#转换并调整图像形状为28x28plt.subplot(5,5,i+1)#创建5x5的子图网格plt.xticks([])#隐藏x轴刻度plt.yticks([])#隐藏y轴刻度plt.grid(False)#关闭网格plt.imshow(image,cmap=plt.cm.binary)#显示灰度图像plt.xlabel(class_names[label])#显示类别标签i+=1#计数器递增#调整子图间距myfiguretop.subplots_adjust(hspace=0.41)plt.show()#显示图像5.3.4循环神经网络识别案例#创建循环神经网络模型model=tf.keras.Sequential([#第一SimpleRNN层:128个单元,输入形状(28,28),展开计算(unroll=True),返回完整序列tf.keras.layers.SimpleRNN(input_shape=(28,28),units=128,unroll=True,return_sequences=True),
#第二SimpleRNN层:64个单元,返回完整序列tf.keras.layers.SimpleRNN(units=64,return_sequences=True),
#展平层:将多维特征图转换为一维向量tf.keras.layers.Flatten(),
#全连接层:128个神经元,ReLU激活tf.keras.layers.Dense(128,activation=tf.nn.relu),
#输出层:10个神经元对应10个类别,Softmax激活输出概率tf.keras.layers.Dense(10,activation=tf.nn.softmax)])#编译模型#optimizer='adam':使用Adam优化器#loss='sparse_categorical_crossentropy':使用稀疏分类交叉熵损失函数#metrics=['accuracy']:评估指标为准确率pile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])#设置训练参数BATCH_SIZE=32#每个训练批次的样本数量#准备训练数据:重复数据集、打乱顺序、分批train_datasetreshape=train_datasetreshape.repeat().shuffle(num_train_examples).batch(BATCH_SIZE)5.3.4循环神经网络识别案例#准备测试数据:分批处理test_datasetreshape=test_datasetreshape.batch(BATCH_SIZE)test_dataset=test_dataset.batch(BATCH_SIZE)#原始测试数据也进行分批#开始模型训练print(''trainstart')model.fit(train_datasetreshape,epochs=1,#训练轮数steps_per_epoch=math.ceil(num_train_examples/BATCH_SIZE)#每轮的训练步数)print('trainok')#在测试集上评估模型性能test_loss,test_accuracy=model.evaluate(test_datasetreshape,steps=math.ceil(num_test_examples/BATCH_SIZE)#计算需要的评估步数)print('Accuracyontestdataset:',test_acc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 海事内部安全制度
- 海运公司内部管理制度
- 云南文化艺术职业学院《内科护理学(二)》2024-2025学年第二学期期末试卷
- 煤矿内部监管制度
- 煤矿通防科内部管理制度
- 烟台科技学院《电子商务物流管理》2024-2025学年第二学期期末试卷
- 甲方内部管理制度
- 监理内部质量考核制度
- 磷矿矿山内部管理制度
- 科室内部报账制度及流程
- 教科版三年级下册科学实验报告(20 篇)
- 【中小学】【语文】2026春季下开学第一课:骐骥驰聘势不可挡
- 【新教材】人美版(2024)小学4年级劳动下册项目一+任务二+蒜蓉西蓝花(教学课件)
- 2026年人教版新教材数学三年级下册教学计划(含进度表)
- 小学元宵节主题班会 课件(希沃版 )
- 2025年江西电力职业技术学院单招职业技能考试题库附答案解析
- 2025-2026学年北京市平谷区九年级(上)期末英语试卷
- pp板施工项方案
- 2026年江西交通职业技术学院单招职业技能测试题库及答案解析(名师系列)
- 部编人教版五年级下册小学道德与法治教案
- 新质生产力下制造业质量管理数字化转型白皮书-深圳市质量强市促进会
评论
0/150
提交评论