自定义图层在 plot_model 上缺少输入

Custom layer misses input on plot_model

我正在学习本教程 https://www.tensorflow.org/guide/keras/train_and_evaluate#handling_losses_and_metrics_that_dont_fit_the_standard_signature

关注的代码是这样的:(复制自教程)

class LogisticEndpoint(keras.layers.Layer):
    def __init__(self, name=None):
        super(LogisticEndpoint, self).__init__(name=name)
        self.loss_fn = keras.losses.BinaryCrossentropy(from_logits=True)
        self.accuracy_fn = keras.metrics.BinaryAccuracy()

    def call(self, targets, logits, sample_weights=None):
        # Compute the training-time loss value and add it
        # to the layer using `self.add_loss()`.
        loss = self.loss_fn(targets, logits, sample_weights)
        self.add_loss(loss)

        # Log accuracy as a metric and add it
        # to the layer using `self.add_metric()`.
        acc = self.accuracy_fn(targets, logits, sample_weights)
        self.add_metric(acc, name="accuracy")

        # Return the inference-time prediction tensor (for `.predict()`).
        return tf.nn.softmax(logits)


import numpy as np

inputs = keras.Input(shape=(3,), name="inputs")
targets = keras.Input(shape=(10,), name="targets")
logits = keras.layers.Dense(10)(inputs)

predictions = LogisticEndpoint(name="predictions")(logits, targets)

model = keras.Model(inputs=[inputs, targets], outputs=predictions)
model.compile(optimizer="adam")  # No loss argument!

我需要绘制模型,所以我调用了

tf.keras.utils.plot_model(model, 'm.png', show_shapes=True)

显然,从教程代码中可以看出,LogisticEndpoint 需要两个输入,即 dense 和 targets 的 return 值。但是在情节中,缺少从 target:InputLayerpredictions:LogisticEndpoint 的 link。

我将如何修改教程代码以使情节正确?

自定义层的输入应该是 list/tuple 两个输入张量,而不是两个单独的输入。查看 docs 了解更多信息。你可以尝试这样的事情:

import tensorflow as tf

class LogisticEndpoint(tf.keras.layers.Layer):
    def __init__(self, name=None):
        super(LogisticEndpoint, self).__init__(name=name)
        self.loss_fn = tf.keras.losses.BinaryCrossentropy(from_logits=True)
        self.accuracy_fn = tf.keras.metrics.BinaryAccuracy()

    def call(self, inputs, sample_weights=None):
        # Compute the training-time loss value and add it
        # to the layer using `self.add_loss()`.
        logits, targets = inputs
        loss = self.loss_fn(targets, logits, sample_weights)
        self.add_loss(loss)

        # Log accuracy as a metric and add it
        # to the layer using `self.add_metric()`.
        acc = self.accuracy_fn(targets, logits, sample_weights)
        self.add_metric(acc, name="accuracy")

        # Return the inference-time prediction tensor (for `.predict()`).
        return tf.nn.softmax(logits)


inputs = tf.keras.Input(shape=(3,), name="inputs")
targets = tf.keras.Input(shape=(10,), name="targets")
logits =tf. keras.layers.Dense(10)(inputs)

predictions = LogisticEndpoint(name="predictions")([logits, targets])

model = tf.keras.Model(inputs=[inputs, targets], outputs=predictions)
model.compile(optimizer="adam")  # No loss argument!

tf.keras.utils.plot_model(model, 'm.png', show_shapes=True)