1. 程式人生 > >Nesterov方法的python實現

Nesterov方法的python實現

梯度 數據 結果 print details bre 構造 odi article

牛頓動量法,相比於上一篇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實現