如何绘制 Keras/Tensorflow 子类化 API 模型? [英] How do I plot a Keras/Tensorflow subclassing API model?
问题描述
我使用 Keras Subclassing API 创建了一个可以正确运行的模型.model.summary()
也能正常工作.当尝试使用 tf.keras.utils.plot_model()
来可视化我的模型的架构时,它只会输出这个图像:
I made a model that runs correctly using the Keras Subclassing API. The model.summary()
also works correctly. When trying to use tf.keras.utils.plot_model()
to visualize my model's architecture, it will just output this image:
这几乎感觉像是 Keras 开发团队的一个笑话.这是完整的架构:
This almost feels like a joke from the Keras development team. This is the full architecture:
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
from sklearn.datasets import load_diabetes
import tensorflow as tf
tf.keras.backend.set_floatx('float64')
from tensorflow.keras.layers import Dense, GaussianDropout, GRU, Concatenate, Reshape
from tensorflow.keras.models import Model
X, y = load_diabetes(return_X_y=True)
data = tf.data.Dataset.from_tensor_slices((X, y)).
shuffle(len(X)).
map(lambda x, y: (tf.divide(x, tf.reduce_max(x)), y))
training = data.take(400).batch(8)
testing = data.skip(400).map(lambda x, y: (tf.expand_dims(x, 0), y))
class NeuralNetwork(Model):
def __init__(self):
super(NeuralNetwork, self).__init__()
self.dense1 = Dense(16, input_shape=(10,), activation='relu', name='Dense1')
self.dense2 = Dense(32, activation='relu', name='Dense2')
self.resha1 = Reshape((1, 32))
self.gru1 = GRU(16, activation='tanh', recurrent_dropout=1e-1)
self.dense3 = Dense(64, activation='relu', name='Dense3')
self.gauss1 = GaussianDropout(5e-1)
self.conca1 = Concatenate()
self.dense4 = Dense(128, activation='relu', name='Dense4')
self.dense5 = Dense(1, name='Dense5')
def call(self, x, *args, **kwargs):
x = self.dense1(x)
x = self.dense2(x)
a = self.resha1(x)
a = self.gru1(a)
b = self.dense3(x)
b = self.gauss1(b)
x = self.conca1([a, b])
x = self.dense4(x)
x = self.dense5(x)
return x
skynet = NeuralNetwork()
skynet.build(input_shape=(None, 10))
skynet.summary()
model = tf.keras.utils.plot_model(model=skynet,
show_shapes=True, to_file='/home/nicolas/Desktop/model.png')
推荐答案
我找到了一些解决方法来使用模型子分类 API 进行绘图.很明显,Sub-Classing API 不支持 Sequential or Functional API,如 model.summary()
和使用 的漂亮可视化绘图模型
.在这里,我将展示两者.
I've found some workaround to plot with the model sub-classing API. For the obvious reason Sub-Classing API doesn't support Sequential or Functional API like model.summary()
and nice visualization using plot_model
. Here, I will demonstrate both.
class my_model(Model):
def __init__(self, dim):
super(my_model, self).__init__()
self.Base = VGG16(input_shape=(dim), include_top = False, weights = 'imagenet')
self.GAP = L.GlobalAveragePooling2D()
self.BAT = L.BatchNormalization()
self.DROP = L.Dropout(rate=0.1)
self.DENS = L.Dense(256, activation='relu', name = 'dense_A')
self.OUT = L.Dense(1, activation='sigmoid')
def call(self, inputs):
x = self.Base(inputs)
g = self.GAP(x)
b = self.BAT(g)
d = self.DROP(b)
d = self.DENS(d)
return self.OUT(d)
# AFAIK: The most convenient method to print model.summary()
# similar to the sequential or functional API like.
def build_graph(self):
x = Input(shape=(dim))
return Model(inputs=[x], outputs=self.call(x))
dim = (124,124,3)
model = my_model((dim))
model.build((None, *dim))
model.build_graph().summary()
它将产生如下:
Layer (type) Output Shape Param #
=================================================================
input_67 (InputLayer) [(None, 124, 124, 3)] 0
_________________________________________________________________
vgg16 (Functional) (None, 3, 3, 512) 14714688
_________________________________________________________________
global_average_pooling2d_32 (None, 512) 0
_________________________________________________________________
batch_normalization_7 (Batch (None, 512) 2048
_________________________________________________________________
dropout_5 (Dropout) (None, 512) 0
_________________________________________________________________
dense_A (Dense) (None, 256) 402192
_________________________________________________________________
dense_7 (Dense) (None, 1) 785
=================================================================
Total params: 14,848,321
Trainable params: 14,847,297
Non-trainable params: 1,024
现在通过使用 build_graph
函数,我们可以简单地绘制整个架构.
Now by using the build_graph
function, we can simply plot the whole architecture.
# Just showing all possible argument for newcomer.
tf.keras.utils.plot_model(
model.build_graph(), # here is the trick (for now)
to_file='model.png', dpi=96, # saving
show_shapes=True, show_layer_names=True, # show shapes and layer name
expand_nested=False # will show nested block
)
它将产生如下:-)
这篇关于如何绘制 Keras/Tensorflow 子类化 API 模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!