当前位置:   article > 正文

深度学习基础------前向传播与反向传播_前向传播和反向传播

前向传播和反向传播

当前,深度学习已经应用到很多领域:无人驾驶汽车,黑科技以及图像分类等等,这些前沿的科技也面临许多挑战,如无人驾驶汽车需要进行物体的检测、行人的检测、标志的识别以及速度识别等等;图像分类已经成为一项重要技术,它是计算机视觉的核心任务,其困难之处在于图像中物体形状的改变、部分遮蔽以及背景的混入等等。让机器学习人类模拟人类大脑的思考过程,需要进行大量的实验研究才能正式投入运行,即将大量的数据分为训练集、验证集以及测试集。

深度学习的过程可以分为前向传播和反向传播两个过程,前向传播。

简单来说,前向传播过程就是数据从输入层传入,经过隐藏层,最终到达输出层的过程。如下图所示,图中包含一个输入层,一个隐藏层和一个输出层。

对于第2层第1个节点的输出有:

对于第3层第1个节点的输出有:

而反向传播的核心在于复合函数的链式求导法则,反向传播的作用在于优化代价函数,这也是训练神经网络的目标。

加法节点

类似于2+3=5,将常数换成变量 x+y=z,如下图所示,就是一个简单的前向传播和反向传播过程(右边的图是对应反向传播过程):

 

 

乘法节点

以 z=x*y 为例,如下图所示,就是一个简单的前向传播和反向传播过程(右边的图是对应反向传播过程):

 

 加法的反向传播只是将上游的值传给下游,并不需要正向传播的输入信号。但是乘法的反向传播需要正向传播时的输入信号值。因此,实现乘法节点的反向传播时,要保存正向传播的输入信号。

从左向右进行计算是一种正方向上的传播,简称为正向传播 (forward propagation)。从右向左的传播称为反向传播 (backward propagation)。
计算图的反向传播:沿着与正方向相反的方向,乘上局部导数。
反向传播的计算顺序是:
将信号 E 乘以节点的局部导数 (∂ y/∂ x),然后将结果传递给下一个节点。这里所说的局部导数是指正向传播中y = f (x) 的导数,也就是 y 关于 x 的导数(∂ y/∂ x)。如 y = f ( x ) = x^2 则局部导数为(∂ y/∂ x) = 2x。把这个局部导数乘以 E,然后传递给前面的节点。这就是反向传播的计算顺序。通过这样的计算,可以高效地求出导数的值,这是反向传播的要点。

 z=f(x,y) 求偏导数:

1)加法的偏导数

 

2)乘法的偏导数

  

举个例子:将乘法和加法组合起来。
物品a的单价是5,数量是8
物品b的单价是6,数量是5
物品的总价是多少?
5×8 + 6×5 = 70
代码如下:

  1. class multiplication_layer:
  2. def __init__(self):
  3. self.x = None
  4. self.y = None
  5. def forward(self, x, y):
  6. self.x = x
  7. self.y = y
  8. out = x * y
  9. return out
  10. def backward(self, d_out):
  11. d_x = d_out * self.y
  12. d_y = d_out * self.x
  13. return d_x, d_y
  14. class addition_layer:
  15. def __init__(self):
  16. pass
  17. def forward(self, x, y):
  18. out = x + y
  19. return out
  20. def backward(self, d_out):
  21. d_x = d_out * 1
  22. d_y = d_out * 1
  23. return d_x, d_y
  24. a_price = 5
  25. a_num = 8
  26. b_price = 6
  27. b_num = 5
  28. # layer
  29. a_layer = multiplication_layer()
  30. b_layer = multiplication_layer()
  31. c_layer = addition_layer()
  32. # forward
  33. a_price = a_layer.forward(a_price, a_num) # (1)
  34. b_price = b_layer.forward(b_price, b_num) # (2)
  35. totoal_price = c_layer.forward(a_price, b_price) # (3)
  36. # backward
  37. d_price = 1
  38. d_a_price, d_b_price = c_layer.backward(d_price) # (3)
  39. d_b, d_b_num = b_layer.backward(d_b_price) # (2)
  40. d_a, d_a_num = a_layer.backward(d_a_price) # (1)
  41. print("totoal_price:", (totoal_price))
  42. print("d_a:", d_a)
  43. print("d_a_num:", (d_a_num))
  44. print("d_b:", d_b)
  45. print("d_b_num:", (d_b_num))
  46. # totoal_price: 70
  47. # d_a: 5
  48. # d_a_num: 8
  49. # d_b: 6
  50. # d_b_num: 5

z=(x+y)^2 由两个式子构成:z = t^2 和 t = x+y

简单实现一个全连接层的前向传播和反向传播
全连接层是fully connected layer,类似的名词是affine或者linear

Y = W X + B

  1. import numpy as np
  2. N=1
  3. X= np.random.random((N,2))
  4. W= np.random.random((2,3))
  5. B= np.random.random((3,))
  6. Y = np.dot(X, W) + B
  7. print(Y)

 

  1. import numpy as np
  2. class fully_connected_layer:
  3. def __init__(self,W, B):
  4. self.X = None
  5. self.W = W
  6. self.B = B
  7. self.dx = None
  8. self.dw = None
  9. self.db = None
  10. def forward(self, input):
  11. self.X = input
  12. out = np.dot(self.X, self.W) + self.B
  13. return out
  14. def backward(self, d_out):
  15. self.dx = np.dot(d_out, self.W.T)
  16. self.dw = np.dot(self.X.T,d_out)
  17. self.db = np.sum(d_out, axis=0)
  18. return self.dx
  19. np.random.seed(2020)
  20. N=2
  21. input= np.random.random((N,2))
  22. weight= np.random.random((2,3))
  23. bias= np.random.random((3,))
  24. print(input.shape)
  25. print("input=\n",input)
  26. print(weight.shape)
  27. print("weight=\n",weight)
  28. print(bias.shape)
  29. print("bias=\n",bias)
  30. linear = fully_connected_layer(W=weight,B=bias)
  31. out = linear.forward(input)
  32. print("out=\n",out)
  33. d_out= np.random.random(out.shape)
  34. dx = linear.backward(d_out)
  35. dw = linear.dw
  36. db = linear.db
  37. print("dx=\n",dx)
  38. print("dw=\n",dw)
  39. print("db=\n",db)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/405512
推荐阅读
相关标签
  

闽ICP备14008679号