机器学习入门--神经网络(正向传播,反向传播)

11 篇文章 0 订阅
7 篇文章 0 订阅

1.正向传播

1)创建节点所需要的标号node_index,输出output,计算所需权重weight_vector

2)将两层间不同神经网络节点连接线上的权重赋给当前计算节点所需要的权重weight_vector

3)按照公式output=weightvector*inputvector+bias计算输出(其中包括了relu的计算)

ps:以下代码可以理解为计算了a_{4}的值

# -*- 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)计算输出层节点梯度:\delta_i=y_i(1-y_i)(t_i-y_i)\qquad

以输出层节点8和节点9为例:\left\{\begin{matrix} \delta_8=y_1(1-y_1)(t_1-y_1)\\ \delta_9=y_2(1-y_2)(t_2-y_2) \end{matrix}\right.

2)计算隐藏层节点梯度:\delta_i=a_i(1-a_i)\sum_{k\in{outputs}}w_{ki}\delta_k\qquad

以隐藏层节点4为例:\delta_4=a_4(1-a_4)(w_{84}\delta_8+w_{94}\delta_9)

3)权重更新:w_{ji}\gets w_{ji}+\eta\delta_jx_{ji}\qquad

更新节点4与节点8、节点9之间的权重:\left\{\begin{matrix} w_{84}\gets w_{84}+\eta\delta_8 a_4\\ w_{94}\gets w_{94}+\eta\delta_9 a_4 \end{matrix}\right.

# -*- 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)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值