侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python机器学习之神经网络(二)

Python  /  管理员 发布于 7年前   163

由于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机器学习之神经网络(一)
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客