您的位置:首页 > 理论基础 > 计算机网络

Python与人工神经网络(11)——为什么深度神经网络很难训练

2017-04-12 18:58 387 查看
之前十期,我们彻头彻尾的介绍了神经网络技术,然而用到的都是只有一个隐藏层的。那种有多个隐藏层的神经网络,叫深度神经网络,比如这种:


在神经网络中,比较浅的隐藏层会处理一些比较简单的任务,比较深的层会处理比较复杂的任务。比如在人脸识别上,可能第一层用于识别这个图片的轮廓,第二层用于识别有没有鼻子眼睛耳朵嘴巴什么的,第三层用于识别眼睛特征、耳朵特征等等。所以理论上来说,在我们的识别MINST的数据集时,用更深度的神经网络或者说是有多个隐藏层的神经网络,会达到更好的效果。来试试看:

使用的是在第八期中优化过的代码,首先来看原来单层隐藏层情况,神经网络大小[784, 30, 10],训练30个周期,每次随机选取10个小样本,训练速率参数0.5,正则化参数5.0,图中展示除的识别率是验证数据集的识别率:



最高识别率在第23周期,96.34%

再来看看我们加了一个隐藏图层,神经网络大小变成了[784, 30,30, 10],其他参数不变的情况:



最高识别率在第15周期,是96.68%,有进步是不是!

当三个隐藏图层,神经网络大小是[784, 30,30,30, 10]时:



最高识别率在第20周期,是96.39%,好像又回去了!

四个隐藏图层,神经网络大小是[784, 30,30,30,30, 10]时:



最高识别率在第29周期,是96.38%。反正就是没啥进步!

为什么隐藏层数再增加的时候,识别率不增加了呢?这是不是说明,其实我们增加的这些个隐藏层,没起什么作用呢?

答案是,是的!因为有些层在偷懒,从训练开始到训练结束,他的w和b值就没咋变。

在第四期,讲反向传播算法时,我们引入过这么一个方程:



说δ大的时候,表示z的改变对C的影响大,如果第L层j个神经元的z改变对C的影响大的话,这个z当然也会经常改变,让C更小。那么我们来看这么一个一根筋的神经网络:



我们来计算δ[1][0],也就是第一层(从0层起算)的的第零个神经元的值(因为是一根筋,每层只有一个神经元,之后的计算会把0省掉):



那我们再来看看S曲线函数σ的导函数:



我们从S曲线的形状就可以看出,当z=0的时候,σ'(z)有最大值,带进去为1/4。也就是说,δ[1] < 1/4*w2*1/4*w3*1/4*w4*δ[4]。

当每层有多个神经元时,无非就是多了一个Σ符号。而且,经常我们的w取值都是小于1的,那么问题就明显了,前面的隐藏层的训练速度远远低于后面的隐藏层的训练速度,也就是,前面的层在偷懒!这种情况叫梯度衰弱问题。

当然,如果w取特别大特别大的值,就会有梯度膨胀问题,一样的会导致训练速度不平衡,只不过反过来了。要达到平衡,同步训练,就太难了,怎么解决呢?请看下期,深度学习!

欢迎关注我的微信公众号获取最新文章:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息