gpt4 book ai didi

python - 此类的 __call__ 方法在没有适当参数的情况下被调用时如何工作?

转载 作者:行者123 更新时间:2023-11-28 22:33:03 25 4
gpt4 key购买 nike

我正在浏览 Daniel Nouri 的 tutorial关于使用 CNN 的面部识别,我遇到了一些我不理解的代码。 Daniel 正在定义一个在网络训练期间每次迭代结束时调用的类,它将决定训练是否应该提前停止:

class EarlyStopping(object):
def __init__(self, patience=100):
self.patience = patience
self.best_valid = np.inf
self.best_valid_epoch = 0
self.best_weights = None

def __call__(self, nn, train_history):
current_valid = train_history[-1]['valid_loss']
current_epoch = train_history[-1]['epoch']
if current_valid < self.best_valid:
self.best_valid = current_valid
self.best_valid_epoch = current_epoch
self.best_weights = nn.get_all_params_values()
elif self.best_valid_epoch + self.patience < current_epoch:
print("Early stopping.")
print("Best valid loss was {:.6f} at epoch {}.".format(
self.best_valid, self.best_valid_epoch))
nn.load_params_from(self.best_weights)
raise StopIteration()

这是有道理的,但是代码中的实际实现看起来像这样:

net8 = NeuralNet(
# ...
on_epoch_finished=[
AdjustVariable('update_learning_rate', start=0.03, stop=0.0001),
AdjustVariable('update_momentum', start=0.9, stop=0.999),
EarlyStopping(patience=200),
],
# ...
)

显然,Daniel 将类作为函数调用。但是,如果没有 __call__(args) 中显示的参数,我不明白他是如何调用它的。 nolearn 的源代码就是这样实现的吗?我很困惑网络如何知道使用 nntrain_history 而没有将它们传递给函数。

最佳答案

他没有使用 EarlyStopping(patience=200) 调用 __call__,而是调用* EarlyStopping.__init__ 签名为:

def __init__(self, patience=100):

并为patience提供替代值;这完全匹配可用于 __init__ 的参数。

EarlyStopping.__call__ 实例被调用;也就是说,如果调用顺序是:

e = EarlyStopping(patience = 200)
e(patience=50) # TypeError Raised

将引发适当的错误。


*让您失望的括号实际上是在打电话。不是调用 EarlyStopping.__call__ 而是调用 type.__call__EarlyStopping 的(元)类。 type.__call__ 是 Python 在初始化对象时执行的第一个操作,它被调用接受传递的任何参数,然后(在其他一些操作之后)调用 __new____init__ 按此顺序;本质上,__init__ 是通过参数 patience=100 间接调用的。

关于python - 此类的 __call__ 方法在没有适当参数的情况下被调用时如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40327404/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com