zoukankan      html  css  js  c++  java
  • 感知机算法及BP神经网络

    简介:感知机在1957年就已经提出,可以说是最为古老的分类方法之一了。是很多算法的鼻祖,比如说BP神经网络。虽然在今天看来它的分类模型在很多数时候泛化能力不强,但是它的原理却值得好好研究。先学好感知机算法,对以后学习神经网络,深度学习等会有很大的帮助。

    一,感知机模型

    (1)、超平面的定义

    令w1,w2,...wn,v都是实数(R) ,其中至少有一个wi不为零,由所有满足线性方程w1*x1+w2*x2+...+wn*xn=v

    的点X=[x1,x2,...xn]组成的集合,称为空间R的超平面。

    从定义可以看出:超平面就是点的集合。集合中的某一点X,与向量w=[w1,w2,...wn]的内积,等于v

    特殊地,如果令v等于0,对于训练集中某个点X:

    w*X=w1*x1+w2*x2+...+wn*xn>0,将X标记为一类

    w*X=w1*x1+w2*x2+...+wn*xn<0,将X标记为另一类

    (2)、数据集的线性可分

    对于数据集T={(X1, y1),(X2, y2)...(XN, yN)},Xi belongs to Rn,yi belongs to {-1, 1},i=1,2,...N

    若存在某个超平面S:w*X=0

    将数据集中的所有样本点正确的分类,则称数据集T线性可分。

    所谓正确地分类,就是:如果w*Xi>0,那么样本点(Xi, yi)中的 yi 等于1

    如果w*Xi<0,那么样本点(Xi, yi)中的 yi 等于-1

    因此,给定超平面 w*X=0,对于数据集 T中任何一个点(Xi, yi),都有yi(w*Xi)>0,这样T中所有的样本点都被正确地分类了。

    如果有某个点(Xi, yi),使得yi(w*Xi)<0,则称超平面w*X对该点分类失败,这个点就是一个误分类的点。

    (3)、感知机模型

    f(X)=sign(w*X+b),其中sign是符号函数。

    感知机模型,对应着一个超平面w*X+b=0,这个超平面的参数是(w,b),w是超平面的法向量,b是超平面的截距。

    我们的目标是,找到一个(w,b),能够将线性可分的数据集T中的所有的样本点正确地分成两类。

    二、感知机策略

    策略的重点是定义损失函数,即构造出一种能都使得损失最小的函数结构

    三、感知机算法

    算法的输入为m个样本,每个样本对应于n维特征和一个二元类别输出1或者-1,如下:  (x(0)1,x(0)2,...x(0)n,y0),(x(1)1,x(1)2,...x(1)n,y1),...(x(m)1,x(m)2,...x(m)n,ym)(x1(0),x2(0),...xn(0),y0),(x1(1),x2(1),...xn(1),y1),...(x1(m),x2(m),...xn(m),ym)

        输出为分离超平面的模型系数θ向量

        算法的执行步骤如下:

        (1) 定义所有x0x0为1。选择θ向量的初值和 步长α的初值。可以将θ向量置为0向量,步长设置为1。要注意的是,由于感知机的解不唯一,使用的这两个初值会影响θ向量的最终迭代结果。

        (2) 在训练集里面选择一个误分类的点(x(i)1,x(i)2,...x(i)n,yi)(x1(i),x2(i),...xn(i),yi), 用向量表示即(x(i),y(i))(x(i),y(i)),这个点应该满足:y(i)θ∙x(i)≤0y(i)θ∙x(i)≤0

        (3) 对θ向量进行一次随机梯度下降的迭代:θ=θ+αy(i)x(i)θ=θ+αy(i)x(i)

        (4)检查训练集里是否还有误分类的点,如果没有,算法结束,此时的θ向量即为最终结果。如果有,继续第2步。

    四、感知机与感知机神经网络 代码实现

    net=newp([0 2],1);
    inputweights=net.inputweights{1,1};
    biases=net.biases{1};
    
    net=newp([-2 2;-2 2],1);
    net.IW{1,1}=[-1 1];
    net.IW{1,1}
    net.b{1}=1;
    net.b{1}
    p1=[1;1],a1=sim(net,p1)
    p2=[1;-1],a2=sim(net,p2)
    p3={[1;1] [1 ;-1]},a3=sim(net,p3) 
    p4=[1 1;1 -1],a4=sim(net,p4)
    net.IW{1,1}=[3,4];
    net.b{1}=[1];
    a1=sim(net,p1)
    
    net=init(net);
    wts=net.IW{1,1}
    bias=net.b{1}
    net.inputweights{1,1}.initFcn='rands';
    net.biases{1}.initFcn='rands';
    net=init(net);
    bias=net.b{1}
    wts=net.IW{1,1}
    a1=sim(net,p1)
    
    net=newp([-2 2;-2 2],1);
    net.b{1}=[0];
    w=[1 -0.8]
    net.IW{1,1}=w;
    p=[1;2];
    t=[1];
    a=sim(net,p)
    e=t-a
    help learnp
    dw=learnp(w,p,[],[],[],[],e,[],[],[],[],[])
    w=w+dw
    net.IW{1,1}=w;
    a=sim(net,p)
    
    
    P=[-0.5 1 0.5 -0.1;-0.5 1 -0.5 1];
    T=[1 1 0 1]
    net=newp([-1 1;-1 1],1);
    plotpv(P,T);
    plotpc(net.IW{1,1},net.b{1});
    %hold on;
    %plotpv(P,T);
    net=adapt(net,P,T);
    net.IW{1,1}
    net.b{1}
    plotpv(P,T);
    plotpc(net.IW{1,1},net.b{1})
    net.adaptParam.passes=3;
    net=adapt(net,P,T);
    net.IW{1,1}
    net.b{1}
    plotpc(net.IW{1},net.b{1})
    net.adaptParam.passes=6;
    net=adapt(net,P,T)
    net.IW{1,1}
    net.b{1}
    plotpv(P,T);
    plotpc(net.IW{1},net.b{1})
    
    plotpc(net.IW{1},net.b{1})
    a=sim(net,p);
    plotpv(p,a)
    
    p=[0.7;1.2]
    a=sim(net,p);
    plotpv(p,a);
    hold on;
    plotpv(P,T);
    plotpc(net.IW{1},net.b{1})
    
    P=[-0.5 -0.5 0.3 -0.1 -40;-0.5 0.5 -0.5 1.0 50]
    T=[1 1 0 0 1];
    net=newp([-40 1;-1 50],1);
    plotpv(P,T);
    hold on;
    linehandle=plotpc(net.IW{1},net.b{1});
    E=1;
    net.adaptParam.passes=3;
    while (sse(E))
        [net,Y,E]=adapt(net,P,T);
        linehandle=plotpc(net.IW{1},net.b{1},linehandle);
        drawnow;
    end;
    axis([-2 2 -2 2]);
    net.IW{1}
    net.b{1}
    net=init(net);
    net.adaptParam.passes=3;
    net=adapt(net,P,T);
    plotpc(net.IW{1},net.b{1});
    axis([-2 2 -2 2]);
    net.IW{1}
    net.b{1}
    
    net=newp([-40 1;-1 50],1,'hardlim','learnpn');
    plotpv(P,T);
    linehandle=plotpc(net.IW{1},net.b{1});
    e=1;
    net.adaptParam.passes=3;
    net=init(net);
    linehandle=plotpc(net.IW{1},net.b{1});
    while (sse(e))
    [net,Y,e]=adapt(net,P,T);
    linehandle=plotpc(net.IW{1},net.b{1},linehandle);
    end;
    axis([-2 2 -2 2]);
    net.IW{1}
    net.b{1}
    
    net=newp([-40 1;-1 50],1);
    net.trainParam.epochs=30;
    net=train(net,P,T);
    pause;
    linehandle=plotpc(net.IW{1},net.b{1});
    hold on;
    plotpv(P,T);
    linehandle=plotpc(net.IW{1},net.b{1});
    axis([-2 2 -2 2]);
    
    p=[1.0 1.2 2.0 -0.8; 2.0 0.9 -0.5 0.7]
    t=[1 1 0 1;0 1 1 0]
    plotpv(p,t);
    hold on;
    net=newp([-0.8 1.2; -0.5 2.0],2);
    linehandle=plotpc(net.IW{1},net.b{1});
    net=newp([-0.8 1.2; -0.5 2.0],2);
    linehandle=plotpc(net.IW{1},net.b{1});
    e=1;
    net=init(net);
    while (sse(e))
    [net,y,e]=adapt(net,p,t);
    linehandle=plotpc(net.IW{1},net.b{1},linehandle);
    drawnow;
    end;

    matlab运行结果:

                                                                                                                                 图:1

    五、BP神经网络

      (1)基本思想

    BP神经网络也称为后向传播学习的前馈型神经网络,是一种典型的神经网络。后向传播是一种学习算法,体现为BP的训练过程,该过程是需要监督学习的;前馈型网络是一种结构,体现为BP的网络构架,如图2就是一个典型的前馈型神经网络.这种神经网络结构清晰,使用简单,而且效率也很高,因此得到了广泛的重视和应用。反向传播算法通过迭代处理的方式,不断的调整连接神经元的网络权重,使得最终输出结果和预期结果的误差最小。广泛应用于各种分类系统,他也包括了训练和使用两个阶段。

                                                                                   图:2

    (2)算法过程

    BP神经网络算法训练阶段的流程图和伪代码如下图所示:

                                                                                 图:3

    步骤一、初始化网络权重

    步骤二、向前传播输入(前馈型网络)

    步骤三、反向误差传播

    步骤四 、网络权重与神经元偏置调整

    步骤五、判断结束

    (3)BP神经网络 代码实现

    % BP网络
    net=newff([-1 2;0 5],[3,1],{'tansig','purelin'},'traingd')
    net.IW{1}
    net.b{1}
    
    p=[1;2];
    a=sim(net,p)
    net=init(net);
    net.IW{1}
    net.b{1}
    a=sim(net,p)
    %net.IW{1}*p+net.b{1}
    p2=net.IW{1}*p+net.b{1}
    a2=sign(p2)
    a3=tansig(a2)
    a4=purelin(a3)
    net.b{2}
    net.b{1}
    
    net.IW{1}
    net.IW{2}
    0.7616+net.b{2}
    a-net.b{2}
    (a-net.b{2})/ 0.7616
    help purelin
    
    p1=[0;0];
    a5=sim(net,p1)
    net.b{2}
    net=newff([-1 2;0 5],[3,1],{'tansig','purelin'},'traingd')
    net.IW{1}
    net.b{1}
    %p=[1;];
    p=[1;2];
    a=sim(net,p)
    net=init(net);
    net.IW{1}
    net.b{1}
    a=sim(net,p)
    net.IW{1}*p+net.b{1}
    p2=net.IW{1}*p+net.b{1}
    a2=sign(p2)
    a3=tansig(a2)
    a4=purelin(a3)
    net.b{2}
    net.b{1}
    
    P=[1.2;3;0.5;1.6]
    W=[0.3 0.6 0.1 0.8]
    net1=newp([0 2;0 2;0 2;0 2],1,'purelin');
    net2=newp([0 2;0 2;0 2;0 2],1,'logsig');
    net3=newp([0 2;0 2;0 2;0 2],1,'tansig');
    net4=newp([0 2;0 2;0 2;0 2],1,'hardlim');
    
    net1.IW{1}
    net2.IW{1}
    net3.IW{1}
    net4.IW{1}
    net1.b{1}
    net2.b{1}
    net3.b{1}
    net4.b{1}
    net1.IW{1}=W;
    net2.IW{1}=W;
    net3.IW{1}=W;
    net4.IW{1}=W;
    a1=sim(net1,P)
    a2=sim(net2,P)
    a3=sim(net3,P)
    a4=sim(net4,P)
    init(net1);
    net1.b{1}
    help tansig
    p=[-0.1 0.5]
    t=[-0.3 0.4]
    w_range=-2:0.4:2;
    b_range=-2:0.4:2;
    
    ES=errsurf(p,t,w_range,b_range,'logsig');
    pause(0.5);
    hold off;
    net=newp([-2,2],1,'logsig');
    net.trainparam.epochs=100;
    net.trainparam.goal=0.001;
    figure(2);
    [net,tr]=train(net,p,t);
    title('动态逼近')
    wight=net.iw{1}
    bias=net.b
    pause;
    close;
    p=[-0.2 0.2 0.3 0.4]
    t=[-0.9 -0.2 1.2 2.0]
    h1=figure(1);
    net=newff([-2,2],[5,1],{'tansig','purelin'},'trainlm');
    net.trainparam.epochs=100;
    net.trainparam.goal=0.0001;
    net=train(net,p,t);
    a1=sim(net,p)
    pause;
    h2=figure(2);
    plot(p,t,'*');
    title('样本')
    title('样本');
    xlabel('Input');
    ylabel('Output');
    pause;
    hold on;
    ptest1=[0.2 0.1]
    ptest2=[0.2 0.1 0.9]
    a1=sim(net,ptest1);
    a2=sim(net,ptest2);
    
    net.iw{1}
    net.iw{2}
    net.b{1}
    net.b{2}

    matlab运行结果:

                                                                                                      图:4

  • 相关阅读:
    如何向线程传递参数
    IntelliJ IDEA 13 Keygen
    单链表的基本操作
    顺序表静态查找
    有向图的十字链表表存储表示
    BF-KMP 算法
    图的邻接表存储表示(C)
    二叉树的基本操作(C)
    VC远控(三)磁盘显示
    Android 数独游戏 记录
  • 原文地址:https://www.cnblogs.com/twzh123456/p/11611878.html
Copyright © 2011-2022 走看看