Q1:为什么我可以简单地运行下面的代码,甚至我的__init__
没有任何位置参数training_signals
看起来像那样training_signals
被传递给forward()
方法。它是如何工作的?
首先,__init__
当您运行此行时调用:
model = LinearRegression()
正如您所看到的,您没有传递任何参数,也不应该传递任何参数。您的签名__init__
与基类之一相同(运行时调用super(LinearRegression, self).__init__()
)。如你看到的here https://github.com/pytorch/pytorch/blob/be757957bace28100e571ec7914765020be4a069/torch/nn/modules/module.py#L69, nn.Module
的 init 签名很简单def __init__(self)
(就像你的一样)。
Second, model
现在是一个对象。当您运行以下行时:
model(training_signals)
你实际上是在调用__call__
方法和传递training_signals
作为位置参数。如你看到的here https://github.com/pytorch/pytorch/blob/be757957bace28100e571ec7914765020be4a069/torch/nn/modules/module.py#L522-L550,除其他事项外,__call__
方法调用forward
method:
result = self.forward(*input, **kwargs)
传递所有参数(位置和命名)__call__
to the forward
.
Q2:怎么办?self.apply(init_weights)
内部工作?是在调用forward方法之前执行的吗?
PyTorch 是开源的,因此您只需转到源代码并检查它即可。如你看到的here https://github.com/pytorch/pytorch/blob/be757957bace28100e571ec7914765020be4a069/torch/nn/modules/module.py#L248-L288,实现非常简单:
def apply(self, fn):
for module in self.children():
module.apply(fn)
fn(self)
return self
引用该函数的文档:it“applies fn
递归到每个子模块(由.children()
) 也self
》。基于实现,你还可以了解到需求:
-
fn
必须是可调用的;
-
fn
仅接收一个输入作为Module
object;