本周课程介绍了浅层神经网络的相关知识
神经网络概览
下图中是一个只有一个神经元和三个输入的简单神经网络。
神经元的任务与我们前面所讲的逻辑回归的任务相同,先将输入的特征值加权求和,再加上常数项,在使用 sigmoid 函数(激活函数)求出最后的结果。
我们将多个这样的神经元进行堆叠,这样就得到了一个简单地浅层神经网络。这个神经网络有两层,也就是说要进行两次逻辑回归的运算。
神经网络表示
如图所示,这是一个简单的神经网络,它拥有三层结构。左边的输入特征 x 所在的层我们称之为输入层,中间节点所在的层称之为隐藏层,最右边的叫作输出层。中间层之所以被叫做隐藏层是因为在训练集中,这些中间结点的真正数值我们是不知道的。
输入特征本来是用 x 来表示,这里我们用 $a^{[0]}$ 来表示,其中 a 表示 “激活”,它意味着网络中不同层的值将会传递到下一层。右上角的方括号表示这些值来自神经网络的哪一层。
有趣的是,在约定俗成的符号约定中,这是一个两层的神经网络,输入层并不计算在内。
计算神经网络的输出
这是单个神经元所进行的计算,与逻辑回归相似。
这是单隐层神经网络中第 [1] 层 4 个节点的计算公式。我们将这些公式以向量化的方式详细的表示出来:
$$
\large
z^{[1]}
=
\begin{bmatrix}
-w_1^{[1]T}- \\\ -w_2^{[1]T}- \\\ -w_3^{[1]T}- \\\ -w_4^{[1]T}-
\end{bmatrix}
\begin{bmatrix}
x_1 \\\ x_2 \\\ x_3
\end{bmatrix}
+
\begin{bmatrix}
b_1 \\\ b_2 \\\ b_3 \\\ b_4
\end{bmatrix}
=
\begin{bmatrix}
w_1^{[1]T}x +b_1 \\\ w_2^{[1]T}x +b_2\\\ w_3^{[1]T}x +b_3\\\ w_4^{[1]T}x +b_4
\end{bmatrix}
=
\begin{bmatrix}
z_1^{[1]} \\\ z_2^{[1]} \\\ z_3^{[1]} \\\ z_4^{[1]}
\end{bmatrix}
\\
a^{[1]}
=
\begin{bmatrix}
a_1^{[1]} \\\ a_2^{[1]}\\\ a_3^{[1]}\\\ a_4^{[1]}
\end{bmatrix}
=\sigma(z^{[1]})
$$
下图给出了,第 [1] 层 和第 [2] 层 向量化的计算公式
多个样本的向量化
上面一节讲述了单个样本的向量化,这一小节解释了多个样本的向量化。
如果我们使用 for 循环来处理多个训练样本,则速度会非常慢。所以我们需要使用向量化的方法来进行计算。
下面是向量化的表示:我们将所有训练样本 $x^{(i)}$ 进行横向的叠加,同时 $z^{[1] (i)}$ 和 $a^{[1] (i)}$ 也进行横向的叠加。那么在这些矩阵中,横向指标对应了不同的样本,而纵向指标则对应了不同的节点。
下面给出了向量化的计算公式,对于本例中的神经网络,$W^{[1]}$ 是 4x3 的矩阵。
$$
\large
Z^{[1]} = W^{[1]}X + b^{[1]} \
A^{[1]} = \sigma(Z^{[1]}) \
Z^{[2]} = W^{[1]}X + b^{[2]} \
A^{[2]} = \sigma(Z^{[2]})
$$
为什么这样的向量化是正确的呢?下图给出了解释,如果你了解线性代数,那么你可以看出这张图片中的解释是正确的,我们用矩阵 $W^{[1]}$ 与各个样本向量相乘,就得到了矩阵 $Z^{[1]}$,为了方便起见,这里省略了 $b^{[1]}$ 这一项。这里只解释了 $Z^{[1]} = W^{[1]}X + b^{[1]}$ 为什么成立,参考这一解释,你可以推导出其他几个式子也是正确的。
激活函数
除了常见的 sigmoid 函数以外,激活函数还有其它的几种选择。
上图中第一个就是我们熟悉的 sigmoid 函数,除非在二分类的输出层,不然绝对不要用它作为激活函数。
这是因为,tanh 函数,上图右上角所示,几乎在所有场合都更优越。
最常用的默认激活函数是 ReLU(修正线性单元)。当你不确定时,最好选择 ReLU。
图中最后一个函数我们称为 “带泄露的ReLU”
名称 | 公式 | 特点 |
---|---|---|
sigmoid | $\large g(z) = \frac{1}{1+e^{-z}}$ | 除了二分类的输出层,几乎不用 |
tanh | $\large g(z) = \frac{e^z-e^{-z}}{e^z+e^{-z}}$ | 几乎在所有场合都优于 sigmoid |
ReLU | $\large g(z) = max(0,z)$ | 当 z 很大时导数不会趋于0而导致速度过慢 |
带泄露的 ReLU | $\large g(z) = max(0.01z,z)$ | 当 z 小于 0 时,导数不是0 |
为什么一定要用非线性的激活函数呢?
如果不使用非线性的激活函数,那么神经网络的运算就只有线性运算。神经网络最后的输出结果只是输入特征的线性组合。这和没有任何隐藏层的标准逻辑回归是一样的,这样就无法学习到更复杂的函数。
激活函数的导数
名称 | 公式 | 导数 |
---|---|---|
sigmoid | $\large g(z) = \frac{1}{1+e^{-z}}$ | $\large g’(z)=\frac{1}{1+e^{-z}}(1-\frac{1}{1+e^{-z}})=g(z)(1-g(z))$ |
tanh | $\large g(z) = \frac{e^z-e^{-z}}{e^z+e^{-z}}$ | $\large g’(z)=1-(g(z))^2$ |
ReLU | $\large g(z) = max(0,z)$ | $\large if\quad z > 0 \quad g’(z)=1 \\ if\quad z<0 \quad g’(z)=0$ |
带泄露的 ReLU | $\large g(z) = max(0.01z,z)$ | $\large if\quad z > 0 \quad g’(z)=1 \\ if\quad z<0 \quad g’(z)=0.01$ |
神经网络的梯度下降法
这里只给出神经网络梯度下降的公式,省略了推导过程。
Forward Propagation
$$
\large
Z^{[1]} = W^{[1]}X+b^{[1]} \\
A^{[1]} = g^{[1]}(Z^{[1]}) \\
Z^{[2]} = W^{[2]}A^{[1]} + b^{[2]} \\
A^{[2]} = g^{[2]}(Z^{[2]})
$$
Back Propagation
$$
\large
dZ^{[2]} = A^{[2]} - Y \\
dW^{[2]} = \frac{1}{m}dZ^{[2]}A^{[1]T} \\
db^{[2]} = \frac{1}{m}np.sum(dZ^{[2]},axis=1,keepdims=True)\\
dZ^{[1]} = W^{[2]T}dZ^{[2]}*g’^{[1]}(Z^{[1]}) \\
dW^{[1]} = \frac{1}{m}dZ^{[1]}X^{T}\\
db^{[1]} = \frac{1}{m}np.sum(dZ^{[1]},axis=1,keepdims=True)
$$
随机初始化
在逻辑回归中我们可以初始化参数为 0 ,但在神经网路中我们不这样做。如果我们将神将网络中的节点的参数都初始化为 0, 那么每一个节点都在做同样的运算,它们对下一层的影响也是相同的,所以这样的神经网络是没有意义的。
正确的做法是对参数随机初始化,这样可以使每个节点学习到不同的参数。