参考连接:https://www.bilibili.com/video/BV1bD4y197EE?from=search&seid=2812665294799649680
一、常用的优化方法
- Momentum方法:通过添加栋梁,提高收敛速度。
- Nestrov方法:在进行当前更新前,先进行预演一次,从而找到一个更加适合当前情况的梯度方向和幅度。
- Adagrad方法:让不同的参数拥有不同的学习率,并且通过引入梯度的平方和作为衰减想,而在训练过程中自动降低的学习率。
- AdaDelta方法:对Adagrad进行改进,让模型在训练后期也能够有较为适合的学习率。
二、Adam算法
案例代码
# ADAM
# 以y=x1+2*x2 为例
# y=np.cdot(x,theta)
import math
import numpy as np
def adam():
# 训练集,每个样本有三个分量
x=np.array([(1,1),(1,2),(2,2),(3,1),(1,3),(2,4),(2,3),(3,3)]) # (x1,x2)
y=np.array([3,5,6,5,7,10,8,9]) # 预测值
# 初始化
m,dim =x.shape # 返回数组的维数 (8,2)
theta=np.zeros(dim) # parameter [0,0]
alpha=0.01 # 学习率 0.001?收敛性不好后修改的
momentum=0.1 # 动量
threshold=0.0001 # 停止迭代的错误阈值
iterations=3000 # 迭代次数
error=0 # 初始误差为0
b1=0.9 # 算法作者建议的默认值
b2=0.999 # 算法作者建议的默认值
e=0.00000001 # 10E-8,以避免除以零
mt=np.zeros(dim)
vt=np.zeros(dim)
for i in range(iterations):
j=i % m
error=-1/(2*m)*np.dot((np.dot(x,theta)-y).T,(np.dot(x,theta)-y)) # 均方误差
if abs (error)<=threshold: # 误差小于设定的阈值,跳出循环,停止迭代
break
gradient=x[j]*(np.dot(x[j],theta)-y[j])
mt=b1*mt+(1-b1)*gradient # update biasied first momant estimate
vt=b2*vt+(1-b2)*(gradient**2) # update biasied second momant estimate
mtt=mt/(1-(b1**(i+1))) # bias-corrected first moment estimate
vtt=vt/(1-(b2**(i+1))) # bias-corrected second moment estimate
vtt_sqrt=np.array([math.sqrt(vtt[0]),math.sqrt(vtt[1])]) # 因为只能对标量进行开放
theta=theta-alpha*mtt/(vtt_sqrt+e) # theta 的更新方式
print('迭代次数:%d' %(i+1),'theta:',theta,'error:%f' % error)
if __name__=='__main__':
adam()