神经网络:delta规则与广义delta规则以及利用SGD,Batch实现delta方法(python代码)

delta规则:

    如果一个输入节点导致一个输出临界点产生误差,则这两个节点之间的权重将根据输入值xj和输出偏差ei成比例地进行调整。该规则可以用公式表现为:

    wij = wij +a*ei*xj;

   其中:

    xj=输入节点的输出(j=1,2,3)

    ei=输出节点i的误差

    wij=输出节点i和输入节点j之间的权重

    a=学习率(0<=a<1)

    ei = di -yi      di表示的是标准输出,yi表示的是输出

使用delta规则训练过程概括如下:

    (1) 以合适的值初始化权值

    (2)从训练数据中获取“输入”,格式为{input,correct,output},并将其输入到神经网络。计算出输出yi与输入所对应的标准输出di的误差。

    (3)根据以下delta规则计算权重的更新:

             @wij = a*ei*xj;

      (4)  将权值调整为:

               wij = wij+a*ei*xj

      (5) 对所有训练数据执行步骤2~4

      (6) 重复步骤2~5直到误差达到可容忍的等级

广义delta规则:

    对于任何的激活函数,delta规则可用以下式子表示:

         wij = wij + a*bi*xj

         bi = z'(vi)*ei

        其中vi表示节点i的加权和

        z'(vi)表示节点i的激活函数z的导数

        ei表示的是标准输出di与输出之间的差值

利用SGD来实现广义delta规则:

       这里选用的激活函数为z(x)=1/(1+e^(-x))

       z'(x)=z(x)*(1-z(x))

       输入的数据有四组,

       标准输入为[[0,0,1],[0,1,1],[1,0,1],[1,1,1]]

       标准输出为[0,0,1,1]

       这里用的是python实现:

     

#!/usr/bin/env python


import math
import random


#Sigmid函数 激活函数的导数
def Sigmid(x):
    y = 1.0/ (1+math.exp(-x));
    return y;
# W 是传递权重的参数, X 是传递训练数据的输入, D是标准输出参数
def DeltaSGD (W,X,D):
    #学习率
    alpha = 0.9
    for  i in range(0,4):
        v = 0;
        d = D[i];
        for j in range(0,3):
            v=v+ W[j]*X[i][j];
        #求得节点的输出
        y = Sigmid(v);
        #求出误差
        e = d - y;
        for j in range(0,3):
            #求得dw
            dw = y*(1-y)*e*alpha*X[i][j];
            W[j] = W[j]+ dw;
    return W;

if __name__ == '__main__':
    #Wij表示输入节点j到输出节点i之间的权值
    W = []
    #标准输入
    data =[[0,0,1],[0,1,1],[1,0,1],[1,1,1]]
    #标准输出
    D =[0,0,1,1]
    #初始化权值
    for i in range(0,3):
        W.append(2*random.random()-1);
    #训练数据
    for i in range(1,10001):
        W=DeltaSGD(W,data,D)
    y=0
    #输出最终训练结果
    for i in range(0,4):
        v =0;
        for j in range(0,3):
            v= v+ W[j]*data[i][j];
        y= Sigmid(v);
        print(y);

输出结果:

利用Batch来实现广义delta规则:

   采用的信息与前面的完全一致

      

#!/usr/bin/env python


import math
import random

#Sigmid函数 激活函数的导数
def Sigmid(x):
    y = 1.0/ (1+math.exp(-x));
    return y;

def Batch (W,X,D):
    alpha = 0.9
    dwSum= [];
    for i in range (0,len(W)):
        dwSum.append(0);
    for i in range(0,len(D)):
        v= 0;
        d = D[i];
        for j in range(0,len(W)):
            v = v + W[j]*X[i][j];
        y = Sigmid(v);
        e = d - y;
        for j in range (0,len(W)):
            #计算每一组数据之间产生的误差
            dw = y*(1-y)*alpha*e*X[i][j];
            #将误差加和
            dwSum[j] = dwSum[j] +dw;
    #更新权值
    for i in range(0,len(W)):
        W[i] = W[i] + dwSum[i]*1.0/len(D);
    return W;
if __name__ == '__main__':
    #Wij表示输入节点j到输出节点i之间的权值
    W = []
    #标准输入
    data =[[0,0,1],[0,1,1],[1,0,1],[1,1,1]]
    #标准输出
    D =[0,0,1,1]
    #初始化权值
    for i in range(0,3):
        W.append(2*random.random()-1);
        #print(W[i]);
    for i in range(0,40000):
        W = Batch(W,data,D)
    for i in range (0,len(D)):
        v = 0
        for j in range(0,len(W)):
            v = v + W[j]*data[i][j];
        y = Sigmid(v);
        print(y);

运行结果:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值