1. 文章
  2. 文章详情

机器学习入门 - 神经网络代价函数和BP算法

代价函数

现在来讨论神经网络模型的代价函数。首先有如下定义:

  • L:网络中的层数
  • $s_l$ :第l层中的单元数(不包括偏差单元)
  • K:输出单元个数

我们记$h_Θ(x)_k$ 表示第k个输出单元。回顾在逻辑回归中,我们使用如下代价函数:

$J(θ) = - \frac{1}{m} \displaystyle \sum_{i=1}^m [y^{(i)}\log (h_θ (x^{(i)})) + (1 - y^{(i)})\log (1 - h_θ(x^{(i)}))] + \fracλ{2m}\sum_{j=1}^nθ_j^2$

对于神经网络,看起来有些复杂:

$J(θ) = - \frac{1}{m} \displaystyle \sum_{i=1}^m\sum_{k=1}^K [y^{(i)}_k\log ((h_θ (x^{(i)}))_k) + (1 - y^{(i)}_k)\log (1 - (h_θ(x^{(i)}))_k)] + \fracλ{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{sl+1}(Θ_{j,i}^{(l)})^2$

公式使用了一个嵌套的求和来计算输出单元的平均偏差。正则项部分,我们需要将L-1Θ矩阵全部求和,同时每个矩阵是$s_{j+1} × (s_j + 1)$ 维的。

总之:

  • 双重嵌套求和试图将全部样本的每个分类输出值求和。
  • 三重嵌套求和试图整个网络的每个Θ求和。
  • 三重嵌套循环中的i,跟第i个训练样本无关,不是一个概念。

反向传播(BP)算法

如果梯度下降是一个最小化回归模型的方法,那么术语反向传播(Backpropagation)用于最小化神经网络模型。我们的目标依旧是$min_ΘJ(Θ)$ ,这表示我们试图找到最优的参数$Θ$来最小化代价函数$J(Θ)$ 。本节介绍如何通过Backpropagation计算$J(Θ)$ 的偏导数:

$\frac∂{∂Θ^{(l)}_{i,j}}J(Θ)$

首先给出BP算法的实现步骤:

假设训练数据集如下

$\lbrace (x^{(1)}, y^{(1)}) \cdots (x^{(m)}, y^{(m)})\rbrace$

$Δ^{(l)}_{ij}$ 为全0矩阵。

for t=1 to m

  1. $a^{(1)} := x^{(t)}$
  2. 通过正向计算,分别算得$a^{(l)}\space l=2,3...L$
  3. 根据实际结果$y^{(t)}$ ,计算$\delta^{(L)} = a^{(L)} - y^{(t)}$ 。由于L是总的层数,所以$a^{(L)}$ 其实是是通过模型得到的输出向量。所以第L层的偏差可以直接通过训练集的实际结果向量y得到。其他层的偏差则是从右往左的顺序依次计算:
  4. (L1) \delta^{(L-1)} ,δ(L2) \delta^{(L-2)} ,...δ2 \delta^{2}$ ,公式为:$δ(l)=((Θ(l))T(l+1).∗a(l).∗(1−a(l)) \delta^{(l)} = ((Θ^{(l)})^T)\delta^{(l+1)} .* a^{(l)} .* ( 1 - a^{(l)})$  要计算第l层的偏差,首先将第l层的Θ矩阵与下一层的偏差向量相乘。放大项$a^{(l)} .* ( 1 - a^{(l)})$ 实际是激励函数g的导数:$g'(z^{(l)} = a^{(l)} .* ( 1 - a^{(l)})$
  5. $Δ^{(l)} := Δ^{(l)} + \delta^{(l+1)}(a^{(l)})^T$

最后,计算

$\frac∂{∂Θ^{(l)}_{i,j}}J(Θ) = D^{(l)}_{i,j}$

$D^{(l)}_{i,j} := \frac{1}{m}\left(\Delta^{(l)}_{i,j} + \lambda\Theta^{(l)}_{i,j}\right)\space\space ,j≠0$

$D^{(l)}_{i,j} := \frac{1}{m}\left(\Delta^{(l)}_{i,j} \right)\space\space ,j=0$

上述算法就是BP算法,确实是个比较难理解的算法,有兴趣的可以参阅如何直观地解释 back propagation 算法?,帮助理解。

得到了J(Θ)的偏导数,意味着得到了梯度,模型就可以训练出Θ

梯度检查

BP算法有很多细节,这些细节可能导致错误的算法实现。我们可以用梯度检查的方法,验证算法是否准确。这种方法也称为数值梯度检查(Numerical Gradient Checking)

Clipboard Image.png

如上图,当前我们希望求解J(Θ)Θ处的导数(即梯度)时,我们可以选取一个很小的 ϵ ,分别计算$J(\Theta + \epsilon)$ 和$J(\Theta - \epsilon)$ ,这两个点的连线应近似等于Θ处的切线方向,只要 ϵ 越接近于0,就越准确。因此可以得到如下公式计算导数:

$\frac{\partial}{\partial\Theta}J(\Theta) \approx \frac{J(\Theta + \epsilon) - J(\Theta - \epsilon)}{2\epsilon}$

ϵ 通常取值为104 10^{-4} 。当Θ是一个多值矩阵时,用如下公式分别计算每个$Θ_j$的梯度:

$\frac{\partial}{\partial\Theta_j}J(\Theta) \approx \frac{J(\Theta_1, \dots, \Theta_j + \epsilon, \dots, \Theta_n) - J(\Theta_1, \dots, \Theta_j - \epsilon, \dots, \Theta_n)}{2\epsilon}$

一旦验证BP算法正确,应该停止使用梯度检查,因为这通常很耗时间,这也是为什么不用数值梯度算法来计算梯度,BP是相对更高效的算法。

随机初始化

当使用梯度下降法时,需要设置Θ初始值。在逻辑回归中,我们可以把初始的Θ设置为0。但在神经网络中,这么做可能会导致同一层单元,其激励值与误差δ相同。进而每次更新,参数对应的每个输入到隐藏层的值是相同的。

通俗的说,当某一层的$Θ^{(j)}$ 表示的权重相同的话,会导致下一层的单元计算结果全部相同,这意味着,特征在传递到下层时,全部压缩为一个特征了。

我们把这种现象称为对称性(Symmetry),可以通过类似如下方法打破对称性(Symmetry Breaking),使初始化θ在 [-ε, ε] 的区间内:

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;

训练神经网络

首先,选择一个神经网络架构,有多少层,每层有多少个单元:

  • 输入单元数:特征$x^{(i)}$ 的维度
  • 输出单元数:分类数量
  • 每个隐藏层的单元数:通常多多益善,但要平衡计算成本。默认使用1个隐藏层,如果多于1个隐藏层,推荐每层的单元数保持相同。

接下来:

  1. 随机初始化权重Θ
  2. 对每一个$x^{(i)}$ 使用前向传导计算$h_θ(x^{(i)})$
  3. 实现代价函数J(Θ)
  4. 实现反向传导计算偏导数
  5. 使用梯度检查,确保反向传播算法正确。然后关闭梯度检查
  6. 使用梯度下降或其他优化函数最小化代价函数

理想情况下,$h_\Theta(x^{(i)}) \approx y^{(i)}$ ,但由于J(Θ)可能是non-convex的,所以,你可能会得到局部最优解。

发表评论

登录后才能评论

评论列表(0条)