Python OOP 问题:class 中的函数如何获取输入值,而 __init__() 函数中未将其作为参数提及?
Python OOP issue: How a function in a class is getting input value, when it is not mentioned in __init__() function as a parameter?
我是面向对象编程的新手,目前正在从事生成对抗网络项目。我遇到了 maxout 激活函数。该函数是通过maxoutclass定义的。请看下面的代码:
class maxout(torch.nn.Module):
def __init__(self, num_pieces):
super(maxout, self).__init__()
self.num_pieces = num_pieces
def forward(self, x):
assert x.shape[1] % self.num_pieces == 0 # 625 % 5 = 0
ret = x.view(*x.shape[:1], # batch_size
x.shape[1] // self.num_pieces,
self.num_pieces, # num_pieces
*x.shape[2:] )
ret, _ = ret.max(dim=2)
return ret
此 maxout 函数后来用于鉴别器 class。以下是鉴别器 class.
的代码
class discriminator(torch.nn.Module):
def __init__(self):
super(discriminator, self).__init__()
self.fcn = torch.nn.Sequential(
# Fully connected layer 1
torch.nn.Linear(
in_features = 784,
out_features=240,
bias = True
),
maxout(5),
# Fully connected layer 2
torch.nn.Linear(
in_features = 48,
out_features=1,
bias = True
) )
def forward(self, batch):
inputs = batch.view(batch.size(0), -1)
outputs = self.fcn(inputs)
outputs = outputs.mean(0)
return outputs.view(1) # it will return a single value
代码运行良好,但根据我对面向对象编程的天真理解,maxout class 中 forward() 函数中 'x' 的值应通过 提供初始化() 函数。
我的问题是:maxout class 的 forward() 函数如何接收输入 'x',而不通过 init() 获取输入功能。
这个问题的另一种表达方式是:How output of Linear layer in discriminator class is passed to maxout function as 'x'?
方法与常规函数的不同之处仅在于它们的第一个参数是定义方法的 class 的对象,并且可以使用点运算符提供第一个参数。
只有程序员决定通过 __init__
传递哪些值以将它们分配给对象属性,以及在第一个 self
参数之后将哪些值作为参数传递。没有要求首先通过 __init__
方法传递我们给其他方法的所有值。
回答你的问题:
torch.nn.Sequential
保存你传递的函数列表,在本例中它的长度为 3,并输出一些可调用对象(一个可以像函数一样工作的对象)。您将其保存到 self.fcn
。然后,当您调用 self.fcn
时,它会调用第一个 torch.nn.Linear
的 forward
方法,然后将它的 return 值传递给 [=] 的 forward
方法19=] 对象 - 那就是给出 x
的地方! - 然后将 maxout(5)
对象的输出传递给第二个 torch.nn.Linear
的 forward
方法,并 return 得到结果。
您将层传递给 Sequential
模型的构造函数,该模型分配给 self.fcn
,而不是您在 discriminator.forward
中调用此模型。它是 __call__
方法,而不是调用它包含的层的所有前向函数。
你可以想象这样的事情正在发生
...
def forward(self, batch):
return torch.nn.Linear(
in_features = 48,
out_features=1,
bias = True
).forward(
maxout(5).forward(
torch.nn.Linear(
in_features = 784,
out_features=240,
bias = True
).forward(batch.view(batch.size(0), -1)
)
).mean(0).view(1)
我是面向对象编程的新手,目前正在从事生成对抗网络项目。我遇到了 maxout 激活函数。该函数是通过maxoutclass定义的。请看下面的代码:
class maxout(torch.nn.Module):
def __init__(self, num_pieces):
super(maxout, self).__init__()
self.num_pieces = num_pieces
def forward(self, x):
assert x.shape[1] % self.num_pieces == 0 # 625 % 5 = 0
ret = x.view(*x.shape[:1], # batch_size
x.shape[1] // self.num_pieces,
self.num_pieces, # num_pieces
*x.shape[2:] )
ret, _ = ret.max(dim=2)
return ret
此 maxout 函数后来用于鉴别器 class。以下是鉴别器 class.
的代码class discriminator(torch.nn.Module):
def __init__(self):
super(discriminator, self).__init__()
self.fcn = torch.nn.Sequential(
# Fully connected layer 1
torch.nn.Linear(
in_features = 784,
out_features=240,
bias = True
),
maxout(5),
# Fully connected layer 2
torch.nn.Linear(
in_features = 48,
out_features=1,
bias = True
) )
def forward(self, batch):
inputs = batch.view(batch.size(0), -1)
outputs = self.fcn(inputs)
outputs = outputs.mean(0)
return outputs.view(1) # it will return a single value
代码运行良好,但根据我对面向对象编程的天真理解,maxout class 中 forward() 函数中 'x' 的值应通过 提供初始化() 函数。
我的问题是:maxout class 的 forward() 函数如何接收输入 'x',而不通过 init() 获取输入功能。
这个问题的另一种表达方式是:How output of Linear layer in discriminator class is passed to maxout function as 'x'?
方法与常规函数的不同之处仅在于它们的第一个参数是定义方法的 class 的对象,并且可以使用点运算符提供第一个参数。
只有程序员决定通过 __init__
传递哪些值以将它们分配给对象属性,以及在第一个 self
参数之后将哪些值作为参数传递。没有要求首先通过 __init__
方法传递我们给其他方法的所有值。
回答你的问题:
torch.nn.Sequential
保存你传递的函数列表,在本例中它的长度为 3,并输出一些可调用对象(一个可以像函数一样工作的对象)。您将其保存到 self.fcn
。然后,当您调用 self.fcn
时,它会调用第一个 torch.nn.Linear
的 forward
方法,然后将它的 return 值传递给 [=] 的 forward
方法19=] 对象 - 那就是给出 x
的地方! - 然后将 maxout(5)
对象的输出传递给第二个 torch.nn.Linear
的 forward
方法,并 return 得到结果。
您将层传递给 Sequential
模型的构造函数,该模型分配给 self.fcn
,而不是您在 discriminator.forward
中调用此模型。它是 __call__
方法,而不是调用它包含的层的所有前向函数。
你可以想象这样的事情正在发生
...
def forward(self, batch):
return torch.nn.Linear(
in_features = 48,
out_features=1,
bias = True
).forward(
maxout(5).forward(
torch.nn.Linear(
in_features = 784,
out_features=240,
bias = True
).forward(batch.view(batch.size(0), -1)
)
).mean(0).view(1)