数学之路(3)-机器学习(3)-机器学习算法-神经网络[12]

来源:互联网 发布:windows xp嵌入式系统 编辑:程序博客网 时间:2024/05/18 05:00

本博客所有内容是原创,未经书面许可,严禁任何形式的转载

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_atanhsigmoid_func=ann_atanhi=0for 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+=1test=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=1y_max=max(err)+0.2y_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 = errplt.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初始化算法做为默认方法。具体内容我们下节介绍