我喜欢(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 那样带有两个下划线。两者之间有什么区别吗?
答案 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},则无需手动转换它},这是一个问题,因为未调用某些内部操作。