问题
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?
回答1:
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 customer reload. __call()__ calls call() as well as some inner operations, so when we reload call() inheriting from tf.keras.Model or tf.keras.Layer, we can call our customer 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 customer code in call() but if you overwrite __call__(), it would be a problem since some inner operations are not called.
来源:https://stackoverflow.com/questions/57103604/why-keras-use-call-instead-of-call