由于Rosenblatt感知器的局限性,对于非线性分类的效果不理想。为了对线性分类无法区分的数据进行分类,需要构建多层感知器结构对数据进行分类,多层感知器结构如下:
该网络由输入层,隐藏层,和输出层构成,能表示种类繁多的非线性曲面,每一个隐藏层都有一个激活函数,将该单元的输入数据与权值相乘后得到的值(即诱导局部域)经过激活函数,激活函数的输出值作为该单元的输出,激活函数类似与硬限幅函数,但硬限幅函数在阈值处是不可导的,而激活函数处处可导。本次程序中使用的激活函数是tanh函数,公式如下:
tanh函数的图像如下:
程序中具体的tanh函数形式如下:
就是神经元j的诱导局部域
它的局部梯度分两种情况:
(1)神经元j没有位于隐藏层:
(2)神经元j位于隐藏层:
其中k是单元j后面相连的所有的单元。
局部梯度得到之后,根据增量梯度下降法的权值更新法则
即可得到下一次的权值w,经过若干次迭代,设定误差条件,即可找到权值空间的最小值。
python程序如下,为了能够可视化,训练数据采用二维数据,每一个隐藏层有8个节点,设置了7个隐藏层,一个输出层,输出层有2个单元:
import numpy as np import random import copy import matplotlib.pyplot as plt #x和d样本初始化 train_x = [[1,6],[3,12],[3,9],[3,21],[2,16],[3,15]] d =[[1,0],[1,0],[0,1],[0,1],[1,0],[0,1]] warray_txn=len(train_x[0]) warray_n=warray_txn*4 #基本参数初始化 oldmse=10**100 fh=1 maxtrycount=500 mycount=0.0 if maxtrycount>=20: r=maxtrycount/5 else: r=maxtrycount/2 #sigmoid函数 ann_sigfun=None ann_delta_sigfun=None #总层数初始化,比非线性导数多一层线性层 alllevel_count=warray_txn*4 # 非线性层数初始化 hidelevel_count=alllevel_count-1 #学习率参数 learn_r0=0.002 learn_r=learn_r0 #动量参数 train_a0=learn_r0*1.2 train_a=train_a0 expect_e=0.05 #对输入数据进行预处理 ann_max=[] for m_ani in xrange(0,warray_txn): #找出训练数据中每一项的最大值 temp_x=np.array(train_x) ann_max.append(np.max(temp_x[:,m_ani])) ann_max=np.array(ann_max) def getnowsx(mysx,in_w): '''''生成本次的扩维输入数据 ''' '''''mysx==>输入数据,in_w==>权值矩阵,每一列为一个神经元的权值向量''' global warray_n mysx=np.array(mysx) x_end=[] for i in xrange(0,warray_n): x_end.append(np.dot(mysx,in_w[:,i])) return x_end def get_inlw(my_train_max,w_count,myin_x): '''''找出权值矩阵均值接近0,输出结果方差接近1的权值矩阵''' #对随机生成的多个权值进行优化选择,选择最优的权值 global warray_txn global warray_n mylw=[] y_in=[] #生成测试权值 mylw=np.random.rand(w_count,warray_txn,warray_n) for ii in xrange (0,warray_txn): mylw[:,ii,:]=mylw[:,ii,:]*1/float(my_train_max[ii])-1/float(my_train_max[ii])*0.5 #计算输出 for i in xrange(0,w_count): y_in.append([]) for xj in xrange(0,len(myin_x)): y_in[i].append(getnowsx(myin_x[xj],mylw[i])) #计算均方差 mymin=10**5 mychoice=0 for i in xrange(0,w_count): myvar=np.var(y_in[i]) if abs(myvar-1)<mymin: mymin=abs(myvar-1) mychoice=i #返回数据整理的权值矩阵 return mylw[mychoice] mylnww=get_inlw(ann_max,300,train_x) def get_inputx(mytrain_x,myin_w): '''''将训练数据经过权值矩阵,形成扩维数据''' end_trainx=[] for i in xrange(0,len(mytrain_x)): end_trainx.append(getnowsx(mytrain_x[i],myin_w)) return end_trainx x=get_inputx(train_x,mylnww)#用于输入的扩维数据 #对测试数据进行扩维 def get_siminx(sim_x): global mylnww myxx=np.array(sim_x) return get_inputx(myxx,mylnww) #计算一层的初始化权值矩阵 def getlevelw(myin_x,wo_n,wi_n,w_count): mylw=[] y_in=[] #生成测试权值 mylw=np.random.rand(w_count,wi_n,wo_n) mylw=mylw*2.-1 #计算输出 for i in xrange(0,w_count): y_in.append([]) for xj in xrange(0,len(myin_x)): x_end=[] for myii in xrange(0,wo_n): x_end.append(np.dot(myin_x[xj],mylw[i,:,myii])) y_in[i].append(x_end) #计算均方差 mymin=10**3 mychoice=0 for i in xrange(0,w_count): myvar=np.var(y_in[i]) if abs(myvar-1)<mymin: mymin=abs(myvar-1) mychoice=i #返回数据整理的权值矩阵 csmylw=mylw[mychoice] return csmylw,y_in[mychoice] ann_w=[] def init_annw(): global x global hidelevel_count global warray_n global d global ann_w ann_w=[] lwyii=np.array(x) #初始化每层的w矩阵 for myn in xrange(0,hidelevel_count): #层数 ann_w.append([]) if myn==hidelevel_count-1: for iii in xrange(0,warray_n): ann_w[myn].append([]) for jjj in xrange(0,warray_n): ann_w[myn][iii].append(0.0) elif myn==hidelevel_count-2: templw,lwyii=getlevelw(lwyii,len(d[0]),warray_n,200) for xii in xrange(0,warray_n): ann_w[myn].append([]) for xjj in xrange(0,len(d[0])): ann_w[myn][xii].append(templw[xii,xjj]) for xjj in xrange(len(d[0]),warray_n): ann_w[myn][xii].append(0.0) else: templw,lwyii=getlevelw(lwyii,warray_n,warray_n,200) for xii in xrange(0,warray_n): ann_w[myn].append([]) for xjj in xrange(0,warray_n): ann_w[myn][xii].append(templw[xii,xjj]) ann_w=np.array(ann_w) def generate_lw(trycount): global ann_w print u"产生权值初始矩阵", meanmin=1 myann_w=ann_w alltry=30 tryc=0 while tryc<alltry: for i_i in range(trycount): print ".", init_annw() if abs(np.mean(np.array(ann_w)))<meanmin: meanmin=abs(np.mean(np.array(ann_w))) myann_w=ann_w tryc+=1 if abs(np.mean(np.array(myann_w)))<0.008:break ann_w=myann_w print print u"权值矩阵平均:%f"%(np.mean(np.array(ann_w))) print u"权值矩阵方差:%f"%(np.var(np.array(ann_w))) generate_lw(15) #前次训练的权值矩阵 ann_oldw=copy.deepcopy(ann_w) #梯度初始化 #输入层即第一层隐藏层不需要,所以第一层的空间无用 ann_delta=[] for i in xrange(0,hidelevel_count): ann_delta.append([]) for j in xrange(0,warray_n): ann_delta[i].append(0.0) ann_delta=np.array(ann_delta) #输出矩阵yi初始化 ann_yi=[] for i in xrange(0,alllevel_count): #第一维是层数,从0开始 ann_yi.append([]) for j in xrange(0,warray_n): #第二维是神经元 ann_yi[i].append(0.0) ann_yi=np.array(ann_yi) #输出层函数 def o_func(myy): myresult=[] mymean=np.mean(myy) for i in xrange(0,len(myy)): if myy[i]>=mymean: myresult.append(1.0) else: myresult.append(0.0) return np.array(myresult) def get_e(myd,myo): return np.array(myd-myo) def ann_atanh(myv): atanh_a=1.7159#>0 atanh_b=2/float(3)#>0 temp_rs=atanh_a*np.tanh(atanh_b*myv) return temp_rs def ann_delta_atanh(myy,myd,nowlevel,level,n,mydelta,myw): anndelta=[] atanh_a=1.7159#>0 atanh_b=2/float(3)#>0 if nowlevel==level: #输出层 anndelta=(float(atanh_b)/atanh_a)*(myd-myy)*(atanh_a-myy)*(atanh_a+myy) else: #隐藏层 anndelta=(float(atanh_b)/atanh_a)*(atanh_a-myy)*(atanh_a+myy) temp_rs=[] for j in xrange(0,n): temp_rs.append(sum(myw[j]*mydelta)) anndelta=anndelta*temp_rs return anndelta def sample_train(myx,myd,n,sigmoid_func,delta_sigfun): '''''一个样本的前向和后向计算''' global ann_yi global ann_delta global ann_w global ann_wj0 global ann_y0 global hidelevel_count global alllevel_count global learn_r global train_a global ann_oldw level=hidelevel_count allevel=alllevel_count #清空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 #清空delta矩阵 for i in xrange(0,hidelevel-1): for j in xrange(0,n): ann_delta[i][j]=0.0 delta=ann_delta #保留W的拷贝,以便下一次迭代 ann_oldw=copy.deepcopy(ann_w) oldw=ann_oldw #前向计算 #对输入变量进行预处理 myo=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 #计算误差与均方误差 myo=yi[hidelevel-1][:len(myd)] myo_end=yi[alllevel-1][:len(myd)] mymse=get_e(myd,myo_end) #反向计算 #输入层不需要计算delta,输出层不需要计算W #计算delta for nowlevel in xrange(level-1,0,-1): if nowlevel==level-1: mydelta=delta[nowlevel] my_n=len(myd) else: mydelta=delta[nowlevel+1] my_n=n myw=ann_w[nowlevel] if nowlevel==level-1: #输出层 mydelta=delta_sigfun(myo,myd,None,None,None,None,None) ## mydelta=mymse*myo elif nowlevel==level-2: #输出隐藏层的前一层,因为输出结果和前一层隐藏层的神经元数目可能存在不一致 #所以单独处理,传相当于输出隐藏层的神经元数目的数据 mydelta=delta_sigfun(yi[nowlevel],myd,nowlevel,level-1,my_n,mydelta[:len(myd)],myw[:,:len(myd)]) else: mydelta=delta_sigfun(yi[nowlevel],myd,nowlevel,level-1,my_n,mydelta,myw) delta[nowlevel][:my_n]=mydelta #计算与更新权值W for nowlevel in xrange(level-1,0,-1): #每个层的权值不一样 if nowlevel==level-1: #输出层 my_n=len(myd) mylearn_r=learn_r*0.8 mytrain_a=train_a*1.6 elif nowlevel==1: #输入层 my_n=len(myd) mylearn_r=learn_r*0.9 mytrain_a=train_a*0.8 else: #其它层 my_n=n mylearn_r=learn_r mytrain_a=train_a pre_level_myy=yi[nowlevel-1] pretrain_myww=oldw[nowlevel-1] pretrain_myw=pretrain_myww[:,:my_n] #第二个调整参数 temp_i=[] for i in xrange(0,n): temp_i.append([]) for jj in xrange(0,my_n): temp_i[i].append(mylearn_r*delta[nowlevel,jj]*pre_level_myy[i]) temp_rs2=np.array(temp_i) temp_rs1=mytrain_a*pretrain_myw #总调整参数 temp_change=temp_rs1+temp_rs2 my_ww=ann_w[nowlevel-1] my_ww[:,:my_n]+=temp_change return mymse def train_update(level,nowtraincount,sigmoid_func,delta_sigfun): '''''一次读取所有样本,然后迭代一次进行训练''' #打乱样本顺序 global learn_r global train_a global train_a0 global learn_r0 global r global x global d global maxtrycount global oldmse x_n=len(x) ids=range(0,x_n) train_ids=[] sample_x=[] sample_d=[] while len(ids)>0: myxz=random.randint(0,len(ids)-1) train_ids.append(ids[myxz]) del ids[myxz] for i in xrange(0,len(train_ids)): sample_x.append(x[train_ids[i]]) sample_d.append(d[train_ids[i]]) sample_x=np.array(sample_x) sample_d=np.array(sample_d) #读入x的每个样本,进行训练 totalmse=0.0 mymse=float(10**-10) for i in xrange(0,x_n): mymse=sample_train(sample_x[i],sample_d[i],warray_n,sigmoid_func,delta_sigfun) totalmse+=sum(mymse*mymse) totalmse=np.sqrt(totalmse/float(x_n)) print u"误差为:%f" %(totalmse) nowtraincount[0]+=1 learn_r=learn_r0/(1+float(nowtraincount[0])/r) train_a=train_a0/(1+float(nowtraincount[0])/r) if nowtraincount[0]>=maxtrycount: return False,True,totalmse elif totalmse<expect_e: #(totalmse-oldmse)/oldmse>0.1 and (totalmse-oldmse)/oldmse<1: print u"训练成功,正在进行检验" totalmse=0.0 for i in xrange(0,x_n): mytemper=(sample_d[i]-simulate(sample_x[i],sigmoid_func,delta_sigfun)) totalmse+=sum(mytemper*mytemper) totalmse=np.sqrt(totalmse/float(x_n)) if totalmse<expect_e: return False,False,totalmse oldmse=totalmse return True,False,totalmse def train(): '''''训练样本,多次迭代''' global hidelevel_count nowtraincount=[] nowtraincount.append(0) #sigmoid函数指定 delta_sigfun=ann_delta_atanh sigmoid_func=ann_atanh tryerr=0 while True: print u"-------开始第%d次训练---------"%(nowtraincount[0]+1), iscontinue,iscountout,mymse=train_update(hidelevel_count,nowtraincount,sigmoid_func,delta_sigfun) if not iscontinue: if iscountout : print u"训练次数已到,误差为:%f"%mymse tryerr+=1 if tryerr>3: break else: print u"训练失败,重新尝试第%d次"%tryerr nowtraincount[0]=0 generate_lw(15+tryerr*2) else: print u"训练成功,误差为:%f"%mymse break 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) level=hidelevel_count allevel=alllevel_count #清空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 #前向计算 myo=np.array([]) 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 return yi[alllevel-1,:len(myd)] train() delta_sigfun=ann_delta_atanh sigmoid_func=ann_atanh for xn in xrange(0,len(x)): if simulate(x[xn],sigmoid_func,delta_sigfun)[0]>0: plt.plot(train_x[xn][0],train_x[xn][1],"bo") else: plt.plot(train_x[xn][0],train_x[xn][1],"b*") temp_x=np.random.rand(20)*10 temp_y=np.random.rand(20)*20+temp_x myx=temp_x myy=temp_y plt.subplot(111) x_max=np.max(myx)+5 x_min=np.min(myx)-5 y_max=np.max(myy)+5 y_min=np.min(myy)-5 plt.xlim(x_min,x_max) plt.ylim(y_min,y_max) for i in xrange(0,len(myx)): test=get_siminx([[myx[i],myy[i]]]) if simulate(test,sigmoid_func,delta_sigfun)[0]>0: plt.plot(myx[i],myy[i],"ro") else: plt.plot(myx[i],myy[i],"r*") plt.show()
图中蓝色是训练数据,红色是测试数据,圈圈代表类型[1,0],星星代表类型[0,1]。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍python机器学习之神经网络(一),包括了python机器学习之神经网络(一)的使用技巧和注意事项,需要的朋友参考一下 python有专门的神经网络库,但为了加深印象,我自己在numpy库的基础上,自己编写了一个简单的神经网络程序,是基于Rosenblatt感知器的,这个感知器建立在一个线性神经元之上,神经元模型的求和节点计算作用于突触输入的线性组合,同时结合外部作用的偏置,对若干
人工神经网络指由大量的神经元互相连接而形成的复杂网络结构。以人的视觉系统为例,人的视觉系统的信息处理是分级的,高层的特征是低层特征的组合,从低层到高层的特征表示越来越抽象,越来越能表达语义或者意图。人工神经网络提出最初的目的是为了模拟生物神经网络传递和处理信息的功能。它按照一定规则将许多神经元连接在一起,并行的处理外接输入信息。人工神经网络的每一层都有若干神经元并用可变权重的有向弧连接,具体训练过程是通过多次迭代对已知信息的反复学习并调整改变神经元的连接权重。
本文向大家介绍什么是机器学习中的神经网络?,包括了什么是机器学习中的神经网络?的使用技巧和注意事项,需要的朋友参考一下 神经网络可以理解为试图模仿人脑工作的隐藏层,输入层和输出层的网络。 隐藏的层可以可视化为输入数据本身的抽象表示。这些层借助其自身的内部逻辑帮助神经网络理解数据的各种特征。 这些神经网络是不可解释的模型。不可解释的模型是即使我们观察到隐藏层也无法解释或理解的模型。这是因为神经网络具
我正在建立一个分类神经网络,以便对两个不同的类进行分类。 所以这是一个二元分类问题,我正尝试用一个前馈神经网络来解决这个任务。 但是网络是不能学习的,事实上,在训练过程中,网络的精度是不变的。 具体而言,数据集由以下人员组成: 65673行22列。 其中一列是具有值(0,1)的目标类,而其他21列是预测器。数据集是这样平衡的: null 可以看到也有NaN值,但我不能删除它,因为在其他列中有值0是
神经网络和深度学习是一本免费的在线书。本书会教会你: 神经网络,一种美妙的受生物学启发的编程范式,可以让计算机从观测数据中进行学习 深度学习,一个强有力的用于神经网络学习的众多技术的集合 神经网络和深度学习目前给出了在图像识别、语音识别和自然语言处理领域中很多问题的最好解决方案。本书将会教你在神经网络和深度学习背后的众多核心概念。 想了解本书选择的观点的更多细节,请看这里。或者直接跳到第一章 开始
本文向大家介绍TensorFlow深度学习之卷积神经网络CNN,包括了TensorFlow深度学习之卷积神经网络CNN的使用技巧和注意事项,需要的朋友参考一下 一、卷积神经网络的概述 卷积神经网络(ConvolutionalNeural Network,CNN)最初是为解决图像识别等问题设计的,CNN现在的应用已经不限于图像和视频,也可用于时间序列信号,比如音频信号和文本数据等。CNN作为一个深度