ValueError: повторяющееся имя узла в графе: «write_summary» при использовании пользовательского обратного вызова с керасом и тензорной доской - PullRequest
3 голосов
/ 20 января 2020

Я получаю Duplicate node name in graph при создании пользовательского обратного вызова. Вот полный код.

import os
import datetime
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers


class MyCallback(tf.keras.callbacks.Callback):

    def __init__(self):
        log_dir = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
        self._logdir = os.path.join('logs', log_dir)

    def on_train_begin(self, logs=None):
        self.summary_writer = tf.summary.create_file_writer(self._logdir)

    def on_epoch_end(self, epoch, logs=None):
        t = tf.reduce_sum(self.model._targets[0])
        with self.summary_writer.as_default():
            tf.summary.scalar("test", t, step=epoch)

    def on_train_end(self, logs=None):
        self.summary_writer.close()


def get_model():
    model = tf.keras.Sequential([
    # Adds a densely-connected layer with 64 units to the model:
    layers.Dense(64, activation='relu', input_shape=(32,)),
    # Add another:
    layers.Dense(64, activation='relu'),
    # Add a softmax layer with 10 output units:
    layers.Dense(10, activation='softmax')])

    model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
        loss='categorical_crossentropy',
        metrics=['accuracy'])

    return model

if __name__ == '__main__':

    model = get_model()
    data = np.random.random((1000, 32))
    labels = np.random.random((1000, 10))

    model.fit(data, labels, epochs=10, batch_size=32, callbacks=[MyCallback()])

Я получаю ошибку:

$ python3 test.py 
2020-01-20 20:09:00.694065: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-01-20 20:09:00.718085: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2592000000 Hz
2020-01-20 20:09:00.718952: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x4bead60 executing computations on platform Host. Devices:
2020-01-20 20:09:00.718974: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): Host, Default Version
Train on 1000 samples
Epoch 1/10
1000/1000 [==============================] - 1s 569us/sample - loss: 45.9223 - accuracy: 0.0980
Epoch 2/10
  32/1000 [..............................] - ETA: 0s - loss: 85.0311 - accuracy: 0.0938Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/framework/ops.py", line 1610, in _create_c_op
    c_op = c_api.TF_FinishOperation(op_desc)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Duplicate node name in graph: 'write_summary'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 48, in <module>
    model.fit(data, labels, epochs=10, batch_size=32, callbacks=[MyCallback()])
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/training.py", line 728, in fit
    use_multiprocessing=use_multiprocessing)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/training_v2.py", line 372, in fit
    prefix='val_')
  File "/usr/lib/python3.6/contextlib.py", line 88, in __exit__
    next(self.gen)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/training_v2.py", line 685, in on_epoch
    self.callbacks.on_epoch_end(epoch, epoch_logs)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/callbacks.py", line 298, in on_epoch_end
    callback.on_epoch_end(epoch, logs)
  File "test.py", line 21, in on_epoch_end
    tf.summary.scalar("test", t, step=epoch)
  File "/usr/local/lib/python3.6/dist-packages/tensorboard/plugins/scalar/summary_v2.py", line 65, in scalar
    metadata=summary_metadata)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/summary_ops_v2.py", line 646, in write
    _should_record_summaries_v2(), record, _nothing, name="summary_cond")
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/framework/smart_cond.py", line 54, in smart_cond
    return true_fn()
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/summary_ops_v2.py", line 640, in record
    name=scope)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/ops/gen_summary_ops.py", line 868, in write_summary
    summary_metadata=summary_metadata, name=name)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/framework/op_def_library.py", line 793, in _apply_op_helper
    op_def=op_def)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/framework/func_graph.py", line 548, in create_op
    compute_device)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/framework/ops.py", line 3429, in _create_op_internal
    op_def=op_def)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/framework/ops.py", line 1773, in __init__
    control_input_ops)
  File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/framework/ops.py", line 1613, in _create_c_op
    raise ValueError(str(e))
ValueError: Duplicate node name in graph: 'write_summary'

Это python3.6 с tensorflow-2.0.0

, отредактированным после комментария из TensorflowSupport Следующее выполнение работает.

class MyCallback(tf.keras.callbacks.TensorBoard):

    def __init__(self):
        log_dir = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
        logdir = os.path.join('logs', log_dir)
        super(MyCallback, self).__init__(logdir)


    def on_epoch_end(self, epoch, logs=None):
        super(MyCallback, self).on_epoch_end(epoch, logs)
        with self._get_writer("train").as_default():
            t = tf.reduce_sum(self.model._targets[0])
            tf.summary.scalar("test", 90, step=epoch)

Следующее также работает

class MyCallback(tf.keras.callbacks.TensorBoard):

    def __init__(self):
        log_dir = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
        logdir = os.path.join('logs', log_dir)
        super(MyCallback, self).__init__(logdir)


    def on_epoch_end(self, epoch, logs=None):
        super(MyCallback, self).on_epoch_end(epoch, logs)
        with self._get_writer("train").as_default():
            tf.summary.scalar("test", 90, step=epoch)

Но это не работает и вызывает ту же ошибку.

class MyCallback(tf.keras.callbacks.TensorBoard):

    def __init__(self):
        log_dir = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
        logdir = os.path.join('logs', log_dir)
        super(MyCallback, self).__init__(logdir)


    def on_epoch_end(self, epoch, logs=None):
        super(MyCallback, self).on_epoch_end(epoch, logs)
        with self._get_writer("train").as_default():
            t = tf.reduce_sum(self.model._targets[0])
            tf.summary.scalar("test", t, step=epoch)

1 Ответ

1 голос
/ 23 января 2020

Я понимаю, что если вы передадите Tensor на tf.summary.scalar, это приведет к ошибке, но если вы передадите Scalar к этому, он выполняется без каких-либо ошибок.

Итак, мы можем преобразовать Тензор в Скаляр и затем передать этот Скаляр в tf.summary.scalar, что приводит к успешному выполнению.

Код, указанный ниже, должен работать:

class MyCallback(tf.keras.callbacks.TensorBoard):

    def __init__(self):
        log_dir = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
        logdir = os.path.join('logs', log_dir)
        super(MyCallback, self).__init__(logdir)


    def on_epoch_end(self, epoch, logs=None):
        super(MyCallback, self).on_epoch_end(epoch, logs)
        with self._get_writer("train").as_default():
            t = tf.reduce_sum(self.model._targets[0])
            t_scalar = t.numpy() #This line will convert Tensor to a Scalar
            tf.summary.scalar("test", t_scalar, step=epoch)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...