所有人!
我的需求是产生光流的问题。我有两个原始图像和一个光流数据作为地面实况,现在我的算法是使用原始图像生成光流,并且可以将生成光流与地面实况之间的欧氏距离定义为损耗值,因此可以实现反向传播以更新参数。
我将其视为回归问题,现在我必须提出想法:
我可以将每个参数设置为(required_grad = true),然后计算损失,然后可以loss.backward()来获取梯度,但是我不知道如何在优化器中添加这些参数来更新它们。
我将算法写为模型。如果设计“自定义”模型,则可以初始化def init()中的几层,例如nn.Con2d(),nn.Linear(),并且可以使用(torch.optim.Adam(model.parameters ())),但是如果我自己定义新层,那么在更新参数集合时应如何添加该层的参数呢?
这个问题使我困惑了好几天。有什么好的方法可以更新用户定义的参数?如果您能给我一些建议,我将不胜感激!
答案 0 :(得分:1)
如果张量值的梯度被计算出来
requires_grad == True
.backward()
的某些价值(通常是损失)。然后,梯度将累积在其.grad
参数中。您可以手动使用它们以执行任意计算(包括优化)。预定义的optimizers接受iterable of parameters,而model.parameters()
就是这样做的-它返回一个可迭代的参数。如果您有一些自定义的“自由浮动”参数,则可以将其传递为
my_params = [my_param_1, my_param_2]
optim = torch.optim.Adam(my_params)
,您还可以将它们与其他可迭代参数合并,如下所示:
model_params = list(model.parameters())
my_params = [my_param_1, my_param_2]
optim = torch.optim.Adam(model_params + my_params)
但是,在实践中,通常可以构造代码来避免这种情况。有nn.Parameter
类包装张量。 nn.Module
的所有子类都将覆盖其__setattr__
,因此,每当您将nn.Parameter
的实例分配为其属性时,它都将成为Module
的{{1}的一部分}。换句话说
.parameters()
将允许您写
class MyModule(nn.Module):
def __init__(self):
super(MyModule, self).__init__()
self.my_param_1 = nn.Parameter(torch.tensor(...))
self.my_param_2 = nn.Parameter(torch.tensor(...))
,并进行module = MyModule()
optim = torch.optim.Adam(module.parameters())
更新optim
和module.my_param_1
。这是首选的方式,因为它有助于使代码保持结构化
module.zero_grad()
并将其所有子module.my_param_2
上的渐变归零。module.cuda()
或module.double()
之类的方法,这些方法同样适用于所有子nn.Parameter
,而无需手动遍历它们。