【问题标题】:How to implement momentum in mini-batch gradient descent with python?如何使用 python 在小批量梯度下降中实现动量?
【发布时间】:2017-07-28 00:49:16
【问题描述】:

我正在阅读有关 momentum 的信息,并试图在我的小批量代码中实现动量方程。

问题是它不起作用,回归线离理想线太远了,我不确定实现是否正确。

def stochastic_gradient_descent_step(m,b,data_sample):

    n_points = data_sample.shape[0] #size of data
    m_grad = 0
    b_grad = 0
    stepper = 0.0001 #this is the learning rate
    z_m = 1.0
    z_b = 1.0
    betha = 0.81

    for i in range(n_points):

        #Get current pair (x,y)
        x = data_sample[i,0]
        y = data_sample[i,1]
        if(math.isnan(x)|math.isnan(y)): #it will prevent for crashing when some data is missing
            #print("is nan")
            continue

        #you will calculate the partical derivative for each value in data
        #Partial derivative respect 'm'
        dm = -((2/n_points) * x * (y - (m*x + b)))

        #Partial derivative respect 'b'
        db = - ((2/n_points) * (y - (m*x + b)))


        #Update gradient
        m_grad = m_grad + dm
        b_grad = b_grad + db

    #calculate the momentum
    z_m = betha*z_m + m_grad
    z_b = betha*z_b + b_grad
    #Set the new 'better' updated 'm' and 'b'   
    m_updated = m - stepper*z_m
    b_updated = b - stepper*z_b

返回 m_updated,b_updated


已编辑

我现在已经编辑了我的代码,按照 Sasha 的建议,我将梯度计算放在一个函数中,将动量放在另一个函数中,我将 z_m 和 z_b 作为全局函数,这样它们就不会在每次迭代中失去其价值。

z_m =0.0 #initilise to 0
z_b =0.0 #initilise to 0
def getGradient(m,b,data_sample):
    global z_m
    global z_b
    n_points = data_sample.shape[0] #size of data
    m_grad = 0
    b_grad = 0
    stepper = 0.0001 #this is the learning rate

    betha = 0.81

    for i in range(n_points):

        #Get current pair (x,y)
        x = data_sample[i,0]
        y = data_sample[i,1]
        if(math.isnan(x)|math.isnan(y)): #it will prevent for crashing when some data is missing
            #print("is nan")
            continue

        #you will calculate the partical derivative for each value in data
        #Partial derivative respect 'm'
        dm = -((2/n_points) * x * (y - (m*x + b)))

        #Partial derivative respect 'b'
        db = - ((2/n_points) * (y - (m*x + b)))


        #Update gradient
        m_grad = m_grad + dm
        b_grad = b_grad + db


    return m_grad,b_grad

def calculateMomentum(m_grad,b_grad,betha=0.81,stepper=0.0001):
    global z_m,z_b
    #calculate the momentum
    z_m = betha*z_m + m_grad
    z_b = betha*z_b + b_grad
    #Set the new 'better' updated 'm' and 'b'   
    m_updated = m - stepper*z_m
    b_updated = b - stepper*z_b
    return m_updated,b_updated 

现在回归线计算正确(也许)。 SGD 的最终误差为 59706304,动量的最终误差为 56729062,但可能是在计算梯度时选择的随机小批量。

【问题讨论】:

  • Not working 是这里的经典无用描述!
  • 对不起,我会更新它
  • 你可以在我的github文件github.com/matvi/GradientDescent/blob/master/SGD.ipynb看到其余的代码
  • 动量使用在这里毫无意义!动量是权重更新之间的某种形式的状态。您的仅用于一次更新,然后随着功能完成而丢失(您的代码需要重构)。除此之外,这些计算看起来也是错误的(想象一下梯度为 0.00001;你总是在上面加上 0.81;显然这不好)。
  • 我知道动力是用来做什么的。但你似乎不明白其中的逻辑。这是在小批量之间持续存在的状态。所以那些不能是你的小批量函数中的局部变量。我认为您应该明白并可以重构您的代码。您可能希望完全避免执行该功能中的步骤;使其成为纯粹的: calc-gradient 函数。那么动量平滑可以用在一个外部函数中。

标签: python machine-learning gradient-descent


【解决方案1】:

首先初始化无效,z_m 和 z_b 应该初始化为 0(因为这是你对梯度的第一次猜测)。其次,在当前的函数形式中,您永远不会为下一次迭代“存储”z_m 或 z_b,因此它们会被重置(为无效值 1)

【讨论】:

  • Sasha 说“这是一种在小批量之间持续存在的状态”。
猜你喜欢
  • 2016-11-04
  • 2020-12-20
  • 2017-03-15
  • 2019-08-28
  • 1970-01-01
  • 1970-01-01
  • 2020-04-28
  • 2018-07-15
  • 2018-09-09
相关资源
最近更新 更多