深度学习实践笔记2——分析BP

1.分析上文的代码,发现跟标准的神经网络相比,它没有偏置,但仍然可用,一般的系统中,偏置一般是全局的,每一层共享一个bias,或者所有层的所有节点 都使用同一个bias。

 

2.一般评估误差(就是循环计算误差终止运算条件),采用均方误差

  也就是所有样本的所有输出节点的误差的平方和。这在代码中也有体现。

   //计算输出误差
   for (j = 0; j < N_Out ; j++)   
         e = e + (y[i][j] - Out2[j]) * (y[i][j] - Out2[j]);

3.初始化网络:就是产生随机数而已

4.权值修正:权系数的调整是由目标和输出的差分方程表达式决定。而 delta 规则是基于梯度降落(也即梯度下降)这样一种思路。(参考http://www.cnblogs.com/hellope/archive/2012/07/05/2577814.html) 如下图:修正量= - 学习率*(错误率对权值求偏导)

求错误率关于权值的偏导的本质就是:找到让错误率下降最快的方向(还记得求导数的意义吗?)

(也许你看了下面这两行会有点懵逼,没事,这是我摘抄的。。)

第1部分:在隐藏节点n和输出节点j之间权系数改变,如下所示:

alpha * s'(a(p,n))*(t(p,n) - y(p,n)) * X(p,n,j)

第 2 部分:在输入节点i和输出节点n之间权系数改变,如下所示:

alpha * s'(a(p,n)) * sum(d(j) * W(n,j)) * X(p,i,n)

 

5.梯度下降:想象一座山(谷)的等高线,想要从边上走到最中央的谷底,最快的方法是,找到当前等高线的切线,然后往垂直方向走一个r,这个r就是学习率,是可控的,走完r后,继续找切线的垂线,往下继续走r。不过貌似跟上文没多大关系。。。额。。只是普及一下。

 

 

6.那怎样实现4的公式呢?

这是上篇文章中的关键代码

 

                        //计算输出层的权修改量    
			for (j = 0; j < N_Out; j++)   
				ChgO[j] = Out2[j] * (1 - Out2[j]) * (y[i][j] - Out2[j]);
			//计算输出误差
			for (j = 0; j < N_Out ; j++)   
				e = e + (y[i][j] - Out2[j]) * (y[i][j] - Out2[j]);
			//计算中间层权修改量
			for (j = 0; j < LayerNum; j++) 
			{         
				Tmp = 0;
				for (k = 0; k < N_Out; k++)
					Tmp = Tmp + w[j][k] * ChgO[k];
				ChgH[j] = Tmp * Out1[j] * (1 - Out1[j]);
			}
			//修改输出层权矩阵
			for (j = 0; j < LayerNum; j++)           
				for (k = 0; k < N_Out; k++)
					w[j][k] = w[j][k] + a * Out1[j] * ChgO[k]; 
			for (j = 0; j < N_In; j++)
				for (k = 0; k < LayerNum; k++)
					v[j][k] = v[j][k] + a * x[i][j] * ChgH[k]; 

 

 

 

 

 

。。。看不太懂

我们只关注两个层之间的W,假设网路只有2层,IN和OUT,中间是W

那么,学习的步骤就是:W = 之前的W + 学习率 * (Out-t) * Out * (1-Out) * IN  (参考https://iamtrask.github.io/2015/07/12/basic-python-network/)

t是期望结果

Out-t就是直接的误差

 

重点来了。。。。(敲黑板)

以下是一个完整的2层网络的训练过程,三个输入一个输出,只有3个W,最后的目标就是让l1输出的结果与label一致。

以下代码参考https://iamtrask.github.io/2015/07/12/basic-python-network/

 

import numpy as np

sample = np.array([[0, 0, 1],
              [0, 1, 1],
              [1, 0, 1],
              [1, 1, 1]])

label = np.array([[0], [0], [1], [1]])

def activate(x):
    return 1/(1+np.exp(-x))

learning_rate = 1.0
w0 = 2 * np.random.random((3, 1)) - 1  # le it cast in -1 to 1

for iter in range(10000):
    l0 = sample
    l1 = activate(np.dot(l0,w0))
    l1_err = label - l1
    w0_delta = l1_err * l1 * (1-l1)
    w0 += learning_rate*np.dot(l0.T,w0_delta)
print l1

注:【1】np.random.random((3.1))表示生成3个0-1之间的浮点随机数,所以w0是-1到1的3个随机数
       【2】np.dot(x,y)是将两个list进行卷积求和,如果x或y是2纬的,就得出2个结果,例:
                a=[1,2,3];b=[1,2,3];c=np.dot(a,b) 输出c:14
                a=[[1,2,3],[1,2,3]];b=[1,2,3];c=np.dot(a,b)输出c:[14,14]
   

w0_delta = l1_err*l1*(1-l1) 

这一行是w0 = l1_err * 激活函数的导数,其意义是:权重的变化是我要修正的数值*激活函数在当前误差时的斜率,这样,当权重变化继续往前,就会使斜率越来越小。


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值