cs231n--反向传播

原博客:https://blog.csdn.net/sinat_36458870/article/details/82824529(此处只做学习记录用)

回顾上次的内容,其实就会发现,虽然我们构造好了损失函数,可以简单使用导数的定义解决损失函数优化问题,但是并不高效。

1. 该课程,主要是

  • 反向传播形成直观而专业的理解
  • 利用链式法则递归计算表达式的梯度
  • 理解反向传播过程及其优点。

如果你想:理解、实现、设计和调试神经网络,请再看一遍。

目的:给出f(x)(x是输入数据的向量),计算f(x).

2. 通过简单表达式理解梯度

先看看二元乘法函数:

f(x,y)=xy, 求一下偏导数

f(x,y)=xydf/dx=y   df/dy=x

啥意思呢?

请记住导数的意义:函数变量在某个点周围的很小区域内变化,而导数就是-->变量变化导致的函数在该方向上的变化率

df(x)​/dlim(h-->0) (f(x+h)f(x)) / h

等同于:

f(x)=lim(h-->0) (f(x+h)f(x)) / h

官方解释:若x = 4, y=-3, 则f(x,y) = -12,

x的导数f/x=3,意思就是x变大多少,表达式值就会变小三倍,变形看看!!!

f(x+h) = f(x) + h· df(x)/dx

导数说明了你有多敏感。

3. 链式法则计算复合函数

比如复合函数:f(x,y,z) = (x+y)z

∂f/ ∂x = (∂f/ ∂q) · (∂q/∂x)

两个梯度数值相乘就好了,简单吧,链式法则示例代码如下:

x = -2;
y=5;
z = -4

# Forward propogation
q = x + y    # q becomes 3
f = q * z    # f becomes -12

# Backward propogation
# 函数整体法: f = q * z

dfdz = q    # df/dz = q,  z的梯度是3
dfdq = z    # df/dq = z, q的梯度是-4

# return到 q = x + y
dfdx = 1.0 * dfdq      # dq/dx = 1. 链式法则核心就是乘, 整体思想
dfdy = 1.0 * dfdq     # dq/dy = 1

看看计算流是怎么样子的:

前向传播是输入到输出绿色,反向传播链式法则计算梯度是红色。

4. 如何理解反向传播

其实就是一个局部过程,每经过一个“神经元” -- “节点”, 可以得到两个东东:

1. 此节点的输出信息
2. 局部梯度

通过q = x + y 加法部分 (类似电路中的门): 输入【-2, 5】, 输出【3】,其实你可以把整个过程想象成一个水流。

 

5. 模块化: sigmoid

几乎任何微分的函数都可以看作门,不是门组合就是门拆分,看一个表达式:

f(w,x)=1 / (1+e(w0*​x0+w1*​x1+w2))     # 这条是sigmoid函数

如果只看做一个简单的输入为x和w, 输出为一个值。

这个函数包含许多门,有加法、乘法、取最大值门,以及四种:

 

 

其中, fc 使用对输入值进行了常量c的平移,fa将输入值扩大了a倍。

我们看作一元门,因为要计算c, a的梯度。整个计算流如下:

 

我们使用sigmoid函数的二维神经元例子: 输入[ x0, x1] 得到权重[w0, w1, w2]

sigmoid函数也叫做:σ(x),其导数就是这样求的:

例子: sigmoid输入为1.0, 则有输出0.73, 那么局部梯度为(1-0.73) * 0.73 ~= 0.2

实际情况就是封装到:一个单独的门单元中,实现代码:

w = [2, -3, -3]  # 随机的初始值
x = [ -1, -2]

# 前向传播
dot = w[0] * x[0]  + w[1] * x[1] + w[2]
f = 1.0 / (1 + math.exp(-dot))      # sigmoid


# 对神经元反向传播
ddot = (1 -f)  * f   # sigmoid函数求导
dx = [w[0]   * ddot,  w[1]  * ddot]    # 回传到x
dw = [x[0]  * ddot, x[1]  * ddot]  #回传到w

# Done

Hint: 分段反向传播为了使反向传播更简单,因此把前向传播分成几个阶段。

原文地址:https://www.cnblogs.com/elitphil/p/12250098.html