【问题标题】:TensorFlow: Difference between functioning of __call__() and call() when designing custom layers?TensorFlow:设计自定义层时 __call__() 和 call() 的功能之间的区别?
【发布时间】:2020-11-15 03:22:01
【问题描述】:

我在 TensorFlow 中设计了一个带有自定义层的神经网络。首先,我使用__call__() 定义前向传递,然后我调用了model.summary()。这给了我以下错误

ValueError: This model has not yet been built. Build the model first by calling `build()` or calling `fit()` with some data, or specify an `input_shape` argument in the first layer(s) for automatic build.  

但是,当我用call() 替换它时,它工作得很好。

问:我想了解幕后情况。

编辑: 我还没有创建build() 并在__init__() 中声明了所有内容

【问题讨论】:

    标签: python tensorflow machine-learning deep-learning neural-network


    【解决方案1】:

    您遇到的ValueError 是合理的。这个问题已经在here 上被询问并得到了回答而且call__call__ 之间的区别也已经在here 上得到了回答;(因为你没有给出任何代码来重现所以我指的是这个关联)。不过,仅供参考,我已经写了一篇关于模型子类化和从头开始自定义训练的文章,希望建模方法部分能给你一些见解(文章link)。

    更新

    评论区的问题太多了,所以我想在这里添加我的回复。基本上,__call__ 方法是在Layer 类中实现的。而这一层类被Model类继承。比方说

    import inspect
    from tensorflow.keras.models import Model
    
    # inspect.getmro(CLASS) returns a tuple of class CLASS's base classes, 
    # including CLASS, in Method Resolution Order (MRO).
    inspect.getmro(Model)
    
    # out
    (tensorflow.python.keras.engine.training.Model,
    tensorflow.python.keras.engine.base_layer.Layer,...)
    

    现在,在Layer 类的__call__ 方法中,已将self.call 方法分配给call_fn。进一步使用here。如:

    def __call__(self, input):
        call_fn = self.call
        outputs = call_fn(input, ...)
        return outputs
    

    所以当我们调用我们的Model类实例时,它继承的__call__方法(来自Layer类)会自动执行,它调用我们自己的call方法。

    模型摘要

    使用 Subclassing API 的建模与 Sequential 或 Functional API 不同。它不是图形网络,因此只有包含模型名称的节点会与这些模型一起绘制。我们不能真正假设任何关于子类模型的结构。这就是我们无法获得输出形状的原因。但是,有一种解决方法可以方便地获取模型形状摘要的工具并绘制它。检查here

    【讨论】:

    • 我的代码中没有任何build() 方法,因此无法调用model.build()。另外,我已经阅读了您分享的两个链接。
    • 如果我使用call(),那么我的代码可以正常工作。所以那里没有问题。我想要回答这个问题的是,call 方法在tf.keras.layers.Layer 中调用了哪些功能,而__call__ 没有引起这个错误。无论如何,很高兴有人回应。
    • 我浏览了您关于 TDS 的文章。我喜欢build_graph 的使用方式。那很聪明。否则我们不会得到输出形状。我想知道,为什么会发生这种情况?
    • 另外,你试过tf.keras.utils.plot_model。让我知道你得到了什么:)
    猜你喜欢
    • 1970-01-01
    • 2012-11-07
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多