听过人工智能,机器学习,神经网络,深度学习等很多名词,你可能看了很多解释也似懂非懂,之前我也是同样如此的,主要是觉得自己用不着,也不用接触这么高级的东西。最近在学习了一些数据分析和机器学习的基础知识后,感觉到还是挺有意思的,就是有一些名称概念太让人生畏了。
人工智能是一个很宽泛的概念,你目前听到的高级概念都是属于人工智能的一部分;机器学习是属于人工智能的一个分支,而机器学习又是一个很大的范畴,简单点说就是专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能。比如人可以通过经验推理预测,根据规则分类等。
之前用过的线性回归,逻辑回归都是属于机器学习中的一种,今天要说的神经网络学习(神经网络)也是机器学习的一种方法;当神经网络的层数变得越来越多,学习的效果变得也越来越好,这也就是深度学习(Deep Learning),本质上可以理解为深层的神经网络。
下面的内容主要来源于《数据科学入门》:
人工神经网络(artifificial neural network,或简称神经网络)是受大脑启发而开发出来的一 种预测模型。我们可以把大脑看作一团相互连接的神经元。每个神经元都以其他神经元的输出为输入,进行相应计算,如果结果超过某个阈值,则这个神经元将会进入激活状态, 否则它会继续保持非激活状态。相应地,人工神经网络则是由人工神经元组成,同样也对输入进行类似的计算。
神经元也叫神经细胞,是神经系统最基本的结构和功能单位。分为细胞体和突起两部分。神经网络也就是很多个神经元连接在一起。
抽象一下变成下图
感知器(perception),也可以称为感知机,可能是最简单的神经网络了,或者说是由具有 n 个二进制输入的单个神经元所组成的神经网络。感知器首先会对输入值加权求和,如果加权和大于等于 0,它就会被激活,模拟神经元对电信号进行反应的函数统称为激活函数:
第一个step_function(x)函数传入一个数据,如果大于等于0,返回结果1,否则返回0,也可以叫做激活函数。
第二个perceptron_output(weights, bias, x)感知机输出函数,函数里的第一行代码通过点乘的方法对对输入值加权求和。
实际上,感知器只是根据点 x 的超平面将问题空间分隔为两部分而已,也就是一个而分类器:
dot(weights,x) + bias == 0
通过正确选用权值,感知器能解决许多简单的问题(图 18-1)。
与门:两个输入均为1时输出1,其他输出0
或门:两个输入均为0时输出0,其他输出1
非门:输入1时输出0,输入0时输出1
异或门:两个输入信号不相同时,输出1,其他输出0
权重weights是控制输入信号的重要性的参数
偏置 bias是调整整个神经元被激活的容易程度的参数。如bias=-3,则输入信号的加权总和必须超过3,神经元才会被激活。
例如,我们可以创建一个与门(即 AND,也就是说,当两个输入都为 1 时,返回 1;只要输入有一个为 0 时,返回0,代码如下所示,weights称为权重,bias叫做偏置。
weights = [2, 2] bias = -3
如果两个输入都为 1,则计算结果为 2 + 2 - 3 = 1,所以输出为 1。但是,只要输入中有一 个为 0,则计算结果为 2 + 0 - 3 = -1,所以输出为 0。
同时,如果两个输入都为 0,则计算 结果为 -3,所以输出还是 0。同样,我们还可以建立一个或门(OR),代码如下所示:
weights = [2, 2] bias = -1
同样,我们还可以建立一个非门(即 NOT,它只有一个输入端,并且会把输入的 1 转换为0,反之亦然),代码如下所示:
weights = [-2] bias = 1
不过,有些问题是单个感知器所无法解决的,比如,无论你如何尝试,都无法通过一个感
知器来构建异或门(XOR),即两个输入不同时输出为 1,否则输出为 0。这种情况下,我们就需要使用更加复杂的神经网络了。
当然,在建立逻辑门的时候,根本无需惟妙惟肖地模仿神经元,看一眼下面的代码你就明白了:
and_gate = minor_gate = maxxor_gate = lambda x, y: 0 if x == y else 1
就像真实的神经元那样,当你将它们连接起来时,就会发生许多有趣的事情。
大脑的拓扑结构极为复杂,我们可以近似地把它看作一个理想化的前馈(feed-forward)神经网络,该网络由多层构成,每层由众多神经元组成,然后逐层相连。一般情况下,前馈神经网络会有一个输入层(接收输入信号,然后无需修改直接向前馈送),一个或者多个“隐藏层”(每层都是由神经元组成,这些神经元以前一层的输出作为其输入,进行某些计算,并将结果传递给下一层),以及一个输出层(这一层提供最终输出)。
正如感知器那样,每个(非输入)神经元的每个输入和偏移项都会有一个权重。为简单起见,我们将偏移项放到权重向量的末尾,并且所有神经元的偏移项的输入都是 1。
类似感知器那样,对于每个神经元而言,其输入与权重之积需要加总处理。不同之处在于,这里不是直接输出step_function 函数应用于输入与权重之积的结果,而是将其平滑处理之后,输出一个近似值。准确地说,这里使用的是 sigmoid 函数,也叫logistic 函数,见图。
为什么使用 sigmoid 函数,而不是更为简单的 step_function 函数呢?因为要训练神经网络,就得使用微积分,而要使用微积分,就得使用光滑函数。我们知道,阶梯函数无法确保处处连续,但是 sigmoid 函数却是它们一个非常好的平滑近似函数。
有了这个函数,我们就可以将神经元简单表示成一个权重列表,列表的长度等于神经元输 入数量加 1,因为还要加上偏移项的权重。这样,神经网络就可以用各个(非输入)层组 成的列表来表示,其中每一层就是该层内的神经元所组成的一个列表。
也就是说,神经网络可以用(权重)列表的(神经元)列表的(层)列表来表示。
有了这种表示方法,神经网络用起来就会非常简便:
如今,我们无需使用感知器就能建立异或门了,这样事情就变得简单多了。所以,我们只需要调整权重,就能使得 neuron_outputs 非常接近 1 或 0 了:
借助于隐藏层,我们就能把一个“与”神经元和一个“或”神经元的输出馈送至“第一个 输入不同于第二个输入”神经元了。这个网络所做的工作,就是判断“或运算的结果不同于与运算的结果”,这实际上就是在执行异或运算,见图 18-3。
通常情况下,我们是不会以手动方式建立神经网络的。部分原因在于,神经网络解决的是比较大型的问题,比如图象识别可能会用到数百或成千上万的神经元。还有一部分原因是,我们通常无法“通过推理得出”这些神经元的安排方式。
相反,我们会像往常一样使用数据用来训练神经网络。一个流行的训练算法是反向传播(backpropagation),它与梯度下降法比较类似。
假如我们有一个训练集,其中含有输入向量和相应的目标输出向量。例如,前面 xor_ network 例子中的输入向量为 [1, 0],对应的目标输出端向量为 [1]。同时,假定我们的网 络已经拥有一组权重,那么接下来,我们就需要使用以下算法来调整这些权重。
1. 在输入向量上运行 feed_forward,从而得到网络所有神经元的输出。
2. 这样,每个输出神经元都会得到一个误差,即目标值与输出值之差。
3. 计算作为神经元权重的函数的误差的梯度,然后根据误差降低最快的方向调整权重。
4. 将这些输出误差反向传播给隐藏层以便计算相应误差。
5. 计算这些误差的梯度,并利用同样的方式调整隐藏层的权重。
主要了解什么是神经网络,最简单的神经网络-感知器是如何工作的,什么是权重,偏置,激活函数,还有前反馈神经网络以及神经网络的反向传播,反向传播比较难理解,之后会结合案例专门写一篇理解。