BP过程中,更新公式长什么样?

众所周知,BP过程中通过权值的不断更新,使得神经网络的输出向groundtruth靠近。

开门见山,直接看图,这部分是为==后面==做铺垫,很简单昂~

1

我们随机给输入a,b添加一个随机值,然后用步长step来控制增加速度,看python代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import random

def multiply(a, b):
return a * b

def func():
a = 5
b = 6
step = 0.01
a = a + step * (random.random())
b = b + step * (random.random())
print(multiply(a, b))

func()

运行程序,输出30.023996846498836,比30大,但是如果继续测试,会出现问题,速看如下代码:

1
2
3
4
5
6
7
8
9
def func():
a = -5
b = -6
step = 0.01
a = a + step * (random.random())
b = b + step * (random.random())
print(multiply(a, b))

func()

运行程序,输出29.982885896252554,比30小,把输入a,b改成负数就失效了,所以对于step后面乘的系数,应该找一个和输入相关的值来控制,也就是一个关于输入值的函数。如果在这个点上,输出结果是随着输入值增加而增加,那么step乘以一个正数即可,反之,则需要乘以一个负数才能使输出结果增加!显然这就是函数在某点上的==微分==(前文铺垫的就是他)的定义!

eg:对于f = f(a, b) ,我们想要更新变量a,b的值,就可以根据下图公式来更新

2

实际上这就是BP的最基本思想啦~假设f就是神经网络的输出,将f与groundtruth计算误差,让f变大(或变小),使其更接近groundtruth,我们将改变f的变量,而f其实是长这样的,f = f(w,b) . 只不过真正的神经网络更复杂。

进一步了解BP

接下来,我们将一步一步地接近最终的神经网络中的BP。

不废话,直接看图。

3

代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
def multiply(x, y):
return x * y

def addition(x, y):
return x + y

def forward(a, b, c):
d = addition(a, b)
return multiply(d, c)

print(forward(5, -6, 7))

输出结果为-7,现在开始训练,就是改变输入的a,b,c三个值,使函数f的值变大,那么就按照下图的方式更新。

更新公式

4

链式求导

现在问题就变成了如何求解f关于a,b,c的微分。
我们将f反着往回写,我们将第一个神经元的输出记作d,那么f = d *c , 继续反着推,d = a +b。这样就成了两个函数。如图:

5

下面开始链式求导,考过数学一二三的人最喜欢这个东西了。

6

继续,==不要停==:

7

然后最终结果如下:

8

反向传播代码实现

代码实现上述过程:

1
2
3
4
5
6
7
8
9
10
def multiply(x, y):
return x * y

def addition(x, y):
return x + y

def forward(a, b, c):
d = addition(a, b)
return multiply(d, c)
print(forward(5, -6, 7))

输出结果为-7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def update(a, b, c):
d = addition(a, b)
h = 0.01

derivative_f_d = c
derivative_f_c = d
derivative_d_a = 1
derivative_d_b = 1

derivative_f_a = derivative_f_d * derivative_d_a
derivative_f_b = derivative_f_d * derivative_d_b

a = a + h * derivative_f_a
b = b + h * derivative_f_b
c = c + h * derivative_f_c

d = addition(a, b)
return multiply(d, c)

print(update(5, -6, 7))

输出结果为-6.0113999999999965
可以看到更新之后的输出确实增大了,说明我们现在已经可以实现嵌套神经元的变量参数的更新了。

总结BP更新本质

首先,前向传播,从输入开始分析,输入值为a=5,b=-6,c=7,第一个神经元的输出d为-1,然后第二个神经元输出为7,最后结果为-7,这就是前向传播的过程。

然后,反向传播,从输出开始分析,目标是将输出变大,输出值是由-1*7得到的,现在要增加输出值,显然就是增加-1,减少7。再来计算微分,微分结果就是增加d,减少c。这里d又是由a,b决定的!那么只要增加a和b就行了,运用链式法则求a,b的微分,也能得到相同的结果。

我们倒着从输出到输入的过程就是反向传播的过程。通过计算微分可以更新变量的值,使得输出朝着我们期待的方向的变化!

好吃又简单的BP,到这里你就懂啦~