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()
方法,但是。{1}}
Module
没有。同样,在线性Module
的doc示例中,它取决于线性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
方法?
也许Function
仅适用于不是由现有火炬功能组成的功能?换句话说:如果他们的Function
方法完全由先前定义的火炬函数组成,那么模块可能不需要关联的forward
?
答案 0 :(得分:12)
此信息是从官方PyTorch Documentaion收集和总结的。
torch.autograd.Function
真正位于PyTorch中autograd包的核心。您在PyTorch中构建的任何图形以及您在PyTorch中Variables
上执行的任何操作都基于Function
。任何功能都需要__init__(), forward()
和backward()
方法(请参阅此处:http://pytorch.org/docs/notes/extending.html)。这使PyTorch能够计算Variables
的结果和计算梯度。
nn.Module()
实际上只是方便您组织模型,不同的图层等。例如,它会在.parameters()
中组织模型中的所有可训练参数,并允许您添加另一个很容易将图层分层到模型等等。不是您定义后向方法的地方,因为在forward()
方法中,您应该使用{的子类{1}},您已为其定义了Function()
。因此,如果您在backward()
中指定了操作顺序,PyTorch已经知道如何反向传播渐变。
现在,什么时候应该使用什么?
如果你的操作只是PyTorch中现有实现函数的一个组合(就像你上面的那样),那么自己添加任何子类到Function()都没有意义。因为您可以堆叠操作并构建动态图形。然而,将这些操作结合在一起是一个明智的想法。如果任何操作涉及可训练的参数(例如神经网络的线性层),则应该将forward()
子类化并在forward方法中将操作组合在一起。这使您可以轻松访问参数(如上所述)以使用nn.Module()
等。如果您没有任何可训练的参数,我可能仍会将它们组合在一起,但是标准的Python函数,其中你照顾你使用的每个操作的瞬间就足够了。
如果你有一个新的自定义操作(例如一个带有一些复杂采样程序的新随机层),你应该继承torch.optim
并定义Function()
和__init__(), forward()
告诉PyTorch如何计算结果以及如何使用此操作计算渐变。之后,如果您的操作具有可训练的参数,您应该创建一个功能版本来处理即时功能并使用您的操作或创建一个模块。同样,您可以在上面的链接中阅读更多相关信息。