zoukankan      html  css  js  c++  java
  • 神经网络中的前向后向传播算法

    神经网络中的代价函数与后向传播算法

    代价(损失)函数

    ​ 依照惯例,我们仍然首先定义一些我们需要的变量:

    L:网络中的总层数,(s_l​):在第l层所有单元(units)的数目(不包含偏置单元),k:输出单元(类)的数目

    ​ 回想一下,在神经网络中,我们可能有很多输出节点。 我们将(h_Theta(x)_k)表示为导致第k个输出的假设。 我们的神经网络的成本函数将是我们用于逻辑回归的一般化。 回想一下,正则逻辑回归的成本函数是:

    ![1.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqeli4spdj20go012jra.jpg)
    ​ 对于神经网络,看起来稍微更加复杂:
    ![2.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqelidj2zj20ky01t749.jpg)
    ​ 我们添加了几个嵌套求和来以计算多个输出节点。 在方程的第一部分,在方括号之前,我们有一个额外的嵌套求和循环遍历输出节点的数量。在正则化部分中,在方括号之后必须考虑多个theta矩阵。 当前theta矩阵中的列数等于当前层中的节点数(包括偏置单元),当前θ矩阵中的行数等于下一层中的节点数(不包括偏置单位)。 如前所述,逻辑回归时应对每个术语进行平方。

    注意:

    • 两级求和公式是对于输出层的每个单元的逻辑回归代价函数相加求和
    • 三级求和是将所有的(Theta)平方后求和
    • 这里i在三级求和中不是代表第i个案例,而是第l层所有单元(units)的数目(不包含偏置单元)

    后向传播算法

    ​ “反向传播”是用于最小化成本函数的神经网络术语,就像之前在逻辑和线性回归中的梯度下降一样。 Goal--目标是计算:(min_Theta J(Theta))

    ​ 也就是说,我们想使用θ中的最佳参数集来最小化我们的成本函数J。 用来计算J(Θ)的偏导数的方程:3.jpg

    ​ 由上,我们利用以下的算法:

    ![4.jpg](http://wx3.sinaimg.cn/mw690/7b8d2108gy1fgqelj0e5yj20kn0b843x.jpg)
    ​ (1)对于给定的训练集{($x^{(1)},y^{(1)}$)....($x^{(m)},y^{(m)}$)},对于训练集t=1到m:设置$a^{(1)}:=x^{(t)}$,

    ​ (2)利用前向传播算法来计算(a^{(l)}),其中l=2,3,...,L。具体的计算流程为:

    ![5.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqelk07q7j20d8071jt7.jpg)
    ​ (3)根据$y^{(t)}$计算$delta^{(L)}=a^{(L)}-y^{(t)}$,其中L是我们的层数,而$a^{(L)}$是输出层的激励单元的输出向量。 所以最后一层的“误差值”只是利用最后一层的实际结果和y中正确输出的差异。 要获得最后一层之前的层的增量值,按照从右到左的步骤。

    ​ (4)依次计算(delta^{(L-1)},delta^{(L-2)},...,delta^{(2)}),主要利用(delta^{(l)}=((Theta^{(l)})^Tdelta^{(l+1)}).*a^{(l)}.*(1-a^{(l)}))

    ​ 层L的δ是通过在与层L的θ矩阵下一层的δ相乘来计算。 接着以元素方式乘以一个称为g'的函数,该值是使用(z^{(l)})给出的输入值进行评估的激励函数g的导数,即(g'(z^{(l)})=a^{(l)}.*(1-a^{(l)}))

    ​ (5)(Δ_{i,j}^{(l)}:=Δ_{i,j}^{(l)}+a_j^{(l)}delta_i^{l+1})

    ​ 或者向量化为:(Delta^{(l)}:=Delta^{(l)}+delta^{(l+1)}(a^{(l)})^T)

    ​ 因此,我们一下总结的公式进行更新:

    ![6.jpg](http://wx1.sinaimg.cn/mw690/7b8d2108gy1fgqelk9qnqj207a02ta9x.jpg)
    ​ 大写的Delta矩阵D是我们作为"accumulator"即加速器,作为加快求和我们一直以来的值,最终计算偏微分的,因此我们有:![7.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqelkrzcgj203k019a9u.jpg)

    直观了解-后向传播

    ​ 一直以来。神经网络的代价函数为:

    ![2.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqelidj2zj20ky01t749.jpg)
    ​ 当仅考虑一类(输出单元k=1)的情形,且忽略掉正则化处理,代价函数可以表示为:

    (cost(t)=y^{(t)}log(h_Theta(x^{(t)}))+(1-y^{(t)})log(1-h_Theta(x^{(t)})))

    ​ 直观感受下:(delta_j^{(l)})是第l层j单元(a_j^{(l)})的误差,为代价函数的偏微分:

    ![8.jpg](http://wx3.sinaimg.cn/mw690/7b8d2108gy1fgqelkudynj205d021t8i.jpg)
    ​ 回想一下,导数是与代价函数相切的直线的斜率,所以斜率越陡越不正确(误差越大)。 让我们考虑下面的神经网络,看看如何计算一些$delta_i^{(l)}$:
    ![9.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqellkoj0j20jx082tad.jpg)
    ​ 在上图中,为了计算$delta_2^{(2)}$,我们将权重$Theta_{12}^{(2)}$和$Theta_{22}^{(2)}$乘以每个边缘右侧的各自的δ值。 从而有:$delta_2^{(2)}=Theta_{12}^{(2)}*delta_1^{(3)}+Theta_{22}^{(2)}*delta_2^{(3)}$。 为了计算每一个可能的$delta_j^{(l)}$,我们可以从图的右侧开始计算。 我们可以将我们的边缘看作是我们的$Theta_{ij}$。 从右到左,计算$delta_j^{(l)}$的值,可以将每个权重乘以δ的所有和。此外,$delta_2^{(3)}=Theta_{12}^{(3)}*delta_1^{(4)}$。

    后向传播算法的实际应用

    实现注意事项:展开参数

    ​ 对于神经网络,我们有以下矩阵集:

    (Theta^{(1)},Theta^{(2)},Theta^{(3)}...)

    (D^{(1)},D^{(2)},D^{(3)}...)

    ​ 为了使用诸如“fminunc()”的优化函数,首先要“展开”所有元素并将它们放入一个长向量中:

    thetaVector = [ Theta1(:); Theta2(:); Theta3(:); ]
    deltaVector = [ D1(:); D2(:); D3(:) ]
    

    ​ 如果参数Theta1的维度为10*11,Theta2的维度为10*11,Theta3的维度为1*11,我们可以按照以下的方式展开矩阵:

    Theta1 = reshape(thetaVector(1:110),10,11)
    Theta2 = reshape(thetaVector(111:220),10,11)
    Theta3 = reshape(thetaVector(221:231),1,11)
    

    ​ 总结如下:

    ![1.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqpxga98dj20eu061dhu.jpg)
    ### 梯度检测

    ​ 梯度检查将确保我们的反向传播按预期工作。 我们可以用以下方法近似我们的成本函数的导数:

    ![2.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqpxgqkm5j207101xq2q.jpg)
    ​ 对于多个theta矩阵,我们可以如下近似相对于$Theta_j$的导数:
    ![3.jpg](http://wx2.sinaimg.cn/mw690/7b8d2108gy1fgqpxhapw3j20eb022jr8.jpg)
    ​ $epsilon$的取值一般如:$epsilon=10^{-4}$保证了数学运算正常。 但如果ε的值太小,我们可能会遇到数值问题。因此,我们只是将$Theta_j$增加或减去ε矩阵。 具体如下:
    epsilon = 1e-4;
    for i = 1:n,
      thetaPlus = theta;
      thetaPlus(i) += epsilon;
      thetaMinus = theta;
      thetaMinus(i) -= epsilon;
      gradApprox(i) = (J(thetaPlus) - J(thetaMinus))/(2*epsilon)
    end;
    

    ​ 我们以前看过如何计算deltaVector。 所以一旦我们计算了我们的gradApprox向量,我们可以检查gradApprox≈deltaVector。一旦验证了您的反向传播算法是否正确,您就不需要再次计算gradApprox实际上计算gradApprox的代码可能非常慢。

    随机初始化

    ​ 将所有theta权重初始化为零不适用于神经网络(当权重初始化为零时,可以推出随着梯度的不断更新,参数会回到原始值,即神经网络的性能下降)。 当我们反向传播时,所有节点将重复更新为相同的值。 相反,我们可以使用以下方法随机初始化我们的Θ矩阵的权重:

    ![4.jpg](http://wx3.sinaimg.cn/mw690/7b8d2108gy1fgqpxhh90jj20ft07hjs4.jpg)
    ​ 因此,我们将每个$Theta_{ij}^{(l)}$初始化为[-ε,ε]之间的随机值。 使用上述公式保证我们得到所需的界限。 同样的过程适用于所有的Θ。 以下是一些实际上的工作代码。
    If the dimensions of Theta1 is 10x11, Theta2 is 10x11 and Theta3 is 1x11.
    
    Theta1 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
    Theta2 = rand(10,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
    Theta3 = rand(1,11) * (2 * INIT_EPSILON) - INIT_EPSILON;
    

    ​ rand(x,y)只是octave软件中自带的一个随机函数,生成值在0-1之间。

    (知识点汇集)Putting it together

    ​ 首先,挑选出一种NN架构:选择你的NN的层数,包含在每一层中所出现的隐藏单元数量,与你一共想拥有多少层。

    • 输入单元数=特征集(x^{(i)})的维度

    • 输出层单元数=欲分类的数目

    • 每层的隐藏单元数=一般越多越好-性能越佳(随着隐藏单元数目的增加,相应地必须增加计算量)

    • 默认:包含一个隐藏层。如果,多余一个隐藏层,建议在每一个隐藏层拥有相同的单元数

    训练一个神经网络

    1.随机初始化权重

    2.利用前向传播函数对每个(x^{(i)})计算假设值(h_Theta(x^{(i)}))

    3.计算代价函数

    4.通过后向传播函数计算偏微分值

    5.使用梯度检查确认您的反向传播是否有效。 然后禁用梯度检查。

    6.使用梯度下降或内置优化函数,以最小化theta中权重的成本函数。

    ​ 在前向和后向传播的计算中,对每一个训练样本都做相同的循环计算:

    for i = 1:m,
       Perform forward propagation and backpropagation using example (x(i),y(i))
       (Get activations a(l) and delta terms d(l) for l = 2,...,L
    

    ​ 下图给出了实现神经网络发生的具体过程:

    ![5.jpg](http://wx3.sinaimg.cn/mw690/7b8d2108gy1fgqpxiazqcj20di07xwgy.jpg)
    ​ 理想情况下,希望$h_Theta(x^{(i)})approx y^{(i)}$。 这将使代价函数最小化。 然而,请记住$J(Theta)$不是凸的,因此我们可以以局部最小值来结束。
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
  • 相关阅读:
    多态
    接口和抽象类
    反射
    C++ 模板和 C# 泛型的区别
    基础类库中的泛型
    运行时中的泛型
    泛型代码中的 default 关键字
    泛型委托
    泛型方法
    泛型接口
  • 原文地址:https://www.cnblogs.com/SrtFrmGNU/p/7050148.html
Copyright © 2011-2022 走看看