Search code examples
tensorflowkeras

Why keras use "call" instead of __call__?


I fond the following code in (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)

The last two lines is call method, while it does not like usual python class method call with two underlines. Is any differences between those?


Solution

  • The following answer is based on https://tf.wiki/zh/basic/models.html.

    Basically in Python, when you call an instance from class ClassA using ClassA(), it is equivalent to ClassA.__call__(). So it seems reasonable to use __call__() instead of call() in this case, right?

    However, the reason we use call() is that when tf.keras calls a model or a layer, it has its own inner operations which are essential to keep its inner structure. As a result, it exposes a method call() for custom overloading. __call__() calls call() as well as some inner operations, so when we overload call() inheriting from tf.keras.Model or tf.keras.Layer, we can call our custom code while keeping tf.keras's inner structure.

    For example, from my experience, if your input is a numpy array instead of a tensor, you don't need to transform it manually if you write custom code in call() but if you overwrite __call__(), it would be a problem since some inner operations are not called.