在pytorch中优化输入而不是网络



我正在尝试优化一些所需任务的输入,我不想在网络冻结时更新它。我写了一个最小的例子,但它不起作用,因为z在所有迭代中都有相同的值。我确信我在这个过程中犯了一些愚蠢的错误。我们非常感谢任何指导。谢谢

import torch
z = torch.rand((1,6))
z.requires_grad_(True)
optimizer = torch.optim.SGD([z], lr= 0.1)
criteria = torch.nn.MSELoss()

for i in range(5):
optimizer.zero_grad()
print(z)
loss = criteria(z, z+torch.rand(1))
#print(loss)
loss.backward()
optimizer.step()
##output
tensor([[0.1105, 0.8152, 0.2820, 0.1122, 0.6645, 0.7211]], requires_grad=True)
tensor([[0.1105, 0.8152, 0.2820, 0.1122, 0.6645, 0.7211]], requires_grad=True)
tensor([[0.1105, 0.8152, 0.2820, 0.1122, 0.6645, 0.7211]], requires_grad=True)
tensor([[0.1105, 0.8152, 0.2820, 0.1122, 0.6645, 0.7211]], requires_grad=True)
tensor([[0.1105, 0.8152, 0.2820, 0.1122, 0.6645, 0.7211]], requires_grad=True)

梯度始终为0。这可以看出如下:

import torch
z = torch.rand((1,6))
z.requires_grad_(True)
z.retain_grad()
optimizer = torch.optim.SGD([z], lr= 0.1)
criteria = torch.nn.MSELoss()

for i in range(5):
optimizer.zero_grad()
# print(z)
loss = criteria(z, z+torch.rand(1))
# print(loss)
loss.backward()
print(z.grad)
optimizer.step()
tensor([[0., 0., 0., 0., 0., 0.]])
tensor([[0., 0., 0., 0., 0., 0.]])
...

我没有数学证明,但它可能来自目标z+torch.rand(1)的定义,它通过简单的加法直接取决于输入z

除了你的标准毫无意义之外,一切似乎都很好。再多的优化也不能减少zz+rand()之间的差异,因为这些值之间的差异是rand(),它完全独立于z。我不确定你想通过这个例子达到或模仿什么。

尝试类似loss = criteria(z, torch.zeros_like(z))的方法,您会看到z在很少的迭代中收敛到0。

是的,问题是我在这个问题中的目标值。但实际上,我在图中的一个块是由于torch.no_grad包装器而中断了梯度的计算,以下是关于未来用户任务的详细信息,因为它是这样的。

import torch
z = torch.rand((1,6))
z.requires_grad_(True)
optimizer = torch.optim.SGD([z], lr= 0.1, momentum=0.9, weight_decay=1e-4)
criteria = torch.nn.MSELoss()
l = torch.nn.Linear(6, 6)#.cuda()
p = torch.nn.Linear(6, 6)#.cuda()
#optimizer = torch.optim.SGD(parameters, lr=0.5)

for i in range(5):
optimizer.zero_grad()
print(z)

fun = l(z)

out = p(fun)
loss1 = criteria(z,fun)
print(loss1)

loss2 = criteria(out,fun)
#print(loss)
loss = loss1 + loss2
loss.backward()
optimizer.step()
print(z.grad)

最新更新