什么时候需要 pytorch 自定义函数(而不仅仅是一个模块)?
when is a pytorch custom function needed (rather than only a module)?
这里是 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
没有。同样,在线性 Module
的文档示例中,它取决于线性 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 来实现这个 without a backward
方法,那么为什么 Function
总是需要 backward
方法?
也许 Function
s 仅适用于不是由现有 torch 函数组成的函数?换句话说:如果模块的 forward
方法完全由先前定义的火炬函数组成,也许模块不需要关联的 Function
?
此信息是从官方 PyTorch 文档中收集和总结的。
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()
方法中,您应该使用Function()
的子类,您已经为其定义了 backward()
。因此,如果您在 forward()
中指定了操作顺序,PyTorch 已经知道如何反向传播梯度。
现在,你应该什么时候使用什么?
如果您的操作只是 PyTorch 中现有已实现函数的组合(如您上面的操作),那么您自己向 Function() 添加任何子类真的没有意义。因为您可以将操作堆叠起来并构建动态图。然而,将这些操作捆绑在一起是一个明智的想法。如果任何操作涉及可训练参数(例如神经网络的线性层),您应该将 nn.Module()
子类化并在 forward 方法中将您的操作捆绑在一起。这使您可以轻松访问参数(如上所述)以使用 torch.optim
等。如果您没有任何可训练的参数,我可能仍会将它们捆绑在一起,但是标准的 Python 函数,在那里你负责你使用的每个操作的实例化就足够了。
如果你有一个新的自定义操作(例如,一个带有一些复杂采样过程的新随机层),你应该继承 Function()
并定义 __init__(), forward()
和 backward()
来告诉 PyTorch 如何使用此操作时计算结果以及如何计算梯度。之后,您应该创建一个功能版本来处理函数的实例化并使用您的操作,或者创建一个模块(如果您的操作具有可训练的参数)。同样,您可以在上面的 link 中阅读更多相关信息。
这里是 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
没有。同样,在线性 Module
的文档示例中,它取决于线性 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 来实现这个 without a backward
方法,那么为什么 Function
总是需要 backward
方法?
也许 Function
s 仅适用于不是由现有 torch 函数组成的函数?换句话说:如果模块的 forward
方法完全由先前定义的火炬函数组成,也许模块不需要关联的 Function
?
此信息是从官方 PyTorch 文档中收集和总结的。
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()
方法中,您应该使用Function()
的子类,您已经为其定义了 backward()
。因此,如果您在 forward()
中指定了操作顺序,PyTorch 已经知道如何反向传播梯度。
现在,你应该什么时候使用什么?
如果您的操作只是 PyTorch 中现有已实现函数的组合(如您上面的操作),那么您自己向 Function() 添加任何子类真的没有意义。因为您可以将操作堆叠起来并构建动态图。然而,将这些操作捆绑在一起是一个明智的想法。如果任何操作涉及可训练参数(例如神经网络的线性层),您应该将 nn.Module()
子类化并在 forward 方法中将您的操作捆绑在一起。这使您可以轻松访问参数(如上所述)以使用 torch.optim
等。如果您没有任何可训练的参数,我可能仍会将它们捆绑在一起,但是标准的 Python 函数,在那里你负责你使用的每个操作的实例化就足够了。
如果你有一个新的自定义操作(例如,一个带有一些复杂采样过程的新随机层),你应该继承 Function()
并定义 __init__(), forward()
和 backward()
来告诉 PyTorch 如何使用此操作时计算结果以及如何计算梯度。之后,您应该创建一个功能版本来处理函数的实例化并使用您的操作,或者创建一个模块(如果您的操作具有可训练的参数)。同样,您可以在上面的 link 中阅读更多相关信息。