400-123-4567

深度学习中的优化器_2

优化问题等同于最小化或最大化某个函数 f(x),如果 x 不是取整个向量空间,则称为有约束的优化问题,约束条件通常通过一系列等式和不等式表示

x^*=\\begin{cases}\\arg \\min _{x \\in \\mathbb{R}^N}f(x) & \	ext{ 无约束 }\\\\ \\arg \\min _x f(x) & \	ext{ subject to constraints, 如 }g_i(x) \\leq 0, h_j(x)=0\\end{cases}

深度学习中最小化损失函数就是一个典型的优化问题,即找到一组参数 \\mathrm{x}^* 使得损失函数 f(x) 达到最小值。 在大多数深度学习应用中,因为模型是人为定义的,我们通常处理无约束的优化问题,意味着我们尝试在整个参数空间 \\mathbb{R}^N 中找到损失函数的最小值。

迭代优化只能保证收敛到局部(邻域)最优解,而不是全局最优解。

局部最优和全局最优

凸优化是一种定义在凸集和凸函数上的特殊的优化问题,能保证局部最优值=全局最优值。 简单来说凸集中的任意两点连线都在凸集内,凸函数任意两点的连线上的值都大于函数值。

凸优化的良好性质也限制了它的表达能力。其实只有两个模型满足凸优化

  • 线性回归 线性回归的平方损失函数(二次函数)是典型的凸函数。
  • Softmax回归 Softmax是交叉熵损失函数(但经过神经网络之后,再交叉熵就不具有凸性了)。

大多数现代深度学习模型并不是基于凸函数,主要的原因是它们所使用的激活函数往往是非凸的。

梯度下降是最简单的迭代求解算法。

每次迭代中,我们都沿着函数的负梯度方向(即最陡峭的下坡方向)进行一定距离的移动。

\\mathbf{x}_{\	ext{新 }}=\\mathbf{x}_{\	ext{旧 }}-学习率\\cdot\\overrightarrow{梯度}

在大型数据集和深度学习模型中,我们通常使用小批量随机梯度下降。在此方法中,每次迭代选择的不是一个样本,而是一个包含多个样本的小批量。用小批量的梯度近似整体梯度,又可以充分利用并行计算能力,从而提高训练速度。

\\mathbb{E}\\left[\\frac{1}{b}\\sum_{i \\in I_t}\
abla \\ell_i(\\mathbf{x})\\right]=\
abla f(\\mathbf{x})

普通SGD迭代时,参数更新只和当前样本有关,容易陷入振荡不定的情况。通过引入“惯性”或“冲量” \\mathbf{v} 这个概念,冲量法可以累积过去的梯度信息,从而使得迭代方向在连续步骤中更为稳定。

\\begin{aligned}
 时间t的梯度\\quad\\mathbf{g}_t&=\\frac{1}{b}\\sum_{i \\in I_t}\
abla \\ell_i\\left(\\mathbf{x}_{t-1}\\right) \\\\
 时间t的冲量\\quad\\mathbf{v}_t&=\\beta \緻brace{\\mathbf{v}_{t-1}}_{上一时刻的冲量}+\\mathbf{g}_t \\\\
 更新规则\\quad\\mathbf{w}_t&=\\mathbf{w}_{t-1}-\\eta \\mathbf{v}_t
\\end{aligned}

\\beta 是一个超参数,它决定了冲量的“惯性”。在实际应用中,\\beta 通常设置为接近1的值,例如 0.9。

可以看到 \\mathbf{v}_t 是每个minibatch的指数级数

\\mathbf{v}_t=\\mathbf{g}_t+\\beta \\mathbf{g}_{t-1}+\\beta^2 \\mathbf{g}_{t-2}+\\beta^3 \\mathbf{g}_{t-3}+\\ldots

所以一般来说它移动得更快,因为它累加了历史梯度。通用的深度学习框架的SGD都内置了冲量参数。

Adagrad希望对每个参数分配个性化的学习率,对于出现频繁的特征(例如NLP中的高频词),Adagrad会降低其学习率,避免过度调整;对于稀疏的特征,Adagrad会增加其学习率。

Adagrad通过累积之前所有迭代中梯度的平方和来刻画特征的出现频率。如果一个特征在训练数据中经常出现,那么它的梯度会大,因此其累积的历史梯度也会增加。

\\begin{aligned}
 时间t的梯度\\quad\\mathbf{g}_t&=\\frac{1}{b}\\sum_{i \\in I_t}\
abla \\ell_i\\left(\\mathbf{x}_{t-1}\\right) \\\\
 时间t的历史梯度平方和\\quad\\mathbf{s}_t&=\\mathbf{s}_{t-1}+\\mathbf{g}_t^2 \\\\
 更新规则\\quad\\mathbf{w}_t&=\\mathbf{w}_{t-1}-\\frac{\\eta}{\\sqrt{\\mathbf{s}_t+\\epsilon}}\\odot \\mathbf{g}_t
\\end{aligned}

\\epsilon 是一个非常小的常数,防止除以零 \\frac{1}{\\sqrt{\\mathbf{s}_t+\\epsilon}}\\odot 对某一维度历史更新梯度量做惩罚,减少高频特征的学习率,增加低频特征的学习率,助力模型更好地跨越鞍点。

Lili Jiang - A Visual Explanation of Gradient Descent Methods

数据集较大时,Adagrad记录的梯度的平方和会越来越多,导致训练实际学习率过早衰减,训练很慢。 RMSProp 通过采用加权平均的方式来控制实际学习率的衰减程度。

\\mathbf{s}_t=\\rho \\mathbf{s}_{t-1}+(1-\\rho) \\mathbf{g}_t^2

\\rho 是一个超参数,通常设置为接近 0.9 以上

Adam是现在最常用的优化器了,它综合了 Momentum 和 RMSProp 的优点,能够同时获得速度加速和自适应学习率的效果。

一阶动量(和Momentum相同)

\\mathbf{m}_t=\\beta_1 \\mathbf{m}_{t-1}+\\left(1-\\beta_1\\right) \\mathbf{g}_t

通常 \\beta_1=0.9。 展开

\\mathbf{v}_t=\\left(1-\\beta_1\\right)\\left(\\mathbf{g}_t+\\beta_1 \\mathbf{g}_{t-1}+\\beta_1^2 \\mathbf{g}_{t-2}+\\beta_1^3 \\mathbf{g}_{t-3}+\\ldots\\right)

可以证明所有 \\mathbf{g} 的权重之和为1

我们称RMSDrop的梯度平方和为二阶动量

\\mathbf{v}_t=\\beta_2 \\mathbf{v}_{t-1}+\\left(1-\\beta_2\\right) \\mathbf{g}_t^2

通常 \\beta_2=0.999

\\mathbf{m}, \\mathbf{v} 初始化为0,而 \\beta_1, \\beta_2 很大(接近于1),导致初始的实际学习率太小。为了消除这种偏差,做出以下修正:

\\begin{aligned}
\\hat{\\mathbf{m}}_t &=\\frac{\\mathbf{m}_t}{1-\\beta_1^t}\\\\
\\hat{\\mathbf{v}}_t &=\\frac{\\mathbf{v}_t}{1-\\beta_2^t}
\\end{aligned}

t较小时,1-\\beta^t\\rightarrow 0

\\mathbf{w}_t=\\mathbf{w}_{t-1}-\\frac{\\eta}{\\sqrt{\\hat{\\mathbf{v}}_t+\\epsilon}}\\odot \\hat{\\mathbf{m}}_t

本文使用 Zhihu On VSCode 创作并发布

Copyright © 2012-2018 杏盛-杏盛娱乐-平台注册登录中心 版权所有

琼ICP备xxxxxxxx号

平台注册入口