吴恩达机器学习个人笔记(四)-神经网络的学习

1 代价函数

     一开始先引入神经网络的新标记方法:   若神经网络的样本有m个,每个包含一组输入x和一组输出信号y,例如下列方式(x^{1},y^{1}),(x^{2},y^{2})\cdots (x^{m},y^{m}) 其中x^{m}和 y^{m} 都可能为向量。L表示为神经网络的层数,S_{l}表示为l层神经网络的神经元数,不包括该层的偏差单元

神经网络的分类可以定义为两种情况:二类分类和多类分类。二类分类时,输出层只有一个单元即 y=0 or 1,y表示为输出信号,K类分类即多类分类时 y_{i}=1,表示为分到第 i类(K>2)这两类情况如下所示。

              

逻辑回归当中,我们的代价函数为:

               \dpi{120} J(\theta)=-\frac{1}{m}\sum_{i=1}^m[y^{(i)}log(h_{\theta }(x^{(i)}))+(1-y^{(i)})log(1-h_{\theta }(x^{(i)}))]+\frac{\lambda }{2m}\sum_{j=1}^n\theta _{j}^{2}

在逻辑回归中,我们只有一个输出变量,然后在神经网络中,每层神经网络有多个神经单元,所以 h_{\theta }(x) 是一个维度为k的向量,因此神经网络的代价函数会比逻辑回归的更复杂,如下所示。

          J(\theta)=-\frac{1}{m}[\sum_{i=1}^m\sum_{k=1}^k[y^{(i)}log(h_{\theta }(x^{(i)}))_{k}+(1-y_{k}^{(i)})log(1-h_{\theta }(x^{(i)})_{k})]+\frac{\lambda }{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_{l}}\sum_{j=1}^{s_{l}+1}\theta _{j}^{2}

看起来比逻辑单元复杂很多,但是思想都是一样的,即通过代价函数来检测算法的误差。只不过由于输出y为k维向量并且\theta为多个矩阵,所以变得异常复杂。

2 反向传播算法(Backpropagation Algorithm)

       之前计算神经网络预测结果的时候采用了一种正向传播的方法,从第一层开始向下一层计算,直到计算出最后的结果。为了计算代价函数的偏导数  \frac{\partial }{\partial \theta _{ij}^{l}}J(\theta ),我们需要采用一种反向传播的算法,也就是首先计算最后一层误差,然后再一层一层反向求出各层的误差,直到倒数第二层。正向传播也就是向前传播如下所示

                       

                                             

第一层为 a^{(1)},为输入的数据x。第二层为a^{(2)},如上图所示 a^{(2)}=g(z^{(2)}),z^{(2)}=a^{(1)}\Theta ^{(1)},\Theta ^{(1)}为第一层到第二层之间的参数,上篇博客讲到,\Theta ^{(1)}的大小为5\times 4。其他层的结果也如此计算。

从最后一层的误差开始计算,误差是激活单元的预测(a^{(4)})与实际值y之间的误差。用\delta来表示误差,即:\delta ^{(4)}=a^{(4)}-y。再利用这个第四层的误差计算前一层的误差 \delta ^{(3)}=\left ( \Theta ^{(3)} \right )^{T}\delta ^{(4)}*g^{'}\left ( z^{(3)} \right ),其中g^{'}\left ( z^{(3)} \right )为之前所讲述的sigmod函数g^{'}\left ( z^{(3)} \right )=a^{(3)}*(1-a^{(3)})。下一步为依据该误差计算第二层的误差\delta ^{(2)}=\left ( \Theta ^{(2)} \right )^{T}\delta ^{(3)}*g^{'}\left ( z^{(2)} \right ),第一层为输入变量,不存在误差。我们有了所有层的(除去输入层)的误差表达式后,即可计算代价函数的偏导数了,假设\lambda =0,即不做任何正则化处理时有偏导数  \frac{\partial }{\partial \theta _{ij}^{l}}J(\theta )=a_{j}^{(l)}\delta _{i}^{(l+1)}

 l代表目前所计算的是第几层。

 j代表目前计算层中的激活单元的下标,也将是下一层的第j个输入变量的下标。

 i代表下一层中误差单元的下标,是受到权重矩阵中第i行影响的下一层中的误差单元的下标

上面所述并且图中,输入数据只有一组为(x,y),如果我们的输入数据为矩阵即(x^{1},y^{1}),(x^{2},y^{2})\cdots (x^{m},y^{m}),那么我们就要为整个训练集计算误差。此时的误差单元也是一个矩阵,用 \Delta _{ij}^{(l)},l表示层数算法如下                               

由于我们的数据集中有m对,因此使用一个for循环。现将每次的输入数据设为a^{(1)},然后使用向前传播算法计算神经网络中的每层的激励单元,计算出最终预测结果后,计算上诉的误差,然后再一层一层的反向传播计算误差,最后相交到一个矩阵。

说实话对这个还有有点迷糊,不过后面吴恩达老师详细解释了反向传播算法。听完还是觉得云里雾里,所以在网上查阅,觉得这篇文章写得很好,读了之后对反向传播有一点认识,至少不会一头雾水一文弄懂神经网络中的反向传播法——BackPropagation

4梯度检验

       当我们对一个较为复杂的模型(例如神经网络)使用梯度下降算法时,可能会存在一些不容易察觉的错误,意味着,虽然代价看上去在不断减小,但最终的结果可能并不是最优解。

       为了避免这样的问题,我们采取一种叫做梯度的数值检验(Numerical Gradient Checking)方法。这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。梯度值就是某一点的导数值,非常的容易理解,如下所示

                                  

这是我们常见的一个点的导数的示意图即  \frac{\partial}{\partial_{\theta }}=\frac{J(\theta +\varepsilon )-J(\theta -\varepsilon )}{2\varepsilon }   ,\varepsilon的取值非常小。当\theta是一个向量时,需要对偏导数进行检验,因为代价函数只针对一个参数逇变化进行检验,如果 \theta _{1}是向量\theta内的一个值,那么针对\theta _{1}的检验为

\frac{\partial}{\partial_{\theta _{1}}}=\frac{J(\theta _{1}+\varepsilon ,\theta _{2},\theta _{3}\cdots \theta _{n})-J(\theta _{1}-\varepsilon ,\theta _{2},\theta _{3}\cdots \theta _{n})}{2\varepsilon }

根据上面的算法,计算出的偏导数存储在矩阵D_{ij}^{(l)}检验时,我们要将该矩阵展开成为向量,同时我们也将 矩阵展开为向量\theta,我们针对每一个 \theta都计算一个近似的梯度值,将这些值存储于一个近似梯度矩阵中,最终将得出的这个矩阵同 D_{ij}^{(l)} 进行比较。如下所示

                          

5随机初始化

任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果我们令所有的初始参数都为0,这将意味着我们第二层的所有激活单元都会有相同的值。同理,如果我们初始所有的参数都为一个非0的数,结果也是一样的。

我们通常初始参数为正负ε之间的随机值,假设我们要随机初始一个尺寸为10×11的参数矩阵,代码如下

            Theta1 = rand(10, 11) * (2*eps) – eps

6总结

总结一下使用神经网络的步骤:

网络结构:第一件要做的事是选择网络结构,即决定选择多少层以及决定每层分别有多少个单元。

第一层的单元数即我们训练集的特征数量。

最后一层的单元数是我们训练集的结果的类的数量。

如果隐藏层数大于1,确保每个隐藏层的单元个数相同,通常情况下隐藏层单元的个数越多越好。

我们真正要决定的是隐藏层的层数和每个中间层的单元数。

训练神经网络:

  1. 参数的随机初始化
  2. 利用正向传播方法计算所有的h_{\theta }(x)
  3. 编写计算代价函数J  的代码
  4. 利用反向传播方法计算所有偏导数
  5. 利用数值检验方法检验这些偏导数
  6. 使用优化算法来最小化代价函数

猜你喜欢

转载自blog.csdn.net/Huang_cainiao/article/details/82988359