Momentum

Momentum的迭代公式为:

\[v_t = \gamma v_{t-1} + \eta \nabla_\theta J(\theta) \\
\theta=\theta-v_t
\]

其中\(J(\cdot)\)一般为损失函数。我们知道,一般的梯度下降,是没有\(\gamma v_{t-1}\)这一项的,有了这一项之后,\(\theta\)的更新和前一次更新的路径有关,使得每一次更新的方向不会出现剧烈变化,所以这种方法在函数分布呈梭子状的时候非常有效。



先来看看这个函数利用梯度下降的效果吧。

import matplotlib.pyplot as plt
import numpy as np """
z = x^2 + 50 y ^2
2x
100y
""" partial_x = lambda x: 2 * x
partial_y = lambda y: 100 * y
partial = lambda x: np.array([partial_x(x[0]),
partial_y(x[1])])
f = lambda x: x[0] ** 2 + 50 * x[1] ** 2 class Decent:
def __init__(self, function):
self.__function = function @property
def function(self):
return self.__function def __call__(self, x, grad, alpha=0.4, beta=0.7):
t = 1
fx = self.function(x)
dist = - grad @ grad
while True:
dx = x - t * grad
fdx = self.function(dx)
if fdx <= fx + alpha * t * dist:
break
else:
t *= beta
return dx grad_decent = Decent(f) x = np.array([30., 15.])
process = []
while True:
grad = partial(x)
if np.sqrt(grad @ grad) < 1e-7:
break
else:
process.append(x)
x = grad_decent(x, grad) process = np.array(process)
print(len(process))
x = np.linspace(-40, 40, 1000)
y = np.linspace(-20, 20, 500)
fig, ax= plt.subplots()
X, Y = np.meshgrid(x, y)
ax.contour(X, Y, f([X, Y]), colors='black')
ax.plot(process[:, 0], process[:, 1])
plt.show()



怎么说呢,有点震荡?289步1e-7的误差


x = np.array([30., 15.])
process = []
v = 0
gamma = 0.7
eta = 0.016
while True:
grad = partial(x)
v = gamma * v + eta * grad
if np.sqrt(grad @ grad) < 1e-7:
break
else:
process.append(x)
x = x - v



用117步,话说,这个参数是不是难调啊,感觉一般\(\eta\)很小啊。

还有一个很赞的分析,在博客:

路遥知马力-Momentum

Nesterov accelerated gradient

比Momentum更快:揭开Nesterov Accelerated Gradient的真面目

NGD的迭代公式是:

\[v_t = \gamma v_{t-1} + \eta \nabla_\theta J(\theta - \gamma v_{t-1}) \\
\theta = \theta-v_t
\]

和上面的区别就是,第\(t\)步更新,我们关心的是下一步(一个近似)的梯度,而不是当前点的梯度,我之前以为这是有一个搜索的过程的,但是实际上没有,所以真的是这个式子具有前瞻性?或许真的和上面博客里说的那样,因为后面的部分可以看成一个二阶导的近似。

x = np.array([30., 15.])
process = []
v = 0
gamma = 0.7
eta = 0.013
while True:
grad = partial(x-gamma*v)
v = gamma * v + eta * grad
if np.sqrt(grad @ grad) < 1e-7:
break
else:
process.append(x)
x = x - v

感觉没有momentum好用啊

NESTEROV 的另外一个方法?

在那个overview里面,引用的是

文献链接

但是里面的方面感觉不是NGD啊,不过的确是一种下降方法,所以讲一下吧。

假设\(f(x)\)满足其一阶导函数一致连续的凸函数,比如用以下条件表示:

\[\|f'(x)-f'(y)\| \le L\|x-y\|, \forall x, y \in E
\]

由此可以推得(不晓得这个0.5哪来的,虽然有点像二阶泰勒展式,但是呢,凸函数好像没有这性质吧,去掉0.5就可以直接证出来了,而且这个0.5对证明没有什么大的影响吧,因为只要让L=0.5L就可以了啊):

\[f(y) \le f(x) + <f'(x), y-x>+0.5L\|y-x\|^2 \quad (2)
\]

为了解决\(\min \{f(x)|x\in E\}\),且最优解\(X^*\)非空的情况,我们可以:

  1. 首先选择一个点\(y_0 \in E\),并令
\[k=0, a_0=1, x_{-1}=y_0, \alpha_{-1}=\|y_0-z\|/\|f'(y_0)-f'(z)\|
\]

其中\(z\)是E中不同于\(y_0\)的任意点,且\(f'(y_0) \ne f'(z)\)

  1. 第k 步:

    a) 计算最小的\(i\)满足:
    \[\]
    \[\]
    \[\]

    a_{k+1} = (1+ \sqrt{4a_k^2 + 1})/2 \

    y_{k+1} = x_k + (a_k - 1)(x_k - x_{k-1}) / a_{k+1} .

    \[
    \]

即在满足上面提到的假设,且利用上面给出的方法所求,可以证明,对于任意的\(k\ge 0\):

\[f(x_k) - f^* \le C / (k+2)^2
\]

其中\(C = 4L\|y_0 - x^*\|^2\)并且\(f^*=f(x^*), x^* \in X^*\)。

还有一些关于收敛步长的分析就不贴了。

证明:

令\(y_k(\alpha) - \alpha f'(y_k)\), 可以得到(通过(2)):

\[f(y_k) - f(y_k (\alpha)) \ge 0.5 \alpha (2 - \alpha L) \|f'(y_k)\|^2
\]

结果就是, 只要\(2^{-i} \alpha_{k-1} \le L^{-1}\),不等式(4)就成立,也就是说\(\alpha_k \ge 0.5L^{-1}, \forall k \ge 0\), 否则\(2^{-i} \alpha_{k-1} > L^{-1}\)。

令\(p_l = (a_k-1)(x_{k-1}-x_k)\),则\(y_{k+1}=x_k - p_k / a_{k+1}\),于是:

\[p_{k+1} - x_{k+1} = p_k - x_k + a_{k+1} \alpha_{k+1} f'(y_{k+1})
\]

于是:

\[\begin{array}{ll}
\|p_{k+1}-x_{k+1}+x^*\|^2
&= \|p_k - x_k + x^*\|^2 + 2(a_{k+1}-1)\alpha_{k+1} <f'(y_{k+1}, p_k> \\
& + 2a_{k+1} \alpha_{k+1} <f'(y_{k+1}, x^* - y_{k+1}> + a_{k+1}^2 \alpha_{k+1}^2 \|f'(y_{k+1})\|^2
\end{array}
\]

利用不等式(4)和\(f(x)\)的凸性,可得:

\[\begin{array}{ll}
<f'(y_{k+1}), y_{k+1} - x^*> &\ge f(x_{k+1}) - f^* + 0.5 \alpha_{k+1} \|f'(y_{k+1})\|^2 (5)\\
0.5 \alpha_{k+1} \|f'(y_{k+1})\|^2 &\le f(y_{k+1}) - f(x_{k+1}) \le f(x_k) - f(x_{k+1}) \\
& \quad -a_{k+1}^{-1} <f'(y_{k+1}, p_k> (6)
\end{array}
\]

其中第一个不等式,先利用凸函数得性质:

\[f^* \ge f(y_{k+1}) + <f'(y_{k+1}), x^*-y_{k+1})
\]

再利用不等式(4):

\[f(y_{k+1}) - f(x_{k+1}) \ge 0.5 \alpha_{k+1}\|f'(y_{k+1})\|^2
\]

代入这俩个不等式可得:

\[\begin{array}{ll}
& \|p_{k+1} - x_{k+1}+x^*\|^2 - \|p_k - x_k + x^*\|^2 \le 2(a_{k+1}-1)\alpha_{k+1}<f'(y_{k+1}), p_k> \\
& \quad -2a_{k+1}\alpha_{k+1} (f(x_{k+1} - f^*) + (a_{k+1}^2 - a_{k+1})\alpha_{k+1}^2 \|f'(y_{k+1})\|^2 \\
& \quad \le -2a_{k+1} \alpha_{k+1} (f (x_{k+1}) - f^*) + 2(a_{k+1}^2 - a_{k+1}) \alpha_{k+1}(f(x_k)-f(x_{k+1})) \\
& \quad = 2\alpha_{k+1} a_k^2 (f(x_k)-f^*) - 2\alpha_{k+1} a_{k+1}^2 (f(x_{k+1}) - f^*) \\
& \quad \le 2\alpha_k a_k^2 (f(x_k)-f^*) - 2\alpha_{k+1} a_{k+1}^2 (f(x_{k+1}) -f^*)
\end{array}
\]

其中第一个不等式用到了(5), 第二个不等式用到了(6), 等式用到了\(a_{k+1}^2-a_{k+1}=a_k^2\),最后一步用到了\(\alpha_k \le \alpha_{k+1}\)且\(f(x_k) \ge f^*\)。

因此:

\[\begin{array}{ll}
& 2\alpha_{k+1}a_{k+1}^2 ( f(x_{k+1}) - f^*) \le 2\alpha_{k+1} a_{k+1}^2 (f(x_{k+1})-f^*) + \|p_{k+1}-x_{k+1} + x^*\|^2 \\
& \le 2 \alpha_k a_k (f(x_k)-f^*) + \|p_k -x_k + x^*\|^2 \\
& \le 2\alpha_0 a_0^2 (f(x_0) - f^*) + \|p_0 - x_0 + x^*\|^2 \le \|y_0-x^*\|^2.
\end{array}
\]

最后一个不等式成立是因为\(p_0 = 0, x_0=y_0\),左边第一项大于等于0.

又\(\alpha_k \ge 0.5L^{-1}, a_{k+1}\ge a_k + 0.5 \ge 1 + 0.5(k+1)\),所以:

\[f(x_{k+1}) - f^* \le C/(k+3)^2
\]

证毕。


class Decent:
def __init__(self, function, grad):
self.__function = function
self.__grad = grad
self.process = [] @property
def function(self):
return self.__function @property
def grad(self):
return self.__grad def __call__(self, y, z):
def find_i(y, alpha):
i = 0
fy = self.function(y)
fdy = self.grad(y)
fdynorm = fdy @ fdy
while True:
temp = self.function(y - 2 ** (-i) * alpha * fdy)
if fy - temp > 2 ** (-i -1) * alpha * fdynorm:
return i, fdy
else:
i += 1
a = 1
x = y
fdy = self.grad(y)
fdz = self.grad(z)
alpha = np.sqrt((y-z) @ (y-z) /
(fdy-fdz) @ (fdy - fdz))
k = 0
while True:
k += 1
self.process.append(x)
i, fdy = find_i(y, alpha)
if np.sqrt(fdy @ fdy) < 1:
print(k)
return x
alpha = 2 ** (-i) * alpha
x_old = np.array(x, dtype=float)
x = y - alpha * fdy
a_old = a
a = (1 + np.sqrt(4 * a ** 2 + 1)) / 2
y = x + (a_old - 1) * (x - x_old) / a grad_decent = Decent(f, partial) x = np.array([30., 15.])
z = np.array([200., 10.])
grad_decent(x, z)
process = np.array(grad_decent.process)
x = np.linspace(-40, 40, 1000)
y = np.linspace(-20, 20, 500)
X, Y = np.meshgrid(x, y)
fig, ax = plt.subplots()
ax.contour(X, Y, f([X, Y]), colors="black")
ax.scatter(process[:, 0], process[:, 1])
ax.plot(process[:, 0], process[:, 1])
plt.show()

用了30步就能到达上面的情况,不过呢,如果想让\(\|f'(x)\|\le 1e-7\)得1000多步,主要是因为会来回振荡。

Momentum and NAG的更多相关文章

  1. SGD vs Momentum vs NAG vs Adagrad vs Adadelta vs RMSprop vs Adam

    梯度下降优化基本公式:\({\theta\leftarrow\theta-\eta\cdot\nabla_\theta{J(\theta)}}\) 三种梯度下降优化框架 这三种梯度下降优化框架的区别在 ...

  2. 梯度下降:SGD vs Momentum vs NAG vs Adagrad vs Adadelta vs RMSprop vs Adam

    原文地址:https://www.jianshu.com/p/7a049ae73f56 梯度下降优化基本公式:\({\theta\leftarrow\theta-\eta\cdot\nabla_\th ...

  3. 深度学习——优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

    在机器学习.深度学习中使用的优化算法除了常见的梯度下降,还有 Adadelta,Adagrad,RMSProp 等几种优化器,都是什么呢,又该怎么选择呢? 在 Sebastian Ruder 的这篇论 ...

  4. 【深度学习】深入理解优化器Optimizer算法(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

    在机器学习.深度学习中使用的优化算法除了常见的梯度下降,还有 Adadelta,Adagrad,RMSProp 等几种优化器,都是什么呢,又该怎么选择呢? 在 Sebastian Ruder 的这篇论 ...

  5. (转) An overview of gradient descent optimization algorithms

    An overview of gradient descent optimization algorithms Table of contents: Gradient descent variants ...

  6. Tensorflow 中的优化器解析

    Tensorflow:1.6.0 优化器(reference:https://blog.csdn.net/weixin_40170902/article/details/80092628) I:  t ...

  7. TensorFlow+Keras 02 深度学习的原理

    1 神经传递的原理 人类的神经元传递及其作用: 这里有几个关键概念: 树突 - 接受信息 轴突 - 输出信息 突触 - 传递信息 将其延伸到神经元中,示意图如下: 将上图整理成数学公式,则有 y = ...

  8. An overview of gradient descent optimization algorithms

    原文地址:An overview of gradient descent optimization algorithms An overview of gradient descent optimiz ...

  9. Deep Learning基础--参数优化方法

    1. 深度学习流程简介 1)一次性设置(One time setup)          -激活函数(Activation functions) - 数据预处理(Data Preprocessing) ...

随机推荐

  1. flink04 -----1 kafkaSource 2. kafkaSource的偏移量的存储位置 3 将kafka中的数据写入redis中去 4 将kafka中的数据写入mysql中去

    1. kafkaSource 见官方文档 2. kafkaSource的偏移量的存储位置 默认存在kafka的特殊topic中,但也可以设置参数让其不存在kafka的特殊topic中   3   将k ...

  2. 源码分析-Producer

    消息生产者的代码都在client模块中,相对于RocketMQ来讲,消息生产者就是客户端,也是消息的提供者. 方法和属性 主要方法介绍 //创建主题 void createTopic(final St ...

  3. 如果通过 IP 判断是否是爬虫

    通过 IP 判断爬虫 如果你查看服务器日志,看到密密麻麻的 IP 地址,你一眼可以看出来那些 IP 是爬虫,那些 IP 是正常的爬虫,就像这样: 在这密密麻麻的日志里面,我们不仅要分辨出真正的爬虫 I ...

  4. 【Android】我有放入Icon到mipmap,但不显示,只显示安卓机器人Icon(Android 8.0 图标适配)

    首先,放上别人写的博客,而我自己的博客,只会写大概思路,给自己留给备忘 https://blog.csdn.net/guolin_blog/article/details/79417483 其实会发生 ...

  5. 【Java 8】Stream中flatMap方法

    在java 8 Stream中,flatMap方法是一个维度升降的方法 举例说明 给 定 单 词 列 表["Hello","World"] ,要返回列表 [&q ...

  6. [云原生]Docker - 容器

    目录 Docker容器 启动容器 新建并启动 启动已终止容器 守护态运行容器 终止容器 进入容器 attach命令 exec命令 导出和导入容器 导出容器 导入容器 删除容器 Docker容器 容器是 ...

  7. 基于Kubernetes的hpa实现pod实例数量的自动伸缩

    Pod 是在 Kubernetes 体系中,承载用户业务负载的一种资源.Pod 们运行的好坏,是用户们最为关心的事情.在业务流量高峰时,手动快速扩展 Pod 的实例数量,算是玩转 Kubernetes ...

  8. 可扩展标记语言XML(淅淅沥沥的小雨)

    XML简述 XML用于描述数据,是当前处理结构化文档信息的有力工具.与操作系统编程语言的开发平台无关,可以实现不同系统之间的数据交互. xml文件结构: 1 <?xml version=&quo ...

  9. mit6.830 - lab1 - 存储模型 - 题解

    1.Intro github : https://github.com/CreatorsStack/CreatorDB lab1实现数据库基本的存储逻辑结构,具体包括:Tuple,TupleDesc, ...

  10. 查找与引用函数(Excel函数集团)

    此处文章均为本妖原创,供下载.学习.探讨! 文章下载源是Office365国内版1Driver,如有链接问题请联系我. 请勿用于商业!谢谢 下载地址:https://officecommunity-m ...