ML 07 - NN Construction

186 阅读7分钟

神经网络进阶

一、代价函数

1. 神经网络(分类)

  1. 基本结构

    假设神经网络的训练样本有m个,每个包含-组输入x和一组输出信号y,L表示神经网络层数,SIS_I表示每层的 neuron个数(SlS_l表示第ll层中的单元个数,不计偏移量单元),sLs_L代表最后一层中处理单元的个数。

8f7c28297fc9ed297f42942018441850.jpg 2. 分类问题类型

  1. 二元分类

    SL=0y=0or1S_L = 0, y=0 or 1表示哪一类 .

  2. 多元分类(返回值个数\ge 3)

    SL=k,yi=1S_L = k, y_i = 1表示分到第 ii类.

主要是返回的数据表示不同。

2. 代价函数比较

以下代价函数都含有正则化项,减轻过拟合倾向。

  1. 逻辑回归

    J(θ)=1m[i=1my(i)loghθ(x(i))+(1y(i))log(1hθ(x(i)))]+λ2mj=1nθj2J(\theta)=-\frac{1}{m}\left[\sum_{i=1}^{m} y^{(i)} \log h_{\theta}\left(x^{(i)}\right)+\left(1-y^{(i)}\right) \log \left(1-h_{\theta}\left(x^{(i)}\right)\right)\right]+\frac{\lambda}{2 m} \sum_{j=1}^{n} \theta_{j}^{2}

    在逻辑回归中,我们只含有一个输出变量,也称标量(scalar),同时也只有一个因变量,但是在神经网络中我们我们可以有很多输出变量,我们的假设函数hθ(x)h_\theta(x)是一个维度为KK的向量,并且我们训练集中的因变量也是同样维度的一个向量,因此我们的代价函数会比逻辑回归更加复杂一些:hθ(x)RK,(hθ(x))i=ithoutputh_\theta(x) \in R^K, (h_\theta(x))_i = i^{th}output

  2. 神经网络

    J(Θ)=1m[i=1mk=1kyk(i)log(hΘ(x(i)))k+(1yk(i))log(1(hΘ(x(i)))k)]+λ2ml=1L1i=1slj=1sl+1(Θji(l))2J(\Theta)=-\frac{1}{m}\left[\sum_{i=1}^{m} \sum_{k=1}^{k} y_{k}^{(i)} \log \left(h_{\Theta}\left(x^{(i)}\right)\right)_{k}+\left(1-y_{k}^{(i)}\right) \log \left(1-\left(h_{\Theta}\left(x^{(i)}\right)\right)_{k}\right)\right]+\frac{\lambda}{2 m} \sum_{l=1}^{L-1} \sum_{i=1}^{s_{l}} \sum_{j=1}^{s_{l}+1}\left(\Theta_{j i}^{(l)}\right)^{2}

    这个看起来复杂很多的代价函数背后的思想还是一样的,我们希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,我们都会给出KK个预测,基本上我们可以利用循环,对每一行特征都预测KK个不同结果,然后在利用循环在KK个预测中选择可能性最高的一个,将其与yy中的实际数据进行比较.

正则化的那一项只是排除了每一层θ0\theta_0后,每一层的 θ\theta矩阵的和。最里层的循环jj循环所有的行(由sls_l +1 层的激活单元数决定),循环ii则循环所有的列,由该层(sls_l层)的激活单元数所决定。即:hθ(x)h_\theta(x)与真实值之间的距离为每个样本-每个类输出的加和,对参数进行regularizationbias项处理所有参数的平方和。

二、反向传播算法

用于优化迭代代价函数。有别于从第一层开始,正向一层一层进行计算,直到最后一层的hθ(x)h_\theta(x)的正向传播算法。为了计算代价函数的Θij(l)J(Θ)\frac{\partial}{\partial \Theta_{ij}^{(l)}} J(\Theta),我们要采用一种反向传播算法,也即是**首先计算最后一层的误差,然后一层一层反向求出各层误差,直到倒数第二层。**倒数第一层是输入层不用计算其误差。

假设我们的训练集只有一个样本(x(1),y(1)(x^{(1)}, y^{(1)},我们的神经网络是一个四层的神经网络,其中K=4,SL=4,L=4K = 4, S_L =4, L =4:

6a0954ad41f959d7f272e8f53d4ee2de.jpg

  1. 梯度下降(前向传播算法)

    1. 过程

      给定训练集:(x,y)(x,y),前向传播:

      a(1)=xz(2)=Θ(1)a(1)a(2)=g(z(2))(adda0(2))z(3)=Θ(2)a(2)a(3)=g(z(3))(adda0(3))z(4)=Θ(3)a(3)a(4)=hΘ(x)=g(z(4))\begin{array}{l} a^{(1)}=x \\ z^{(2)}=\Theta^{(1)} a^{(1)} \\ a^{(2)}=g\left(z^{(2)}\right) \quad\left(\operatorname{add} a_{0}^{(2)}\right) \\ z^{(3)}=\Theta^{(2)} a^{(2)} \\ a^{(3)}=g\left(z^{(3)}\right) \quad\left(\operatorname{add} a_{0}^{(3)}\right) \\ z^{(4)}=\Theta^{(3)} a^{(3)} \\ a^{(4)}=h_{\Theta}(x)=g\left(z^{(4)}\right) \end{array}

    2. 计算方式

      • 我们从最后一层的误差开始计算,误差是激活单元的预测(a(4)a^{(4)})与实际值(yky^k)之间的误差,(k = 1:k)。 我们用δ\delta来表示误差,则:δ(4)=a(4)y\delta^{(4)} = a^{(4)} -y 我们利用这个误差值来计算前一层的误差: δ(3)=(Θ(3))Tδ(4)g(z(3))\delta^{(3)}=\left(\Theta^{(3)}\right)^{T} \delta^{(4)} * g^{\prime}\left(z^{(3)}\right)其中 g(z(3)g^{\prime}(z^{(3)}是S 形函数的导数,g(z(3))=a(3)(1a(3))g^{\prime}\left(z^{(3)}\right)=a^{(3)} *\left(1-a^{(3)}\right)。而(Θ(3))Tδ(4)(\Theta^{(3)})^{T} \delta^{(4)}则是权重导致的误差的和。下一步是继续计算第二层的误差: δ(2)=(Θ(2))Tδ(3)g(z(2))\delta^{(2)}=\left(\Theta^{(2)}\right)^{T} \delta^{(3)} * g^{\prime}\left(z^{(2)}\right) ,因为第一层是输入变量,不存在误差。我们有了所有的误差的表达式后,便可以计算代价函数的偏导数了,假设λ=0\lambda = 0,即我们不做任何正则化处理时有:Θij(l)J(Θ)=aj(l)δil+1\frac{\partial}{\partial \Theta_{i j}^{(l)}} J(\Theta)=a_{j}^{(l)} \delta_{i}^{l+1}

      • 重要的是清楚地知道上面式子中上下标的含义:

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

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

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

      • 如果我们考虑正则化处理,并且我们的训练集是一个特征矩阵而非向量。在上面的特殊情况中,我们需要计算每一层的误差单元来计算代价函数的偏导数。在更为一般的情况中,我们同样需要计算每一层的误差单元,但是我们需要为整个训练集计算误差单元,此时的误差单元也是一个矩阵,我们用Δij(l)\Delta^{(l)}_{ij}来表示这个误差矩阵。第 ll层的第 ii个激活单元受到第 jj个参数影响而导致的误差。

  2. 反向传播算法计算梯度

    1. 表示:

      5514df14ebd508fd597e552fbadcf053-16522758089307.jpg

      即首先用正向传播方法计算出每一层的激活单元,利用训练集的结果与神经网络预测的结果求出最后一层的误差,然后利用该误差运用反向传播法计算出直至第二层的所有误差。

    2. 在求出了 Δij(l)\Delta_{i j}^{(l)} 之后,我们便可以计算代价函数的偏导数了,计算方法如下: Dij(l):=1mΔij(l)+λΘij(l)ifj0Dij(l):=1mΔij(l) if j=0 D_{i j}^{(l)}:=\frac{1}{m} \Delta_{i j}^{(l)}+\lambda \Theta_{i j}^{(l)} i f j \neq 0 D_{i j}^{(l)}:=\frac{1}{m} \Delta_{i j}^{(l)} \text { if } j=0

三、理解反向传播算法

  1. 前向传播算法

    1. 过程 63a0e4aef6d47ba7fa6e07088b61ae68.png
  2. 反向传播算法具体内容

    1. 计算过程:

    57aabbf26290e2082a00c5114ae1c5dc.png

    1. 代价函数:

      J(Θ)=1m[i=1mk=1kyk(i)log(hΘ(x(i)))k+(1yk(i))log(1(hΘ(x(i)))k)]+λ2ml=1L1i=1slj=1sl+1(Θji(l))2J(\Theta)=-\frac{1}{m}\left[\sum_{i=1}^{m} \sum_{k=1}^{k} y_{k}^{(i)} \log \left(h_{\Theta}\left(x^{(i)}\right)\right)_{k}+\left(1-y_{k}^{(i)}\right) \log \left(1-\left(h_{\Theta}\left(x^{(i)}\right)\right)_{k}\right)\right]+\frac{\lambda}{2 m} \sum_{l=1}^{L-1} \sum_{i=1}^{s_{l}} \sum_{j=1}^{s_{l}+1}\left(\Theta_{j i}^{(l)}\right)^{2}

四、梯度检验

主要用于神经网络使用反向传播进行梯度下降迭代算法时产生的误差:代价函数值不断减小,但是精确值不高的情况。采取一种叫做梯度的数值检验(Numerical Gradient Checking)方法。这种方法的思想是通过估计梯度值来检验我们计算的导数值是否真的是我们要求的。

  1. 对梯度的估计方式:

    在代价函数上沿着切线的方向选择离两个非常近的点然后计算两个点的平均值用以估计梯度。即对于某个特定的 θ\theta,我们计算出在 θ\theta - ε\varepsilon 处和 θ\theta + ε\varepsilon 的代价值( ε\varepsilon 是一个非常小的值,通常选取 0.001),然后求两个代价的平均,用以估计在 处的θ\theta代价值。

    5d04c4791eb12a74c843eb5acf601400.png

  2. 多变量梯度:

    当是θ\theta一个向量时,我们则需要对偏导数进行检验。因为代价函数的偏导数检验只针对一个参数的改变进行检验,下面是一个只针对θ1\theta_1进行检验的示例:θ1=J(θ1+ε1,θ2,θ3θn)J(θ1ε1,θ2,θ3θn)2ε\frac{\partial}{\partial \theta_{1}}=\frac{J\left(\theta_{1}+\varepsilon_{1}, \theta_{2}, \theta_{3} \ldots \theta_{n}\right)-J\left(\theta_{1}-\varepsilon_{1}, \theta_{2}, \theta_{3} \ldots \theta_{n}\right)}{2 \varepsilon},依次类推可以得出θn\theta_n的偏导数:θn=J(θ1,θ2,θ3θn+εn)J(θ1,θ2,θ3θnεn)2ε\frac{\partial}{\partial \theta_{n}}=\frac{J\left(\theta_{1}, \theta_{2}, \theta_{3} \ldots \theta_{n}+\varepsilon_{n}\right)-J\left(\theta_{1}, \theta_{2}, \theta_{3} \ldots \theta_{n}-\varepsilon_{n}\right)}{2 \varepsilon}.

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

五、随机初始化

1. 0初始化

对权值进行0初始化对逻辑回归是可行的,但是对于神经网络来说一定不行。如果我们令所有的初始参数都为0,这将意味着我们第二层的所有激活单元都会有相同的值(输入值)。同理,如果我们初始所有的参数都为一个相同的非0的数,结果也是一样的。

2. 随机初始化

通常我们把所有参数随机初始化为一个非常小的数:位于[ε,+ε][- \varepsilon, +\varepsilon ]之间。Pytorch的Linear会自动进行随机初始化。

六、回顾

1. 训练一个神经网络

  1. 基本概念
    1. 网络结构:第一件要做的事是选择网络结构,即决定选择多少层以及决定每层分别有多少个单元。
    2. 第一层的单元数即我们训练集的特征数量。
    3. 最后一层的单元数是我们训练集的结果的类的数量。
    4. 如果隐藏层数大于1,确保每个隐藏层的单元个数相同,通常情况下隐藏层单元的个数越多越好。
    5. 我们真正要决定的是隐藏层的层数和每个中间层的单元数
  2. 训练网络的基本步骤
    1. 随机初始化各层权重
    2. 实现前向传播
    3. 计算代价函数
    4. 反向传播计算各层偏导数(不包括输入层)
    5. 使用梯度检查,比较反向传播得出的偏导数和纯数值计算得出的偏导数,然后禁用提督检查码
    6. 使用梯度下降或者之前的优化迭代方式结合反向传播来降低代价函数的值