import math

import numpy as np

import matplotlib.pyplot as plt

RATIO = 3 # 椭圆的长宽比

LIMIT = 1.2 # 图像的坐标轴范围

class PlotComparaison(object):

"""多种优化器来优化函数 x1^2 + x2^2 * RATIO^2.每次参数改变为(d1, d2).梯度为(dx1, dx2)t+1次迭代,标准GD,d1_{t+1} = - eta * dx1d2_{t+1} = - eta * dx2带Momentum,d1_{t+1} = eta * (mu * d1_t - dx1_{t+1})d2_{t+1} = eta * (mu * d2_t - dx2_{t+1})带Nesterov Accent;,d1_{t+1} = eta * (mu * d1_t - dx1^{nag}_{t+1})d2_{t+1} = eta * (mu * d2_t - dx2^{nag}_{t+1})其中(dx1^{nag}, dx2^{nag})为(x1 + eta * mu * d1_t, x2 + eta * mu * d2_t)处的梯度RMSProp,w1_{t+1} = beta2 * w1_t + (1 - beta2) * dx1_t^2w2_{t+1} = beta2 * w2_t + (1 - beta2) * dx2_t^2d1_{t+1} = - eta * dx1_t / (sqrt(w1_{t+1}) + epsilon)d2_{t+1} = - eta * dx2_t / (sqrt(w2_{t+1}) + epsilon)Adam,每次参数改变为(d1, d2)v1_{t+1} = beta1 * v1_t + (1 - beta1) * dx1_tv2_{t+1} = beta1 * v2_t + (1 - beta1) * dx2_tw1_{t+1} = beta2 * w1_t + (1 - beta2) * dx1_t^2w2_{t+1} = beta2 * w2_t + (1 - beta2) * dx2_t^2v1_corrected = v1_{t+1} / (1 - beta1^{t+1})v2_corrected = v2_{t+1} / (1 - beta1^{t+1})w1_corrected = w1_{t+1} / (1 - beta2^{t+1})w2_corrected = w2_{t+1} / (1 - beta2^{t+1})d1_{t+1} = - eta * v1_corrected / (sqrt(w1_corrected) + epsilon)d2_{t+1} = - eta * v2_corrected / (sqrt(w2_corrected) + epsilon)AdaGrad,w1_{t+1} = w1_t + dx1_t^2w2_{t+1} = w2_t + dx2_t^2d1_{t+1} = - eta * dx1_t / sqrt(w1_{t+1} + epsilon)d2_{t+1} = - eta * dx2_t / sqrt(w2_{t+1} + epsilon)Adadeltaupdate1_{t+1} = rho * update1_t + (1 - rho) * d1_t^2update2_{t+1} = rho * update2_t + (1 - rho) * d2_t^2w1_{t+1} = rho * w1_t + (1 - rho) * dx1_t^2w2_{t+1} = rho * w2_t + (1 - rho) * dx2_t^2d1_{t+1} = - dx1 * rms(update1_{t+1}) / rms(w1_{t+1})d2_{t+1} = - dx2 * rms(update2_{t+1}) / rms(w2_{t+1})定义 rms(x) = sqrt(x + epsilon)"""

def __init__(self, eta=0.1, mu=0.9, beta1=0.9, beta2=0.99, rho=0.9, epsilon=1e-10, angles=None, contour_values=None,

stop_condition=1e-4):

# 全部算法的学习率

self.eta = eta

# 启发式学习的终止条件

self.stop_condition = stop_condition

# Nesterov Momentum超参数

self.mu = mu

# RMSProp超参数

self.beta1 = beta1

self.beta2 = beta2

self.epsilon = epsilon

# Adadelta的超参数

self.rho = rho

# 用正态分布随机生成初始点

self.x1_init, self.x2_init = np.random.uniform(LIMIT / 2, LIMIT), np.random.uniform(LIMIT / 2, LIMIT) / RATIO

self.x1, self.x2 = self.x1_init, self.x2_init

# 等高线相关

if angles == None:

angles = np.arange(0, 2 * math.pi, 0.01)

self.angles = angles

if contour_values == None:

contour_values = [0.25 * i for i in range(1, 5)]

self.contour_values = contour_values

setattr(self, "contour_colors", None)

def draw_common(self, title):

"""画等高线,最优点和设置图片各种属性"""

# 坐标轴尺度一致

plt.gca().set_aspect(1)

# 根据等高线的值生成坐标和颜色

# 海拔越高颜色越深

num_contour = len(self.contour_values)

if not self.contour_colors:

self.contour_colors = [(i / num_contour, i / num_contour, i / num_contour) for i in range(num_contour)]

self.contour_colors.reverse()

self.contours = [

[

list(map(lambda x: math.sin(x) * math.sqrt(val), self.angles)),

list(map(lambda x: math.cos(x) * math.sqrt(val) / RATIO, self.angles))

]

for val in self.contour_values

]

# 画等高线

for i in range(num_contour):

plt.plot(self.contours[i][0],

self.contours[i][1],

linewidth=1,

linestyle='-',

color=self.contour_colors[i],

label="y={}".format(round(self.contour_values[i], 2))

)

# 画最优点

plt.text(0, 0, 'x*')

# 图片标题

plt.title(title)

# 设置坐标轴名字和范围

plt.xlabel("x1")

plt.ylabel("x2")

plt.xlim((-LIMIT, LIMIT))

plt.ylim((-LIMIT, LIMIT))

# 显示图例

plt.legend(loc=1)

def forward_gd(self):

"""SGD一次迭代"""

self.d1 = -self.eta * self.dx1

self.d2 = -self.eta * self.dx2

self.ite += 1

def draw_gd(self, num_ite=5):

"""画基础SGD的迭代优化.包括每次迭代的点,以及表示每次迭代改变的箭头"""

# 初始化

setattr(self, "ite", 0)

setattr(self, "x1", self.x1_init)

setattr(self, "x2", self.x2_init)

# 画每次迭代

self.point_colors = [(i / num_ite, 0, 0) for i in range(num_ite)]

plt.scatter(self.x1, self.x2, color=self.point_colors[0])

for _ in range(num_ite):

self.forward_gd()

# 迭代的箭头

plt.arrow(self.x1, self.x2, self.d1, self.d2,

length_includes_head=True,

linestyle=':',

label='{}ite'.format(self.ite),

color='b',

head_width=0.08

)

self.x1 += self.d1

self.x2 += self.d2

print("第{}次迭代后,坐标为({},{})".format(self.ite, self.x1, self.x2))

plt.scatter(self.x1, self.x2) # 迭代的点

if self.loss < self.stop_condition:

break

def forward_momentum(self):

"""带Momentum的SGD一次迭代"""

self.d1 = self.eta * (self.mu * self.d1_pre - self.dx1)

self.d2 = self.eta * (self.mu * self.d2_pre - self.dx2)

self.ite += 1

self.d1_pre, self.d2_pre = self.d1, self.d2

def draw_momentum(self, num_ite=5):

"""画带Momentum的迭代优化."""

# 初始化

setattr(self, "ite", 0)

setattr(self, "x1", self.x1_init)

setattr(self, "x2", self.x2_init)

setattr(self, "d1_pre", 0)

setattr(self, "d2_pre", 0)

# 画每次迭代

self.point_colors = [(i / num_ite, 0, 0) for i in range(num_ite)]

plt.scatter(self.x1, self.x2, color=self.point_colors[0])

for _ in range(num_ite):

self.forward_momentum()

# 迭代的箭头

plt.arrow(self.x1, self.x2, self.d1, self.d2,

length_includes_head=True,

linestyle=':',

label='{}ite'.format(self.ite),

color='b',

head_width=0.08

)

self.x1 += self.d1

self.x2 += self.d2

print("第{}次迭代后,坐标为({},{})".format(self.ite, self.x1, self.x2))

plt.scatter(self.x1, self.x2) # 迭代的点

if self.loss < self.stop_condition:

break

def forward_nag(self):

"""Nesterov Accelerated的SGD一次迭代"""

self.d1 = self.eta * (self.mu * self.d1_pre - self.dx1_nag)

self.d2 = self.eta * (self.mu * self.d2_pre - self.dx2_nag)

self.ite += 1

self.d1_pre, self.d2_pre = self.d1, self.d2

def draw_nag(self, num_ite=5):

"""画Nesterov Accelerated的迭代优化."""

# 初始化

setattr(self, "ite", 0)

setattr(self, "x1", self.x1_init)

setattr(self, "x2", self.x2_init)

setattr(self, "d1_pre", 0)

setattr(self, "d2_pre", 0)

# 画每次迭代

self.point_colors = [(i / num_ite, 0, 0) for i in range(num_ite)]

plt.scatter(self.x1, self.x2, color=self.point_colors[0])

for _ in range(num_ite):

self.forward_nag()

# 迭代的箭头

plt.arrow(self.x1, self.x2, self.d1, self.d2,

length_includes_head=True,

linestyle=':',

label='{}ite'.format(self.ite),

color='b',

head_width=0.08

)

self.x1 += self.d1

self.x2 += self.d2

print("第{}次迭代后,坐标为({},{})".format(self.ite, self.x1, self.x2))

plt.scatter(self.x1, self.x2) # 迭代的点

if self.loss < self.stop_condition:

break

def forward_rmsprop(self):

"""RMSProp一次迭代"""

w1 = self.beta2 * self.w1_pre + (1 - self.beta2) * (self.dx1 ** 2)

w2 = self.beta2 * self.w2_pre + (1 - self.beta2) * (self.dx2 ** 2)

self.ite += 1

self.w1_pre, self.w2_pre = w1, w2

self.d1 = -self.eta * self.dx1 / (math.sqrt(w1) + self.epsilon)

self.d2 = -self.eta * self.dx2 / (math.sqrt(w2) + self.epsilon)

def draw_rmsprop(self, num_ite=5):

"""画RMSProp的迭代优化."""

# 初始化

setattr(self, "ite", 0)

setattr(self, "x1", self.x1_init)

setattr(self, "x2", self.x2_init)

setattr(self, "w1_pre", 0)

setattr(self, "w2_pre", 0)

# 画每次迭代

self.point_colors = [(i / num_ite, 0, 0) for i in range(num_ite)]

plt.scatter(self.x1, self.x2, color=self.point_colors[0])

for _ in range(num_ite):

self.forward_rmsprop()

# 迭代的箭头

plt.arrow(self.x1, self.x2, self.d1, self.d2,

length_includes_head=True,

linestyle=':',

label='{}ite'.format(self.ite),

color='b',

head_width=0.08

)

self.x1 += self.d1

self.x2 += self.d2

print("第{}次迭代后,坐标为({},{})".format(self.ite, self.x1, self.x2))

plt.scatter(self.x1, self.x2) # 迭代的点

if self.loss < self.stop_condition:

break

def forward_adam(self):

"""AdaM一次迭代"""

w1 = self.beta2 * self.w1_pre + (1 - self.beta2) * (self.dx1 ** 2)

w2 = self.beta2 * self.w2_pre + (1 - self.beta2) * (self.dx2 ** 2)

v1 = self.beta1 * self.v1_pre + (1 - self.beta1) * self.dx1

v2 = self.beta1 * self.v2_pre + (1 - self.beta1) * self.dx2

self.ite += 1

self.v1_pre, self.v2_pre = v1, v2

self.w1_pre, self.w2_pre = w1, w2

v1_corr = v1 / (1 - math.pow(self.beta1, self.ite))

v2_corr = v2 / (1 - math.pow(self.beta1, self.ite))

w1_corr = w1 / (1 - math.pow(self.beta2, self.ite))

w2_corr = w2 / (1 - math.pow(self.beta2, self.ite))

self.d1 = -self.eta * v1_corr / (math.sqrt(w1_corr) + self.epsilon)

self.d2 = -self.eta * v2_corr / (math.sqrt(w2_corr) + self.epsilon)

def draw_adam(self, num_ite=5):

"""画AdaM的迭代优化."""

# 初始化

setattr(self, "ite", 0)

setattr(self, "x1", self.x1_init)

setattr(self, "x2", self.x2_init)

setattr(self, "w1_pre", 0)

setattr(self, "w2_pre", 0)

setattr(self, "v1_pre", 0)

setattr(self, "v2_pre", 0)

# 画每次迭代

self.point_colors = [(i / num_ite, 0, 0) for i in range(num_ite)]

plt.scatter(self.x1, self.x2, color=self.point_colors[0])

for _ in range(num_ite):

self.forward_adam()

# 迭代的箭头

plt.arrow(self.x1, self.x2, self.d1, self.d2,

length_includes_head=True,

linestyle=':',

label='{}ite'.format(self.ite),

color='b',

head_width=0.08

)

self.x1 += self.d1

self.x2 += self.d2

print("第{}次迭代后,坐标为({},{})".format(self.ite, self.x1, self.x2))

plt.scatter(self.x1, self.x2) # 迭代的点

if self.loss < self.stop_condition:

break

def forward_adagrad(self):

"""AdaGrad一次迭代"""

w1 = self.w1_pre + self.dx1 ** 2

w2 = self.w2_pre + self.dx2 ** 2

self.ite += 1

self.w1_pre, self.w2_pre = w1, w2

self.d1 = -self.eta * self.dx1 / math.sqrt(w1 + self.epsilon)

self.d2 = -self.eta * self.dx2 / math.sqrt(w2 + self.epsilon)

def draw_adagrad(self, num_ite=5):

"""画AdaGrad的迭代优化."""

# 初始化

setattr(self, "ite", 0)

setattr(self, "x1", self.x1_init)

setattr(self, "x2", self.x2_init)

setattr(self, "w1_pre", 0)

setattr(self, "w2_pre", 0)

# 画每次迭代

self.point_colors = [(i / num_ite, 0, 0) for i in range(num_ite)]

plt.scatter(self.x1, self.x2, color=self.point_colors[0])

for _ in range(num_ite):

self.forward_adagrad()

# 迭代的箭头

plt.arrow(self.x1, self.x2, self.d1, self.d2,

length_includes_head=True,

linestyle=':',

label='{}ite'.format(self.ite),

color='b',

head_width=0.08

)

self.x1 += self.d1

self.x2 += self.d2

print("第{}次迭代后,坐标为({},{})".format(self.ite, self.x1, self.x2))

plt.scatter(self.x1, self.x2) # 迭代的点

if self.loss < self.stop_condition:

break

def forward_adadelta(self):

"""Adadelta一次迭代"""

w1 = self.rho * self.w1_pre + (1 - self.rho) * (self.dx1 ** 2)

w2 = self.rho * self.w2_pre + (1 - self.rho) * (self.dx2 ** 2)

update1 = self.rho * self.update1_pre + (1 - self.rho) * (self.d1 ** 2)

update2 = self.rho * self.update2_pre + (1 - self.rho) * (self.d2 ** 2)

self.ite += 1

self.update1_pre, self.update2_pre = update1, update2

self.w1_pre, self.w2_pre = w1, w2

self.d1 = - self.rms(update1) / self.rms(w1) * self.dx1

self.d2 = - self.rms(update2) / self.rms(w2) * self.dx2

def draw_adadelta(self, num_ite=5):

"""画Adadelta的迭代优化."""

# 初始化

for attr in ["w{}_pre", "update{}_pre", "d{}"]:

for dim in [1, 2]:

setattr(self, attr.format(dim), 0)

setattr(self, "ite", 0)

setattr(self, "x1", self.x1_init)

setattr(self, "x2", self.x2_init)

# 画每次迭代

self.point_colors = [(i / num_ite, 0, 0) for i in range(num_ite)]

plt.scatter(self.x1, self.x2, color=self.point_colors[0])

for _ in range(num_ite):

self.forward_adadelta()

# 迭代的箭头

plt.arrow(self.x1, self.x2, self.d1, self.d2,

length_includes_head=True,

linestyle=':',

label='{}ite'.format(self.ite),

color='b',

head_width=0.08

)

self.x1 += self.d1

self.x2 += self.d2

print("第{}次迭代后,坐标为({},{})".format(self.ite, self.x1, self.x2))

plt.scatter(self.x1, self.x2) # 迭代的点

if self.loss < self.stop_condition:

break

@property

def dx1(self, x1=None):

return self.x1 * 2

@property

def dx2(self):

return self.x2 * 2 * (RATIO ** 2)

@property

def dx1_nag(self, x1=None):

return (self.x1 + self.eta * self.mu * self.d1_pre) * 2

@property

def dx2_nag(self):

return (self.x2 + self.eta * self.mu * self.d2_pre) * 2 * (RATIO ** 2)

@property

def loss(self):

return self.x1 ** 2 + (RATIO * self.x2) ** 2

def rms(self, x):

return math.sqrt(x + self.epsilon)

def show(self):

# 设置图片大小

plt.figure(figsize=(20, 20))

# 展示

plt.show()

num_ite = 10

xixi = PlotComparaison()

print("起始点为({},{})".format(xixi.x1_init, xixi.x2_init))

xixi.draw_momentum(num_ite)

xixi.draw_common("Optimize x1^2+x2^2*{}Using SGD With Momentum".format(RATIO ** 2))

xixi.show()

xixi.draw_rmsprop(num_ite)

xixi.draw_common("Optimize x1^2+x2^2*{}Using RMSProp".format(RATIO ** 2))

xixi.show()

def adagrad(eta):

xixi.eta = eta

xixi.draw_adagrad(num_ite)

xixi.draw_common("Optimize x1^2+x2^2*{}Using AdaGrad with eta={}".format(RATIO ** 2, eta))

xixi.show()

adagrad(1e-1)

adagrad(1)

adagrad(10)

adagrad(100)

def adadelta(epsilon):

xixi.epsilon = epsilon

xixi.draw_adadelta(num_ite)

xixi.draw_common("Optimize x1^2+x2^2*{}Using Adadelta with epsilon={}".format(RATIO ** 2, epsilon))

xixi.show()

adadelta(1e-2)

adadelta(1e-1)

adadelta(1e-2)

adadelta(1e-3)

adadelta算法_机器学习中的优化算法(3)-AdaGrad, Adadelta(附Python示例)相关推荐

  1. louvian算法 缺点 优化_机器学习中的优化算法(1)-优化算法重要性,SGD,Momentum(附Python示例)...

    本系列文章已转至 机器学习的优化器​zhuanlan.zhihu.com 优化算法在机器学习中扮演着至关重要的角色,了解常用的优化算法对于机器学习爱好者和从业者有着重要的意义. 这系列文章先讲述优化算 ...

  2. 机器学习知识总结系列-机器学习中的优化算法总结(1-4)

    文章目录 1.梯度下降 1.1批量梯度下降(BGD) 1.2随机梯度下降(SGD) 1.3 小批量随机梯度下降(MSGD) 1.4 比较: 1.5 动量算法(momentum) 1.6 Nestrov ...

  3. 机器学习中的优化算法介绍

    在机器学习中,有很多的问题并没有解析形式的解,或者有解析形式的解但是计算量很大(譬如,超定问题的最小二乘解),对于此类问题,通常我们会选择采用一种迭代的优化方式进行求解.   这些常用的优化算法包括: ...

  4. 机器学习中的优化算法!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:李祖贤,Datawhale高校群成员,深圳大学 在机器学习中,有很 ...

  5. 机器学习朴素贝叶斯算法_机器学习中的朴素贝叶斯算法

    机器学习朴素贝叶斯算法 朴素贝叶斯算法 (Naive Bayes Algorithm) Naive Bayes is basically used for text learning. Using t ...

  6. 最小径集的算法_机器学习的利器——集成算法

    最近在打算法竞赛的时候用到了集成算法,效果还不错,索性就总结了一篇集成算法的文章,希望能帮到正在转行的数据分析师们. 集成算法核心思想 集成算法的核心思想是通过构建并结合多个学习器来完成学习任务,也就 ...

  7. adam算法_关于损失函数和优化算法,看这一篇就够了

    在进行神经网络训练时,很多同学都不太注重损失函数图和损失函数的优化算法的理解,造成的结果就是:看起来效果不错,但是不知道训练的参数是否合理,也不知道有没有进一步优化的空间,也不知道初始点的选择是否恰当 ...

  8. java 寻路算法_游戏中的寻路算法解析

    游戏角色的自动寻路,已经是游戏中一个历史比较悠久的领域,较为成熟也有很多种实现.这里摘录一句后面所提的参考资料中的描述:"业内AI开发者中有一句话:"寻路已不是问题."我 ...

  9. minibatchgd代码_神经网络中的优化算法

    上一篇文章讲了神经网络的参数初试化,可以看到不同的初始化方法对我们的学习效果有很大影响.(参见:[DL笔记]神经网络参数初始化的学问) 本文继续讨论如何进一步优化我们的梯度下降算法,使得我们的学习更快 ...

  10. id长度 雪花算法_分布式系统中唯一ID算法之雪花算法

    背景 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有些时候我们希望能使用一种 ...

最新文章

  1. Access里执行SQL
  2. C++ STL,ATL,WTL之间的联系和区别
  3. ASP.NET 框架 之HttpHandler
  4. Spark in meituan http://tech.meituan.com/spark-in-meituan.html
  5. chrome插件 vscode_2020年,前端开发者必备的10个VS Code扩展插件
  6. 面向对象的思想是什么?
  7. TOPSIS与模糊Borda 的组合应用(以第二届大湾区杯和国赛为案例)
  8. sql backup database备份d盘_Oracle-备份与恢复(二)RMAN备份-自动备份计划任务脚本...
  9. mysql升更新命令_MySQL升级的3种方法
  10. 一键报警(IP对讲)
  11. H5app 调用手机摄像头拍照、录制视频并上传demo
  12. Win10电脑关机后立即自动重启怎么办
  13. Android IntentService deprecated|笔记
  14. 润乾报表如何解决F5负载均衡设备下URL限制问题
  15. 太虚幻境 文/江湖一劍客
  16. TS进阶之keyof
  17. 【微机原理与接口技术】之一微型计算机系统概述
  18. 存储过程之八-java代码调用oracle存储过程
  19. 微软PowerApps整合PowerBI
  20. 微服务 - Hystrix 熔断器

热门文章

  1. CISSP的2021年认证大纲、CISSP学习大纲、中国考点,及如何考取成功
  2. 电商数据应用体系建设总结(一)—— 数据应用架构剖析
  3. kettle中的switch_kettle 教程(三):条件判断 Switch Case
  4. Xshell5(远程终端工具)工具的安装使用 【免费】
  5. 怎么批量修改文件后缀名?
  6. 五 Zabbix全网监控
  7. 智能运维发展史及核心技术研究
  8. Junit 4 与Junit 5区别
  9. EXCEL常用函数汇总
  10. 计算机音乐专业学什么软件有哪些内容,电脑音乐入门装备(软件篇)