zoukankan      html  css  js  c++  java
  • 机器学习-感知机实现(1)

    前提

    这系列文章不是为了去研究那些数学公式怎么推导,而是为了能将机器学习的思想快速用代码实现。最主要是梳理一下自己的想法。

    感知机

    感知机,就是接受每个感知元(神经元)传输过来的数据,当数据到达某个阀值的时候就会产生对应的行为
    如下图,对应每个感知元有一个对应的权重,当数据到达阀值u的时候就会执行对应的行为。

    u = w0 + w1x1 + w2x2 +......wnxn

    对应到垃圾邮件处理上,当u > 0时就是正常邮件。相反则为垃圾邮件
    对于这样的模型就可以称之为简单的感知机。也就是一个神经网络的基本单位。

    权重向量的更新
    上面所提到的w1,w2等就是就是对应每个是否是垃圾邮件的衡量标准,而x1,x2...就是邮件中被监测的词组的数目
    比如x1和x2相同的时候,w1和w2的绝对值较大的一方对结果,也就是u的影响更大。所以,我们也把w1,w2....称之为x1,x2..的权重值
    向量即为权重向量

    根据训练数据中的期待结果和预测结果不断的修改权重即可。那么具体到项目中应该怎么修改w呢

    1. 随机为w1,w2,...wn设置一个值
    2. 不断重复以下步骤
      * 输入训练数据,如果结果不正确就进行修改
      * 当所有的训练数据的结果都正确时就结束运算
    思想很简单,那么[不正确就修改]这一句话,在简单的感知机中能够很简单的修改,那么在深度神经网络中的时候该怎么计算呢

    梯度下降法
    首先介绍一个定义[误差函数(即损失函数)]E,即输出结果和期待结果的差值
    为了方便以后的计算这个定义又可以改为变化根据向量w的变化误差函数是否在朝着最小变化的方向递进
    w和误差函数的关系如下图所示

    曲线最下方的w的值即为一次计算所期望的值,如果仔细分析我们可以知道这种计算就是微分计算
    而这种变化趋势就是微分计算的值

    那么wi的变化过程即为

    简单的理解就是当变化趋势为负时wi朝正直方向移动,反之亦然.但是当变化趋势很大的时候wi的变化就会很大,
    而变化趋势很小的时候wi的变化就又会很小。这样的计算会让整个过程很难收敛,因此我们会设置一个比较小的正数参数
    来参与计算。

    在上面的表达之中p就是学习速率。一般会设置一个比1小的正数。但是如果太小的话同样会让计算量大大增加。
    这种通过不断的微分修正权重的方法就是_梯度下降法_。如果想要知道更多关于梯度下降的细节可以参考我之前的[一篇文章]

    然后就是误差函数的具体表达形式了。

    简单感知机的误差函数
    对于一个感知机,我们使用以下的公式来表达他的误差函数

    E = max(0,-twx)

    max(a,b)就是选取a,b中较大值的运算函数。t就是正确与否的标志
    t = 1(正常邮件),t=-1(垃圾邮件)
    这里有个细节就是垃圾邮件的判断是-1而不是0.
    那么为什么要误差函数要采用max(0,-twx)形式呢。

    考虑以下x1,x2的二次元方程。
    对于算式wx(w0 + w1x1 + w2x2)的值。在直线wx=0上面的所有值毫无疑问就是0,而在直线上方的就是正值
    在直线下方的就是负值。当t=1的所有点都在正值区域,而-1的点都在负值区域的时候训练就结束。
    类似于下图。

    这种就是学习还没有结束的情况,B和D的区分暂时处于一个错误的区域。


    可以着重看一下A的情况 :
    A是一个垃圾邮件,而现在的分类情况也是正确的,那么wx>0。也就是t=1。

    所以我们可以看到-twx = -wx<0。因此E = max(0,-twx) = 0,误差函数的结果为0。

    因此对于误差函数,当点x被正确分类成功的时候可以得到误差值0,相反则是|wx|。

    那么|wx|到底代表着什么呢?简单的理解就是这个点和直线wx=0的距离。没记错的话这个距离计算应该是高中知识。

    感知机算法的实现
    根据上文介绍的权重的更新的函数

    对于误差函数E = max(0,-twx),当误差不为0 的时候就返回-twx。我们来简单推算以下。

    因此可以得到更新后的运算公式:

    权重整体来表达的时候如下:

    根据以上的推论我们可以得到一个感知机的伪代码如下:

    * 为w1,w2....wn设置随机值
    * 输入每一个训练数据
      * 输入的训练数据所得到的结果与期望值是否一致

        * 一致,进行下一组运算
        * 不一致,按照来进行运算
    * 在上一组循环运算中w的值是否发生了改变
      * 被改变了,那么再重复一此上述的循环
      * 没有改变(所有的值都是期望值),训练结束

    这个伪代码的我用python实现了。如果需要可以参考[这里]

    阀值
    _提示,这节对于这篇文章没有太多帮助,主要为了下一篇文章,多层感知机做铺垫_
    对于每一个感知机都是一个激活阀值,当参数到达了该阀值的时候被能执行某个行为。那么如何确定这个阀值呢?

    决定输出值的阀值又被称为激活参数。简单来说激活参数的表达式如下f(u)=u。
    类似于垃圾邮件分类我们可以有如下表达式:

    用图表示的时候如下:

    换成我们上面使用的-1和1 的形式

    以上,如果有疑问欢迎讨论。

  • 相关阅读:
    Linux命令应用大词典-第11章 Shell编程
    Kubernetes 学习12 kubernetes 存储卷
    linux dd命令
    Kubernetes 学习11 kubernetes ingress及ingress controller
    Kubernetes 学习10 Service资源
    Kubernetes 学习9 Pod控制器
    Kubernetes 学习8 Pod控制器
    Kubernetes 学习7 Pod控制器应用进阶2
    Kubernetes 学习6 Pod控制器应用进阶
    Kubernetes 学习5 kubernetes资源清单定义入门
  • 原文地址:https://www.cnblogs.com/dinghing154/p/6129307.html
Copyright © 2011-2022 走看看