【发布时间】: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