神经网络和反向传播
神经网络
![](https://i-blog.csdnimg.cn/blog_migrate/bc90786df05bb5cfd7ddbac3ae38414d.png)
如上图,是一个2层的神经网络,其中 h = m a x ( 0 , x ) h=max(0,x) h=max(0,x),函数 m a x ( 0 , x ) max(0,x) max(0,x) 称作激活函数(activation function),通过它引入了非线性。
几种常用的激活函数:
![](https://i-blog.csdnimg.cn/blog_migrate/dbcee81fcbf1e064d8ea2c1aa9179693.png)
神经网络的结构:
反向传播
链式法则
举例说明:
# set some inputs
x = -2; y = 5; z = -4
# perform the forward pass
q = x + y # q becomes 3
f = q * z # f becomes -12
# perform the backward pass (backpropagation) in reverse order:
# first backprop through f = q * z
dfdz = q # df/dz = q, so gradient on z becomes 3
dfdq = z # df/dq = z, so gradient on q becomes -4
# now backprop through q = x + y
dfdx = 1.0 * dfdq # dq/dx = 1. And the multiplication here is the chain rule!
dfdy = 1.0 * dfdq # dq/dy = 1
变量的梯度[dfdx,dfdy,dfdz]
告诉我们变量x,y,z
对f
的敏感性。
可视化:
模块化:Sigmoid示例
f ( w , x ) = 1 1 + e − ( w 0 x 0 + w 1 x 1 + w 2 ) f(w,x) = \frac{1}{1+e^{-(w_0x_0 + w_1x_1 + w_2)}} f(w,x)=1+e−(w0x0+w1x1+w2)1
具有sigmoid激活函数的2D神经元的示例电路。输入是 [x0,x1],(可学习的)神经元的权值是[w0,w1,w2]。神经元计算与输入的点积,然后它的激活被sigmoid函数柔化,使其在0到1的范围内。![]()
sigmoid函数以及对其输入的导数:
σ
(
x
)
=
1
1
+
e
−
x
→
d
σ
(
x
)
d
x
=
e
−
x
(
1
+
e
−
x
)
2
=
(
1
+
e
−
x
−
1
1
+
e
−
x
)
(
1
1
+
e
−
x
)
=
(
1
−
σ
(
x
)
)
σ
(
x
)
\sigma(x) = \frac{1}{1+e^{-x}} \\\\ \rightarrow \hspace{0.3in} \frac{d\sigma(x)}{dx} = \frac{e^{-x}}{(1+e^{-x})^2} = \left( \frac{1 + e^{-x} - 1}{1 + e^{-x}} \right) \left( \frac{1}{1+e^{-x}} \right) = \left( 1 - \sigma(x) \right) \sigma(x)
σ(x)=1+e−x1→dxdσ(x)=(1+e−x)2e−x=(1+e−x1+e−x−1)(1+e−x1)=(1−σ(x))σ(x)
某点梯度 = 上游梯度×局部梯度,即:
g
r
a
d
i
e
n
t
=
[
u
p
s
t
r
e
a
m
g
r
a
d
i
e
n
t
]
∗
[
l
o
c
a
l
g
r
a
d
i
e
n
t
]
gradient=[upstream\ gradient] * [local\ gradient]
gradient=[upstream gradient]∗[local gradient]
在上例中
- 正向传播:sigmoid表达式接收输入1.0并计算输出0.73。
- 反向传播:由sigmoid的局部梯度公式,局部梯度将简化为(1-0.73)* 0.73〜= 0.2,上游梯度为红框中的1,二者相乘得该点梯度。
该神经元的反向传播代码:
w = [2,-3,-3] # assume some random weights and data
x = [-1, -2]
# 前向传播
dot = w[0]*x[0] + w[1]*x[1] + w[2]
f = 1.0 / (1 + math.exp(-dot)) # sigmoid function
# 反向传播
ddot = (1 - f) * f # gradient on dot variable, using the sigmoid gradient derivation
dx = [w[0] * ddot, w[1] * ddot] # backprop into x
dw = [x[0] * ddot, x[1] * ddot, 1.0 * ddot] # backprop into w
# we're done! we have the gradients on the inputs to the circuit
注意:
缓存前向传播的变量。 要计算反向传播,拥有一些在前向传播中使用的变量非常有帮助。