神经网络是一个非线性算法,非线性就体现在激活函数上。通俗解释一下,Y = x * a * b * c (abc是常数)我们总可以找到一个d = a * b *c 但是如果 Y = ln(10 * sin(cos(x))) 并且我们规定只有cosx>0.5时,再进行sin() sin(cos(x))>0.1时再进行ln().就像生物的神经元,刺激达到一定的程度,再释放神经递质再传递给下一个神经元。
1. 神经网络能干什么?
线性回归和逻辑回归虽然可以解决简单问题但是不他能解决复杂的问题。我们假设用离散数学的与、或、非运算来描述下图,下面的四个球不能用一个运算给分类,所以单一的层不好使(图2),这种可以用两层的有两种运算得来的结果。[(!x
⋀
\bigwedge
⋀!y)
⋁
\bigvee
⋁(x
⋀
\bigwedge
⋀y)] x,y
∈
\in
∈(0,1) .这样的话我们可以设置两层网络来求解这个问题(图3)。神经网络可以说是有很多个逻辑回归而组成的网络(分层)。可以有强大的作用。
2. 神经网络简介
下面一段话解释了为什么需要反向传播
训练集的数据从输入层经过多个 权值矩阵 流向输出层,这时产生输出,与正确的Y 一比产生误差,这时我们可以根据这俩误差,根据梯度下降的道理修正Layer3与Layer4之间的权值(其实这一句表述并不准确,如果仅仅是根据梯度下降的道理去更新权值的话,我们就把输入层与输出层之间的全部当成一个权重矩阵,而不是分层的。失去了意义)。我们要想办法让输出层和隐藏层的 输出 和“应该的输出”有误差。因为如果隐藏层没误差,别说我们就是隐藏层也会感觉自己很棒,因为没误差,太完美了!!如果这样隐藏层的意义仅仅是W*a,啥有用的也没干,毫无意义。所以我们让输出层的误差让他向前传播到隐藏层。这样我们就可以更新输出层和隐藏层之间的权值,隐藏层之间的权值。这就引入了神经网络中非常重要的反向传播。其实神经网络可以概括为下面代码!
while(误差>设定值){
训练集正向传播到输出层与真实结果产生误差;
误差反向传播到各层(输入层除外,我们认为输入数据都是正确的);
各层根据误差修改权值;
if(迭代次数>设置值){
break;
}
}
3. 符号约定
-
输入的单个数据 输入的向量是m维的,有m个特征
x ⃗ = [ x 1 x 2 … x i … x m ] , i = 1 , 2 , … , m \vec{x}=\left[\begin{array}{llllll} x_{1} & x_{2} & \ldots & x_{i} & \ldots & x_{m} \end{array}\right], i=1,2, \ldots, m x=[x1x2…xi…xm],i=1,2,…,m -
{输出层}输出向量 输出的向量是n维的(分层n类)
y ⃗ = [ y 1 y 2 … y k … y n ] , k = 1 , 2 , … , n \vec{y}=\left[\begin{array}{llllll} y_{1} & y_{2} & \ldots & y_{k} & \ldots & y_{n} \end{array}\right], k=1,2, \ldots, n y=[y1y2…yk…yn],k=1,2,…,n -
L代表神经网络的层数,如上图代表L=4
-
l l l代表当前算到第几层
-
各层输出向量通式, s l s_{l} sl是L层神经元的数目
a ( l ) = [ a 1 ( l ) a 2 ( l ) … a j ( l ) … a s l ( l ) ] , j = 1 , 2 , … , s l a^{(l)}=\left[a_{1}^{(l)} \quad a_{2}^{(l)} \quad \ldots \quad a_{j}^{(l)} \quad \ldots \quad a_{s_{l}}^{(l)}\right], j=1,2, \ldots, s_{l} a(l)=[a1(l)a2(l)…aj(l)…asl(l)],j=1,2,…,sl -
z l z^{l} zl= a l − 1 a^{l-1} al−1* w l − 1 w^{l-1} wl−1(注:左侧权值)+b(注:偏置项)
我们这里是把Layer2左侧的连线(权值)成为 w 1 w^{1} w1 -
各层公式梳理
a ( 1 ) = x z ( 2 ) = W ( 1 ) a ( 1 ) + b 0 ( 2 ) a ( 2 ) = g ( z ( 2 ) ) z ( 3 ) = W ( 2 ) a ( 2 ) + b 0 ( 3 ) a ( 3 ) = g ( z ( 3 ) ) z ( 4 ) = W ( 3 ) a ( 3 ) + b 0 ( 4 ) a ( 4 ) = h Θ ( x ) = g ( z ( 4 ) ) g ( x ) = 1 1 + e − x \begin{array}{l} a^{(1)}=x \\ z^{(2)}=W^{(1)} a^{(1)}+b_{0}^{(2)} \\ a^{(2)}=g\left(z^{(2)}\right) \quad \\ z^{(3)}=W^{(2)} a^{(2)} +b_{0}^{(3)}\\ a^{(3)}=g\left(z^{(3)}\right)\\ z^{(4)}=W^{(3)} a^{(3)} +b_{0}^{(4)}\\ a^{(4)}=h_{\Theta}(x)=g\left(z^{(4)}\right)\\ g(x)=\frac{1}{1+e^{-x}} \end{array} a(1)=xz(2)=W(1)a(1)+b0(2)a(2)=g(z(2))z(3)=W(2)a(2)+b0(3)a(3)=g(z(3))z(4)=W(3)a(3)+b0(4)a(4)=hΘ(x)=g(z(4))g(x)=1+e−x1
4. 反向传播
我们这里介绍两种代价函数并给出推导过程
为了节省篇幅我们不求某一层的某一个单独的一个权值,而是直接按矩阵算。
- 吴恩达介绍的从逻辑回归中带来的(去除正则化项)
J = − 1 m [ ∑ i = 1 m ∑ k = 1 k y k ( i ) log ( h w ( x ( i ) ) ) k + ( 1 − y k ( i ) ) log ( 1 − ( h w ( x ( i ) ) ) k ) ] J=-\frac{1}{m}\left[\sum_{i=1}^{m} \sum_{k=1}^{k} y_{k}^{(i)} \log \left(h_{w}\left(x^{(i)}\right)\right)_{k}+\left(1-y_{k}^{(i)}\right) \log \left(1-\left(h_{w}\left(x^{(i)}\right)\right)_{k}\right)\right] J=−m1[i=1∑mk=1∑kyk(i)log(hw(x(i)))k+(1−yk(i))log(1−(hw(x(i)))k)]- 博文中常见的 J = 1 2 ( y − a L ) 2 J=\frac{1}{2}(y-a^{L})^{2} J=21(y−aL)2
4.1 吴恩达所讲的代价函数的推导过程
下面先介绍按吴恩达代价函数的推导过程(其实他俩推导思路一样,只是吴恩达的有些让人误解)先把上面的图拿下来看图来说。
我们想着更新Layer4左侧的权重矩阵,我们首先要算出L4的输出与真实的Y相差多少,然后才能依据这个去做下一步,这时,按1. 代价函数算一下吧,(太长了我们用C代替)。算好了,接下来我们想如何更新左侧权值的呢?就是梯度下降算法!我们来对他进行求偏导吧!Σ(っ °Д °;)っ代价函数中竟然没有
w
3
w^{3}
w3(左侧权值),那只能一层层拨开了!
J
(
w
)
=
−
1
m
[
∑
i
=
1
m
∑
k
=
1
k
y
k
(
i
)
log
(
h
w
(
x
(
i
)
)
)
k
+
(
1
−
y
k
(
i
)
)
log
(
1
−
(
h
w
(
x
(
i
)
)
)
k
)
]
J(w)=-\frac{1}{m}\left[\sum_{i=1}^{m} \sum_{k=1}^{k} y_{k}^{(i)} \log \left(h_{w}\left(x^{(i)}\right)\right)_{k}+\left(1-y_{k}^{(i)}\right) \log \left(1-\left(h_{w}\left(x^{(i)}\right)\right)_{k}\right)\right]\\
J(w)=−m1[i=1∑mk=1∑kyk(i)log(hw(x(i)))k+(1−yk(i))log(1−(hw(x(i)))k)]
a
(
4
)
=
h
w
(
x
)
=
g
(
z
(
4
)
)
a^{(4)}=h_{w}(x)=g\left(z^{(4)}\right)
a(4)=hw(x)=g(z(4))
z
(
4
)
=
w
(
3
)
a
(
3
)
+
b
0
(
4
)
z^{(4)}=w^{(3)} a^{(3)} +b_{0}^{(4)}
z(4)=w(3)a(3)+b0(4)
那么一层一层求偏导吧
∂
C
∂
w
3
=
∂
C
∂
g
∂
g
∂
z
∂
z
∂
w
3
\frac{\partial C}{\partial w^{3}}= \frac{\partial C}{\partial g}\frac{\partial g}{\partial z}\frac{\partial z}{\partial w^{3}}
∂w3∂C=∂g∂C∂z∂g∂w3∂z
我们按输出向量只有一个维度,数据集只有一个数据=>简单起见((●ˇ∀ˇ●))
代价函数可以简化为
C
=
y
∗
log
(
g
)
+
(
1
−
y
)
∗
log
(
1
−
g
)
C=y * \log \left(g\right)+(1-y) * \log \left(1-g\right)
C=y∗log(g)+(1−y)∗log(1−g)
那么我们更新
w
3
w^{3}
w3的简单形式(忽略下标)可以由如下进行推导。
∂
C
∂
w
3
=
∂
C
∂
g
∂
g
∂
z
∂
z
∂
w
3
=
[
y
g
+
(
1
−
y
)
∗
−
1
1
−
g
]
∗
[
g
′
]
∗
[
a
3
]
=
y
(
1
−
g
)
−
g
(
1
−
y
)
g
(
1
−
g
)
∗
[
g
′
]
∗
[
a
3
]
=
[
g
′
]
g
(
1
−
g
)
∗
(
y
(
1
−
g
)
−
g
(
1
−
y
)
)
∗
[
a
3
]
=
[
g
′
]
g
(
1
−
g
)
∗
(
y
−
g
)
∗
[
a
3
]
=
[
g
′
]
g
(
1
−
g
)
∗
(
y
−
a
)
∗
[
a
3
]
=
[
(
1
1
−
e
−
z
)
′
]
g
(
1
−
g
)
∗
(
y
−
a
)
∗
[
a
3
]
=
[
−
e
−
z
(
1
−
e
−
z
)
2
]
g
(
1
−
g
)
∗
(
y
−
a
)
∗
[
a
3
]
=
[
1
−
e
−
z
−
1
(
1
−
e
−
z
)
2
]
g
(
1
−
g
)
∗
(
y
−
a
)
∗
[
a
3
]
=
[
1
−
e
−
z
(
1
−
e
−
z
)
2
−
1
(
1
−
e
−
z
)
2
]
g
(
1
−
g
)
∗
(
y
−
a
)
∗
[
a
3
]
=
[
g
−
g
2
]
g
(
1
−
g
)
∗
(
y
−
a
)
∗
[
a
3
]
=
(
y
−
a
)
∗
[
a
3
]
\begin{aligned} \frac{\partial C}{\partial w^{3}}&= \frac{\partial C}{\partial g}\frac{\partial g}{\partial z}\frac{\partial z}{\partial w^{3}} \\ &= [\frac{y}{g}+(1-y)*\frac{-1}{1-g}]*[g']*[a_3]\\ &=\frac{y(1-g)-g(1-y)}{g(1-g)}*[g']*[a_3]\\ &=\frac{[g']}{g(1-g)}*(y(1-g)-g(1-y))*[a_3]\\ &=\frac{[g']}{g(1-g)}*(y-g)*[a_3]\\ &=\frac{[g']}{g(1-g)}*(y-a)*[a_3]\\ &=\frac{[(\frac{1}{1-e^{-z}})']}{g(1-g)}*(y-a)*[a_3]\\ &=\frac{[\frac{-e^{-z}}{(1-e^{-z})^{2}}]}{g(1-g)}*(y-a)*[a_3]\\ &=\frac{[\frac{1-e^{-z}-1}{(1-e^{-z})^{2}}]}{g(1-g)}*(y-a)*[a_3]\\ &=\frac{[\frac{1-e^{-z}}{(1-e^{-z})^{2}}-\frac{1}{(1-e^{-z})^{2}}]}{g(1-g)}*(y-a)*[a_3]\\ &=\frac{[g-g^2]}{g(1-g)}*(y-a)*[a_3]\\ &=(y-a)*[a_3] \end{aligned}
∂w3∂C=∂g∂C∂z∂g∂w3∂z=[gy+(1−y)∗1−g−1]∗[g′]∗[a3]=g(1−g)y(1−g)−g(1−y)∗[g′]∗[a3]=g(1−g)[g′]∗(y(1−g)−g(1−y))∗[a3]=g(1−g)[g′]∗(y−g)∗[a3]=g(1−g)[g′]∗(y−a)∗[a3]=g(1−g)[(1−e−z1)′]∗(y−a)∗[a3]=g(1−g)[(1−e−z)2−e−z]∗(y−a)∗[a3]=g(1−g)[(1−e−z)21−e−z−1]∗(y−a)∗[a3]=g(1−g)[(1−e−z)21−e−z−(1−e−z)21]∗(y−a)∗[a3]=g(1−g)[g−g2]∗(y−a)∗[a3]=(y−a)∗[a3]
你会发现吴恩达讲的最后一层的误差
(
y
−
a
L
)
(y-a^{L})
(y−aL)并不是直接用求出来的减去真实值,而是对
z
L
z^{L}
zL求偏导的结果,只是这两个一样的公式罢了!!!
那么我们怎么更新
w
2
w^{2}
w2呢?其实方法是一样的!一直偏导下去, 直到出现
w
2
w^{2}
w2.来吧!
∂
C
∂
w
2
=
[
∂
C
∂
a
4
∂
a
4
∂
z
4
]
[
∂
z
4
∂
a
3
]
[
∂
a
3
∂
z
3
]
[
∂
z
3
∂
w
2
]
=
(
y
−
a
)
∗
(
w
3
)
∗
(
g
′
)
∗
[
a
2
]
=
(
w
3
)
T
(
y
−
a
)
∗
(
g
′
)
∗
[
a
2
]
\begin{aligned} \frac{\partial C}{\partial w^{2}} &= [\frac{\partial C}{\partial a^4}\frac{\partial a^{4}}{\partial z^{4}}][\frac{\partial z^{4}}{\partial a^{3}}][ \frac{\partial a^{3}}{\partial z^{3}} ][\frac{\partial z^{3}}{\partial w^{2}} ] \\ &=(y-a)*(w^{3})*(g')*[a_2]\\ &=(w^{3})^{T}(y-a)*(g')*[a_2] \end{aligned}
∂w2∂C=[∂a4∂C∂z4∂a4][∂a3∂z4][∂z3∂a3][∂w2∂z3]=(y−a)∗(w3)∗(g′)∗[a2]=(w3)T(y−a)∗(g′)∗[a2]
通过对比这两个我们可以发现明白了,但是计算太麻烦了!我们就要借助动态规划的思想,用空间换时间!我们定义一个变量(如下)—>对于输出层
δ
(
L
)
=
∂
C
∂
z
L
\delta^{(L)} = \frac{\partial C}{\partial z^{L} }
δ(L)=∂zL∂C
对于
l
l
l
∈
\in
∈(2、3…L-1)
δ
(
l
)
=
(
w
l
)
T
∗
δ
(
l
+
1
)
∗
(
g
′
(
z
l
)
)
\delta^{(l)} = (w^{l})^{T}*\delta^{(l+1)}*(g'(z^{l}))
δ(l)=(wl)T∗δ(l+1)∗(g′(zl))
那么
∂
C
∂
w
l
=
a
l
∗
δ
l
+
1
\begin{aligned} \frac{\partial C}{\partial w^{l}} = a^{l}*\delta^{l+1} \end{aligned}
∂wl∂C=al∗δl+1
4.2答疑
- 为什么不算偏置项的偏导?
因为我们在用python或者matlab运算的时候完全可以让 w 0 l w^{l}_{0} w0l设为偏导值。不需要单独设置。
4.2 1 2 ( y − a L ) 2 \frac{1}{2}(y-a^{L})^{2} 21(y−aL)2代价函数的推导过程
仅仅是一点点不同
∂
C
∂
w
3
=
∂
C
∂
g
∂
g
∂
z
∂
z
∂
w
3
=
[
y
−
a
L
]
∗
[
g
′
]
∗
[
a
3
]
=
[
y
−
a
L
]
∗
g
(
1
−
g
)
∗
[
a
3
]
\begin{aligned} \frac{\partial C}{\partial w^{3}}&= \frac{\partial C}{\partial g}\frac{\partial g}{\partial z}\frac{\partial z}{\partial w^{3}} \\ &= [y-a^{L}]*[g']*[a_3]\\ &= [y-a^{L}]*g(1-g)*[a_{3}]\\ \end{aligned}
∂w3∂C=∂g∂C∂z∂g∂w3∂z=[y−aL]∗[g′]∗[a3]=[y−aL]∗g(1−g)∗[a3]
4.3 两种代价函数对比
- 我们直观感受是吴恩达的代价函数复杂无比,但是求导后却只有 ( y − a L ) (y-a^{L}) (y−aL)。网上常见的 1 2 ( y − a L ) 2 \frac{1}{2}(y-a^{L})^{2} 21(y−aL)2的代价函数虽然看着非常简单,但是求导后却比吴恩达讲的代价函数多一个 g ( 1 − g ) g(1-g) g(1−g) g这是个Sigmod函数,计算的时候肯定复杂不少。
5. 更新权值
我们先为每一层初始化一个全零
Δ
W
l
\Delta W^{l}
ΔWl,然后再遍历每一个数据集把每一个
X
i
X^{i}
Xi的误差(
∇
\nabla
∇)都传递到各层,然后在累加起来。最后更新现有的
Δ
W
\Delta W
ΔW。
η
\eta
η为学习速度。
Δ
W
(
l
)
+
=
∇
W
(
l
)
(
i
)
\Delta W^{(l)} += \nabla W^{(l)}(i)
ΔW(l)+=∇W(l)(i)
W
(
l
)
=
W
(
l
)
+
η
m
Δ
W
(
l
)
W^{(l)}=W^{(l)}+\frac{\eta}{m} \Delta W^{(l)}
W(l)=W(l)+mηΔW(l)
在前辈基础上做一些总结,喜欢就点个赞吧!!
如果公式推导不严谨还请您指正
参考资料
- [1] BP神经网络推导过程详解
- [2] 一文搞懂反向传播算法
- [2] 反向传播输出层误差 δ