我想实现我在执行SGD与气势气势。从我的理解这个更新是这样的:
parameters -= (lr * (p.grad*0.1 + p_delta_prev*0.9))
我的问题是我应该怎么我以前的增量存储从每一次更新
以下是我在我的更新功能:
#we now want to do the update with momentum
#momentum takes derivative, multiplies it by 0.1, then takes the previous update,
#multiplies it by 0.9 and we add the two together
#alpha = 0.1, beta = 0.9; p-=grad*0.1 + p*0.9
def update(x,y,lr):
wd = 1e-5
y_hat = model(x)
# weight decay
w2 = 0.
for p in model.parameters(): w2 += (p**2).sum()
# add to regular loss
loss = loss_func(y_hat, y) + w2*wd
loss.backward()
with torch.no_grad():
for p in model.parameters():
#p.grad is the slope of the line of that parameter
#current_p-previous_p to get difference
p_update = (lr * (p.grad*0.1 + p*0.9))
p.sub_(p_update)
p.grad.zero_()
return loss.item()
在这里,p*0.9
应当由p_delta_prev更换。但是我应该如何存储这些增量为每一个参数?如果我将它们保存到张量不会我会得到有效复制的重量增量来记忆使我的模型大小的两倍。什么是做到这一点的好办法?我不希望使用内置的函数,它是激活了我。我也考虑了pytorch sgd.py,它看起来像商店的状态。
我已经更新的代码:
#we now want to do the update with momentum
#momentum takes derivative, multiplys it by 0.1, then takes the previous update,
#multiplies it by 0.9 and we add the two together
#alpha = 0.1, beta = 0.9; p-=grad*0.1 + p*0.9
p_delta = {}
def update(x,y,lr):
wd = 1e-5
y_hat = model(x)
# weight decay
w2 = 0.
for p in model.parameters(): w2 += (p**2).sum()
# add to regular loss
loss = loss_func(y_hat, y) + w2*wd
loss.backward()
with torch.no_grad():
i = 0
for p in model.parameters():
#p.grad is the slope of the line of that parameter
if i not in p_delta:#check if key exists
p_delta[i] = torch.zeros_like(p)
p_update = (lr *p.grad) + (p_delta[i]*0.9)
p_delta[i] = p_update.clone()
p.sub_(p_update)
p.grad.zero_()
print((p_delta[i]))
i+=1
return loss.item()
我想在Excel电子表格中的代码不正确。杰里米似乎表明:lr* ((p.grad*0.1) + (p_delta[i]*0.9))
但很多教程似乎表明:(lr *p.grad) + (p_delta[i]*0.9)
如果我们实现了Jeremy的代码的损失其实比香草GD慢。视频的部分是在这里:https://youtu.be/CJKnDu2dxOE?t=6581
是的,它存储在字典中的参数动量,他们的名字索引,通过model.named_parameters()
返回。我不知道如何严格证明这一点,但我坚信这是不可能申请势头,而无需使用额外的内存的两倍模型的大小。
话虽这么说,我不会担心,因为模型的大小是很少在整个算法的内存消耗的一大因素 - 保持中间网络激活的BP算法是昂贵得多。服用VGG-16网络作为一个例子,它有1.38亿参数(从here截取的图),如果存储在单精度这相当于比0.5GB稍多。与6GB比较这+合理的现代GPU中。