DeepLearning.ai笔记:(1-3)-- 浅层神经网络(Shallow neural networks)

前面两周讲的是一些logistic和向量化的内容,以及numpy的基本使用,在他之前的机器学习课程中已经讲过了,这里就不再赘述。Week3主要讲了如何搭建两层的神经网络。

神经网络的表示

这周的内容就围绕着这一张图来讲。

$$a_{j}^{[i]}$$

这就是每一层神经元的表达方式,上标中括号[],表示是第几层的神经元;下标表示这个是某一层的第几个神经元。

Input Layer:输入层,也用$a_{j}^{[0]}$,表示第0层

Hidden Layer:表示除了最后一层输出层以外的内部隐藏层

Output Layer:输出层,表示最后一层

而通常神经网络的层数一般不包括输入层。

$w^{[i]}$:每一层的参数$w$的维度是(该层神经元个数,前面一层神经元个数)

$b^{[i]}$:为(每一层的神经元个数,1)

计算单个数据的神经网络

由此得到,计算单个数据的神经网络只需要4步:

$$z^{[1]} = W^{[1]}a^{[0]} + b^{[1]}$$

$$a^{[1]} = \sigma(z^{[1]})$$

$$z^{[2]} = W^{[2]}a^{[1]} + b^{[2]}$$

$$a^{[2]} = \sigma(z^{[2]})$$

多数据的向量化表示

我们知道,多个数据的表示就是$x^{(i)}$,使用小括号的上标。神经元也是一样。

如$a^{[1] (i)}$表示第1层神经元的第i个样本。

那么如果有m个样本,一直做for循环来计算出这些神经元的值,实在是太慢了,所以跟logistic一样,可以直接用向量化来表示,这个时候用大写字母来表示。

$$Z^{[1]} = W^{[1]}A^{[0]} + b^{[1]}$$

$$A^{[1]} = \sigma(Z^{[1]})$$

$$Z^{[2]} = W^{[2]}A^{[1]} + b^{[2]}$$

$$A^{[2]} = \sigma(Z^{[2]})$$

这个时候,例如$A^{[1]}$是一个$(n,m)$的矩阵,m是样本数,每一列表示一个样本,n是该层的神经元个数。

从水平上看,矩阵 A代表了各个训练样本。竖直上看,A的不同索引对应不用的隐藏单元。

对矩阵Z和X也是类似,水平方向对应不同的样本,竖直方向上对应不同的输入特征,也就是神经网络输入层的各个节点。

激活函数

在此前都是用sigmoid作为激活函数的。但是激活函数不只有这一种,常用的有4种,分别是:sigmoid, tanh, ReLu, Leaky ReLu。

  • sigmoid: $a = \frac{1}{1 + e^{-z}}$
    • 导数:$a^{\prime} = a(1-a)$
  • tanh: $a = \frac{e^z - e^{-z}}{e^z + e^{-z}}$
    • 导数:$a^{\prime} = 1 - a^2$
  • ReLu(修正线性单元): $a = max(0, z)$
  • Leaky ReLu: $a = max(0.01z, z)$

tips:

  • tanh函数在值域上处于-1和+1之间,所以均值更接近0,使用tanh比sigmoid更能够中心化数据,使得平均值接近0,而不是0.5。
  • tanh在大多数场合都是优于sigmoid的。
  • 但是sigmoid和tanh有共同的缺点就是z在特别大或者特别小的时候,梯度很小,收敛速度很慢。
  • 而ReLu弥补了两者的不足,在$z > 0$时,梯度始终为1,提高了速度。
  • Leaky ReLu保证了$z < 0$时,梯度不为0,但是实际上效果差不多。

结论:

  • sigmoid:除了输出层是一个二分类问题的时候使用,不然基本不用
  • tanh:几乎适用于任何场合
  • ReLu:默认使用这个,如果不确定你要用哪个激活函数,那就选ReLu或者Leaky ReLu

为什么要使用非线性的激活函数

如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与只有一个隐藏层效果相当,这种情况就是多层感知机(MLP)了。
正因为上面的原因,我们决定引入非线性函数作为激励函数,这样深层神经网络就有意义了(不再是输入的线性组合,可以逼近任意函数)。

梯度下降法公式

这里给出了浅层神经网络的梯度下降法公式。其中$g^{[1]’}(Z^{[1]})$表示你的激活函数的导数。

参数随机初始化

在神经网络中,如果将参数全部初始化为0 会导致一个问题,例如对于上面的神经网络的例子,如果将参数全部初始化为0,在每轮参数更新的时候,与输入单元相关的两个隐藏单元的结果将是相同的。

所以初始化时,W要随机初始化,b不存在对称性问题,所以可以设置为0

1
2
W = np.random.rand((2,2))* 0.01
b = np.zero((2,1))

将W乘以0.01是为了让W初始化足够小,因为如果很大的话,Z就很大,用sigmoid或者tanh时,所得到的梯度就会很小,训练过程会变慢。

ReLU和Leaky ReLU作为激活函数时,不存在这种问题,因为在大于0的时候,梯度均为1。

好好做作业,才能有更深的体会!

分享到