书影书言论程序员

你应该懂得的反向传播(backprop)

2018-08-23  本文已影响0人  书影随行

当我们在学习或者工作中使用tensorflow,pytorch之类去复现网络的时候,一般没人去单独去写backward,因为这些优秀的框架已经给我们打好了根基,它们的一句话即可自动的帮我们去反向传播,我们负责写好forward就可。

我听到的更多的抱怨是来自实践的团队,“如果我们工作中根本不用去写反向传播,为什么要去学习如何自己写呢”,反方的观点则是诸如 “这些知识懂了的话理解神经网络会更深”,“你可能有机会去接触神经网络的更底层”等等,这些话确实很苍白无力。

但其实我们应该去写写并懂得反向传播的原因是因为它是一个有漏洞的方法

简单来说,它很容易陷入学习过程中的一些陷阱,这些陷阱就发生在你手到擒来的写了个自己觉得完美无缺的网络,前向反向都如你意的过程中。

一个反向传播的例子

另外一个比较有意思的事情就是sigmoid的梯度:sigmoid x (1 - sigmoid)最大值为0.25(z=0.5)。这就意味着每次反向传播经过sigmoid一次,它的大小将至少减少为原来的1/4,那么特别是达到网络的前几层的时候,反向传播的梯度将会越来越小。如果你恰巧又用了SGD,那么整个网络的训练将会更加的漫长。

举个例子:

z = np.maximum(0, np.dot(W,x)) #前向传播
dW = np.outer(z > 0, x) # 反向传播:计算W的梯度

你可以看到当如果有神经元在前向传播后(z的值中)被ReLU激活后为0值时,它的权重的梯度将也为0,这时将会导致出现神经元的死亡的现象,这些神经元将永不再更新。出现这种情况的原因有两个,1个是ReLU神经元的权重被初始化的不够好,另一个是神经元的权重在训练的过程中被大幅更新,这些神经元将永久的处于死亡状态。它就像永久死亡的大脑的细胞。如果你在用ReLU,那么有时你就会发现在训练时大约有40%左右的神经元已经是0处于死亡的状态。

那么如果你懂得了反向传播的这个问题,你就可以很小心的去对待死亡ReLU的问题,对待这些对你训练集的所有数据都输出为0,永久的死去了神经元。神经元也会在训练的中途死掉,比如你设置了比较大的学习率。

那么来个反向传播的话

此时如果w的初始值比较大的话(比如100),那么

之后不断的相乘的结果就是网络的前层的梯度成指数级的增长。再拿这个超级大的梯度来更新我们的w的话,就导致网络的不稳定,在极端情况下,权重的值会变得特别大,以至于结果溢出,出现NAN值。

最后 反向传播并不是一个健壮的方法,如果你因为“Tensorflow或者Pytorch已经自动的帮我们实现了”就忽视它,那么你面对他带来的问题的时候讲无所适从,对于调试一个网络来说也会变得困难。庆幸的是反向传播理论并不是那么的不食人间烟火,只要你认真的关注并研究几篇文章,那么你很快会掌握它的。

上一篇下一篇

猜你喜欢

热点阅读