为什么keras使用“ call”而不是__call __?

时间:2019-07-18 22:59:39

标签: tensorflow keras

我喜欢(https://www.tensorflow.org/tutorials/eager/custom_layers)中的以下代码

class MyDenseLayer(tf.keras.layers.Layer):
  def __init__(self, num_outputs):
    super(MyDenseLayer, self).__init__()
    self.num_outputs = num_outputs

  def build(self, input_shape):
    self.kernel = self.add_variable("kernel",
                                shape=[int(input_shape[-1]),
                                       self.num_outputs])

  def call(self, input):
    return tf.matmul(input, self.kernel)

最后两行是call方法,但它不像通常的python类方法 call 那样带有两个下划线。两者之间有什么区别吗?

1 个答案:

答案 0 :(得分:1)

以下答案基于https://tf.wiki/zh/basic/models.html

基本上在Python中,当您使用ClassA从类ClassA()调用实例时,它等效于ClassA.__call__()。因此在这种情况下使用__call__()代替call()似乎是合理的,对吧?

但是,我们使用call()的原因是,当tf.keras调用模型或层时,它具有自己的内部操作,这些操作对于保持其内部结构必不可少。结果,它公开了方法call()用于客户重新加载。 __call()__会调用call()以及一些内部操作,因此当我们重新加载从call()tf.keras.Model继承的tf.keras.Layer时,我们可以在保持{的同时调用我们的客户代码{1}}的内部结构。

例如,根据我的经验,如果您的输入是一个numpy数组而不是张量,那么如果您在tf.keras中编写客户代码,而您却覆盖了{{1},则无需手动转换它},这是一个问题,因为未调用某些内部操作。