由于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([])