1.正向传播
1)创建节点所需要的标号node_index,输出output,计算所需权重weight_vector
2)将两层间不同神经网络节点连接线上的权重赋给当前计算节点所需要的权重weight_vector
3)按照公式计算输出(其中包括了relu的计算)
ps:以下代码可以理解为计算了的值
# -*- coding: UTF-8 -*-
import os
#创建一个节点
class Node(object):
def __init__(self,node_index):
self.node_index = node_index #节点索引
self.output = 0.0 #节点输出
self.weight_vector = [] #节点前向连接的权重向量
def cal_output(self,bias,input_x_vector):
check_input_weight_vector = Except(self.weight_vector,input_x_vector)
check_input_weight_vector.EQ_input_weight() #异常检测
for w_index in range(len(self.weight_vector)): #计算
self.output = self.weight_vector[w_index] * input_x_vector[w_index] + self.output
self.output = self.sigmoid(self.output+bias)
def sigmoid(self,value): #relu
if value<0:
self.value = 0
else:
self.value = value
return self.value
def set_weight_vector(self,weight_vector): #将上层所有节点与当前节点连接线上的权重赋给当前节点
for w in weight_vector:
self.weight_vector.append(w)
class Except(object):
def __init__(self,vec0,vec1):
self.vec0 = vec0
self.vec1 = vec1
def EQ_input_weight(self):
if type(self.vec0)!=type(self.vec1):
raise "input vector type is different with weight vector type!"
if len(self.vec0)!=len(self.vec1):
raise "the length of input vector is not equal to the length of weight type!"
class Connection(object):
def __init__(self,con_index,weight):
self.con_index = con_index
self.weight = weight
if __name__=="__main__":
#前向传播---固定输入,连接权重,以计算节点4输出为例
b = 3
X = [-0.1,0.4,5]
con40 = Connection(0,0.1)
con41 = Connection(1,0.2)
con42 = Connection(2,-0.4)
node4_input_weight_vec = [con40.weight,con41.weight,con42.weight]
print(node4_input_weight_vec)
node4 = Node(0)
node4.set_weight_vector(node4_input_weight_vec)
print(node4.weight_vector)
node4.cal_output(b,X)
print(node4.output)
2、反向传播
1)计算输出层节点梯度:
以输出层节点8和节点9为例:
2)计算隐藏层节点梯度:
以隐藏层节点4为例:
3)权重更新:
更新节点4与节点8、节点9之间的权重:
# -*- coding: UTF-8 -*-
import os
class Back_propagation(object):
def __init__(self,target=0.0):
self.target = target
self.delta_output_layer = 0.0
self.delta_hidden_layer = 0.0
#输出层delta = y_i*(1-y_i)*(target_i-y_i)
def _derivative_output_layer(self,y):
self.delta_output_layer = y*(1-y)*(self.target-y)
#隐藏层delta = a(1-a)*(w_j0*delta_0+w_j1*delta_1+……)
def _derivative_hidden_layer(self,a,node_connect_weight,node_connect_delta):
check_node_next_connect = Except(node_connect_delta,node_connect_weight)
check_node_next_connect.EQ_vector()
temp = 0.0
for next_index in range(len(node_connect_delta)):
temp = temp + node_connect_delta[next_index]*node_connect_weight[next_index]
self.delta_hidden_layer = a*(1-a)*temp
def update_weight(self,lr,a,weight_vector,delta_vector):
for index in range(len(weight_vector)):
weight_vector[index] = weight_vector[index] + lr*delta_vector[index]*a
return weight_vector
if __name__=="__main__":
#反向传播---先固定一个输出层节点8和9的目标、输出和隐藏层其中一个节点(比如隐藏层节点4)连接权重
output_layer_node8_target = 0.0
output_layer_node9_target = 1.0
output_layer_node8_y = 0.8
output_layer_node9_y = 0.6
node4_next_connect_weight_vector=[0.2,0.4]
back_propagation_node8 = Back_propagation(output_layer_node8_target)
back_propagation_node8._derivative_output_layer(output_layer_node8_y)
back_propagation_node9 = Back_propagation(output_layer_node9_target)
back_propagation_node9._derivative_output_layer(output_layer_node9_y)
node4_connect_delta_vector = [back_propagation_node8.delta_output_layer,back_propagation_node9.delta_output_layer]
print(node4_connect_delta_vector)
back_propagation_node4 = Back_propagation()
node4_a = node4.output
back_propagation_node4._derivative_hidden_layer(node4_a,node4_next_connect_weight_vector,node4_connect_delta_vector)
print(back_propagation_node4.delta_hidden_layer)
lr_rate = 0.01
node4_next_connect_weight_vector = back_propagation_node4.update_weight(lr_rate,node4_a,node4_next_connect_weight_vector,node4_connect_delta_vector)
print(node4_next_connect_weight_vector)