咱们在设计机器学习系统时,特别但愿可以创建相似人脑的一种机制。神经网络就是其中一种。可是考虑到实际状况,通常的神经网络(BP网络)不须要设计的那么复杂,不须要包含反馈和递归。
人工智能的一大重要应用,是分类问题。本文经过分类的例子,来介绍神经网络。node
一个最简单的分类,是在平面上画一条直线,左边为类0,右边为类1,直线表示为\(z=ax+by+c\)
这是一个分类器,输入(x,y),那么,要求的参数有三个:a,b,c。另外注意c的做用,若是没有c,这条直线必定会过原点。
所以,咱们能够设计一个简单的神经网络,包含两层,输入层有三个节点,表明x,y,1,三条线分别表明a,b,cg(z)对传入的值x进行判别,并输出结果。
\[z=θ_0+θ_1X_1+θ_2X_2\]
可是,因为z的值可能为[\(-\infty,+\infty\)],为了方便处理,须要将其压缩到一个合理的范围,还需sigmoid函数:
\[a(z)=\frac{1}{1-e^{-z}}\]
这样的激励函数,可以将刚才的区间,压缩到\([0,1]\)。
至于如何训练,会在以后的章节中讲解。算法
刚才展现了最简单的二分类,若是有四个分类,那一条线就没法知足要求了。想象两条直线,就会将平面划分为四个区域,一个三角区域至关于两个子平面求交集。
所以直觉告诉咱们,若是有多个神经元,那么这样的问题能表现为问题的“逻辑与”操做。将第一节中介绍的神经网络的输出,再作一个判断层,即多层网络。
可是,如何实现逻辑与呢?用下面的图一目了然:
仔细看下,这至关于建立一条线,除非\(x_1\)和\(x_2\)都等于1,不然\(h_\theta(x)<0\)。
进一步地,若是咱们可以对区域求并集,那么总能够对不一样的子区域求并。而实现并操做和与操做是相似的:
此处就能看到sigmoid函数的做用了,若是没有它对数值的放缩,并和与的操做就没法实现了。
输出还能做为下一级的输入,从而增长了一个隐层,产生了单隐层神经网络,再复杂一些,若是网络层数特别多,则叫作深度学习网络,简称深度学习。
以前针对一个线性不可分的区域,须要将其变换到更高维度的空间去处理。但若是用神经网络,你总能够经过n条直线,将整个区间围起来。只要直线数量够多,总能绘制出任意复杂的区域。每个子区域都是凸域:
简直不能更酷!下面这张图总结了不一样类型的神经网络具有的功能:
数学家证实了,双隐层神经网络可以解决任意复杂的分类问题。但咱们的问题到此为止了吗?不见得!
这里还有几个问题:网络
若是一个平面,有6个点,分红三类。如何设计呢?
一种最狂暴的方法,是对每个点都用四条线围起来,以后,再对六个区域两两取并集。造成下面这张超复杂的图:
解释一下为何要有这么多个节点:
第一层:x,y再加bias,三个
第二层:每一个点须要四条线围起来,加上bias,总共4*6+1=25个
第三层:一个节点处于该类的条件是在四条线的中间(交集),所以每四个点汇成一个点,24/4+1=7个
第四层:三分类问题,须要对每两个区域求并集,所以须要6/2+1=4个机器学习
但这样的解法,使用了3+25+7+4=39个节点,须要111个参数。这样的系统很是复杂,对未知节点几乎没有任何扩展性。
仔细思考这个问题, 咱们可以经过更少的节点和层数,来简化这个问题嘛?只要三条直线就能够!节点数量大大减小。不只训练效率更高,并且可扩展能力很强。对更复杂的例子,咱们又不是神仙,怎么知道设计几个隐层和多少个节点呢?
所谓超参数,就是模型以外的参数,在这个例子中,就是隐层的数量和节点的数量。一般来讲,线性分类器(回归)只须要两层便可,对于通常的分类问题,三层足够。
一个三层的神经网络,输入和输出节点的数量已经肯定,那如何肯定中间层(隐层)的节点数量呢?通常有几个经验:函数
如何表示一个神经网络?网络有m层,每层的节点分别为\(node_0,node_1...node_m\),节点最多的层,有m个节点,那么咱们能够将其表达为一个矩阵W,规模为\(m*n\),内部有些值是没有定义的。性能
若是输入和输出是线性关系(或者是正相关),那么想象咱们在调节一个参数时,当输出过大,那就把输入调小一些,反之调大一些,最后当输出和咱们想要的很是接近时,训练结束。这个就比如,在平面上,若是一个点被分配到了错误的输出,就应该对直线平移和扭转,减小该直线到这个点的距离,从而实现从新分区。
进一步地,若是向量的多个份量互相独立,那么方法也和上面的相似\(x_1=>y_1,x_2=>y_2\),分别调节\(x_1\)和\(x_2\)的参数,最终让结果接近,训练结束。
而一个感知器结构可表示以下:
反思上面的过程,咱们其实是在衡量偏差,根据偏差来修改权重。学习
若是输入和输出的关系比较复杂,如二次函数\(y=x^2\),那当超过x=0的位置以后,反而成了递增了,此时一个线性的判断函数就不起做用了。所以,上面的方法,不能推广到全部的前馈网络中。
怎么办?那就只能使用梯度(LMS)法了。
梯度法,是对于样本集\(X_1,X_2..X_n\),找到一个\(W^*\),使得\(f(W^* \dot X_i) X_i\)与输出\(Y_i\)尽量接近,其中\(f\)是激励函数。偏差表示为:
\[e= \frac{1}{2}\sum_{i=1}^{n}{(Y_i-Y_i^*)}^{2}\]
为了可以调节偏差e,使之尽量小,则须要求其导数,发现其降低的方向:
\[grad_w e= \frac{\partial e}{\partial W} = \sum_{k=1}^{n}\frac{\partial e_k}{\partial W}\]
其中:
\[e_k=\frac{1}{2} {(Y_k-Y^-_k)}^2\]
对偏导进行求解:
每次迭代的计算公式为:
最终:
其几何意义就是,偏差的偏导,等于在\(X_k\)位置上的值,乘以偏差,再乘以激励函数的偏导。
因此,每次的权重矩阵\(W\)的修改,应当经过求偏差的偏导(梯度)来实现。比以前的直接经过偏差来调整,具有更好的适应性。
可是,这样的梯度法,对于实际学习来讲,效率仍是太慢,咱们须要更快的收敛方法。人工智能
BP算法就是所谓的反向传播算法,它将偏差进行反向传播,从而获取更高的学习效率。这很像烽火台,若是前线战败了,那么消息就经过烽火台传递回指挥部,指挥部去反思问题,最终改变策略。
但这带来一个问题,中间层的偏差怎么计算?咱们能简单地将权重和残差的乘积,返回给上一层节点(这种想法真暴力,从左到右和从右到左是同样的)。
spa
这至关于三次传播:设计
-第一步:从前向后传播FP -第二步:获得值z,偏差为y,将偏差反向传播,得到每一个节点的误差$\sigma$ -第三步:再次正向传播,经过上一步的$\sigma$,再乘以步长,修改每个神经元突触的权重。
下面一张图展现了完整的BP算法的过程,我看了不下20遍:
更有趣的是,sigmoid求导以后,特别像高斯(正态)分布,并且sigmoid求导很是容易。
这样的一篇文章真是够长了,本来还想再介绍一个神经网络的Python实现,但是考虑到篇幅的限制,最终做罢。在下一期继续介绍如何实现BP神经网络和RNN(递归神经网络)。