BP的原理及实践

来源:互联网 发布:windows ntp配置 编辑:程序博客网 时间:2024/05/17 22:34

为了更好理解神经网络的反向传播(BP), 本文我们自己推导出一个两层模型的BP的计算公式和并进行实际演算。然后会给出演算后的最终结果及python代码。

提出问题

以下是我们目标公式和输入数据,看我们如何通过反向推导的方式求出w和b:
这里写图片描述

首先随便初始化各个参数,当然也可以用随机数生成满足正态分布,这里为了计算流程方便,用了指定参数。

  • W = [3,2,1] ………………………………………. 实际值为[1,2,3]

  • b = 0 ………………………………………………实际值为1

看一下用这组参数算出来的:

sum=I1W1+I2W2+I3W3+b=23+02+11+0=7.........6

数学公式的推导

我们看看怎么样能够通过调整参数满足条件。我们需要一个个的调整这四个参数。

w1,sum(7)(6),I1W1I1W1W1

那么到底调多少呢? 我们假设当期他参数不变的情况下,cost值随w的变化如下:
这里写图片描述

显然,cost随w变化的幅度越大,则我们应该调整得越多,cost随w变化的幅度越小,我们应该调整得越少,这也符合我们的常识。在微积分领域,我们得出:调整的幅度其实就是cost针对w的微分。也就是:

首先给出我们的数学公式:

sum=i=02IiWi+b

由于我们的目标是使:
cost=sumoutput0

那么微分方程为:

costw1=(sumout)sumsumw1=costsumI1

同理:

costb=(sumout)sumsumb=costsum

因为我们有四个参数, 因此每次不能一下调整到位, 因此, 我们设了一个参数 代表调整的系数

λ=0.1

因此调整公式为:

wi=wiλ(cost/sum)Ii......................................................(1)

b=bλ(cost/sum)............................................................(2)

实际演算

所以, 我们按照这个逻辑试着计算一下:

1.sum=23+02+11+0=7

2.cost=sumoutput=76=1

3.w1=w1λ(cost/sum)I1=30.1(1/7)2=2.9714

4.b=bλ(cost/sum)=30.1(1/7)=0.014286

接下来按照相同的input和output调整其他的w和b参数.

按照这一算法,我们演算的各个步骤及结果如下:
这里写图片描述

其中,每轮变化的参数以红色字体标出,而紫色的数列代表了每轮的误差数值(cost/sum), 可以看到其绝对值是逐渐变小的。

演算1000轮后的结果

w= [1.000386951.999955152.99970678] b= 0.999463501861TotaoLoss= 0.000114250142628

可以看出基本达到了目的,最终各个参数的演变情况如下图(1000回合):
这里写图片描述

而误差值的变化情况如下:
这里写图片描述

实际代码

lmbda=0.1n_input=3n_output=1training_epochs=1000#y = x1+x2*2+x3*3+1input = [np.array([2, 0, 1]), np.array([4, 5, 3]), np.array([7, 6, 8]), np.array([ 9, 10, 11]), np.array([14, 12, 13])] output = [6, 24, 44, 63, 78]def act(z):    return zdef PointMat(a,b):    return np.dot(a,b)def Learn(Input,Output):    w,b = GenWB()#准备后续画图的参数w0a=[]w1a=[]w2a=[]ba=[]lossa=[]for i in range(training_epochs):#Train 1000 rounds    losssum = 0    for j in range(len(Input)):#Train each data pairs        for k in range(len(Input[j])): #Adjust each w            sumup = np.float64(PointMat(Input[j],w)+b)            loss = (sumup-Output[j])/sumup            losssum += abs(loss)            delta = 0            if Input[j][k] < 1e-06:                continue            else:                delta = lmbda*act(loss)*Input[j][k]                oldwk = w[k]                w[k] = w[k] - delta            b = b - lmbda*act(loss) #adjust bias    #Try to draw graph    w0a.append(w[0])    w1a.append(w[1])    w2a.append(w[2])    ba.append(b)    lossa.append(losssum)    print("w=",w,"b=",b,",TotaoLoss=",losssum)#开始画图xa = np.arange(training_epochs)plt.plot(xa, w0a, 'r-', label='W0')plt.plot(xa, w1a, 'g-', label='W1')plt.plot(xa, w2a, 'b-', label='W2')plt.plot(xa, ba, 'c-', label='Bias')plt.legend()plt.show()plt.plot(xa, lossa, 'ro', label='loss')plt.legend()plt.show()
原创粉丝点击