• 机器学习-感知机实现(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 的形式

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

  • 相关阅读:
    ASP.NET Core依赖注入(DI)
    SQLSERVER 创建索引视图注意事项
    Git的基本使用方法(0基础小白也能看懂)
    并发系列64章(异步编程二)第三章
    并发系列64章(异步编程)第二章
    并发系列64章(并发概要)第一章
    SQL Server配置邮件服务器
    SQL Server常用函数及命令
    SQL Server将一段字符串根据特定分隔符转换成一个表变量
    SQL Server双机热备之发布、订阅实现实时同步
  • 原文地址:https://www.cnblogs.com/dinghing154/p/6129307.html
Copyright © 2020-2023  润新知