梯度下降法和反向传导法

最近在看关于CNN的一些论文,经常遇到一些概念不明不白的,所以下决心把那些基础概念整明白。

本次博客主要是先介绍梯度下降法然后介绍反向传导法。其实从某种方向上看两者是很相似的。


一,梯度下降法

梯度下降法又称最速下降法。首先我们应该清楚,一个多元函数的梯度方向是该函数值增大最陡的方向。具体到假如是一元函数,其梯度方向就是切线方向。举个例子:

有函数y=x*x-3*x+2,有x0=0,步长为0.5,收敛精度为0.00001.其求解如下:

        (1)计算x第i次的迭代公式:x(i)=x(i)-0.5*(2*x(i)-3);

(2)将初始的y0的值赋值给y1,并将x(i)带入到y0中去

(3)y0与y1的差值,若差值小于收敛精度就结束,否则迭代(1),(2),(3)直到差值达到收敛精度。


另外与最小二乘法类似梯度下降法主要是用于解决线性拟合问题。例如有m个样本点{(x1,y1),(x2,y2),...,(xm,ym)}

我们假设给出的函数模型是h(θ)=θ0+θ1*x1+...+θm*xm ,根据样本点求取具体θ集合的值。首先我们创建一个对函数模型h(θ)进行好坏评估的的损失函数:

我们的目标是根据θ集来求取最小的J(θ)的值。

梯度下降法是按下面的流程进行的:

1)首先对θ赋值,这个值可以是随机的。

2)改变θ的值,使得J(θ)按梯度下降的方向进行减少。

首先我们对函数J(θ)相对于向量θ的每个分量求偏导。

然后利用求得的偏导分量迭代的求θ的值,

最后根据得到的θ值带入到J(θ)中,若J(θ)变化不大,则结束,否则迭代求解。



二,反向传导法

反向传播算法的思路如下:给定一个样例 \textstyle (x,y),我们首先进行“前向传导”运算,计算出网络中所有的激活值,包括 \textstyle h_{W,b}(x) 的输出值。之后,针对第 \textstyle l 层的每一个节点 \textstyle i,我们计算出其“残差” \textstyle \delta^{(l)}_i,该残差表明了该节点对最终输出值的残差产生了多少影响。对于最终的输出节点,我们可以直接算出网络产生的激活值与实际值之间的差距,我们将这个差距定义为 \textstyle \delta^{(n_l)}_i (第 \textstyle n_l 层表示输出层)。对于隐藏单元我们如何处理呢?我们将基于节点(译者注:第 \textstyle l+1 层节点)残差的加权平均值计算 \textstyle \delta^{(l)}_i,这些节点以 \textstyle a^{(l)}_i 作为输入。下面将给出反向传导算法的细节:

  1. 进行前馈传导计算,利用前向传导公式,得到 \textstyle L_2, L_3, \ldots 直到输出层 \textstyle L_{n_l} 的激活值。
  2. 对于第 \textstyle n_l 层(输出层)的每个输出单元 \textstyle i,我们根据以下公式计算残差:
    \begin{align}\delta^{(n_l)}_i= \frac{\partial}{\partial z^{(n_l)}_i} \;\;        \frac{1}{2} \left\|y - h_{W,b}(x)\right\|^2 = - (y_i - a^{(n_l)}_i) \cdot f'(z^{(n_l)}_i)\end{align}
    [译者注:
    \begin{align}\delta^{(n_l)}_i &= \frac{\partial}{\partial z^{n_l}_i}J(W,b;x,y) = \frac{\partial}{\partial z^{n_l}_i}\frac{1}{2} \left\|y - h_{W,b}(x)\right\|^2 \\ &= \frac{\partial}{\partial z^{n_l}_i}\frac{1}{2} \sum_{j=1}^{S_{n_l}} (y_j-a_j^{(n_l)})^2 = \frac{\partial}{\partial z^{n_l}_i}\frac{1}{2} \sum_{j=1}^{S_{n_l}} (y_j-f(z_j^{(n_l)}))^2 \\ &= - (y_i - f(z_i^{(n_l)})) \cdot f'(z^{(n_l)}_i) = - (y_i - a^{(n_l)}_i) \cdot f'(z^{(n_l)}_i)\end{align}
    ]
  3. 对 \textstyle l = n_l-1, n_l-2, n_l-3, \ldots, 2 的各个层,第 \textstyle l 层的第 \textstyle i 个节点的残差计算方法如下:
    \delta^{(l)}_i = \left( \sum_{j=1}^{s_{l+1}} W^{(l)}_{ji} \delta^{(l+1)}_j \right) f'(z^{(l)}_i)
    {译者注:
    \begin{align}\delta^{(n_l-1)}_i &=\frac{\partial}{\partial z^{n_l-1}_i}J(W,b;x,y) = \frac{\partial}{\partial z^{n_l-1}_i}\frac{1}{2} \left\|y - h_{W,b}(x)\right\|^2  = \frac{\partial}{\partial z^{n_l-1}_i}\frac{1}{2} \sum_{j=1}^{S_{n_l}}(y_j-a_j^{(n_l)})^2 \\&= \frac{1}{2} \sum_{j=1}^{S_{n_l}}\frac{\partial}{\partial z^{n_l-1}_i}(y_j-a_j^{(n_l)})^2 = \frac{1}{2} \sum_{j=1}^{S_{n_l}}\frac{\partial}{\partial z^{n_l-1}_i}(y_j-f(z_j^{(n_l)}))^2 \\&= \sum_{j=1}^{S_{n_l}}-(y_j-f(z_j^{(n_l)})) \cdot \frac{\partial}{\partial z_i^{(n_l-1)}}f(z_j^{(n_l)}) = \sum_{j=1}^{S_{n_l}}-(y_j-f(z_j^{(n_l)})) \cdot  f'(z_j^{(n_l)}) \cdot \frac{\partial z_j^{(n_l)}}{\partial z_i^{(n_l-1)}} \\&= \sum_{j=1}^{S_{n_l}} \delta_j^{(n_l)} \cdot \frac{\partial z_j^{(n_l)}}{\partial z_i^{n_l-1}} = \sum_{j=1}^{S_{n_l}} \left(\delta_j^{(n_l)} \cdot \frac{\partial}{\partial z_i^{n_l-1}}\sum_{k=1}^{S_{n_l-1}}f(z_k^{n_l-1}) \cdot W_{jk}^{n_l-1}\right) \\&= \sum_{j=1}^{S_{n_l}} \delta_j^{(n_l)} \cdot  W_{ji}^{n_l-1} \cdot f'(z_i^{n_l-1}) = \left(\sum_{j=1}^{S_{n_l}}W_{ji}^{n_l-1}\delta_j^{(n_l)}\right)f'(z_i^{n_l-1})\end{align}
    将上式中的\textstyle n_l-1\textstyle n_l的关系替换为\textstyle l\textstyle l+1的关系,就可以得到:
    \delta^{(l)}_i = \left( \sum_{j=1}^{s_{l+1}} W^{(l)}_{ji} \delta^{(l+1)}_j \right) f'(z^{(l)}_i)
    以上逐次从后向前求导的过程即为“反向传导”的本意所在。 ]
  4. 计算我们需要的偏导数,计算方法如下:
    \begin{align}\frac{\partial}{\partial W_{ij}^{(l)}} J(W,b; x, y) &= a^{(l)}_j \delta_i^{(l+1)} \\\frac{\partial}{\partial b_{i}^{(l)}} J(W,b; x, y) &= \delta_i^{(l+1)}.\end{align}


最后,我们用矩阵-向量表示法重写以上算法。我们使用“\textstyle \bullet” 表示向量乘积运算符(在Matlab或Octave里用“.*”表示,也称作阿达马乘积)。若 \textstyle a = b \bullet c,则 \textstyle a_i = b_ic_i。在上一个教程中我们扩展了 \textstyle f(\cdot) 的定义,使其包含向量运算,这里我们也对偏导数 \textstyle f'(\cdot) 也做了同样的处理(于是又有 \textstyle f'([z_1, z_2, z_3]) = [f'(z_1), f'(z_2), f'(z_3)] )。


那么,反向传播算法可表示为以下几个步骤:

  1. 进行前馈传导计算,利用前向传导公式,得到 \textstyle L_2, L_3, \ldots直到输出层 \textstyle L_{n_l} 的激活值。
  2. 对输出层(第 \textstyle n_l 层),计算:
    \begin{align}\delta^{(n_l)}= - (y - a^{(n_l)}) \bullet f'(z^{(n_l)})\end{align}
  3. 对于 \textstyle l = n_l-1, n_l-2, n_l-3, \ldots, 2 的各层,计算:
    \begin{align}\delta^{(l)} = \left((W^{(l)})^T \delta^{(l+1)}\right) \bullet f'(z^{(l)})\end{align}
  4. 计算最终需要的偏导数值:
    \begin{align}\nabla_{W^{(l)}} J(W,b;x,y) &= \delta^{(l+1)} (a^{(l)})^T, \\\nabla_{b^{(l)}} J(W,b;x,y) &= \delta^{(l+1)}.\end{align}

公式说明:J(W,b;x,y)表示的是单个样本(x,y)的损失函数,

你可能感兴趣的:(图像处理)