在pytorch中使用两个不同的优化器进行替代优化

时间:2019-07-26 16:11:13

标签: optimization pytorch gradient-descent

  • 我有两个损失函数l1l2,分别由两个独立的ADAM优化器opt1opt2优化。
  • 我的参数的当前值为x
  • 我想分别使用xopt1更新opt2,然后根据梯度的大小“合并” x的结果新值。 / li>

伪代码

grad1 = get_grad(l1)
grad2 = get_grad(l2)
n1 = norm(grad1)
n2 = norm(grad2)
x1 = opt1(grad1)
x2 = opt2(grad2)
w = n1 / (n1 + n2)
x = w*x1 + (1-w)*x2

我该如何在pytorch中进行操作?我不确定如何使用backward()step()

1 个答案:

答案 0 :(得分:0)

在@UmangGupta注释之后,我通过初始化x的三个副本来做到这一点:两个分别用于x1x2,另一个用于备份x。然后我做如下

def copy(target, source):
    for x, y in zip(target.parameters(), source.parameters()):
        x.data.copy_(y.data)

def merge(target, source1, source2, tau):
    for x, y1, y2 in zip(target.parameters(), source1.parameters(), source2.parameters()):
        x.data.copy_(tau * y1.data + (1.0 - tau) * y2.data)

def grad_norm(x)
    n = 0.
    for p in x.parameters():
        p_norm = p.grad.data.norm(2)
        n += p_norm.item() ** 2
    return n ** (1. / 2)

...

copy(x_backup, x)

opt1.zero_grad()
l1.backward()
n1 = grad_norm(x)
opt1.step()
copy(x1, x)
copy(x, x_backup)

# same for opt2, x2, n2

merge(x, x1, x2, n1 / (n1 + n2))

如果可能的话,我仍然希望有一种更简洁的方式(不确定是否经常复制值会使我的代码变慢)。