1

每个人 !

我的需求是产生光流的问题。我有两个原始图像和一个光流数据作为ground truth,现在我的算法是使用原始图像生成光流,生成光流和ground truth之间的欧几里德距离可以定义为损失值,所以它可以实现一个反向传播以更新参数。

我把它当作一个回归问题,我现在必须思考:

我可以将每个参数设置为 (required_grad = true),并计算损失,然后我可以 loss.backward() 来获取梯度,但我不知道如何在优化器中添加这些参数来更新这些参数。

我把我的算法写成一个模型。如果我设计一个“自定义”模型,我可以在 def init() 中初始化多个层,例如 nn.Con2d()、nn.Linear(),并且可以在 (torch.optim.Adam(model.parameters) 等方法中更新参数())),但是如果我自己定义新的层,我应该如何在更新参数集合时添加这个层的参数???

这个问题困扰了我好几天。有没有什么好的方法来更新用户定义的参数?如果您能给我一些建议,我将不胜感激!

4

1 回答 1

1

如果张量值有梯度,则计算它们

  1. requires_grad == True
  2. 用于计算您调用的某个值(通常是损失).backward()

然后梯度将在它们的.grad参数中累积。您可以手动使用它们来执行任意计算(包括优化)。预定义的优化器接受一个可迭代的参数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.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_1module.my_param_2。这是首选方式,因为它有助于使您的代码更有条理

  1. 创建优化器时,您不必手动包含所有参数
  2. 您可以调用module.zero_grad()所有子nn.Parameters 上的梯度并将其归零。
  3. 您可以调用诸如module.cuda()or之类的方法,这些方法module.double()同样适用于所有子nn.Parameter项,而无需手动遍历它们。
于 2018-12-28T13:14:49.137 回答