神经网络算法性能分析

简介: 训练神经网络的算法有成千上万个,最常用的有哪些,哪一个又最好?作者在本文中介绍了常见的五个算法,并从内存和速度上对它们进行对比。最后,他最推荐莱文贝格-马夸特算法。

训练神经网络的算法有成千上万个,最常用的有哪些,哪一个又最好?作者在本文中介绍了常见的五个算法,并从内存和速度上对它们进行对比。最后,他最推荐莱文贝格-马夸特算法。
  用于神经网络中执行学习过程的程序被称为训练算法。训练算法有很多,各具不同的特征和性能。
  问题界定
  神经网络中的学习问题是以损失函数f的最小化界定的。这个函数一般由一个误差项和一个正则项组成。误差项评估神经网络如何拟合数据集,正则项用于通过控制神经网络的有效复杂性来防止过拟合。
  损失函数取决于神经网络中的自适应参数(偏差和突触权值)。我们可以简便地把它们组合成单个n维权值向量w。下图表示损失函数f(w)
  


  如上图所示,点w 是该损失函数的最小值。在任何点A,我们可以计算损失函数的一阶和二阶导数。一阶导数用梯度向量组成,可以写成:
  ?if(w) = df/dwi(i = 1,...,n)
  类似地,损失函数的二阶导数可以用Hessian矩阵,写成:
  Hi,jf(w) = d2f/dwi·dwj(i,j = 1,...,n)
  许多连续和可微函数的最小化问题已经有许多研究。这些问题的常规方法可直接适用于训练神经网络。
  一维优化方法
  虽然损失函数取决于许多参数,一维优化方法在这里非常重要。实际上,一维优化方法经常用于神经网络的训练过程。
  许多训练算法先计算训练方向d,然后计算使该方向上的损失最小的训练速率η,写作f(n)。下图描述了一维损失函数:
  

  点η1和η2定义包含f(n)的最小值η
的间隔。这里,一维优化方法搜索给定的一维函数的最小值。广泛使用的算法有黄金分割法和布伦特法。
  多维优化方法
  神经网络的学习问题被界定为搜索使损失函数f得到最小值的参数向量w*。如果神经网络的损失函数已经取得最小值,则梯度是零向量。
  一般来说,损失函数是参数的非线性函数。因此,不可能找到最小值的封闭训练算法。反之,我们考虑通过在一系列步骤组成的参数空间中搜寻最小值。每一步中,损失会随着神经网络参数的调整而减少。
  这样,我们从一些参数向量(通常随机选择)着手训练神经网络。然后,我们会生成一系列参数,使得损失函数在算法的每次迭代中减小损失值。两次迭代间的损失值变化称为损失减量。当满足特定条件或到达停止标准使,训练算法停止。
  接下来将介绍训练神经网络的五种最重要的算法。
  

  1. 梯度下降法(Gradient descent)
  梯度下降法,又称最速下降法,是最简单的训练算法。它需要来自梯度向量的信息,因此它是一阶方法。
  设f(wi) = fi,?f(wi) = gi。该方法从点w0开始,在训练方向di = -gi上从wi移动到wi+1,直到满足停止标准。因此,梯度下降法按照以下公式迭代:
  wi+1= wi- di·ηi, i=0,1,...
  参数η是训练速率。该值可以设置为固定值,或者在沿训练方向的每一步一维优化中找到。训练速率的最佳值通常可通过每个连续步骤的线性最小化得到。然而,仍然有许多软件工具只使用固定值的训练速率。
  下图描绘了梯度下降法的训练过程。可以看到,参数向量通过两个步骤提升:首先,计算梯度下降训练方向; 然后,找到合适的训练速率。
  

  梯度下降训练算法的严重缺点是需要对具有长而窄的山谷结构的函数进行许多次迭代。实际上,下坡梯度是损失函数下降最快的方向,但不一定能产生最快的收敛性。下图说明了这个问题。
  

  当神经网络非常大、参数非常多时,梯度下降法是推荐的算法。因为该方法仅存储梯度向量(大小是n),而不存储Hessian矩阵(大小是n2)。
  2. 牛顿法(Newton's method)
  牛顿法是一种二阶算法,因为它使用了Hessian矩阵。这种方法的目的是通过使用损失函数的二阶导数找到更好的训练方向。
  设f(wi) = fi,?f(wi) = gi,同时Hf(wi)= Hi。使用泰勒级数得到f在w0上的二次近似值:
  f = f0+ g0· (w - w0) + 0.5 · (w - w0)2· H0
  H0是在点w0处估计的f的Hessian矩阵。通过对f(w)的最小值设置g=0,得到下一个等式:
  g = g0+ H0· (w - w0) = 0
  这样,从参数向量w0开始,牛顿法按照下面的公式迭代:
  wi+1= wi- Hi-1·gi, i=0,1,...
  矢量Hi-1·gi被称为牛顿步。需要注意的是,这些参数的变化可能朝向最大值而不是最小值移动。如果Hessian矩阵不是正定的,就会发生这种情况。因此,不能保证每次迭代都减小函数值。为了避免这种麻烦,牛顿法的方程式通常修改为:
  wi+1= wi- (Hi-1·gi)·ηi, i=0,1,...
  训练速率η可以设置为固定值或通过线性最小化找到。向量d = Hi-1·gi现在称为牛顿训练方向。
  牛顿法的训练过程如下图所示,先是得到牛顿训练方向,然后得到合适的训练速率来执行参数的改进。
  

  下图描述了这种方法的性能。可以看到,牛顿法需要的梯度下降步骤比寻找损失函数的最小值所需的步骤更少。
  

  但是,牛顿法的缺点在于,它对Hessian矩阵及其逆矩阵的精确估计在计算层面上是相当昂贵的。
  3. 共轭梯度法(Conjugate gradient)
  共轭梯度法可以被认为是介于梯度下降和牛顿法之间的方法。它能加快梯度下降法典型的慢收敛,同时避免了牛顿法对Hessian矩阵的评估、存储和反转所需的信息。
  在共轭梯度训练算法中,搜索沿着共轭方向执行,通常能比梯度下降方向产生更快的收敛。这些训练方向与Hessian矩阵相关。
  用d表示训练方向向量。然后,从初始参数向量w0和初始训练方向向量d0 = -g0开始,共轭梯度法构造训练方向的序列可表示为:
  di+1= gi+1+ di·γi, i=0,1,...
  这里γ称为共轭参数,有不同的计算方法。其中两种最常用的方法是Fletcher–Reeves和Polak–Ribière。对于所有共轭梯度算法,训练方向周期性地重置为梯度的负值。
  然后,参数根据以下等式改进,训练速率η通常通过线性最小化得到:
  wi+1= wi+ di·ηi, i=0,1,...
  下图描述了使用共轭梯度法的训练过程。如图所示,参数的改进步骤是先计算共轭梯度训练方向,然后计算该方向上的合适训练速率。
  
  这种方法已经证明比梯度下降法在训练神经网络方面更有效。因为它不需要Hessian矩阵,所以当神经网络非常大时,也建议使用共轭梯度法。
  4. 拟牛顿法(Quasi-Newton method)
  牛顿法在计算上是相当昂贵的,因为它需要许多操作来评估Hessian矩阵并计算其逆矩阵。为了解决这个缺点,出现了被称为拟牛顿法或可变矩阵法的替代方法。这种方法在算法的每次迭代中建立并逼近Hessian逆矩阵,而不是直接计算Hessian矩阵,然后评估其逆矩阵。该近似值仅使用损失函数的一阶导数的信息来计算。
  Hessian矩阵由损失函数的二阶偏导数组成。拟牛顿法背后的主要思想是仅使用损失函数的一阶偏导数,通过另一矩阵G得到近似Hessian矩阵的逆。拟牛顿法的公式可表示为:
  wi+1= wi- (Gi·gi)·ηi, i=0,1,...
  训练速率η可以设置为固定值或通过线性最小化得到。最常用的两个公式是Davidon-Fletcher-Powell公式(DFP)和Broyden-Fletcher-Goldfarb-Shanno公式(BFGS)。
  拟牛顿法的训练过程如下图所示。先得到拟牛顿训练方向,然后找到满意的训练速率来执行参数的改进。
  

  这是在大多数情况下使用的默认方法:它比梯度下降法和共轭梯度法更快,并且不需要精确计算和反转Hessian矩阵。
  5. Levenberg-Marquardt algorithm(莱文贝格-马夸特算法)
  Levenberg-Marquardt算法,又称阻尼最小二乘法,被设计为采用误差平方和形式的损失函数特定的算法。它不需精确计算Hessian矩阵,适用于梯度向量和Jacobian矩阵。
  下图是使用Levenberg-Marquardt算法的神经网络训练过程。第一步是计算损失值、梯度和Hessian逼近,然后调整阻尼参数,以减少每次迭代的损失。
  

  Levenberg-Marquardt算法是针对误差平方和型函数的特定方法。这使它在训练神经网络中测量这种误差时非常快。但是,该算法也有一些缺点。缺点之一是它不能应用于诸如均方根误差或交叉熵误差函数。此外,它与正则项不兼容。最后,对于非常大的数据集和神经网络,Jacobian矩阵会变得非常大,因此需要的内存也非常大。因此,当数据集和/或神经网络非常大时,不推荐使用Levenberg-Marquardt算法。
  内存和速度比较
  下图比较了本文中讨论的训练算法的计算速度和存储要求。可以看到,最慢的训练算法是梯度下降法,但它需要的内存最小。相反,最快的是Levenberg-Marquardt算法,但需要的内存也最大。比较好的折衷可能是拟牛顿法。
  

  总而言之,如果我们的神经网络有成千上万的参数,我们可以使用梯度下降法或共轭梯度法,以节省内存。如果我们要训练的神经网络只有几千个样本和几百个参数,最好的选择可能是Levenberg-Marquardt算法。其余情况下,可以选择拟牛顿法。

目录
相关文章
|
21天前
|
机器学习/深度学习 存储 算法
神经网络分类算法原理详解
神经网络分类算法原理详解
43 0
|
25天前
|
机器学习/深度学习 算法 PyTorch
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
180 1
|
26天前
|
机器学习/深度学习 算法 计算机视觉
|
6天前
|
机器学习/深度学习 算法
【MATLAB】GA_ELM神经网络时序预测算法
【MATLAB】GA_ELM神经网络时序预测算法
278 9
|
6天前
|
机器学习/深度学习 数据采集 算法
|
8天前
|
机器学习/深度学习 自然语言处理 算法
|
25天前
|
机器学习/深度学习 算法 Python
LSTM(长短期记忆)网络的算法介绍及数学推导
LSTM(长短期记忆)网络的算法介绍及数学推导
16 0
|
30天前
|
负载均衡 算法 应用服务中间件
Docker Swarm总结+service创建和部署、overlay网络以及Raft算法(2/5)
Docker Swarm总结+service创建和部署、overlay网络以及Raft算法(2/5)
88 0
|
1月前
|
机器学习/深度学习 人工智能 算法
神经网络算法——损失函数(Loss Function)
神经网络算法——损失函数(Loss Function)
22 0
|
1月前
|
机器学习/深度学习 人工智能 算法
神经网络算法——反向传播 Back Propagation
神经网络算法——反向传播 Back Propagation
26 0