您的位置:首页 > 理论基础 > 计算机网络

小白学习机器学习---第五章:神经网络简单模型python实现

2018-03-29 15:17 1046 查看
简单的单隐层神经网络实现,需要注意的是,隐层的结点个数需要经过多次试验获得最佳参数,如果设置太多可能引起过拟合问题,目前就简单实现其原理。

import numpy as np

class BP_network:
def __init__(self):
###初始化变量###
###每一层的节点数
self.input_node=0 #输入层
self.hide_node=0 #隐层
self.output_node=0 #输出层

###初始化每一层的输出变量
self.input_out=[]
self.hide_out=[]
self.output_out=[]

###初始化输入层到隐层与隐层到输出层的权值
self.ih_weight=[]
self.ho_weight=[]

###初始化隐层与输出层的阈值
self.hide_threshold=[]
self.output_threshold=[]

####定义可选的激活函数与导数
self.fun={
'Sigmoid':Sigmoid,
'SigmoidDerivate':SigmoidDerivate
}

def CreateNN(self,ni,nh,no,actiFun):
"""
创建一个神经网络结构并且初始化参数
ni,nh,no为三层节点个数
actiFun:string,为激活函数

"""
###给各层节点数赋值
self.input_node=ni
self.hide_node=nh
self.output_node=no

###给各层输出的值赋初值
self.input_out=np.zeros(self.input_node) #赋0 [0,0,0.......,0]
self.hide_out=np.zeros(self.hide_node)
self.output_out=np.zeros(self.output_node)

###给两层之间的权值赋初值
self.ih_weight=np.zeros([self.input_node,self.hide_node])
self.ho_weight=np.zeros([self.hide_node,self.output_node])

####给所有权值赋初始值,(0,1)
for i in range(self.input_node):
for h in range(self.hide_node):
self.ih_weight[i][h]=rand(0,1)

for h in range(self.hide_node):
for j in range(self.output_node):
self.ho_weight[h][j]=rand(0,1)

###给阈值赋初始值(0,1)###
self.hide_threshold=np.zeros(self.hide_node)
self.output_threshold=np.zeros(self.output_node)

for h in range(self.hide_node):
self.hide_threshold[h]=rand(0,1)

for j in range(self.output_node):
self.output_threshold[j]=rand(0,1)

####初始化激活函数
self.activateFunc=self.fun[actiFun]
self.actiFuncDerivation=self.fun[actiFun+'Derivate']

def Predict(self,x):
###通过构造的神经网络预测结果
###参数x为一个list,保存input层的输入值

#激活输出层
for i in range(self.input_node):
self.input_out[i]=x[i]

#激活隐层
for h in range(self.hide_node):
total=0.0
for i in range(self.input_node):
total+=self.ih_weight[i][h]*self.input_out[i]
self.hide_out[h]=self.activateFunc(total-self.hide_threshold[h])

#激活输出层
for j in range(self.output_node):
total=0.0
for h in range(self.hide_node):
total+=self.ho_weight[h][j]*self.hide_out[h]
self.output_out[j]=self.activateFunc(total-self.output_threshold[j])
#return self.output_out#######################################3

def BackPropagate(self,x,y,learningRate):
"""
通过一个样本进行BP算法,
x与y是数组:输入与输出的数据集
learningRate:学习率

"""
#将样例输入进行预测
self.Predict(x)

#计算梯度

#计算Gj
o_gradient=np.zeros(self.output_node)
for j in range(self.output_node):
o_gradient[j]=(y[j]-self.output_out[j])*self.actiFuncDerivation(self.output_out[j])

#计算Eh
h_gradient=np.zeros(self.hide_node)
for h in range(self.hide_node):
for j in range(self.output_node):
h_gradient[h]+=self.ho_weight[h][j]*o_gradient[j]
h_gradient[h]=h_gradient[h]*self.actiFuncDerivation(self.hide_out[h])

###更新参数

#更新W hj
for h in range(self.hide_node):
for j in range(self.output_node):
self.ho_weight[h][j]+=learningRate*o_gradient[j]*self.hide_out[h]
#更新V ih
for i in range(self.input_node):
for h in range(self.hide_node):
self.ih_weight[i][h]+=learningRate*h_gradient[h]*self.input_out[i]

#更新θj
for j in range(self.output_node):
self.output_threshold[j]-=learningRate*o_gradient[j]

#更新γh
for h in range(self.hide_node):
self.hide_threshold[h]-=learningRate*h_gradient[h]

def TrainStandard(self,data_in,data_out,learningRate=0.05):
"""
标准BP算法

"""

#误差,list
E_k=[]
for k in range(len(data_in)):
x=data_in[k]
y=data_out[k]
self.BackPropagate(x,y,learningRate)

y_delta2=0
for j in range(self.output_node):
y_delta2+=(self.output_out[j]-y[j])*(self.output_out[j]-y[j])
E_k.append(y_delta2/2)

#训练总误差
error=sum(E_k)/len(E_k)
return error,E_k

def PredictLabel(self,X):
#通过神经网络预测结果

y=[]
for m in range(len(X)):
self.Predict(X[m])
if(self.output_out[0]>0.5):
y.append(1)
else:
y.append(0)

return np.array(y)

def Sigmoid(x):
from math import exp
return 1.0/(1.0+exp(-x))

def SigmoidDerivate(y):
return y*(1-y)

def rand(a,b):
from random import random
return (b-a)*random()+a

if __name__=='__main__':
from sklearn.datasets import make_circles
import matplotlib.pyplot as plt

X,y=make_circles(100,noise=0.05)#不设置noise则会围成一个标准的椭圆

"""
X : array of shape [n_samples, The generated samples.
y : array of shape [n_samples]
The integer labels (0 or 1) for class membership of each sample.
noise:Standard deviation of Gaussian noise added to the data. Double or None(default=none)
"""
f1=plt.figure(1)
plt.scatter(X[:,0],X[:,1],s=40,c=y)
# plt.scatter(0,0.5,s=50,c='red')
plt.title("circles data")

#plt.show()

#BP实现

nn=BP_network()
nn.CreateNN(2,6,1,'Sigmoid')

e=[]
for i in range(2000):
err,err_k=nn.TrainStandard(X,y.reshape(len(y),1),learningRate=0.1)
e.append(err)
print(len(e))
f2=plt.figure(2)
plt.xlabel("epochs")
plt.ylabel("accumulated error")
plt.title("circles convergence curve")

plt.plot(e)
plt.show()
predictResult=nn.PredictLabel(X)
accuracy=0
for i in range(len(y)):
t=predictResult[i]
#print(t,y[i])
if(t==y[i]):
accuracy+=1
print("accuracy:%d %%"%(accuracy))最后结果:





效果还是不错的,神经网络太强大了,我更佩服哪位率先将生物中的MP-神经元模型引入机器学习的,脑洞有点大~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: