zoukankan      html  css  js  c++  java
  • 神经网络模型基本原理

    人工神经网络是一个数学模型,旨在模拟人脑的神经系统对复杂信息的处理机制,其网络结构是对人脑神经元网络的抽象,两者有很多相似之处。

    当然 ANN 还远没有达到模拟人脑的地步,但其效果也让人眼前一亮。

    1. 人工神经元结构

       人工神经元是一个多输入单输出的信息处理单元,是对生物神经元的建模。建模方式可以有很多种,不同的建模方式就意味着不同的人工神经元结构。

       比较著名的人工神经元模型是 MP 神经元,直到今天,我们仍然在使用这个神经元模型。MP 神经元是模仿生物的神经元设计的:

           1)输入向量 $x$ 模拟生物神经元中其他神经细胞给该细胞的刺激,值越大刺激越大;

           2)$w$ 向量模拟该细胞不同来源的刺激的敏感度;

           3)用阈值 $ heta$ 来描述激活该神经元的难易程度,越大越难激活;

           4)用 $w_{1}x_{1} + w_{2}x_{2} + ... + w_{n}x_{n} - heta$ 来计算神经元的兴奋程度;

           5)$y = f(x)$ 为激活函数,用来计算神经元的输出,因为生物神经元的输出是有上下限的,所以激活函数也是能够“饱和”的有界函数;

           6)在 MP 神经元中,激活函数为阶梯函数。兴奋函数大于阈值输出 $1$,小于阈值输出 $0$;

       下图是 MP 神经元模型的示意图:

          

       将激活函数代入,将项 $- heta$ 设为 $b$,则可以得到 MP 神经元的数学模型:

    $$y = sgn left ( sum_{i=1}^{n}(w_{i}x_{i} + b) ight )  = sgn left ( w^{T}x + b ight )$$

       惊讶得发现它就是一个线性分类模型,和感知机的数学模型是完全一样的,所以一个 MP 神经元的作用就是:对输入进行二分类

       这是符合生物神经元的特点的,因为一个生物神经元对输入信号所产生的作用就是:兴奋或这抑制。

       所以通俗来讲:一条直线把平面一分为二,一个平面把三维空间一分为二,一个 $n-1$ 维超平面把 $n$ 维空间一分为二,两边分属不同的两类,

                     这种分类器就叫做神经元,一个神经元只能分两类,输出是一个能体现类别的标量。

       一个神经元的作用就是这么简单,所做的也只能是线性分类,但是当多个神经元互联的时候就会产生神奇的效果,下面再叙述。

       MP 神经元的输出是样本点所属的类别,它把直线一侧变为 $0$,另一侧变为 $1$,这东西不可微,不利于数学分析,经常用其它类似于 $sgn$ 的可微

       函数来做激活函数,如:

          

       用上面的激活函数,比使用符号函数能体现样本的更多信息。

    2. 多层感知器

       由于 MP 神经元的输入来自于其他神经元,我们显然不能指望单独一个神经元就有什么功能,而多个神经元可以组成不同的结构。

       下面介绍一个二层感知器,来直观得感受下神经网络到底是如何工作的?其网络结构图如下:

          

       用这个网络对输入 $(0,0),(0,1),(1,0),(1,1)$ 四个点进行分类,其中红点是一类,蓝点是一类,使用的激活函数是 $sgn$。

              

       因为一个神经元的作用就是切一刀,即做一次线性分割,很显然对于上面的四个点没有办法只切一刀就完成分类,于是考虑用两个神经元,

       即现在隐藏层有两个神经元,即再切一刀,现在我们分析一下隐藏层两个神经元的输出情况:

    $$x_{1}  ;;; x_{2}  ;;;  y_{1} ;;; y_{2}  \
    0  ;;;;;   1 ;;;; 1 ;;;;; 1 \  
    0  ;;;;;   0 ;;;; 0 ;;;;; 1 \
    1  ;;;;;   1 ;;;; 0 ;;;;; 1 \
    1  ;;;;;   0 ;;;; 0 ;;;;; 0$$

       我们将隐藏层的输出 $(y_{1},y_{2})$ 绘制在坐标系上,如上右图。神奇的事情发生了,原本无法一刀切的四个点,经过隐藏层

       的后,变成了线性可分的,此时通过一条直线可以完成分类,所以输出层的神经元一个就够了。

       神经网络是由一层一层构建的,那么每层究竟在做什么呢?

       由上面的例子可以理解到,每一层神经元就是用线性变换跟随着非线性变化,将输入空间投向另一个空间,变换手段有:

           1)升维/降维

           2)放大/缩小

           3)旋转

           4)平移

           5)弯曲

       其中 $1,2,3$ 操作由 $w^{T}x$ 完成,$4$ 操作由 $+b$ 完成,$5$ 操作由激活函数 $f$ 完成。

       我们知道空间是由基决定的,首先我们先定义一个参考系 $S_{1}$,整个神经网络以它为坐标系。

       将一个变换作用在一个向量上面,该怎么理解为空间的改变呢?举一个例子;在参考系 $S_{1}$ 下面的一个向量 $(a,b)$,将它做如下变换:

    $$ai^{'} + bj^{'}$$

       其中 $i^{'},j^{'}$ 线性无关,那么这个输出相当于以向量 $i^{'},j^{'}$ 为基(参考系还是 $S_{1}$)进行合成,因为基 $i^{'},j^{'}$ 本身就可

       以表示一个空间,变换本质在这个空间里进行与原空间 $S_{1}$ 相同效果的向量合成,只不过新的空间是以参考系 $S_{1}$ 来进行坐标表示的。

       关键就在于变化前后的参考系没有改变,那么只要有足够的合适的神经元,空间的扭曲形变终究会使样本点线性可分。

       注:这个地方理解得不对,参考系也变化到对应维度的空间去了。

    3. 神经网络模型训练算法

       1)单层感知器梯度下降法

             

          激活函数为 $sigma(u)$,故该网络的数学模型:

    $$hat{f} = sigma(w^{T}x + b)$$

          对于一个输入向量,期望的网络输出为 $f$(训练集中已知的量),模型的实际输出为 $hat{f}$,损失函数定义为:

    $$L(w,b) = frac{1}{2} left ( f - hat{f} ight )^{2} = frac{1}{2} left [ f - sigma(w^{T}x + b) ight ]^{2}$$

          这个误差只是针对一个样本点的,除以 $2$ 的目的仅是为了求梯度时更好看,训练的时候是一个一个样本代入求损失函数的最小值,是随机梯度下降法。

          需要确定的参数是 $w_{i},i = 1,2,...,n$ 和 $b$,根据链式法则求偏导得:

    $$frac{partial L}{partial w_{i}} = frac{partial L}{partial hat{f}} cdot frac{partial sigma}{partial u} cdot frac{partial u}{partial w_{i}} = - left ( f - hat{f} ight ) cdot x_{i} cdot frac{partial sigma}{partial u}
    ; Rightarrow ; frac{partial L}{partial w} = left ( f - hat{f} ight ) cdot X cdot frac{partial sigma}{partial u} \
    frac{partial L}{partial b} =  frac{partial L}{partial hat{f}} cdot frac{partial sigma}{partial u} cdot frac{partial u}{partial b} = - left ( f - hat{f} ight ) cdot frac{partial sigma}{partial u}$$

          所以参数更新方法为:

    $$w = w + eta left ( f - hat{f} ight ) cdot X cdot frac{partial sigma}{partial u} \
    b = b + eta left ( f - hat{f} ight ) cdot frac{partial sigma}{partial u}$$

       2)多层感知器的反向传播算法  

         

           图中 $i$ 表示输入层单元,$j$ 表示中间层单元,$k$ 表示输出层单元。多层感知器的误差函数 $L(w,b)$ 等于个输出单元的误差总和,即

    $$L(w,b) = frac{1}{2}sum_{k=1}^{q}(r_{k} - y_{k})^{2}$$

           $r_{k}$ 表示期望的输出,是已知量(训练集提供),$y_{k}$ 为模型的实际输出,设激活函数为 $sigma(u)$。

           先来看一下各层的函数关系:

    $$y_{k} = sigma_{2k} left ( sum_{j=1}^{m}w_{2jk}z_{j} + b_{2k} ight ) \
    z_{j} = sigma_{1j} left ( sum_{i=1}^{n}w_{1ij}x_{i} + b_{1j} ight )$$

           需要确定的参数就是 $w_{1ij},w_{2jk},b_{1j},b_{2k}$,对每一层的各个参数求偏导有:

    $$frac{partial L}{partial w_{2jk}} = frac{partial L}{partial y_{k}} cdot frac{partial sigma_{2k}}{partial u_{2k}} cdot frac{partial u_{2k}}{partial w_{2jk}} = -(r_{k} - y_{k}) cdot z_{j} cdot frac{partial sigma_{2k}}{partial u_{2k}}$$

    $$frac{partial L}{partial w_{1ij}} = sum_{k=1}^{q}frac{partial L}{partial y_{k}} cdot frac{partial sigma_{2k}}{partial u_{2k}} cdot frac{partial u_{2k}}{partial z_{j}} cdot frac{partial sigma_{1j}}{partial u_{1j}} cdot frac{partial u_{1j}}{partial w_{1ij}} = -sum_{k=1}^{q}(r_{k} - y_{k}) cdot frac{partial sigma_{2k}}{partial u_{2k}} cdot w_{2jk} cdot frac{partial sigma_{1j}}{partial u_{1j}} cdot x_{i}$$

    假设激活函数为 $sigmod$,上面的过程可总结为下面两张图,图中的 $E$ 就是误差函数 $L$。  

          

    纵观整个过程,对于 ANN,当我们需要使用它时,是从最前面给出输入,然后一步步往后计算得出这个庞大复杂函数的输出的;

    而当我们需要训练它时,则是从最后面的参数开始,一步步向前求导,调整各个参数的。并且计算前面的参数时一般都会用到之前计算过的中间结果。

    这样,ANN 调整参数的过程就可以看作是一个误差反向传播(BP)的过程。

  • 相关阅读:
    前端必须掌握的 docker 技能(2)
    前端必须掌握的 docker 技能(1)
    异步 map 和模块打包
    import 和组件库按需引入
    babel-node 和 nodemon
    linux和mac 终端代理
    yarn.lock 是干什么的
    pwa 总结
    设计模式(5): vue 不监听绑定的变量
    django+celery+redis应用
  • 原文地址:https://www.cnblogs.com/yanghh/p/13776266.html
Copyright © 2011-2022 走看看