机器学习算法python实现【2】--ForwardPass&BackPropagation

我们前面已经谈到,在构建一个网络时,主要的思路可以分为两部分:

Loop:{

  前向传播——计算结果,得到loss_function

反向传播——逐层计算梯度,调整参数数值

}until convergence


今天我们来添加构建网络的最后一块砖石:前向和反向传播算法实现

之前我们讲过了梯度下降,是一种优化方法,用它来优化损失函数。至于损失函数的选择,各种教程都有说明.....不管是cross_entropy, SVM, softmax......选一个适合的就好


OK,前传和后传都是基于一种叫做computation graph的计算模型,大概就是以下这个样子:

机器学习算法python实现【2】--ForwardPass&BackPropagation_第1张图片

有种门电路的感觉,事实上也是这样。这里我们暂时可以称每一个节点为一个门(gate),在网络中我们更喜欢叫他层(layer),因为是一个复合门。OK,我们看到的绿色为前传的数值,红色为后传的梯度。现在我们从后往前看,它遵循偏导数的chain rule

,大致规则如下:

1.从输出传到最后一个门的grad是1 ,say, df/df

2.向后传给下一个门的grad = grad(前)*对该门的导数

因此可以把这个看成一个整体(back时):


它传入的grad0 == 1,那么向上一个门传出的grad1 = grad0 * [d(1/x)/dx],代入值就行,发现它正向向前传出的值是0.73,为1/x的值,而导数为-(1/x)**2,代入即可。grad1 = 1*(-1/0.73**2),就是-0.53

 

同理,去看上一个,它反馈给前一个的梯度grad2=grad1*1=-0.53


就是这样,逐级去计算。

注意:

1.每个节点需要有记忆功能,记住流过它的变量是什么,传出的值是什么,因为接下来后传需要。记忆功能在TF里自动实现。

2.基本三种门:

ADD_gate: 将grad原封不动分配到下级每个门

MUL_gate: 交换下层两个门的传出值作为自己的grad

MAX_gate :  选择传出值大的那个门原封不动分配grad,另一个分配值为0

其他门根据实际情况计算


现在我要对一个函数分别进行前传和后传:

sigma是sigmoid函数

代码如下:

# a simple example of forward passing and back propagation
# f(x,y) = [x+sigmoid(y)]/sigmoid(x)+(x+y)**2
#stanford cs231n CNN page7
#forward passing & back propgation

import numpy as np

def forwardPass_backProp(x, y):
    #forward
    sigx = 1.0/1+np.exp(-x)
    sigy = 1.0/1+np.exp(-y)
    num = x+sigy
    xpy = x+y
    xpysqr = (x+y)**2
    den = sigx+xpysqr
    invden = 1.0/den
    f = num*invden
    #back
    d_num = invden  #step1: MUL_gate
    d_invden = num
      #first follow the stream of invden
    d_den = d_invden*(-1.0/(den**2))  #step2: 1/x_gate
    d_sigx = d_den  #step3: ADD_gate
    d_xpysqr = d_den
    d_xpy = (2*xpy)*d_xpysqr  #step4: x**2 gate
    d_x = d_xpy  #step5: ADD_gate
    d_y = d_xpy
    d_x += (1-sigx)*sigx*d_sigx  #step6: to sigx
      #then follow the stream of num
    d_x += d_num #step1: ADD_gate
    d_sigy = d_num
    d_y +=(1-sigy)*sigy*d_sigy

    return f, d_x, d_y

x = raw_input("input x")
x = int(x)
y = raw_input("input y")
y = int(y)
print forwardPass_backProp(x, y)  #return a tuple(x,y,z)
   注意对分支的处理。graph中是没有回路的。

这里x,y参与了多个门运算,因此最后梯度要分别相加。

这样我们就可以简单地搭一个神经网络了,而不是一个简单的感知器~~


天空鱼

Every Machine Owns a ❤

你可能感兴趣的:(机器学习算法python实现【2】--ForwardPass&BackPropagation)