Tensorflow系列专题(四):神经网络篇之前馈神经网络综述

简介:

目录:

 ●  神经网络前言
 ●  神经网络
 ●  感知机模型
 ●  多层神经网络
 ●  激活函数
 ●  Logistic函数
 ●  Tanh函数
 ●  ReLu函数
 ●  损失函数和输出单元
 ●  损失函数的选择
 ●  均方误差损失函数
 ●  交叉熵损失函数
 ●  输出单元的选择
 ●  线性单元
 ●  Sigmoid单元
 ●  Softmax单元
 ●  参考文献

一.神经网络前言

从本章起,我们将正式开始介绍神经网络模型,以及学习如何使用TensorFlow实现深度学习算法。人工神经网络(简称神经网络)在一定程度上受到了生物学的启发,期望通过一定的拓扑结构来模拟生物的神经系统,是一种主要的连接主义模型(人工智能三大主义:符号主义、连接主义和行为主义)。本章我们将从最简单的神经网络模型感知器模型开始介绍,首先了解一下感知器模型(单层神经网络)能够解决什么样的问题,以及它所存在的局限性。为了克服单层神经网络的局限性,我们必须拓展到多层神经网络,围绕多层神经网络我们会进一步介绍激活函数以及反向传播算法等。本章的内容是深度学习的基础,对于理解后续章节的内容非常重要。

深度学习的概念是从人工神经网络的研究中发展而来的,早期的感知器模型只能解决简单的线性分类问题,后来发现通过增加网络的层数可以解决类似于“异或问题”的线性不可分问题,这种多层的神经网络又被称为多层感知器。对于多层感知器,我们使用BP算法进行模型的训练[1],但是我们发现BP算法有着收敛速度慢,以及容易陷入局部最优等缺点,导致BP算法无法很好的训练多层感知器。另外,当时使用的激活函数也存在着梯度消失的问题,这使得人工神经网络的发展几乎陷入了停滞状态。为了让多层神经网络能够训练,学者们探索了很多的改进方案,直到2006年Hinton等人基于深度置信网络(DBN)提出了非监督贪心逐层训练算法,才让这一问题的解决有了希望,而深度学习的浪潮也由此掀起。

本章内容主要包括五个部分,第一部分我们介绍一下神经网络的基本结构,从基本的感知器模型到多层的神经网络结构;第二部分介绍神经网络中常用的激活函数;第三部分介绍损失函数和输出单元的选择;第四部分介绍神经网络模型中的一个重要的基础知识——反向传播算法;最后我们使用TensorFlow搭建一个简单的多层神经网络,实现mnist手写数字的识别。

二、神经网络

1. 感知机模型

感知器(Perceptron)是一种最简单的人工神经网络,也可以称之为单层神经网络,如图1所示。感知器是由Frank Rosenblatt在1957年提出来的,它的结构很简单,输入是一个实数值的向量,输出只有两个值:1或-1,是一种两类线性分类模型。

d724ce95b9f554c45016fb8062a5d5d8f431f573

图1 感知器模型

如图3-1所示,感知器对于输入的向量先进行了一个加权求和的操作,得到一个中间值,假设该值为,则有:

2a3fe4f795bab5f813fa00ed4737581ccbfe6abc

接着再经过一个激活函数得到最终的输出,该激活函数是一个符号函数:

87d158d303074bcdc878b424cac110055f948988

公式1中的可以看做是一个阈值(我们通常称之为偏置项),当输入向量的加权和大于该阈值时(两者之和)感知器的输出为1,否则输出为-1。

2. 多层神经网络

感知器只能解决线性可分的问题,以逻辑运算为例:

bf6c09bba3338d2d65b3fb26ca33525e87e956c4

感知器可以解决逻辑“与”和逻辑“或”的问题,但是无法解决“异或”问题,因为“异或”运算的结果无法使用一条直线来划分。为了解决线性不可分的问题,我们需要引入多层神经网络,理论上,多层神经网络可以拟合任意的函数(本书配套的GitHub项目中有相关资料供参考)。

与单层神经网络相比,多层神经网络除了有输入层和输出层以外,还至少需要有一个隐藏层,如图3所示是含有一个隐藏层的两层神经网络:

746a55812ae52fb9a9f07889b36b30dcf1ef4e93

为了更直观的比较一下单层神经网络和多层神经网络的差别,我们利用TensorFlow PlayGround来演示两个例子。TensorFlowPlayGround是Google推出的一个深度学习的可视化的演示平台:http://playground.tensorflow.org/。

我们首先看一个线性可分的例子,如图4所示。图的右侧是数据可视化后的效果,数据是能够用一条直线划分的。从图中可以看到,我们使用了一个单层神经网络,输入层有两个神经元,输出层只有一个神经元,并且使用了线性函数作为激活函数。

51ec32f1e075bfc30bb82c05578d0cc2d047afe4

我们点击开始训练的按钮,最终的分类结果如图5所示:

3a3010fae84b5f8994ecd48dae05f85adb238780

在上面的例子里我们使用单层神经网络解决了一个线性可分的二分类问题,接下来我们再看一个线性不可分的例子,如图6所示:

2d160821cfe962b734f9c5990dd27c968314142e

在这个例子里,我们使用了一组线性不可分的数据。为了对这组数据进行分类,我们使用了一个含有一层隐藏层的神经网络,隐藏层有四个神经元,并且使用了一个非线性的激活函数ReLU。要想对线性不可分的数据进行分类,我们必须引入非线性的因素,即非线性的激活函数,在下一小节里,我们会再介绍一些常用的激活函数。

最终的分类结果如图7所示。

753dffae445001974cb2c1241057f770f327070a

感兴趣的读者可以尝试使用线性的激活函数,看会是什么样的效果,还可以尝试其它的数据,试着增加网络的层数和神经元的个数,看看分别对模型的效果会产生什么样的影响。

三.激活函数

为了解决非线性的分类或回归问题,我们的激活函数必须是非线性的函数,另外我们使用基于梯度的方式来训练模型,因此激活函数也必须是连续可导的。

1. Logistic函数

Logistic函数(又称为sigmoid函数)的数学表达式和函数图像如图8所示:

78cfb7264cb8f25e406e6f1f46f903e7e11a7688

Logistic函数在定义域上单调递增,值域为,越靠近两端,函数值的变化越平缓。因为Logistic函数简单易用,以前的神经网络经常使用它作为激活函数,但是由于Logistic函数存在一些缺点,使得现在的神经网络已经很少使用它作为激活函数了。它的缺点之一是容易饱和,从函数图像可以看到,Logistic函数只在坐标原点附近有很明显的梯度变化,其两端的函数变化非常平缓,这会导致我们在使用反向传播算法更新参数的时候出现梯度消失的问题,并且随着网络层数的增加问题会越严重。

2. Tanh函数

Tanh函数(双曲正切激活函数)的数学表达式和函数图像如图9所示:

7f113896649a81005cda82193277f3cff18bb999

Tanh函数很像是Logistic函数的放大版,其值域为。在实际的使用中,Tanh函数要优于Logistic函数,但是Tanh函数也同样面临着在其大部分定义域内都饱和的问题。

3. ReLu函数

ReLU函数(又称修正线性单元或整流线性单元)是目前最受欢迎,也是使用最多的激活函数,其数学表达式和函数图像如图10所示:

d88b6c9b39fd40455ce8160bce416c32fb0afb8d

ReLU激活函数的收敛速度相较于Logistic函数和Tanh函数要快很多,ReLU函数在轴左侧的值恒为零,这使得网络具有一定的稀疏性,从而减小参数之间的依存关系,缓解过拟合的问题,并且ReLU函数在轴右侧的部分导数是一个常数值1,因此其不存在梯度消失的问题。但是ReLU函数也有一些缺点,例如ReLU的强制稀疏处理虽然可以缓解过拟合问题,但是也可能产生特征屏蔽过多,导致模型无法学习到有效特征的问题。

除了上面介绍的三种激活函数以外,还有很多其它的激活函数,包括一些对ReLU激活函数的改进版本等,但在实际的使用中,目前依然是ReLU激活函数的效果更好。现阶段激活函数也是一个很活跃的研究方向,感兴趣的读者可以去查询更多的资料,包括本书GitHub项目中给出的一些参考资料等。

四.损失函数和输出单元

损失函数(LossFunction)又称为代价函数(Cost Function),它是神经网络设计中的一个重要部分。损失函数用来表征模型的预测值与真实类标之间的误差,深度学习模型的训练就是使用基于梯度的方法最小化损失函数的过程。损失函数的选择与输出单元的选择也有着密切的关系。

1. 损失函数的选择

1.1 均方误差损失函数

均方误差(MeanSquared Error,MSE)是一个较为常用的损失函数,我们用预测值和实际值之间的距离(即误差)来衡量模型的好坏,为了保证一致性,我们通常使用距离的平方。在深度学习算法中,我们使用基于梯度的方式来训练参数,每次将一个批次的数据输入到模型中,并得到这批数据的预测结果,再利用这批预测结果和实际值之间的距离更新网络的参数。均方误差损失函数将这一批数据的误差的期望作为最终的误差值,均方误差的公式如下:

034e21b141bcd8e7d623ffdb7df0f944f64ad0f9

上式中为样本数据的实际值,为模型的预测值。为了简化计算,我们一般会在均方误差的基础上乘以,作为最终的损失函数:

c8cfc3bf79d80304e3f3c70bb29bba3fc1d7de7c

1.2交叉熵损失函数

交叉熵(Cross Entropy)损失函数使用训练数据的真实类标与模型预测值之间的交叉熵作为损失函数,相较于均方误差损失函数其更受欢迎。假设我们使用均方误差这类二次函数作为代价函数,更新神经网络参数的时候,误差项中会包含激活函数的偏导。在前面介绍激活函数的时候我们有介绍,Logistic等激活函数很容易饱和,这会使得参数的更新缓慢,甚至无法更新。交叉熵损失函数求导不会引入激活函数的导数,因此可以很好地避免这一问题,交叉熵的定义如下:

fce31852bfff89ab20e262ea2804440dab3b40e7

上式中为样本数据的真实分布,为模型预测结果的分布。以二分类问题为例,交叉熵损失函数的形式如下:

094f38781745f43bfc78aaa8124fcc9747cd4dd1

上式中为真实值,为预测值。对于多分类问题,我们对每一个类别的预测结果计算交叉熵后求和即可。

2. 输出单元的选择

2.1 线性单元

线性输出单元常用于回归问题,当输出层采用线性单元时,收到上一层的输出后,输出层输出一个向量。线性单元的一个优势是其不存在饱和的问题,因此很适合采用基于梯度的优化算法。

2.2 Sigmoid单元

Sigmoid输出单元常用于二分类问题,Sigmoid单元是在线性单元的基础上,增加了一个阈值来限制其有效概率,使其被约束在区间之中,线性输出单元的定义为:

eab8e31695a2269af92e7bb559991a1157017379

上式中是Sigmoid函数的符号表示,其数学表达式在3.2.1节中有介绍。

2.3 Softmax单元

Softmax输出单元适用于多分类问题,可以将其看作是Sigmoid函数的扩展。对于Sigmoid输出单元的输出,我们可以认为其值为模型预测样本为某一类的概率,而Softmax则需要输出多个值,输出值的个数对应分类问题的类别数。Softmax函数的形式如下:

51fab47c34ec11aa2ad98bbe7ce9b2819856e891

我们以一个简单的图示来解释Softmax函数的作用,如图3-11所示。原始输出层的输出为,,,增加了Softmax层后,最终的输出为:

a2c5d4134716acc5d2e1aa6f73c89035952e848a

上式中、和的值可以看做是分类器预测的结果,值的大小代表分类器认为该样本属于该类别的概率,

3a845870f954fff3520ba711b5135c202caaddea

需要注意的是,Softmax层的输入和输出的维度是一样的,如果不一致,可以通过在Softmax层的前面添加一层全连接层来解决问题。

接下来将介绍第四部分:神经网络模型中的一个重要的基础知识——反向传播算法;与第五部分:使用TensorFlow搭建一个简单的多层神经网络,实现mnist手写数字的识别。


原文发布时间为:2018-11-2

本文作者:磐石001

本文来自云栖社区合作伙伴“磐创AI”,了解相关信息可以关注“磐创AI”。

相关文章
|
3月前
|
机器学习/深度学习 算法 TensorFlow
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
动物识别系统。本项目以Python作为主要编程语言,并基于TensorFlow搭建ResNet50卷积神经网络算法模型,通过收集4种常见的动物图像数据集(猫、狗、鸡、马)然后进行模型训练,得到一个识别精度较高的模型文件,然后保存为本地格式的H5格式文件。再基于Django开发Web网页端操作界面,实现用户上传一张动物图片,识别其名称。
100 1
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
|
15天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
58 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
19天前
|
机器学习/深度学习 TensorFlow 算法框架/工具
利用Python和TensorFlow构建简单神经网络进行图像分类
利用Python和TensorFlow构建简单神经网络进行图像分类
44 3
|
1月前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
74 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
3月前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
110 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
2月前
|
机器学习/深度学习 SQL 数据采集
基于tensorflow、CNN网络识别花卉的种类(图像识别)
基于tensorflow、CNN网络识别花卉的种类(图像识别)
33 1
|
2月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
63 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
3月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
109 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
2月前
|
机器学习/深度学习 存储 自然语言处理
深度学习入门:循环神经网络------RNN概述,词嵌入层,循环网络层及案例实践!(万字详解!)
深度学习入门:循环神经网络------RNN概述,词嵌入层,循环网络层及案例实践!(万字详解!)
|
4月前
|
测试技术 数据库
探索JSF单元测试秘籍!如何让您的应用更稳固、更高效?揭秘成功背后的测试之道!
【8月更文挑战第31天】在 JavaServer Faces(JSF)应用开发中,确保代码质量和可维护性至关重要。本文详细介绍了如何通过单元测试实现这一目标。首先,阐述了单元测试的重要性及其对应用稳定性的影响;其次,提出了提高 JSF 应用可测试性的设计建议,如避免直接访问外部资源和使用依赖注入;最后,通过一个具体的 `UserBean` 示例,展示了如何利用 JUnit 和 Mockito 框架编写有效的单元测试。通过这些方法,不仅能够确保代码质量,还能提高开发效率和降低维护成本。
54 0