Bra*_*wan 4 python deep-learning pytorch
通常, ann.Module可以被子类继承,如下所示。
def init_weights(m):
if type(m) == nn.Linear:
torch.nn.init.xavier_uniform(m.weight) #
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression, self).__init__()
self.fc1 = nn.Linear(20, 1)
self.apply(init_weights)
def forward(self, x):
x = self.fc1(x)
return x
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是,为什么我可以简单地运行下面的代码,即使我__init__没有任何 positinoal 参数,training_signals并且它看起来像training_signals传递给forward()方法。它是如何工作的?
model = LinearRegression()
training_signals = torch.rand(1000,20)
model(training_signals)
Run Code Online (Sandbox Code Playgroud)
第二个问题是self.apply(init_weights)内部如何运作?它是在调用forward方法之前执行吗?
Q1:为什么即使我
__init__没有任何位置参数,我也可以简单地运行下面的代码,training_signals并且看起来它training_signals已传递给forward()方法。它是如何工作的?
首先,__init__当您运行此行时会调用 :
model = LinearRegression()
Run Code Online (Sandbox Code Playgroud)
如您所见,您没有传递任何参数,而且您不应该传递任何参数。您的签名__init__与基类的签名相同(您在运行时调用super(LinearRegression, self).__init__())。正如您在此处看到的,nn.Module的 init 签名很简单def __init__(self)(就像您的一样)。
第二,model现在是一个对象。当您运行以下行时:
model(training_signals)
Run Code Online (Sandbox Code Playgroud)
您实际上是在调用该__call__方法并training_signals作为位置参数传递。正如您在此处看到的,除许多其他事项外,该__call__方法调用该forward方法:
result = self.forward(*input, **kwargs)
Run Code Online (Sandbox Code Playgroud)
将 的所有参数(位置和命名)传递__call__给forward.
Q2:
self.apply(init_weights)内部如何运作?它是在调用 forward 方法之前执行的吗?
PyTorch 是开源的,因此您只需转到源代码并检查它。正如您在此处看到的,实现非常简单:
def apply(self, fn):
for module in self.children():
module.apply(fn)
fn(self)
return self
Run Code Online (Sandbox Code Playgroud)
引用函数的文档:它“递归地应用于fn每个子模块(由 返回.children())以及self”。基于实现,您还可以了解需求:
fn 必须是可调用的;fn仅接收一个Module对象作为输入;