我们在上一篇博客《数值优化:算法分类及收敛性分析基础》介绍了数值优化算法的历史发展、分类及其收敛性/复杂度分析基础。本篇博客我们重点关注一阶确定性优化算法及其收敛性分析。
梯度下降法[1]是最古老的一阶方法,由Cauchy在1847年提出。
梯度下降法的基本思想是:最小化目标函数在当前迭代点处的一阶泰勒展开,从而近似地优化目标函数本身。具体地,对函数\(f:\mathbb{R}^n \rightarrow \mathbb{R}\),将其在第\(t\)轮迭代点\(w^t\)处求解下述问题:
上式右端关于自变量\(w\)是线性的,并且使得\(\nabla f(w^t)^Tw\)最小的方向与梯度\(\nabla f(w^t)\)的方向相反。于是梯度下降法的更新规则如下:
其中\(\eta>0\)是步长,也常被称作学习率。
梯度下降法描述如下:
针对不同性质的目标函数,梯度下降法具有不同的收敛速率。由于梯度下降法只适用于梯度存在的函数(没有梯度需要考虑使用次梯度的方法),这里考虑梯度下降法对于光滑凸函数和光滑强凸函数的收敛速率。
光滑凸函数收敛性 假设目标函数\(f: \mathbb{R}^d \rightarrow \mathbb{R}\)是凸函数,且\(\beta\)-光滑,当步长\(\eta = \frac{1}{\beta}\)时,梯度下降法具有\(\mathcal{O}(\frac{1}{t})\)的次线性收敛速率:
光滑强凸函数收敛性 假设目标函数\(f: \mathbb{R}^d \rightarrow \mathbb{R}\)是\(\alpha\)-强凸函数,且\(\beta\)-光滑,当步长\(\eta = \frac{1}{\beta}\)时,梯度下降法具有\(\mathcal{O}(e^{-\frac{t}{Q}})\)的线性收敛速率:
其中\(Q = \frac{\beta}{\alpha}\),一般被称为条件数。
通过以上两个定理可知,强凸性质会大大提高梯度下降法的收敛速率。进一步地,强凸性质越好(即\(\alpha\)越大),条件数\(Q\)越小,收敛越快。
而光滑性质在凸和强凸两种情形下都会加快梯度下降法的收敛速率,即\(\beta\)越小(强凸情景下,条件数\(Q\)越小),收敛越快。可以说凸情形中的光滑系数和强凸情形中的条件数在一定程度上刻画了优化问题的难易程度。
梯度下降法有两个局限,一是只适用于无约束优化问题,二是只适用于梯度存在的目标函数。投影次梯度法[2]可以解决梯度下降法的这两个局限性。
投影次梯度下降法相比梯度下降法,具有次梯度选择和约束域投影两个特性:
得到\(v^{t+1}\)。

投影次梯度下降法描述如下:
在一定步长的选取规则下,投影次梯度法是收敛的,并且收敛速度也依赖于目标函数的凸性和光滑性。
对于\(\beta\)-光滑的凸/强凸函数,当步长为\(\frac{1}{\beta}\)时,投影次梯度下降法的收敛率和梯度下降法相同,对于凸函数是\(\mathcal{O}(\frac{1}{t})\),强凸函数是\(\mathcal{O}(e^{-\frac{t}{Q}})\)。
不过,由于投影次梯度算法适用于有次梯度存在的目标函数,因而不仅适用于光滑函数的优化,也适用于Lipschitz连续函数的优化。对于Lipschitz连续函数,投影次梯度下降法收敛。对于凸函数,步长\(\eta = \mathcal{O}(\frac{1}{\sqrt{t}})\)时,收敛速率为\(\mathcal{O}(\frac{1}{\sqrt{t}})\);对于强凸函数,步长\(\eta = \mathcal{O}(\frac{1}{t})\)时,收敛速率为\(\mathcal{O}(\frac{1}{t})\)。可以看到其收敛速率在凸和强凸两种情形相比光滑函数显著降低,都是次线性。
近端梯度法[3]是投影次梯度法的一种推广,适用于如下形式的部分不可微的凸目标函数的优化问题:
其中\(l(w)\)是其中的可微凸函数部分,\(R(w)\)是不可微的凸函数(例如\(L_1\)正则项)。算法的基本思想是先按照可微的\(l\)函数进行一步梯度下降更新:
然后再经过近端映射\(\text{prox}_R(\space \cdot \space)\)做为本轮最终的迭代更新:
近端梯度下降法描述如下:

如下定理所示,近端梯度下降法可以达到线性收敛速率。
近端梯度下降法收敛性 假设目标函数中的\(l\)函数是\(\mathbb{R}^d\)上的\(\alpha\)-强凸函数,且\(\beta\)-光滑;\(R\)函数是\(\mathbb{R}^d\)上的凸函数, 当步长\(\eta = \frac{1}{\beta}\)时,近端梯度下降法具有\(\mathcal{O}(e^{-\frac{t}{Q}})\)的线性收敛速率:
其中\(Q = \frac{\beta}{\alpha}\)为\(l\)函数的条件数。
Frank-Wolfe算法[4]是投影次梯度下降法的另一个替代算法。投影次梯度算法虽然适用于有约束优化问题,但是如果投影的计算很复杂,投影次梯度下降的效率将会称为瓶颈。为了解决此问题,不同于投影次梯度下降法中先进行梯度下降再对约束域进行投影的做法,Frank-Wolfe算法在最小化目标函数的泰勒展开时就将约束条件考虑进去,直接得到满足约束的近似最小点,即:
为了使算法的解更稳定,Frank-Wolfe算法将求解上述子问题得到的\(v^t\)与当前状态\(w^t\)做线性加权:
如下图所示:
\
Frank-Wolfe算法描述如下:
Frank-Wolfe算法收敛速率如下列定理所示:
Frank-Wolfe法收敛性 假设目标函数中的\(f\)函数是\(\mathbb{R}^d\)上的凸函数,且\(\beta\)-光滑,当加权系数\(\gamma^t = \frac{2}{t+1}\)时,Frank-Wolfe算法具有\(\mathcal{O}(\frac{1}{t})\)的次线性收敛速率:
其中\(D = \underset{w, v \in \mathcal{W}}{\text{sup}}\lVert w - v \rVert\)。
由于Frank-Wolfe算法的收敛速率和投影次梯度下降法相同,可以依据要解决问题中的投影计算是否困难,在两种算法中选择一种使用。
考虑以上所有的一阶算法。在Lipschitz连续的条件下,梯度下降法达到了一阶算法的收敛速率下界。然而对于光滑函数,一阶方法的收敛速率的下界小于梯度下降法的收敛速率。一阶方法在凸情形下的收敛率下界为\(\mathcal{O}(\frac{1}{t^2})\),强凸情形下的下界为\(\mathcal{O}(e^{-\frac{t}{\sqrt{Q}}})\);而梯度下降法在凸情形下的收敛率为\(\mathcal{O}(\frac{1}{t})\),强凸情形下的收敛率为\(\mathcal{O}(e^{-\frac{t}{Q}})\)。这说明我们可以针对光滑函数设计收敛速率更快的一阶方法。
Nesterov在1983年对光滑度目标函数提出了加快一阶优化算法收敛的方法[5]。我们这里以梯度下降法为例,介绍Nesterov加速法的具体实现。
Nesterov算法的基本原理如下图所示:
\
当任意时刻\(t\),对当前状态\(w^t\)进行一步梯度迭代得到辅助变量\(v^{t+1}\):
然后将新的辅助变量和上一轮迭代计算的辅助变量\(v^t\)做线性加权,做为第\(t+1\)轮迭代的参数\(w^{t+1}\)。对于凸和强凸的目标函数,线性加权系数有所不同。
具体地,对于强凸的目标函数,加权规则如下:
其中\(\gamma^t = \frac{1-\sqrt{Q}}{1 + \sqrt{Q}}\),\(Q\)为条件数。
对于凸的目标函数,加权规则如下:
其中\(\gamma^t = \frac{1 - \lambda^t}{\lambda^{t+1}}\),\(\lambda^0 = 0\), \(\lambda^t = \frac{1 + \sqrt{1 + 4{(\lambda^{t-1})}^2}}{2}\)。
Nesterov加速算法描述如下:
Nesterov证明了用以上方法加速之后的梯度下降法的收敛速率可以达到针对光滑目标函数的一阶方法的收敛速率下界:
光滑凸函数收敛性 假设目标函数\(f: \mathbb{R}^d \rightarrow \mathbb{R}\)是凸函数,并且\(\beta\)-光滑,当步长\(\eta = \frac{1}{\beta}\)时,Nesterov加速法能够将收敛速率提高到\(\mathcal{O}({\frac{1}{t^2}})\)(不过仍是次线性收敛速率):
光滑强凸函数收敛性 假设目标函数\(f: \mathbb{R}^d \rightarrow \mathbb{R}\)是\(\alpha\)-强凸函数,并且\(\beta\)-光滑,当步长\(\eta = \frac{1}{\beta}\)时,Nesterov加速法能够将收敛速率提高到\(\mathcal{e^{-\frac{t}{\sqrt{Q}}}}\)(不过仍是线性收敛速率):
其中\(Q = \frac{\beta}{\alpha}\)为条件数。
坐标下降法[6]是另外一种常见的最小化实值函数的方法。其基本思想是,在迭代的每一步,算法选择一个维度,并更新这一维度,其它维度的参数保持不变;或者将维度分为多个块,每次只更新某块中的维度,其它维度保持不变。坐标下降法的更新公式如下:
其中,\(\mathcal{W}_j\)为第\(j\)个维度块的约束域。
对于维度的选择,坐标下降法一般遵循以下本征循环选择规则(Essential Cyclic Rule):存在一个常数\(r\geqslant d\),使得对任意的\(s\),对于每一个维度\(j\),在第\(s\)轮和第\(s + r - 1\)轮之间都至少选择一次。最常见的方法是循环选择规则,即对于任意\(j=1,...,d\),分别在第\(j, d + j, 2d + j,...\)次算法迭代中选择维度\(j\)(即每隔\(d\)轮选择一次)。
坐标下降法的算法描述如下所示:

可以证明对于强凸并且光滑的目标函数,循环坐标下降法具有线性的收敛速率[6]。
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
有没有一种简单的方法可以判断ruby脚本是否已经在运行,然后适本地处理它?例如:我有一个名为really_long_script.rb的脚本。我让它每5分钟运行一次。当它运行时,我想看看之前运行的是否还在运行,然后停止第二个脚本的执行。有什么想法吗? 最佳答案 ps是一种非常糟糕的方法,并且可能会出现竞争条件。传统的Unix/Linux方法是将PID写入文件(通常在/var/run中)并在启动时检查该文件是否存在。例如pid文件位于/var/run/myscript.pid然后你会在运行程序之前检查它是否存在。有一些技巧可以避免
我想查找字符串的结尾是否与单独字符串的开头重叠。例如,如果我有这两个字符串:string_1='Peoplesaynothingisimpossible,butI'string_2='butIdonothingeveryday.'如何找到string_1末尾的“butI”部分与string_2开头相同?我可以编写一个方法来遍历这两个字符串,但我希望得到一个包含我错过的Ruby字符串方法或Ruby习惯用法的答案。 最佳答案 将MARKER设置为一些从未出现在您的string_1和string_2中的字符串。有一些方法可以动态地做到这一
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG
目录0专栏介绍1平面2R机器人概述2运动学建模2.1正运动学模型2.2逆运动学模型2.3机器人运动学仿真3动力学建模3.1计算动能3.2势能计算与动力学方程3.3动力学仿真0专栏介绍?附C++/Python/Matlab全套代码?课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。?详情:图解自动驾驶中的运动规划(MotionPlanning),附几十种规划算法1平面2R机器人概述如图1所示为本文的研究本体——平面2R机器人。对参数进行如下定义:机器人广义坐标
网站的日志分析,是seo优化不可忽视的一门功课,但网站越大,每天产生的日志就越大,大站一天都可以产生几个G的网站日志,如果光靠肉眼去分析,那可能看到猴年马月都看不完,因此借助网站日志分析工具去分析网站日志,那将会使网站日志分析工作变得更简单。下面推荐两款网站日志分析软件。第一款:逆火网站日志分析器逆火网站日志分析器是一款功能全面的网站服务器日志分析软件。通过分析网站的日志文件,不仅能够精准的知道网站的访问量、网站的访问来源,网站的广告点击,访客的地区统计,搜索引擎关键字查询等,还能够一次性分析多个网站的日志文件,让你轻松管理网站。逆火网站日志分析器下载地址:https://pan.baidu.