如果我问你下图中的花是什么花?你可能会毫不犹豫地说出:“这是玫瑰花”。这个问题对于任何一个正常的成年人来说是一个非常简单的问题,但是如果我们让计算机来回答这个问题,这就很有难度了。如何以程序的方式来描述玫瑰花的特征,并且这些特征需要和其他花的特征区分开来,并且需要达到较高的识别准确率,这对于传统的计算机程序来说非常难,但是以神经网络为基础的深度学习则可以很好地解决这个问题。在当前深度学习的应用如火如荼地开展之际,作为一名大数据工作者,很有必要对神经网络及深度学习有深入的了解,并尝试用这种新的方法去解决实际的问题。本文对深度学习的基础—神经网络模型做了框架性的介绍,以建立起对神经网络的初步认识。
1. 什么是神经网络?
首先来看一下百度百科中对神经网络的定义:人工神经网络(Artificial Neural Network,缩写ANN),简称神经网络(Neural Network,缩写NN),是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。神经网络是一种有监督的机器学习算法,广泛地应用于分类预测、图像识别等领域。
从上面的定义我们可能很难建立起一个直观的印象,还是回到本文前面的例子,先看一下我们人类是如何识别花的。当你眼中看到一朵花时,并不是眼睛告诉你这是一朵玫瑰花,而是大脑经过处理判断后告诉你的。从眼睛看到图片到认出玫瑰花,看起来是一瞬间的事情,但是却经过了一系列复杂的过程。首先眼睛作为一个感觉器官,接收外面进来的光信号,并将光信号转换成生物信号,传输给大脑神经,大脑中的神经元和之前印象中的玫瑰花特征进行比较,发现和以前经验留下的玫瑰花特征吻合度非常高,最后大脑得到一个结论:“这是一朵玫瑰花”。
但是如果拿这个问题去问一个正在上幼儿园的小朋友,那他极有可能回答不上来。因为他的大脑中还一片空白,还没有对玫瑰花这个事物建立起认知。当大人拿着图片或者指着实物告诉小朋友这是玫瑰花,经过多次的学习之后,才能在小朋友的头脑中建立起对玫瑰花的印象,当学习之后再去问小朋友的时候他才能正确地认出玫瑰花。而神经网络正是模拟了人类的这一学习过程,神经网络模型中也有输入和输出、中间有多层的神经元,需要经过大量的有监督的训练之后才能发挥作用。没有训练前的神经网络就像幼儿园的小朋友,头脑中是一片空白的,需要拿数据来训练神经网络,训练的过程中会在神经网络中记录下模型参数,相当于玫瑰花的特征,训练结束之后神经网络就可以正确地识别玫瑰花了。
2. 神经网络的三个主要元素
神经网络模型中主要包括三个元素,分别为神经网络的结构、神经网络的激活函数和学习算法。
神经网络的结构
神经网络的结构由三部分组成,分别为输入层、隐藏层和输出层。输入层用于接收外部的数据输入,隐藏层是中间的处理层,可以有多层 ,输出层输出最后的处理结果。每一层中有相应数量的神经元组成,相邻的两层神经元之间相互连接,但是同一层中的神经元之间不产生连接。上图中的神经网络包含四层,输入层包括6个神经元,中间两层为隐藏层,分别含有4个和3个神经元,输出层只包括1个神经元。相邻两层的神经元之间两两相互连接,这种连接方式的神经网络为全连接的神经网络。
神经网络的激活函数
在了解了神经网络的结构之后,那么数据是如何在这个神经网络中传递的?以上图中的第二层的第一个神经元为例,他的输出结果为:
其中w表示上一层神经元的权重,b表示偏差项,σ表示神经元的激活函数。首先对上一层神经元的输出按照权重相加(线性组合),然后再根据激活函数将权重相加后的结果转换成一个输出值。神经网络中最为常用的激活函数为sigmoid激活函数(有很多其他激活函数,这里以sigmoid函数为例说明),可以将sigmoid函数理解为压缩函数[或者理解为是将连续值转换为阶跃值],将定义域上的数值转换成0-1之间的某一个数值,当x∗w+b的结果为无穷大的时候,则sigmoid函数输出结果近似等于1,当x∗w+b的结果为无穷小的时候,则sigmoid函数输出结果近似等于0。神经网络中其他神经元的结果都是按照这种方式进行计算,并将神经元的输出结果传递到下一层的神经元,直到输出最终结果为止。
上面的描述非常的数学化,我们怎么从业务上来理解上面的输入x,权重w,偏差项b,以及激活函数σ呢?我们可以将输入神经元(x1,…,x6)理解为事物的6项特征,而将与他们连接的下一层神经元理解为一种更高层次的抽象后的特征(例如输入特征为“是否有眼睫毛”、“是否有眼皮”、“是否有眼球”,下一层神经元的输出特征为“是否为一只眼睛”),权重w表示各项输入特征的重要性,如果某个输入特征的权重很高,就表示这个输入特征在判断更高层次抽象特征中所起的作用更大。偏差项则表示了判断是否为更高层次抽象特征的阈值,只有当输入特征的加权之和超过某个阈值时,我们才将他判断为具有某个更高层次的特征,否则我们认为不具有某个更高层次的特征[是否到了阶跃的阈值]。而激活函数的作用就相当于转化成判断是否具有某个更高层次特征的概率,当激活函数输出结果为1的时候,我们认为具有某个更高层次特征的概率很高,如果激活函数的输出结果为0,则我们认为基本不具有某个更高层次的特征。
以下面判断图片中是否为人脸的神经网络为例,输入为图片的像素数据,隐藏层的第一个神经元用来判断“左上角是否有眼睛”,第二神经元用来判断“右上角是否有眼睛”,第三个神经元用来判断“中间是否有鼻子”,第四个判断“底部是否有一张嘴”,最后一个判断“顶部是否有头发”。这五个特征又作为最终输出的的输入,对这五个特征进行加权求和,当图片中具有上述五个特征的大部分特征时,我们判断为图片中有一张人脸,如果五个特征中只有少量特征为真,则判断为图片没有出现人脸。
学习算法
神经网络中的权重w,偏差项b起着重要的作用,这些参数相当于我们大脑中记录下来的玫瑰花的特征,当新的图片进来的时候,需要靠这些特征来比对和判断。那我们怎么通过数据的训练来学习到这些特征(经验)呢?神经网络中用到了梯度下降算法来学习参数,它的基本思想是通过某种策略来不断逼近最佳的参数估计值。
3. 神经网络的训练过程
假如我们构建了一个神经网络,用来判断图片中的花是否为玫瑰花,假设有1万个训练样本数据,最理想的情况当然是这个神经网络能够完全正确地识别这1万个样本,最差的情况是1万个样本全部判断错误,实际情况大部分是介于这两者之间。那么我们如何来衡量这个神经网络的识别能力的好坏呢,一种方法是构建一个损失函数,最为常用的损失函数为均方误差函数:
上述公式中的y(x)表示训练数据的真实结果,1表示为玫瑰花,0表示为非玫瑰花,a表示神经网络根据输入数据计算后得到的结果,它是介于0到1之间的一个值。如果所有样本都识别正确,则误差为零。我们的目标是希望这个误差越小越好,即我们希望通过训练得到一组参数的估计值,这组估计值能够使得误差达到最小值。
我们仔细来看这个损失函数的话,它的本质上是关于参数w、b一个函数,这样神经网络的训练问题就直接转化成为了一个数学问题,即求一个函数的极小值问题。从数学角度来看,这个问题如同求y=x**2这个函数的极小值问题没有本质的区别,无非就是神经网络中的参数很多,而y=x**2中只有一个参数而已。神经网络用来训练参数的方法为梯度下降算法,其基本步骤如下:
a. 首先将所有的参数(w和b)设置成一个随机值(可以理解为随机取了多维空间中的一个点),作为起始点;
b. 在随机设置的这个点上,求各个变量的偏导数,形成梯度
c. 在起始点的基础上,让参数(w和b)的取值向梯度相反的方向前进
d. 不断重复上述过程,让参数的取值不断逼近最小值点,直到收敛为止
上面的描述仍显得过于抽象,下面以最简单的一维变量的函数y=x**2为例来说明梯度下降算法的过程。我们的目的是求y=x**2这个函数的最小值,当然在这里我们直接可以用肉眼看到在x=0处为最小值,假设我们无法用肉眼判断出来,如何用梯度下降的思想来求的最小值点呢?
1) 我们首先为x变量设置一个随机值,假如x=3
2) 求y=x**2函数在x=3这个点的导数,在点x=3处的导数为6,这形成了一个梯度。导数为6的意思是,当x增加1个单位的时候y将增加6。我们的目的是让y值越来越小,因此我们要让x向梯度相反的方向运动,假设学习步长为1/6,那么x前进的距离为1/6*6=1,但是我们需要向梯度相反方向运动,所以x的取值需要更新为3-1=2,即让变量x在3这个点向负方向前进1个单位,x变量的取值更新为了2。
3)在x=2这个点求导数,这里导数为4,同时在让x向梯度相反的方向前进,这样x就更新为2-1/6*4,我们可以发现这个新的x取值越来越逼近我们的目标值0。
4)不断重复这个过程,我们可以发现最终的x取值将会逼近到0附近。那么有没有可能x的取值越过0这个点,不断向负无穷的方法逼近呢,这是不可能的。因为在x=0这个点附近,他的导数接近于0,因此越逼近0这个点的时候,后面x变化的距离也越来越接近0。
本文对神经网络的构成及训练的思想做了概要性的描述,但是并未涉及到具体的细节,后续将对神经网络的一些细节具体展开描述。
本文荟萃自公众号: 陈永刚 超级进化,只做学术交流学习使用,不做为临床指导,本文观点不代表数字重症立场。