l1
和l2
,分别由两个独立的ADAM优化器opt1
和opt2
优化。x
。x
和opt1
更新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()
。
答案 0 :(得分:0)
在@UmangGupta注释之后,我通过初始化x
的三个副本来做到这一点:两个分别用于x1
和x2
,另一个用于备份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))
如果可能的话,我仍然希望有一种更简洁的方式(不确定是否经常复制值会使我的代码变慢)。