tf.keras plot_model: add_node () получил объект класса, отличного от узла - PullRequest
1 голос
/ 05 мая 2020

Я возвращаюсь в python и пробую кое-что с tenorflow и keras. Я хотел использовать функцию plot_model, и после устранения некоторых проблем с графиком я теперь получаю эту ошибку -

TypeError: add_node () получил объект класса, отличного от узла:

Я сам пытался найти ответ, но у меня не получилось, так как единственный ответ, который я нашел с этой ошибкой, похоже, не связан с tf. Приветствуются любые предложения или альтернативные идеи. Вот код и сообщение об ошибке - мой первый вопрос здесь, извините, если я что-то пропустил, просто дайте мне знать.

Я использую miniconda3 с python 3.8

import tensorflow as tf
from tensorflow.keras import Model
from tensorflow.keras.layers import Conv2D, MaxPool2D, Flatten, Dense, Dropout
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import plot_model
from tensorflow.keras.callbacks import EarlyStopping

from numpy import argmax
from matplotlib import pyplot
from random import randint

tf.keras.backend.set_floatx("float64")
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

class mnist_model(Model):
    def __init__(self):
        super(mnist_model, self).__init__()
        self.conv = Conv2D(32, 3, activation = tf.nn.leaky_relu, kernel_initializer = 'he_uniform', input_shape = (28, 28, 3))
        self.pool = MaxPool2D((2,2))
        self.flat = Flatten()
        self.den1 = Dense(128, activation = tf.nn.relu, kernel_initializer = 'he_normal')
        self.drop = Dropout(0.25)
        self.den2 = Dense(10, activation = tf.nn.softmax)

    def call(self, inputs):
        n = self.conv(inputs)
        n = self.pool(n)
        n = self.flat(n)
        n = self.den1(n)
        n = self.drop(n)
        return self.den2(n)

model = mnist_model()

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

limit = EarlyStopping(monitor = 'val_loss', patience = 5)

history = model.fit(x_train, y_train, batch_size=64, epochs = 1, verbose = 2, validation_split = 0.15, steps_per_epoch = 100, callbacks = [limit])
print("\nTraining finished\n\nTesting 10000 samples")
model.evaluate(x_test, y_test, verbose = 1)
print("Testing finished\n")


plot_model(model, show_shapes = True, rankdir = 'LR')


##################################################################################################################################################################
                              ## Error message: ##

Train on 51000 samples, validate on 9000 samples

Training finished

Testing 10000 samples
10000/10000 [==============================] - 7s 682us/sample - loss: 0.2447 - accuracy: 0.9242
Testing finished

Traceback (most recent call last):

  File "C:\Users\Thomas\Desktop\Various Python\Tensorflow\Tensorflow_experimentation\tc_mnist.py", line 60, in <module>
    plot_model(model, show_shapes = True, rankdir = 'LR')

  File "C:\Users\Thomas\miniconda3\envs\tensorflow\lib\site-packages\tensorflow_core\python\keras\utils\vis_utils.py", line 283, in plot_model
    dpi=dpi)

  File "C:\Users\Thomas\miniconda3\envs\tensorflow\lib\site-packages\tensorflow_core\python\keras\utils\vis_utils.py", line 131, in model_to_dot
    dot.add_node(node)

  File "C:\Users\Thomas\miniconda3\envs\tensorflow\lib\site-packages\pydotplus\graphviz.py", line 1281, in add_node
    'class object: {}'.format(str(graph_node))

TypeError: add_node() received a non node class object: <pydotplus.graphviz.Node object at 0x00000221C7E3E888>`



1 Ответ

0 голосов
/ 05 мая 2020

Я думаю, что root - проблема связана с выводом формы модели с подклассом, где model.summary показывает multiple как Output Shape. Я добавил вызов модели в подкласс модели, как показано ниже.

def model(self):
        x = tf.keras.layers.Input(shape=(28, 28, 1))
        return Model(inputs=[x], outputs=self.call(x))

С этой модификацией выведение формы автоматически c в функциональном API. В качестве функциональной и последовательной модели в виде статических c графиков слоев мы можем легко получить вывод формы. Однако модель с подклассом - это часть кода python (метод вызова), и нет графа слоев, который можно было бы легко вывести. Мы не можем знать, как слои связаны друг с другом (потому что это определено в теле вызова, а не как явная структура данных), поэтому мы не можем вывести формы ввода / вывода.

Plot_model looks like

Пожалуйста, проверьте полный код здесь для справки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...