纯python代码实现反向传播神经网络
import numpy as np
def sigmod(z):
h=1./(1+np.exp(-z))
return h
def de_sigmoid(h):
return h*(1-h)
# dim in:输入特征的维度
# list_num hidden:每层输出节点的数目# list_actfuns:每层的激活函数
# list de act funs:反向传播时的函数
def bulid_net(dim_in,list_num_hidden,list_act_funs,list_de_act_funs):
layers=[]
#逐层的进行网络构建
for i in range (len(list_num_hidden)):
layer={}
#定义每一层的权重if i ==0 :
layer["w"]=0.2*np.random.randn(dim_in,list_num_hidden[i])-0.1
else:
layer["w"]=0.2*np.random.randn(list_num_hidden[i-1],list_num_hidden[i])-0.1
#定义每一层的偏置
layer["b"]=0.1*np.ones([1,list_num_hidden[i]])
layer["act_fun"]=list_act_funs[i]
layer["de_act_fun"]=list_de_act_funs[i]
layers.append(layer)
return layers
返回每一层的输入与最后一层的输出
def fead_forward(datas,layers):
input_layers=[]
for i in range(len(layers)):
layer=layers[i]
if i ==0:
inputs=datas
z=np.dot(inputs,layer["w"])+layer["b"]
h=layer['act_fun'](z)
input_layers.append(inputs)
else:
inputs=h
z=np.dot(inputs,layer["w"])+layer["b"]
h=layer['act_fun'](z)
input_layers.append(inputs)
return input_layers,h
进行参数更新更新
def updata_wb(datas,labs,layers, loss_fun,de_loss_fun ,alpha=0.01):
N,D=np.shape(datas)
进行前馈操作
inputs,output=fead_forward(datas,layers)计算loss
loss=loss_fun(output,labs)
deltas0=de_loss_fun(output,labs)
从后向前计算误差deltas=[]
for i in range(len(layers)):
index=-i-1
if i==0:
delta=deltas0*layers[index]["de_act_fun"](output)
else:
h=inputs[index+1]
delta=np.dot(delta,layers[index+1]["w"].T)*layers[index]["de_act_fun"](h)
deltas.insert(0,delta)
#利用误差对每一层的权重进行修成for i in range ( len ( layers)) :
#计算dw与db
for i in range(len(layers)):
dw=np.dot(inputs[i].T,deltas[i])
db=np.sum(deltas[i],axis=0,keepdims=True)#梯度下降
layers[i]["w"]=layers[i]["w"]-alpha*dw
layers[i]["b"]=layers[i]["b"]-alpha*db
return layers,loss
def test_accuracy(datas,labs_true,layers) :
_,output=fead_forward(datas,layers)
lab_det=np.argmax(output,axis=1)
labs_true=np.argmax(labs_true,axis=1)
N_error=np.where(np.abs(labs_true-lab_det)>0)[0].shape[0]
error_rate=Nerror/np.shape(datas)[0]
return error rate
def load dataset_iris(file_data,N_train) :
#数据读取
datas=np.loadtxt(file_data,dtype=np.float,delimiter=',',usecols=(0,1,2,3))
labs=np.loadtxt(file_data,dtype=str,delimiter=',',usecols=(4))
N,D=np.shape(datas)
N_test =N-N_train
unqiue_labs =np.unique(labs).tolist()
dic_str2index={}
dic_index2str={}
for i in range(len(unqiue_labs)):
lab_str=unqiue_labs[i]
dic_str2index[lab_str]=idic_index2str[i]=lab_str
labs_onehot=np.zeros([N,len(unqiue_labs)])
for i in range(N):
lbs_onehot[i,dic_str2index[labs[i]]]=1
perm=np.random.permutation(N)
index_train=perm[:N_train]
index_test=perm[N_train:]
data_train=datas[index_train,:]
lab_train_onehot=labs_onehot[index_train,:]
data_test=datas[index_test,:]
lab_test_onehot=labs_onehot[index_test]
return data_train,lab_train_onehot,data_test,lab_test_onehot,dic_index2str