深度学习入门笔记(七):深层神经网络

欢迎关注WX公众号:【程序员管小亮】

专栏——深度学习入门笔记

声明

1)该文章整理自网上的大牛和机器学习专家无私奉献的资料,具体引用的资料请看参考文献。
2)本文仅供学术交流,非商用。因此每一部分具体的参考资料并无详细对应。若是某部分不当心侵犯了你们的利益,还望海涵,并联系博主删除。
3)博主才疏学浅,文中若有不当之处,请各位指出,共同进步,谢谢。
4)此属于初版本,如有错误,还需继续修正与增删。还望你们多多指点。你们都共享一点点,一块儿为祖国科研的推动添砖加瓦。html

深度学习入门笔记(七):深层神经网络

一、深层神经网络

目前为止,学习了只有一个单独隐藏层的神经网络(深度学习入门笔记(六):浅层神经网络)的正向传播和反向传播,还有逻辑回归(深度学习入门笔记(二):神经网络基础),而且还学到了向量化(深度学习入门笔记(四):向量化),这在随机初始化权重(深度学习入门笔记(六):浅层神经网络)时是很重要。程序员

这一次所要作的是把这些理念集合起来,就能够组建并执行一个术语你本身的 深度神经网络,有没有一种乐高积木的感受呢?web

简单复习下前面的内容:算法

逻辑回归,下图左边。一个隐藏层的神经网络,下图右边。
在这里插入图片描述
神经网络层数的定义方式:从左到右,由隐藏层开始,定义为第一层,好比上边右图, x 1 {x}_{1} x 2 {x}_{2} x 3 {x}_{3} 这一层右边的隐藏层是第一层,因此浅层神经网络是两层网络。编程

由此类推,下图左边是两个隐藏层的三层神经网络,右边是五个隐藏层的六层神经网络。(这个层数叫法是存在不一样的结论的,最简单且不出错的方法是说隐藏层的层数,好比左边的是两个隐藏层,右边的是五个隐藏层)
在这里插入图片描述
因此,严格意义上来讲,逻辑回归也是一个一层的神经网络,而上边右图一个深得多的模型,是一个六层的神经网络。咱们所说的浅层神经网络和深层神经网络中的浅与深,仅仅是指一种程度,也就是相对而言的。缓存

小结一下: 严格的说,有一个隐藏层的神经网络,就是一个两层神经网络。记住算神经网络的层数时,不算输入层,只算隐藏层和输出层。网络

二、前向传播和反向传播

深度神经网络的每一层都有 前向传播 步骤以及一个相反的 反向传播 步骤,那么这两个步骤是如何实现的呢?app

先说前向传播 l l 表示层数,网络的输入 a [ l 1 ] {a}^{[l-1]} ,网络的输出是 a [ l ] {a}^{[l]} ,网络的缓存为 z [ l ] {z}^{[l]} ;从实现的角度来讲能够缓存下 w [ l ] {w}^{[l]} b [ l ] {b}^{[l]} ,这样更容易在不一样的环节中调用函数。框架

因此前向传播的步骤能够写成:机器学习

(1) z [ l ] = W [ l ] a [ l 1 ] + b [ l ] {z}^{[l]}={W}^{[l]}\cdot{a}^{[l-1]}+{b}^{[l]}

(2) a [ l ] = g [ l ] ( z [ l ] ) {{a}^{[l]}}={{g}^{[l]}}\left( {{z}^{[l]}}\right)

向量化(深度学习入门笔记(四):向量化)整个过程以后,能够写成:

(1) z [ l ] = W [ l ] A [ l 1 ] + b [ l ] {z}^{[l]}={W}^{[l]}\cdot {A}^{[l-1]}+{b}^{[l]}

(2) A [ l ] = g [ l ] ( Z [ l ] ) {A}^{[l]}={g}^{[l]}({Z}^{[l]})

前向传播须要喂入 A [ 0 ] {A}^{[0]} 也就是 X X ,即输入特征,来进行初始化,初始化的是第一层的输入值。 a [ 0 ] {a}^{[0]} 对应于一个训练样本中的输入特征,而 A [ 0 ] {{A}^{[0]}} 对应于一整个训练样本中的输入特征,因此这就是这条链的第一个前向函数的输入,重复这个步骤就能够从左到右计算前向传播。

再讲反向传播,具体的原理和推导能够看这个博客——深度学习100问之深刻理解Back Propagation(反向传播),输入为 d a [ l ] {{da}^{[l]}} ,输出为 d a [ l 1 ] {{da}^{[l-1]}} d w [ l ] {{dw}^{[l]}} , d b [ l ] {{db}^{[l]}}

因此反向传播的步骤能够写成:

(1) d z [ l ] = d a [ l ] g [ l ] ( z [ l ] ) d{{z}^{[l]}}=d{{a}^{[l]}}*{{g}^{[l]}}'( {{z}^{[l]}})

(2) d w [ l ] = d z [ l ] a [ l 1 ]   d{{w}^{[l]}}=d{{z}^{[l]}}\cdot{{a}^{[l-1]}}~

(3) d b [ l ] = d z [ l ]    d{{b}^{[l]}}=d{{z}^{[l]}}~~

(4) d a [ l 1 ] = w [ l ] T d z [ l ] d{{a}^{[l-1]}}={{w}^{\left[ l \right]T}}\cdot {{dz}^{[l]}}

(5) d z [ l ] = w [ l + 1 ] T d z [ l + 1 ]   g [ l ] ( z [ l ] )   d{{z}^{[l]}}={{w}^{[l+1]T}}d{{z}^{[l+1]}}\cdot \text{ }{{g}^{[l]}}'( {{z}^{[l]}})~

式子(5)由式子(4)带入式子(1)获得,前四个式子就可实现反向传播。

向量化实现过程能够写成:

(6) d Z [ l ] = d A [ l ] g [ l ] ( Z [ l ] )    d{{Z}^{[l]}}=d{{A}^{[l]}}*{{g}^{\left[ l \right]}}'\left({{Z}^{[l]}} \right)~~

(7) d W [ l ] = 1 m d Z [ l ] A [ l 1 ] T d{{W}^{[l]}}=\frac{1}{m}\text{}d{{Z}^{[l]}}\cdot {{A}^{\left[ l-1 \right]T}}

(8) d b [ l ] = 1 m   n p . s u m ( d z [ l ] , a x i s = 1 , k e e p d i m s = T r u e ) d{{b}^{[l]}}=\frac{1}{m}\text{ }np.sum(d{{z}^{[l]}},axis=1,keepdims=True)

(9) d A [ l 1 ] = W [ l ] T d Z [ l ] d{{A}^{[l-1]}}={{W}^{\left[ l \right]T}}\cdot d{{Z}^{[l]}}

小结一下:

吴恩达老师手稿以下,举一个简单的三层(两层隐藏层)神经网络。

在这里插入图片描述

  • 前向传播:第一层可能有一个 ReLU 激活函数,第二层为另外一个 ReLU 激活函数,第三层(输出层)多是 sigmoid 函数(若是作二分类的话),输出值为 y ^ \hat y ,用来和 y y 计算损失 L L
  • 反向传播:向后迭代,进行反向传播求导来求 d w [ 3 ] {{dw}^{[3]}} d b [ 3 ] {{db}^{[3]}} d w [ 2 ] {{dw}^{[2]}} d b [ 2 ] {{db}^{[2]}} d w [ 1 ] {{dw}^{[1]}} d b [ 1 ] {{db}^{[1]}} 。在计算的时候,缓存会把 z [ 1 ] {{z}^{[1]}} z [ 2 ] {{z}^{[2]}} z [ 3 ] {{z}^{[3]}} 传递过来,而后回传 d a [ 2 ] {{da}^{[2]}} d a [ 1 ] {{da}^{[1]}} d a [ 0 ] {{da}^{[0]}}
  • 前向递归:用输入数据 x x 来初始化,那么反向递归(使用 Logistic 回归作二分类),对 A [ l ] {{A}^{[l]}} 求导。

三、核对矩阵的维数

当实现深度神经网络的时候,其中一个最经常使用的也是最好用的检查代码是否有错的方法,就是拿出一张纸过一遍算法中矩阵的维数。或者有一个笨方法就是,一直运行,一直 d e b u g debug ,不过这样过低效了。

向量化前,变量的维度以下:

  • w w 的维度是(下一层的维数,前一层的维数),即 w [ l ] {{w}^{[l]}} :( n [ l ] {{n}^{[l]}} , n [ l 1 ] {{n}^{[l-1]}} );

  • b b 的维度是(下一层的维数,1),即 b [ l ] {{b}^{[l]}} :( n [ l ] , 1 ) {{n}^{[l]}},1)

  • z z a a 的维度是(下一层的维数,1),即 z [ l ] {{z}^{[l]}} , a [ l ] {{a}^{[l]}} : ( n [ l ] , 1 ) ({{n}^{[l]}},1)

  • d w [ l ] {{dw}^{[l]}} w [ l ] {{w}^{[l]}} 维度相同;

  • d b [ l ] {{db}^{[l]}} b [ l ] {{b}^{[l]}} 维度相同;

w w b b 向量化维度不变,但 z z , a a 以及 x x 的维度会向量化后发生变化。
在这里插入图片描述

向量化后:

  • Z [ l ] {Z}^{[l]} 能够当作由每个单独的 z [ l ] {z}^{[l]} 叠加而获得, Z [ l ] = ( z [ l ] [ 1 ] z [ l ] [ 2 ] z [ l ] [ 3 ] z [ l ] [ m ] ) {Z}^{[l]}=({{z}^{[l][1]}},{{z}^{[l][2]}},{{z}^{[l][3]}},…,{{z}^{[l][m]}}) m m 为训练集大小,因此 Z [ l ] {Z}^{[l]} 的维度再也不是 ( n [ l ] , 1 ) ({{n}^{[l]}},1) ,而是 ( n [ l ] , m ) ({{n}^{[l]}},m)

  • A [ l ] {A}^{[l]} Z [ l ] {Z}^{[l]} 同样,维度变成 ( n [ l ] , m ) ({n}^{[l]},m) ,其中 A [ 0 ] = X = ( n [ l ] , m ) {A}^{[0]} = X =({n}^{[l]},m)
    在这里插入图片描述
    到这里,一个深层神经网络就设计完成了,理论知识也大概讲述完毕了。

四、参数VS超参数

想要你的深度神经网络起很好的效果,维度的准确性是最基本的东西,代码不出错也是必须的一步,除了这些之外,还须要规划好参数以及超参数。

  • 什么是超参数?

定义:在机器学习的上下文中,超参数是在开始学习过程以前设置值的参数,而不是经过训练获得的参数数据。一般状况下,须要对超参数进行优化,给学习机选择一组最优超参数,以提升学习的性能和效果。

  • 超参数和参数的区别是什么?

参数是从数据中自动估计的,而超参数是手动设置的。

  • 超参数是如何影响神经网络的?

超参数,实际上控制了最后的参数 W W b b 的值,影响了模型。

  • 超参数有哪些呢?

好比算法中的 learning rate(学习率)、iterations(梯度降低法循环的数量)、 L L (隐藏层数目)、 n [ l ] {{n}^{[l]}} (隐藏层单元数目)、choice of activation function(激活函数的选择)等等,这些都须要你来设置。

输了一些比较熟悉的超参数,你可能有点感受了,可是实际上深度学习有不少不一样的超参数,以后也会介绍一些其余的超参数,如 momentum(动量)、mini batch size(批大小)、regularization parameters(正则化参数)等等。

  • 如何寻找超参数的最优值?
    在这里插入图片描述

其实这个过程和人类的思惟过程相似,为何这么说呢?人类在大脑风暴的过程当中,是先有 Idea,而后 Realize,最后 Experiment。不过深度学习中,是 Idea—Code—Experiment—Idea 这个大循环,Realize 是用 Code 替换的,再尝试各类不一样的参数,实现模型并观察是否成功,而后再迭代。

深度学习的应用领域,是个很经验性的过程:一般有个想法(Idea),好比你可能大体知道一个别人用的最好的学习率值,可能说 a = 0.0001 1 0 4 a=0.0001(10^{-4}) 效果最好,我在作图像处理实验的时候,真的发现这个学习率很不错,建议你也能够尝试一下。

那么我会想说,先试试看,而后能够实际更改一下,再训练一下,最后看看效果如何。

基于这个尝试的结果,你会发现,学习率设定再提升到 0.0005 5 1 0 4 0.0005(5*10^{-4}) 可能会比较好。

可是你又不肯定什么值是最好的,这个时候大能够先试试你猜测的新学习率 a a 到底怎么样,更改参数从新实验,再看看损失函数 J J 的值有没有降低?

若是没有的话,你能够试一试再大一些的值,若是这个时候,你发现损失函数的值不但没减小,反而增长而且发散了。恭喜你,你失败了2333。

而后可能须要试试其余的一些数,再改再看实验结果,看损失函数是否降低的很快或者收敛到在更高的位置?

你可能尝试不一样的 a a 并观察损失函数 J J 这么变了,试试一组值,而后可能损失函数变成这样,这个 a a 值会加快学习过程,而且收敛在更低的损失函数值上,而后敲定,我就用这个 a a 值了。

再或者还可能你发现,固定学习率并不能知足你的要求,这个时候你须要学习率是变化的,好比学习率衰减——深度学习100问之学习率衰减

可能有的小伙伴就会说了,这也太麻烦了吧,这不是一直试试试的???这也是工做量的一部分,因此深度学习也被人吐槽说是一个经验主义学科。。。应用深度学习领域,一个很大程度基于经验的过程,凭经验的过程通俗来讲,就是试直到你找到合适的数值。

只能说调参是门玄学,好与坏不是你我说了算的。

以前在知乎上看到过一个文章说可使用算法调参,可是我还没接触过。。。论文:Hyperparameter Optimization: A Spectral Approach,有兴趣的小伙伴能够看一看,这但是顶端科学技术了。
在这里插入图片描述

五、调参

一个近来深度学习的影响是,它能够用于解决不少问题,从 计算机视觉语音识别,到 天然语言处理,到不少 结构化的数据应用,好比 网络广告 或是 网页搜索产品推荐 等等。

不少领域的研究人员,对这些领域中的一个问题进行研究,尝试了不一样的参数设置,有时候这种设置超参数的直觉是能够推广的,但有时又不会。因此刚开始应用新问题的人们,去试必定范围的值看看结果如何(好比咱们实验室的方向,就是近两年才开始结合深度学习做为方法论,进行问题的研究与解决)。

而后是其余状况,好比你已经用了好久的模型进行问题的解决,可能你在作网络广告应用,也多是其余的,在开发的过程当中,颇有可能学习率的最优数值或是其余超参数的最优值是会变的!!!因此即便天天都在用当前最优的参数调试系统,你仍是会发现,最优值过一年就会变化,这多是不少缘由致使的,其中一种可能就是由于电脑的基础设施,CPU 或是 GPU 可能会变化很大,好比你是一个 GPU,那么 GPU 的型号?(以N卡的天梯为例)

在这里插入图片描述
(图源:http://www.mydrivers.com/zhuanti/tianti/gpu/

因此以前的经验规律可能每几个月就会变,若是你的工做台一直不变,那么数据也可能会有变化,再或者你的网络结构也会有微调,等等。因此要常常试试不一样的超参数,勤于检验结果,看看有没有更好的超参数数值,相信慢慢的,你会获得设定超参数的直觉,知道你的问题最好用什么数值。😃

这可能的确是深度学习比较让人不满的一部分,也就是你必须尝试不少次不一样可能性。但参数设定这个领域,深度学习研究还在进步中,因此可能过段时间就会有更好的方法决定超参数的值,也颇有可能因为 CPUGPU、网络和数据都在变化,这样的指南可能只会在一段时间内起做用,只有不断尝试,而且尝试保留交叉检验或相似的检验方法,而后挑一个对你的问题效果比较好的数值,这种方法才是如今最好的解决办法。

近年来,受深度学习影响或者能够称之为 冲击,不少领域发生了变化,从计算机视觉到语音识别到天然语言处理到不少结构化的数据应用,好比网络广告、网页搜索、产品推荐等等;有些同一领域设置超参数的直觉能够推广,但有时又不能够,特别是那些刚开始研究新问题的人们应该去尝试必定范围内的结果如何,甚至那些用了好久的模型得学习率或是其余超参数的最优值也有可能会改变。咱们能作的只有以不变应万变!!!这也是这个领域的项目经验或者经历更为重要的缘由之一。

最后,记住一条经验规律:常常试试不一样的超参数,勤于检查结果,看看有没有更好的超参数取值,你将会获得设定超参数的直觉。

推荐阅读

参考文章

  • 吴恩达——《神经网络和深度学习》视频课程