Momentum(動量)方法的python實現


Momentum方法可以說是對SGD的進一步優化,細節可以參考這里

這里用python對其進行簡單實現,如下:

# coding=utf-8
"""
基於小批量梯度下降來實現的Momentum(動量)
參考:https://blog.csdn.net/bvl10101111/article/details/72615621
作用:
    在學習率較小的時候,適當的momentum能夠起到一個加速收斂速度的作用;
    在學習率較大的時候,適當的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]

    for i in range(len(sample_data)):
        dif = (np.dot(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])

同樣的收斂條件,速度確實比MBGD要快,用的次數更少

結果:

loop count = 432     w:[8.285241, 3.150939]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM