问题
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