当前位置:   article > 正文

线性回归之Nesterov梯度下降(nesterov)_梯度下降nestrov动量

梯度下降nestrov动量

对于梯度下降,只能说:没有最可怕,只有更可怕。
当动量梯度下降出来之后不久,就有大神再次提出nesterov梯度下降的方法,也是继承了动量梯度的思修,但是它认为,即使当前的梯度为0,由于动量的存在,更新梯度依然会存在并继续更新w。

而继续当前点w的梯度是不太有意义的,有意义的是,假设下一个点w(仅靠动量滚到下一个点的w)的梯度方向才是决定当前梯度的重要因素。

举个通俗的例子就是,你在下坡时,如果在下坡快到底,但又未到底时,动量梯度下降会让你冲到坡的对面去Nesterov梯度下降会预知你的下一步将会时到坡的对面去,所以会提示你提前刹车,避免过度冲到坡的对面去。这包含了一种提前计算下一步的梯度,来指导当前梯度的想法。

而这个怎么实现呢?先看公式:
o l d w = w oldw=w oldw=w
w = w − η ∗ l g ∗ d i s c o u n t w=w-\eta*lg*discount w=wηlgdiscount
计算下一个 w w w的梯度
w = o l d w w=oldw w=oldw
l g = l g ∗ d i s c o u n t + g lg=lg*discount+g lg=lgdiscount+g
w = w − η ∗ l g w=w-\eta*lg w=wηlg

就是每次计算梯的时候用下一次的权重,这样下一次的变化就会反应在这次计算的梯度上,如果下一次权重计算的梯度很大,则说明更新权重的时候更应该把下一次的梯度给加上去。

'''
普通的全梯度下降方法
'''
import numpy as np
import math 
import time

print(__doc__)

sample = 10
num_input = 5

#加入训练数据
np.random.seed(0)
normalRand = np.random.normal(0,0.1,sample)      # 10个均值为0方差为0.1 的随机数  (b)
weight = [5,100,-5,-400,0.02]                    # 1 * 5 权重
x_train = np.random.random((sample, num_input))  # x 数据(10 * 5)
y_train = np.zeros((sample,1))                   # y数据(10 * 1)

for i in range (0,len(x_train)):
    total = 0
    for j in range(0,len(x_train[i])):
        total += weight[j]*x_train[i,j]
    y_train[i] = total+ normalRand[i]

# 训练
np.random.seed(0)
weight = np.random.random(num_input+1)
np.random.seed(0)
recordGrade  = np.random.random(num_input+1)

discount = 0.9
rate = 0.02

start = time.clock()
for epoch in range(0,500):
    #预先走一步,计算下一个的权重w
    oldweight = np.copy(weight)
    for i in range(0,len(weight)):
        weight[i] = weight[i] - rate * discount *  recordGrade[i]

    # 计算loss
    predictY = np.zeros((len(x_train))) 
    for i in range(0,len(x_train)):
        predictY[i] = np.dot(x_train[i],weight[0:num_input])+ weight[num_input]

    loss = 0


    for i in range(0,len(x_train)):
        loss += (predictY[i]-y_train[i])**2     
    print("epoch: %d-loss: %f"%(epoch,loss))  #打印迭代次数和损失函数

    if loss < 0.1:
        end = time.clock()
        print("收敛时间:%s ms"%str(end-start))
        print("收敛成功%d-epoch"%epoch)
        break

    # 计算梯度并更新
    weight = oldweight

    for i in range(0,len(weight)-1):   #权重w
        grade = 0
        for j in range(0,len(x_train)):
            grade += 2*(predictY[j]-y_train[j])*x_train[j,i]
        #计算梯度用下一个权重,计算权重用原来的
        recordGrade[i] = recordGrade[i]*discount + grade
        weight[i] = weight[i] - rate*recordGrade[i]

    grade = 0
    for j in range(0,len(x_train)):    #偏差b

        grade += 2*(predictY[j]-y_train[j])
    recordGrade[num_input]   = recordGrade[num_input]*discount + grade
    weight[num_input] = weight[num_input] - rate*recordGrade[num_input]

print(weight)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/687859
推荐阅读
相关标签
  

闽ICP备14008679号