本博客所有内容是原创,未经书面许可,严禁任何形式的转载
http://blog.csdn.net/u010255642
我们使用最原始的纯随机生成方法产生多层感知器网络 的权值矩阵,这个权值矩阵要保证输入项在网络中均匀分布,要保证权值矩阵本身的均匀分布
我们修改前面的程序,不使用偏置,目标是使之更稳定,收敛效果更好,修改的基本策略是为:
1、输出层的学习率较低,动量参数较高
2、输入层的学习率较低,运量参数较低
3、随机生成若干个权值矩阵,选择最优化的权值矩阵
选择的策略是:
1、输入项的方差尽可能靠近1
2、权值矩阵的均值尽可能小,其方差尽可能与神经元的突触连接数成反比
按这个策略来生成权值矩阵,一个好的权值矩阵能使网络快速收敛,使网络更稳定。
修改后部分代码如下:
def simulate(myx,sigmoid_func,delta_sigfun):
'''一个样本的仿真计算'''
print u"仿真计算中"
global ann_yi
global ann_w
global ann_wj0
global ann_y0
global hidelevel_count
global alllevel_count
global d
myd=d[0]
myx=np.array(myx)
n=len(myx)
#清空yi输出信号数组
hidelevel=hidelevel_count
alllevel=alllevel_count
for i in xrange(0,alllevel):
#第一维是层数,从0开始
for j in xrange(0,n):
#第二维是神经元
ann_yi[i][j]=0.0
ann_yi=np.array(ann_yi)
yi=ann_yi
#前向计算
myy=np.array([])
for nowlevel in xrange(0,alllevel):
#一层层向前计算
#计算诱导局部域
my_y=[]
myy=yi[nowlevel-1]
myw=ann_w[nowlevel-1]
if nowlevel==0:
#第一层隐藏层
my_y=myx
yi[nowlevel]=my_y
elif nowlevel==(alllevel-1):
#线性输出层,使用线性激活
my_y=o_func(yi[nowlevel-1,:len(myd)])
yi[nowlevel,:len(myd)]=my_y
elif nowlevel==(hidelevel-1):
#最后一层隐藏输出层,使用线性激活
for i in xrange(0,len(myd)):
temp_y=sigmoid_func(np.dot(myw[:,i],myy))
my_y.append(temp_y)
yi[nowlevel,:len(myd)]=my_y
else:
#中间隐藏层
#中间隐藏层需要加上偏置
for i in xrange(0,len(myy)):
temp_y=sigmoid_func(np.dot(myw[:,i],myy))
my_y.append(temp_y)
yi[nowlevel]=my_y
if isdebug:
print "============="
print u"***权值矩阵***"
print ann_w
print u"***输出矩阵***"
print yi
print "============="
return yi[alllevel-1,:len(myd)]
train()
delta_sigfun=ann_delta_atanh
sigmoid_func=ann_atanh
i=0
for xn in xrange(0,len(x)):
print u"样本:%d===%d => "%(train_x[xn][0],train_x[xn][1])
print simulate(x[xn],sigmoid_func,delta_sigfun)
print u"=====正确目标值====="
print d[i]
i+=1
test=np.array(get_siminx([[8,70]]))
print u"测试值:%f===%f "%(8,70)
print simulate(test,sigmoid_func,delta_sigfun)
print u"正确目标值:[1,0]"
test=np.array(get_siminx([[6.5,272]]))
print u"测试值:%f===%f "%(6.5,272)
print simulate(test,sigmoid_func,delta_sigfun)
print u"正确目标值:[0,1]"
x_max=len(err)
x_min=1
y_max=max(err)+0.2
y_min=0.
plt.xlabel(u"traincount")
plt.xlim(x_min, x_max)
plt.ylabel(u"mse")
plt.ylim(y_min, y_max)
lp_x1 = xrange(1,len(err)+1)
lp_x2 = err
plt.plot(lp_x1,lp_x2,'g-')
plt.show()
因为输出在[0,1] 之间,所以我们将硬限幅函数改为:
def o_func(myy):
myresult=[]
for i in xrange(0,len(myy)):
if myy[i]>=0.5:
myresult.append(1.0)
else:
myresult.append(0.0)
return np.array(myresult)
运行后
>>> runfile(r'K:\book_prog\ann_bp2.py', wdir=r'K:\book_prog')
产生权值初始矩阵 . . . . . . . . . . . . . . .
权值矩阵平均:-0.000020
权值矩阵方差:0.225179
-------开始第1次训练--------- # # # # # # 误差为:1.438673
-------开始第2次训练--------- # # # # # # 误差为:0.797030
-------开始第3次训练--------- # # # # # # 误差为:0.892678
-------开始第4次训练--------- # # # # # # 误差为:0.879112
-------开始第5次训练--------- # # # # # # 误差为:0.833455
-------开始第6次训练--------- # # # # # # 误差为:0.844114
-------开始第7次训练--------- # # # # # # 误差为:0.810777
-------开始第8次训练--------- # # # # # # 误差为:0.787920
-------开始第9次训练--------- # # # # # # 误差为:0.796668
-------开始第10次训练--------- # # # # # # 误差为:0.779119
-------开始第11次训练--------- # # # # # # 误差为:0.757985
-------开始第12次训练--------- # # # # # # 误差为:0.710222
-------开始第13次训练--------- # # # # # # 误差为:0.742117
-------开始第14次训练--------- # # # # # # 误差为:0.674491
-------开始第15次训练--------- # # # # # # 误差为:0.680690
-------开始第16次训练--------- # # # # # # 误差为:0.648421
-------开始第17次训练--------- # # # # # # 误差为:0.666049
-------开始第18次训练--------- # # # # # # 误差为:0.646533
-------开始第19次训练--------- # # # # # # 误差为:0.639212
-------开始第20次训练--------- # # # # # # 误差为:0.589234
-------开始第21次训练--------- # # # # # # 误差为:0.590960
-------开始第22次训练--------- # # # # # # 误差为:0.621176
-------开始第23次训练--------- # # # # # # 误差为:0.540087
-------开始第24次训练--------- # # # # # # 误差为:0.523377
-------开始第25次训练--------- # # # # # # 误差为:0.581184
-------开始第26次训练--------- # # # # # # 误差为:0.491719
-------开始第27次训练--------- # # # # # # 误差为:0.491724
-------开始第28次训练--------- # # # # # # 误差为:0.510832
-------开始第29次训练--------- # # # # # # 误差为:0.489421
-------开始第30次训练--------- # # # # # # 误差为:0.462534
-------开始第31次训练--------- # # # # # # 误差为:0.456467
-------开始第32次训练--------- # # # # # # 误差为:0.444740
-------开始第33次训练--------- # # # # # # 误差为:0.438514
-------开始第34次训练--------- # # # # # # 误差为:0.453501
-------开始第35次训练--------- # # # # # # 误差为:0.392037
-------开始第36次训练--------- # # # # # # 误差为:0.441301
-------开始第37次训练--------- # # # # # # 误差为:0.400053
-------开始第38次训练--------- # # # # # # 误差为:0.382636
-------开始第39次训练--------- # # # # # # 误差为:0.382823
-------开始第40次训练--------- # # # # # # 误差为:0.372177
-------开始第41次训练--------- # # # # # # 误差为:0.376414
-------开始第42次训练--------- # # # # # # 误差为:0.366853
-------开始第43次训练--------- # # # # # # 误差为:0.335673
-------开始第44次训练--------- # # # # # # 误差为:0.370068
-------开始第45次训练--------- # # # # # # 误差为:0.313533
-------开始第46次训练--------- # # # # # # 误差为:0.329891
-------开始第47次训练--------- # # # # # # 误差为:0.367869
-------开始第48次训练--------- # # # # # # 误差为:0.312933
-------开始第49次训练--------- # # # # # # 误差为:0.340246
-------开始第50次训练--------- # # # # # # 误差为:0.310565
-------开始第51次训练--------- # # # # # # 误差为:0.314349
-------开始第52次训练--------- # # # # # # 误差为:0.298326
训练成功,正在进行检验
仿真计算中
仿真计算中
仿真计算中
仿真计算中
仿真计算中
仿真计算中
训练成功,输出误差为:0.000000
样本:4===11 =>
仿真计算中
[ 1. 0.]
=====正确目标值=====
[1, 0]
样本:7===340 =>
仿真计算中
[ 0. 1.]
=====正确目标值=====
[0, 1]
样本:10===95 =>
仿真计算中
[ 1. 0.]
=====正确目标值=====
[1, 0]
样本:3===29 =>
仿真计算中
[ 0. 1.]
=====正确目标值=====
[0, 1]
样本:7===43 =>
仿真计算中
[ 1. 0.]
=====正确目标值=====
[1, 0]
样本:5===128 =>
仿真计算中
[ 0. 1.]
=====正确目标值=====
[0, 1]
测试值:8.000000===70.000000
仿真计算中
[ 1. 0.]
正确目标值:[1,0]
测试值:6.500000===272.000000
仿真计算中
[ 0. 1.]
正确目标值:[0,1]
>>>
误差曲线图为:
随机生成法是一种比较笨的方法,关于权值矩阵的生成方法可以选择:
(1)随机初始化。
(2)逐步搜索法。
(3)根据Nguyen-Widrow初始化算法为层产生初始权重和偏置值,使得每层神经元的活动区域能大致平坦的分布在输入空间。
Nguyen-Widrow初始化算法是比较好的初始化权值的经典方法,关于多层感知器网络有很多现成的较好的库,大部分神经网络库包括 matlab神经网络工具箱都使用了Nguyen-Widrow初始化算法做为默认方法。具体内容我们下节介绍