神经网络和深度学习WU Week3——浅层神经网络

1. 符号约定

  • [],中括号表示与层相关,如[1]表示第一层,以此类推,输入层表示为[0]层,一个神经网络的层数不包括输入层;
  • (),仍然表示和样本相关,如(1)表示第一个样本点;
  • 每一层都计算 和 ,最后输出层计算出来的就是输出;
  • 特征矩阵 ,参数,类似的,表示第二隐层的参数矩阵;
  • ,即特征向量(自变量);
  • ,第一个隐藏层第个节点的输出值;
  • 隐藏层与输出层有参数,如隐藏层的参数

2. 只有一个隐层的神经网络

2.1单隐层神经网络

  • 输入层
  • 输出层
  • 隐藏层,之所以叫隐藏层是因为中间层的数值在训练集看不到。
    如下图所示,相关符号的意义参见符号规定节。


    单隐层神经网络图

2.2 计算神经网络的输出——单样本点

图例中的隐藏层有4个节点,在每个节点处进行如下的计算。


节点计算示意图
  • 计算步骤(以第一个节点为例,第几个节点只需要修改上标[]内的对应数值)
    • Step1 计算;
    • Step2 利用激活函数(sigmoid函数),计算
      即得到如下的计算式
      \begin{array}{l}{z_{1}^{[1]}=w_{1}^{[1] T} x+b_{1}^{[1]}, a_{1}^{[1]}=\sigma\left(z_{1}^{[1]}\right)} \\ {z_{2}^{[1]}=w_{2}^{[1] T} x+b_{2}^{[1]}, a_{2}^{[1]}=\sigma\left(z_{2}^{[1]}\right)} \\ {z_{3}^{[1]}=w_{3}^{[1] T} x+b_{3}^{[1]}, a_{3}^{[1]}=\sigma\left(z_{3}^{[1]}\right)} \\ {z_{4}^{[1]}=w_{4}^{[1] T} x+b_{4}^{[1]}, a_{4}^{[1]}=\sigma\left(z_{4}^{[1]}\right)}\end{array}
  • 向量化
    ,即为的列向量



    所以有


    考虑到可以记作,从而有如下单隐层神经网络的计算公式:

\begin{array}{l}{z^{[1]}=W^{[1]} a^{[0]}+b^{[1]}} \\ {a^{[1]}=\sigma\left(z^{[1]}\right)} \\ {z^{[2]}=W^{[2]} a^{[1]}+b^{[2]}} \\ {a^{[2]}=\sigma\left(z^{[2]}\right)}\end{array}

2.3 计算单隐层神经网络的输出——多样本训练集

  • 如果训练集有个样本,需要对每个样本都计算上面4个式子。

for i=1 to m:
\begin{aligned} z^{[1](i)} &=W^{[1]} x^{(i)}+b^{[1]} \\ a^{[1](i)} &=\sigma\left(z^{[1](i)}\right) \\ z^{[2](i)} &=W^{[2]} a^{[1](i)}+b^{[2]} \\ a^{[2](i)} &=\sigma\left(z^{[2](i)}\right) \end{aligned}

  • 向量化
    仍然采用前面的记号
    ,即为矩阵,一列代表一个样本。
    ,即为矩阵,一列代表一个样本在不同节点的值。
    ,即为矩阵,一列代表一个样本在不同节点的值。
    即一列是同一层不同的节点,一行是同一层同一节点的不同样本。
    从而有向量化结果:

\begin{aligned} Z^{[1]} &=W^{[1]} X+b^{[1]} \\ A^{[1]} &=\sigma\left(Z^{[1]}\right) \\ Z^{[2]} &=W^{[2]} A^{[1]}+b^{[2]} \\ A^{[2]} &=\sigma\left(Z^{[2]}\right) \end{aligned}

考虑到,所以可以写成如下对称的形式:

\begin{aligned} Z^{[1]} &=W^{[1]} A^{[0]}+b^{[1]} \\ A^{[1]} &=\sigma\left(Z^{[1]}\right) \\ Z^{[2]} &=W^{[2]} A^{[1]}+b^{[2]} \\ A^{[2]} &=\sigma\left(Z^{[2]}\right) \end{aligned}

3 激活函数

3.1 激活函数

在前面的推导中,我们的激活函数一直用的 sigmoid函数,还有其他的激活函数可以用(一般是非线性函数,后面会解释为什么是非线性函数)。

  • 双曲正切函数(hyperbolic tangent function)
    ,函数值在-1与1之间,函数图像为
    双曲正切函数
  • 在隐藏层,如果激活函数取为双曲正切函数效果基本都比sigmoid函数好。因为双曲正切函数的均值是0,从而有类似数据中心化的作用,从而让下一层的学习更方便一点。所以几乎大部分情况都用此激活函数
  • 有一个例外,二分类的输出层用sigmoid函数作为激活函数效果更好。

\begin{aligned} Z^{[1]} &=W^{[1]} X+b^{[1]} \\ A^{[1]} &=g^{[1]}(z)=tanh\left(Z^{[1]}\right) \\ Z^{[2]} &=W^{[2]} A^{[1]}+b^{[2]} \\ A^{[2]} &= g^{[2]}(z)=\sigma\left(Z^{[2]}\right) \end{aligned}

  • sigmoid函数和tanh函数都有的一个就是如果非常大或者非常小,导数就接近于0,从而拖慢梯度下降方法。另一个常用的激活函数就是ReLU函数(rectified linear unit),函数图像为

    ReLU函数图像

    • ,导数为1
    • ,导数为0
    • ,导数不存在,可以定义为0或1,并不影响
  • 选择激活函数的经验

    • 二分类,即输出为0或1,用sigmoid函数;
    • 其他都用ReLU函数。ReLU已经成为激活函数的默认选择了,尤其如果你不知道用什么激活函数那就用ReLU函数!
  • ReLU函数的就是是导数为0,为此有leaky ReLU函数,修改是函数取值不为0,例如可以定义为,即。函数图像为

    leaky ReLu函数图像

  • ReLU与leaky ReLU的就是没有斜率离0很远,从而梯度类方法很快。

3.2 为什么需要非线性激活函数?

  • 为什么在神经网络中不简单的使用线性函数作为激活函数?让我们来看一下。

\begin{aligned} Z^{[1]} &=W^{[1]} X+b^{[1]} \\ A^{[1]} &=g^{[1]}(z)=Z^{[1]} \\ Z^{[2]} &=W^{[2]} A^{[1]}+b^{[2]} \\ A^{[2]} &= g^{[2]}(z) = Z^{[2]} \end{aligned}

从而有


所以无论你的神经网络有多少层,实际上效果仍然是去掉中间所有隐层的线性回归,类似的,如果,那么无论有多少层都效果都是logistic回归。

  • 有一种情况可以使用线性函数,就是回归问题(预测值是实数)的输出层,此时的隐藏层仍然不用线性函数。

3.3 激活函数的导数

  • Sigmoid激活函数
    sigmoid函数

    实际上,前面已经计算过了
    • 当比较大时,从而,与图像吻合;
    • 当比较小时,从而,与图像吻合;
      当,,从而,与图像吻合。
    • 只要计算出的值就能很快算出来导数为。
  • tanh激活函数
    tanh激活函数



    • 当比较大时,从而,与图像吻合;
    • 当比较小时,从而,与图像吻合;
    • 当,,从而,与图像吻合;
    • 只要计算出的值就能很快算出来导数为。
  • ReLU激活函数与Leaky ReLU激活函数
    • ReLU激活函数
      ReLU与leaky ReLU激活函数


      事实上,借助一次梯度的概念,可以定义为
    • leaky ReLU 激活函数

      事实上,借助一次梯度的概念,可以定义为

4. 神经网络的梯度下降法

  • 目的:学习神经网络的参数

  • 参数:

  • cost function:

  • 前向传播(Forward Propagation):

  • 反向传播(Backward Propagation):

    • ,


    • ,

      • 上式第一个乘积是矩阵乘积,得到维矩阵, 是维,所以后面的是逐个元素乘积。
    • ,keepdims参数可以不用,但为了防止出现秩为1的奇怪数组,需用reshape命令。

    随后迭代



  • 小结:正向与反向传播的主要公式如下


    正向与反向传播主要公式

5. 参数初始化

  • Logistic回归可以把参数初始化为0
  • 但除Logistic回归外,一般参数会随机初始化,而不是初始化为0。
    如果把神经网络的全部参数都初始化为0,再使用梯度下降法,则会失效。
    此时会出现完全对称话,影响主要是权重参数,事实上,如果把偏置参数都初始化为0是可以的。但是对权重参数如果都初始化为0,那么无论你的隐层有多少个节点,事实上它们计算的都是同一个函数,和只有一个节点是一样一样的,如下图所示:
    权重初始化为0示意图
  • 解决方法
W^[1] = np.random.randn(n^[1],n) * 0.01
b^[1] = np.zeros(n^[1],1)
W^[2] = np.random.randn(n^[2],n^[1]) * 0.01
b^[2] = np.zeros(n^[2],1)

之所以要乘以一个很小的0.01,是考虑到如果激活函数使用的是sigmoid函数或者tanh函数,很大时,此时梯度下降算法很慢,会减慢学习速度。

你可能感兴趣的:(神经网络和深度学习WU Week3——浅层神经网络)