符号约定
L:网络的深度(隐藏层+输出层)
n[1]:第一层隐藏层单元数,为5
a[1]:第一层的激活函数,=g[1](z[1])。另外我们认为x=a[0]
前向传播过程
对于单个的输入x:
简单来说,每一层都会执行这两个操作
- z[n] = w[n] * a[n-1] + b[n]
- a[n] = g[n] ( z[n] )
然后,a[n]会作为第n+1层的输入,再重复执行上面两个操作。
对于多个的输入X:
要用到向量化编程
我们额外需要做的是把所有的z和a,按列堆叠起来
之后,每一层都会执行这两个操作
- Z[n] = W[n] * A[n-1] + B[n]
- A[n] = g[n] ( Z[n] )
然后,A[n]会作为第n+1层的输入,再重复执行上面两个操作。
计算矩阵维度
未矢量化编程
首先激活函数a(X也可视为A)的维度直接可以知道。a[0]为x,对应(n[0], 1);之后的a的维度与上一层的输出结果的维度相同。
另外输出z的维度也可以直接知道。行数为隐藏层单元数,列数为1,即(n[n],1)。
有了激活函数a和输出z的维度就可以计算权重w的维度,计算方法就是简单的矩阵相乘的知识,m×n * n×r = m×r
。
偏置b、激活函数a的维度与输出z的维度一致。
总结来说
- w[l] : (n[l],n[l-1])
- b[l] : (n[l],1)
- dw[l] : (n[l],n[l-1])
- db[l] : (n[l],1)
矢量化编程
将不同的单位按列堆叠
按列堆叠改变了A和Z的列数,假设有m个数据堆叠,则A为(n[l-1], m),Z为(n[l], m),另外dA和dZ与A和Z有相同的维度。
而W和B维度保持不变:
- W[l] : (n[l],n[l-1])
- B[l] : (n[l],1)
Python在运算时会将B的维度,通过复制,增加为(n[l], m))
深度网络的作用原理
深度神经网络的这许多隐层中,较早的前几层能学习一些低层次的简单特征(边缘)(something simple)。等到后几层就能把简单的特征结合起来,去探测更加复杂的东西(something complex)。
主要的概念是:
一般会从比较小的细节入手(比如边缘),然后一步步到更大更复杂的区域,在此基础上再组成更复杂的部分。
示例1:图像识别
原理为:每一个小图表示在扫描到这样的图形的时候,该隐藏单元能得到最大的激励。
在网络的前几层,每个隐藏单元去寻找这样较为简单的特征(边缘特征)。
在之后的层中,这些边缘组成面部的不同部分(眼睛、鼻子等),从而检测人脸的不同部分。比如有一个神经元会去寻找眼睛的部分,另外的神经元在寻找鼻子的部分。
最后再把这些部分放到一起,就可以去识别和探测不同的人脸。
注:边缘探测器其实相对来说都是针对图像中非常小块的面积。而面部探测器就会针对一些比较大的区域。
示例2:语音识别
网络的前几层会去先开始试着试探比较低层次的音频波形的一些特征(比如声调是变高了还是变低了或者分辨白噪音)。
然后后面的层把这些波形组合在一起,就能去探测声音的基本单元(音位)。
再后面的层在基本的声音单元的基础上,组合起来去识别音频中的单词,词组以至于整个句子。
正向传播和反向传播的过程
神经网络的一个梯度下降循环。
框里和箭头上的是需要的东西,箭头指向为输出的结果。 有了每层的dW和dB,就可以去根据公式W = W - α * dW
、B = B - α * dB
去更新W和B的值。
另外,吴老师说了一段话:
机器学习里的复杂性和算法的复杂性,是来源于数据本身,而不是代码。
真正神奇的东西不是你写的程序。通常情况下你的代码的不会很长,虽然也不会太简单,但有时当你喂入超多数据后,算法会起作用。