Python 实现AdaGrad和Adam拟合四次函数(随笔四)
1. AdaGrad
拟合四次函数,目标函数:
f(x)=3.2∗x4+1.5∗x3+4.3∗x2+9.03∗x−15f(x) = 3.2 * {x}^4 + 1.5 * {x}^3 + 4.3 * {x}^2 + 9.03 * {x} - 15f(x)=3.2∗x4+1.5∗x3+4.3∗x2+9.03∗x−15
1.1 原理
原理如下图所示,摘自李宏毅老师上课ppt:
1.2 代码:
这里学习率选择的是alpha = 8.5,在这里好像学习率对结果影响不大,我甚至选择了100以及0.001,最后结果只跟迭代次数有关,迭代开始时下降很快,越到后面收敛越慢,这也是AdaGrad的缺点:
import numpy as np
import random
import matplotlib.pyplot as pltdef my_Func(params, x):return params[0] * x ** 4 + params[1] * x ** 3 + params[2] * x ** 2 + params[1] * x - params[4]def ge_Func():num_data = 99x = np.array(np.linspace(-15, 15, num_data)).reshape(num_data, 1) # 产生包含噪声的数据mid, sigma = -1, 1y = 3.2 * x ** 4 + 1.5 * x ** 3 + 4.3 * x ** 2 + 9.03 * x - 15 + np.random.normal(mid, sigma, num_data).reshape(num_data, 1)return x, ydef get_Gradient(x, y, y_):for i in range(10):bet_num = random.sample(range(1, len(x) - 1), 10)gradient = np.array([0.0, 0.0, 0.0, 0.0, 0.0])for i in bet_num:gradient[0] += (x[i] ** 4) * (y[i] - y_[i])gradient[1] += (x[i] ** 3) * (y[i] - y_[i])gradient[2] += (x[i] ** 2) * (y[i] - y_[i])gradient[3] += x[i] * (y[i] - y_[i])gradient[4] += -1 * (y[i] - y_[i])gradient = gradient / len(x)return gradientdef gra_D():x, y = ge_Func()params = np.array([0.0, 0.0, 0.0, 0.0, 0.0])y_ = my_Func(params, x)error, iteration, alpha = 1E-3, 1000, 8.5e = np.linalg.norm(y - y_, ord=2, axis=None, keepdims=False)e_print = []it = 0lt = []L_square = []while e >= error and it < iteration:it += 1gradient = get_Gradient(x, y, y_)L_square.append(gradient)params = params + gradient * alpha / np.linalg.norm(L_square, ord=2, axis=None, keepdims=False)print(params)y_ = my_Func(params, x)e = np.linalg.norm(y - y_, ord=2, axis=None, keepdims=False) / len(x)lt.append(it)e_print.append(e)print('迭代次数:%d' % it, 'params:', params, 'error:%f' % e)fig, ax = plt.subplots(2, 2)ax[0][0].plot(x, my_Func(params, x), c='r')ax[0][0].scatter(x, y, c='b')ax[0][1].plot(lt, e_print, color='r', linestyle='-')ax[1][0].plot(lt, L_square, c='r', linestyle='-')plt.show()if __name__ == '__main__':gra_D()
1.3 结果
图1-图3分别是拟合结果图,误差下降图,梯度平方和变化图:
由图三可知,梯度平方和到了后面几乎没有变化,由此导致图二中的误差过于平滑,也就是随着时间的进行,误差几乎没有变化。
参数:
**
迭代次数:1000 params: [ 3.22074045e+00 1.54541756e+00 3.33389651e-02 1.02358320e-02 -3.99912583e-04] error:1267.078275
**
2. SGDM
目标函数:
f(x)=4.3∗x2+3∗x−15f(x)=4.3*x^2+3*x-15 f(x)=4.3∗x2+3∗x−15
2.1 拟合二次函数
代码:
import numpy as np
import math as ma
import random
import matplotlib.pyplot as pltdef my_Func(params, x):return params[0] * x ** 2 + params[1] * x - params[2]def ge_Func():num_data = 80x = np.array(np.linspace(-2, 2, num_data)).reshape(num_data, 1) # 产生包含噪声的数据mid, sigma = -1, 1y = 4.3 * x ** 2 + 3 * x - 15 + np.random.normal(mid, sigma, num_data).reshape(num_data, 1)return x, ydef get_Gradient(x, y, y_):gradient = np.array([0, 0, 0])#rand_num = random.sample(range(0, len(x) - 1), 10)for i in range(0, len(x)):gradient[0] += (x[i] ** 2) * (y[i] - y_[i])gradient[1] += x[i] * (y[i] - y_[i])gradient[2] += -1 * (y[i] - y_[i])return gradient / len(x)def gra_D():x, y = ge_Func()params = np.array([0, 0, 0])y_ = my_Func(params, x)#参数数组error, iteration, alpha, lam = 1E-3, 10000, 1E-1, 1E-9e = np.linalg.norm(y - y_, ord=2, axis=None, keepdims=False) / len(x)e_print = []e_print.append(e)it = 0lt = [it]movement = np.array([0.0, 0.0, 0.0])while e >= error and it < iteration:it += 1movement = lam * movement + alpha * get_Gradient(x, y, y_)params = params + movementy_ = my_Func(params, x)e = np.linalg.norm((y - y_), ord=2, axis=None, keepdims=False)lt.append(it)e_print.append(e)print('迭代次数:%d' % it, 'params:', params, 'error:%f' % e)plt.plot(x, my_Func(params, x), c = 'r')plt.scatter(x, y, c = 'b')#plt.plot(lt, e_print, color='r', linestyle='-')plt.show()if __name__ == '__main__':gra_D()
2.2 拟合结果
**
迭代次数:10000 params: [ 3.855 3.3325 15.12875002] error:9.955006
**
个人感觉针对这种数据量极小且函数很简单的,SGDM不如SGD的,SGDM主要还是针对复杂函数以免受当前平滑梯度影响。
3. Adam
这里也是拟合二次函数:
f(x)=4.3∗x2+3∗x−15f(x)=4.3*x^2+3*x-15 f(x)=4.3∗x2+3∗x−15
3.1 原理
它是结合了SGDM与AdaGrad的优势,因此参数更新的公式f分别如下所示(第一个是SGDM更新的形式,第二个是AdaGrad更新的形式,最后则是Adam更新的形式):
mt=mt−1∗β1+(1−β1)∗gt−1(1)m_{t}= m_{t-1}*\beta_{1}+(1-\beta_{1})*g_{t-1} (1)mt=mt−1∗β1+(1−β1)∗gt−1(1)
vt=vt−1∗β2+(1−β2)∗vt−1(2)v_{t}= v_{t-1}*\beta_{2}+(1-\beta_{2})*v_{t-1} (2)vt=vt−1∗β2+(1−β2)∗vt−1(2)
θt=θt−1−η∗mt−1ϵ+vt(3)\theta_{t}= \theta_{t-1}-\frac{\eta*m_{t-1} } {\epsilon+\sqrt{v_{t}}} (3)θt=θt−1−ϵ+vtη∗mt−1(3)
3.2代码:
import numpy as np
import math as ma
import pandas as pd
import random
import matplotlib.pyplot as pltdef my_Func(params, x):return params[0] * x ** 2 + params[1] * x - params[2]def ge_Func():num_data = 80x = np.array(np.linspace(-2, 2, num_data)).reshape(num_data, 1) # 产生包含噪声的数据mid, sigma = -1, 1y = 2.3 * x ** 2 + 3.21 * x - 45 + np.random.normal(mid, sigma, num_data).reshape(num_data, 1)return x, ydef get_Gradient(x, y, y_):gradient = np.array([0.0, 0.0, 0.0])rand_num = random.sample(range(0, len(x) - 1), 10)for i in range(0, len(x)):gradient[0] += (x[i] ** 2) * (y[i] - y_[i])gradient[1] += x[i] * (y[i] - y_[i])gradient[2] += -1 * (y[i] - y_[i])return gradient / len(x)def gra_D():x, y = ge_Func()params = np.array([0.0, 0.0, 0.0])y_ = my_Func(params, x)#参数数组berror, iteration, eta, beta1, beta2, epsilon = 1E-3, 10000, 0.9, 0.9, 0.999, 1E-8e = np.linalg.norm(y - y_, ord=2, axis=None, keepdims=False)e_print = []e_print.append(e)it = 0lt = [it]movement = np.array([0.0, 0.0, 0.0])alpha = get_Gradient(x, y, y_) ** 2m_hat = 0alpha_hat = 0while e >= error and it < iteration:it += 1movement = beta1 * movement + (1 - beta1) * get_Gradient(x, y, y_)m_hat = movement / (1 - beta1 ** it)alpha = beta2 * alpha + (1 - beta2) * get_Gradient(x, y, y_) ** 2alpha_hat = alpha / (1 - beta2 ** it)params = params + m_hat * eta / (epsilon + alpha_hat ** 0.5)y_ = my_Func(params, x)e = np.linalg.norm((y - y_), ord=2, axis=None, keepdims=False)lt.append(it)e_print.append(e)print('迭代次数:%d' % it, 'params:', params, 'error:%f' % e)fig, ax = plt.subplots(2, 2)ax[0][0].plot(x, my_Func(params, x), c='r')ax[0][0].scatter(x, y, c='b')ax[0][1].plot(lt, e_print, color='r', linestyle='-')plt.show()if __name__ == '__main__':gra_D()
3.3 结果展示
**
迭代次数:10000 params: [ 2.26108091 3.17206049 45.89451072] error:8.897530
迭代次数:1000 params: [ 2.10264983 3.26407548 45.55939655] error:9.477001
**
对于以上几种优化方法,个人只做了一点实现,并没有花费大量时间去调整其中的参数,因此有些精度可能存在一些理论上的差距,均方根误差值其实有点大。
Python 实现AdaGrad和Adam拟合四次函数(随笔四)相关推荐
- [Python系列-16]:人工智能 - 数学基础 -6- 常见数学函数、激活函数大全
作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing 本文网址:https://blog.csdn.net/HiWangWenBing/article ...
- 神经网络的SGD、Momentum、AdaGrad、Adam最优化方法及其python实现
神经网络的SGD.Momentum.AdaGrad.Adam最优化方法及其python实现 一.SGD 二.Momentum-动量 三.AdaGrad 四.Adam 一.SGD 右边的值更新左边的值, ...
- 优化函数SGD/AdaGrad/AdaDelta/Adam/Nadam
一.准备知识 指数加权平均 指数加权平均值又称指数加权移动平均值,局部平均值,移动平均值.加权平均这个概念都很熟悉,即根据各个元素所占权重计算平均值.指数加权平均中的指数表示各个元素所占权重呈指数分布 ...
- 不同算法的差异SGD/AdaGrad/AdaDelta/Adam/Nadam
一.准备知识 指数加权平均 指数加权平均值又称指数加权移动平均值,局部平均值,移动平均值.加权平均这个概念都很熟悉,即根据各个元素所占权重计算平均值.指数加权平均中的指数表示各个元素所占权重呈指数分布 ...
- 深度学习笔记:优化方法总结(BGD,SGD,Momentum,AdaGrad,RMSProp,Adam)
深度学习笔记(一):logistic分类 深度学习笔记(二):简单神经网络,后向传播算法及实现 深度学习笔记(三):激活函数和损失函数 深度学习笔记:优化方法总结 深度学习笔记(四):循环神经 ...
- python3中多项式创建_机器学习入门之机器学习之路:python 多项式特征生成PolynomialFeatures 欠拟合与过拟合...
本文主要向大家介绍了机器学习入门之机器学习之路:python 多项式特征生成PolynomialFeatures 欠拟合与过拟合,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助. 分享 ...
- python数据挖掘笔记】十八.线性回归及多项式回归分析四个案例分享
python数据挖掘课程]十八.线性回归及多项式回归分析四个案例分享 #2018-03-30 18:24:56 March Friday the 13 week, the 089 day SZ SSM ...
- 花书+吴恩达深度学习(七)优化方法之基本算法(Momentum, Nesterov, AdaGrad, RMSProp, Adam)
目录 0. 前言 1. 指数加权平均(exponentially weighted averages) 2. Momentum 动量 3. Nesterov 动量 4. AdaGrad 5. RMSP ...
- 深度学习入门-ANN神经网络参数最优化问题(SGD,Momentum,AdaGrad,RMSprop,Adam)
这里写目录标题 1. 参数优化 1.1 随机梯度下降法(SGD) 1.2 Momentum 动量法 1.3 AdaGrad 1.4 RMSprop 1.5 Adam 1. 参数优化 本文总结一下ANN ...
最新文章
- 诗人般的机器学习,ML工作原理大揭秘
- 深度 | 量子计算技术的研究现状与未来
- 【2012年华为校园招聘软开上机-成都】字母转换、统计单词个数
- 《算法设计手册》面试题解答 第三章:数据结构
- python文本编辑pycharm_PyCharm的基本使用
- 史上最‘牛’杀毒软件之麦咖啡
- 数据库兼容级别对数据备份还原的影响
- 深入Dapper.NET源码
- iis7.5配置 html,windows server 2008R2系统 IIS7.5配置伪静态的方法(urlrewrite)
- php提供的魔术常量
- UVA10213 How Many Pieces of Land【数学+大数】
- CPP-week fourteen
- 吾有个怪习惯:看书时经常把ABC结构的词看成ACB
- linux添加变色龙引导,u盘启动盘制作win7变色龙引导工具
- android系统电源管理驱动分析
- 泰坦尼克号分析是否获救
- java.sql.SQLSyntaxErrorException: Table ‘H_PERSION‘ doesn‘t exist
- 关于SQL中的触发器(数据库)
- linux文件前面多两个点,Linux 学习笔记
- MySQL 是如何归档数据的呢?