• 深度学习——深度神经网络(DNN)反向传播算法


      深度神经网络(Deep Neural Networks,简称DNN)是深度学习的基础。

      回顾监督学习的一般性问题。假设我们有$m$个训练样本$\{(x_1, y_1), (x_2, y_2), …, (x_m, y_m)\}$,其中$x$为输入向量,$y$为输出向量,利用这个训练样本训练模型的参数,使得给定模型一个$x_{test}$,其能够预测$y_{test}$。

      采用CNN模型的时候,$x$输入向量全部喂给输入层,$y$输出向量和输出层的向量一起计算损失函数,而其中若干个神经元的隐藏层,每一个隐藏层都有对应的权重矩阵$W$和偏置向量$b$,对于训练过程中,喂入样本$x$得到$y_{predict}$,根据$y_{predict}$以及$y$计算出的损失函数,怎么去更新网络中的参数,即需要反向传播算法。在机器学习中,求出损失函数的最小极值,其对应的参数即为我们所期望的到的。在DNN中,常用的优化极值求解过程的方法为梯度下降法,其他还有牛顿法、拟牛顿法等等。

      综上,对DNN的损失函数采用梯度下降法进行迭代优化求极小值的过程即为反向传播算法。

    1 - DNN反向传播算法

      定义一个损失函数,度量训练样本通过模型的预测输出与真实输出之间的差距(损失)。训练样本的预测输出可以通过一系列对于第l层的一般公式${a^{l}}=\sigma(z^{l})=\sigma(W^{l}a^{l-1}+b^{l})$计算得出。输出层对应的${a^{L_{output}}}$即为模型预测的输出。

    DNN常用可选择均方差来作为损失函数,其公式如下$$J(W,b,x,y)=\frac{1}{2}\begin{Vmatrix}a^{L}-y \end{Vmatrix}^2_2$$

      其中$a^L$和$y$分别为预测输出和期望真实输出(期望输出),而$\begin{Vmatrix}S\end{Vmatrix}_2$为$S$的$L2$范数。

    对于输出层$L_{output}$,其$W_{output}$和$b_{output}$满足如下公式:$${a^{L_{output}}}=\sigma(z^{L_{output}})=\sigma(W^{L_{output}}a^{L_{output\_prev}}+b^{L_{output}})$$

    因此,对于输出层的参数,我们有损失函数如下:

    $$J(W,b,x,y)=\frac{1}{2}\begin{Vmatrix}a^{L_{output}}-y\end{Vmatrix}^2_2=\frac{1}{2}\begin{Vmatrix} \sigma(W^{L_{output}}a^{L_{output\_prev}}+b^{L_{output}})-y\end{Vmatrix}^2_2$$

    因此对于该损失函数,可对其对于输出层的$W_{output}$和$b_{output}$分别求偏导数从而得到梯度,如下:

    $$\frac{\partial J(W,b,x,y)}{\partial W^{L_{output}}}=\frac{\partial J(W,b,x,y)}{\partial z^{L_{output}}}\frac{\partial z^{L_{output}}}{\partial W^{L_{output}}}=(a^{L_{output}}-y)\bigodot \sigma^{'}(z^{L_{output}})(a^{L_{output\_prev}})^T$$

    $$\frac{\partial J(W,b,x,y)}{\partial b^{L_{output}}}=\frac{\partial J(W,b,x,y)}{\partial z^{L_{output}}}\frac{\partial z^{L_{output}}}{\partial b^{L_{output}}}=(a^{L_{output}}-y)\bigodot \sigma^{'}(z^{L_{output}})$$

    上述$\bigodot$代表$Hadamard$积,对于两个维度相同的向量$A(a_1,a_2,...,a_n)^T$和$B(b_1,b_2,...,b_n)^T$,有${A}\bigodot{B}=(a_1b_1,a_2b_2,...,a_n,b_n)^T$。

    对于$W_{output}$和$b_{output}$,有公共部分$\frac{\partial J(W,b,x,y)}{\partial z^{L_{output}}}$,将其记做$\delta^L$,如下:

    $$\delta^L=\frac{\partial J(W,b,x,y)}{\partial z^{L_{output}}}=(a^{L_{output}}-y)\bigodot \sigma^{'}(z^{L_{output}})$$

    以上就是计算输出层的梯度,而对于第l层的梯度,根据链式法则可得公式如下:

    $$\delta^l=\frac{\partial J(W,b,x,y)}{\partial z^{l}}=\frac{\partial J(W,b,x,y)}{\partial z^{L_{output}}}\frac{\partial z^{L_{output}}}{\partial z^{L-1}}\frac{\partial z^{L-1}}{\partial z^{L-2}}...\frac{\partial z^{l+1}}{\partial z^{l}}$$

    注意到,其中$L_{output}$等价于$L$。这对于任意第l层,计算出该层的$W^l$和$b^l$的梯度如下:

    $$\frac{\partial J(W,b,x,y)}{\partial W^{l}}=\frac{\partial J(W,b,x,y)}{\partial z^{l}}\frac{\partial z^{l}}{\partial W^{l}}=\delta^l(a^{l-1})^T $$

    $$\frac{\partial J(W,b,x,y)}{\partial b^{l}}=\frac{\partial J(W,b,x,y)}{\partial z^{l}}\frac{\partial z^{l}}{\partial b^{l}}=\delta^l $$

    因此,关键是需要求出$\delta^l$。注意到有递推公式$\delta^l=\frac{\partial J(W,b,x,y)}{\partial z^l}=\frac{\partial J(W,b,x,y)}{\partial z^{l+l}}\frac{z^{l+1}}{z^l}=\delta^{l+1}\frac{\partial z^{l+1}}{\partial z^l}$,所以关键在于求解$\frac{\partial z^{l+1}}{\partial z^l}$。而$z^{l+1}$和$z^l$的关系可以表示为$z^{l+1}=W^{l+1}a^l+b^{l+1}=W^{l+1}\sigma(z^l)+b^{l+1}$,可以得出如下关系:

    $$\frac{\partial z^{l+1}}{\partial z^l}=(W^{l+1})^T\bigodot\begin{matrix}\underbrace{(\sigma^{'}(z^l),...,\sigma^{'}(z^l))}\\ n={l+1}\end{matrix}$$

    代入上式可以得到:

    $$\delta^l=\delta^{l+1}\frac{\partial z^{l+1}}{\partial z^l}=(W^{l+1})^T\delta^{l+1}\bigodot\sigma^{'}(z^{l})$$

    综上,可以通过$\delta^l$求出对应l层的$W^l$和$b^l$的梯度。

    2 - DNN反向传播伪代码

    initialize all variables by random value
    for loop from 1 to num_epoch 
        choose x_i as the model input 
        compute the output of the output-layer a^L 
        compute the δ^L of the output-layer 
        for l=L to 2 
            compute the δ^l based on δ^(l+1) and W^(l+1) and z^l 
            compute the gradient of W^l and b^l 
            update the W^l and b^l in lth-layer:W^l = W^l-αsum(δ^l(a^(l-1)^T), b^l=b^l-αsum(δ^l)

     

    3 - 参考资料

    https://www.cnblogs.com/pinard/p/6422831.html

  • 相关阅读:
    python--多线程&多进程
    python--MyRequest请求模块封装
    python--面向对象
    python--异常处理
    python--sys.argv 运行python文件时获取参数
    python--搭建测试环境
    mac常用快捷键
    九、django通过forms对页面数据校验
    八、django后台管理
    七、django页面请求处理
  • 原文地址:https://www.cnblogs.com/CZiFan/p/9474615.html
Copyright © 2020-2023  润新知