13

Pytorch 初学者在这里!考虑以下自定义模块:

class Testme(nn.Module):
    def __init__(self):
        super(Testme, self).__init__()

def forward(self, x):
    return x / t_.max(x).expand_as(x)

据我了解文档:我相信这也可以作为自定义实现Function。的子类Function需要backward()方法,但 Module不需要。同样,在 Linear 的文档示例中Module,它取决于 Linear Function

class Linear(nn.Module):
    def __init__(self, input_features, output_features, bias=True):
        ...    
    def forward(self, input):
        return Linear()(input, self.weight, self.bias)

问题:我不明白 和 之间的Module关系Function。在上面的第一个清单(模块Testme)中,它应该有关联的功能吗?如果不是,那么可以通过子类化 Module 来实现这一点而无需backward方法,那么为什么Function总是需要backward方法呢?

也许Functions 仅适用于不是由现有的火炬功能组成的功能?Function换一种说法:如果模块的forward方法完全由先前定义的 Torch 函数组成,也许模块不需要关联?

4

1 回答 1

16

这些信息是从官方 PyTorch 文档中收集和总结的。

torch.autograd.Function真正位于 PyTorch 中 autograd 包的核心。您在 PyTorch 中构建的任何图表以及您在 PyTorch 中执行的任何操作Variables都基于Function. 任何函数都需要一个 __init__(), forward()andbackward()方法(在此处查看更多信息:http: //pytorch.org/docs/notes/extending.html)。这使 PyTorch 能够计算结果并计算Variables.

nn.Module()相反,它实际上只是为组织模型、不同层等提供便利。例如,它将模型中的所有可训练参数组织在其中,.parameters()并允许您轻松地将另一层添加到模型中等等。它不是您定义后向方法的地方,因为在该forward()方法中,您应该使用Function()您已经定义的 的子类backward()。因此,如果您在 中指定了操作顺序forward(),PyTorch 已经知道如何反向传播梯度。

现在,什么时候应该使用什么?

如果您的操作只是 PyTorch 中现有已实现函数的组合(就像上面的内容),那么您自己向 Function() 添加任何子类确实没有意义。因为您可以将操作堆叠起来并构建动态图。然而,将这些操作捆绑在一起是一个明智的想法。如果任何操作涉及可训练的参数(例如神经网络的线性层),您应该nn.Module()在 forward 方法中将您的操作子类化和捆绑在一起。这使您可以轻松访问参数(如上所述)以使用torch.optim等。如果您没有任何可训练的参数,我可能仍会将它们捆绑在一起,但是一个标准的 Python 函数,您可以在其中处理您使用的每个操作就足够了。

如果你有一个新的自定义操作(例如一个带有一些复杂采样过程的新随机层),当你使用这个操作时,你应该继承Function()并定义__init__(), forward()backward()告诉 PyTorch 如何计算结果以及如何计算梯度。之后,如果您的操作具有可训练的参数,您应该创建一个函数版本来处理实例化函数并使用您的操作或创建一个模块。同样,您可以在上面的链接中阅读更多相关信息。

于 2017-06-10T16:09:40.840 回答