您的位置:首页 > 其它

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

2017-08-11 16:33 295 查看
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


最后定义:

W的学习方式为:W + (样本标签-本次输出) * 本次输出 * (1-本次输出)  点乘 本次输入

公式推导太麻烦,就这么用吧。。不想尝试了(逃
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐