tensorflow2.2 使用 keras.utils.plot_model 绘制可视化模型时,报错:“AttributeError: 'dict' object has no attribute 'name'”

我的环境是 ubuntu16.04,cuda10.2,python3.7,tensorflow2.2,阅读 keras 官网这一节时,发现如下奇怪的代码:

import tensorflow as tf
import numpy as np
from tensorflow import keras

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)

    @classmethod
    def from_config(cls, config):
        return cls(**config)

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

model = keras.Model(inputs=[inputs, targets], outputs=predictions)
model.compile(optimizer="adam")

data = {
    "inputs": np.random.random((3, 3)),
    "targets": np.random.random((3, 10)),
}
model.fit(data)

我觉得这样的模型的 inputs 似乎有些多余,就想绘制出可视化图确认下,于是加了下面这行代码:

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

提示错误:

“ImportError: Failed to import pydot. You must install pydot and graphviz for pydotprint to work.”

于是使用 pip 命令安装这两个库:

$ pip install pydot 
$ pip install graphviz 

结果还是报错,尝试使用 apt 命令安装:

$ apt install python-pydot python-pydot-ng graphviz

不再报这个错误了。但是另一个错误出现了:

File ".../vis_utils.py", line 143, in model_to_dot
    layer_name = layer.name
AttributeError: 'dict' object has no attribute 'name'

查询了下,在 GitHub 上找到了关于这个问题的讨论,似乎有 bug,这个我不关心,我关心的是如何解决问题:出现这种错误应该是某些层没有 name 属性,但是绘制函数认为它有,我们把这些层过滤掉就可以了:

model._layers = [layer for layer in model.layers if not isinstance(layer, dict)]
model.summary()
keras.utils.plot_model(model, 'strange.png', show_shapes=True)

到这里就成功了,可以看出 inputs 果然和我估计的一致。 奇怪的模型

看看哪些层没有 name 属性,在上述代码之前添加下面这些代码:

for layer in model.layers:
    if not isinstance(layer, dict):
        print(layer)

得到如下输出:

<tensorflow.python.keras.engine.input_layer.InputLayer object at 0x7fbfe8411ef0>
<tensorflow.python.keras.layers.core.Dense object at 0x7fbf6f671390>
<tensorflow.python.keras.engine.input_layer.InputLayer object at 0x7fbf6f671208>
<__main__.LogisticEndpoint object at 0x7fbf6f671d68>

和估计的差不多。

阅读更多:   tensorflow , Python , 深度学习
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif