码迷,mamicode.com
首页 > 编程语言 > 详细

Nesterov方法的python实现

时间:2018-08-22 21:55:51      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:+=   现在   odi   index   ilo   初始   for   import   numpy   

牛顿动量法,相比于上一篇Momentum,不一样的地方是应用了临时更新

这里用python对其进行简单实现,如下:

# coding=utf-8
"""
基于小批量梯度下降来实现的Nesterov
参考:https://blog.csdn.net/bvl10101111/article/details/72615961
    相比于上一篇的Momentum,不一样的地方是应用了临时更新
@author: Reynold
@date: 2018-08-21
"""
import numpy as np
import random

# 构造训练数据
x = np.arange(0., 10., 0.2)
m = len(x)
x0 = np.full(m, 1.0)
input_data = np.vstack([x0, x]).T  # 将偏置b作为权向量的第一个分量
target_data = 3 * x + 8 + np.random.randn(m)

# 两种终止条件
max_iter = 10000
epsilon = 1e-5

# 初始化权值
np.random.seed(0)
w = np.random.randn(2)
v = np.zeros(2)  # 更新的速度参数

alpha = 0.001  # 步长
diff = 0.
error = np.zeros(2)
count = 0  # 循环次数

eps = 0.9  # 衰减力度,可以用来调节,该值越大那么之前的梯度对现在方向的影响也越大

while count < max_iter:
    count += 1

    sum_m = np.zeros(2)
    index = random.sample(range(m), int(np.ceil(m * 0.2)))
    sample_data = input_data[index]
    sample_target = target_data[index]

    # 应用临时更新,先更新一下参数w的值
    tmp_w = w + eps * v
    for i in range(len(sample_data)):
        dif = (np.dot(tmp_w, input_data[i]) - target_data[i]) * input_data[i]
        sum_m = sum_m + dif
    v = eps * v - alpha * sum_m  # 在这里进行速度更新
    w = w + v  # 使用动量来更新参数

    if np.linalg.norm(w - error) < epsilon:
        break
    else:
        error = w
print loop count = %d % count, \tw:[%f, %f] % (w[0], w[1])

结果,由于数据量太小,相比于Momentum提升不是很大:

loop count = 437     w:[7.930222, 3.088267]

 

Nesterov方法的python实现

标签:+=   现在   odi   index   ilo   初始   for   import   numpy   

原文地址:https://www.cnblogs.com/leixingzhi7/p/9520135.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!