Python 如何从Keras模型中获取数据进行可视化?

Python 如何从Keras模型中获取数据进行可视化?,python,tensorflow,keras,conv-neural-network,Python,Tensorflow,Keras,Conv Neural Network,我使用的是Tensorflow 1.12,它将Keras与Python3.6.x集成在一起 我希望使用Keras来简化模型构建,但也希望使用中间层上的数据来可视化特征图和内核,以便更好地理解机器学习的工作原理(尽管这一点不太明显) 我正在使用mnist数据库和一个非常基本的Keras模型来尝试做我想做的事情 这是密码 import tensorflow as tf from tensorflow.keras import layers from tensorflow import keras

我使用的是Tensorflow 1.12,它将Keras与Python3.6.x集成在一起

我希望使用Keras来简化模型构建,但也希望使用中间层上的数据来可视化特征图和内核,以便更好地理解机器学习的工作原理(尽管这一点不太明显)

我正在使用mnist数据库和一个非常基本的Keras模型来尝试做我想做的事情

这是密码

import tensorflow as tf
from tensorflow.keras import layers
from tensorflow import keras

print(tf.VERSION)
print(tf.keras.__version__)

tf.keras.backend.clear_session()

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train_shaped = np.expand_dims(x_train, axis=3) / 255.0
x_test_shaped = np.expand_dims(x_test, axis=3) / 255.0

def create_model():

  model = tf.keras.models.Sequential([
    keras.layers.Conv2D(32, kernel_size=(4, 4),strides=(1,1),activation='relu', input_shape=(28,28,1)),
    keras.layers.Dropout(0.5),
    keras.layers.MaxPooling2D(pool_size=(2,2), strides=(2,2)),
    keras.layers.Conv2D(24, kernel_size=(8, 8),strides=(1,1)),
    keras.layers.Flatten(),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
  ])

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

  return model
上面设置了数据集和模型 接下来,我定义Tensorflow的会话并进行培训

这一切都很好,但现在我想得到我的数据,例如,第一层作为理想的numpy阵列,我可以在其上进行可视化

我的
模型.layers[0]。输出
按预期为我提供
(?,25,25,32)
张量
,现在我尝试执行
eval()
,然后执行
.numpy()
方法以获得结果

错误消息是

You must feed a value for placeholder tensor 'conv2d_6_input' with dtype float and shape [?,28,28,1]
我正在寻找有关如何将我的数据(32个25x25像素的特征贴图)作为numpy阵列进行可视化的帮助

sess = tf.Session(graph=tf.get_default_graph())
tf.keras.backend.set_session(sess)

with sess.as_default():
   model = create_model()
   model.summary()

   model.fit(x_train_shaped[:10000], y_train[:10000], epochs=2, 
   batch_size=64, validation_split=.2,)

   model.layers[0].output
   print(model.layers[0].output.shape)
   my_array = model.layers[0].output
   my_array.eval()

tf.keras.backend.clear_session()
sess.close()

首先,您必须注意,只有在向输入层提供一些数据时,获取模型或层的输出才有意义。你得到了模型的一些东西(即输入数据),你得到了一些回报(即输出或特征映射或激活映射)。这就是为什么它会产生以下错误:

您必须为占位符张量“conv2d\u 6”输入一个值

你还没有喂过孩子,所以它会哭:)

现在,建立新的Keras模型的想法适得其反。当您首先拥有一个大型模型时,您可能希望插入某种现成的代码,以获得要素地图的输出并将其可视化。所以这条路线似乎不是很有趣

我认为您错误地认为,当您从另一个模型的层构建一个新模型时,一个全新的模型被克隆。事实并非如此,因为层的参数将共享

具体而言,您所寻找的目标可以通过以下方式实现:

viz_conv = Model(model.input, model.layers[0].output)
conv_active = viz_conv(my_input_data)  # my_input_data is a numpy array of shape `(num_samples,28,28,1)`
viz_conv
的所有参数都与
model
共享,并且它们也没有被复制。在引擎盖下,他们使用相同的重量张量

或者,您可以定义一个后端函数来执行此操作:

from tensorflow.keras import backend as K

viz_func = K.function([model.input], [any layer(s) you would like in the model])
output = viz_func([my_input_data])

这一点已在中介绍过,我强烈建议您也阅读。

感谢您的及时回复。现在,建立新的Keras模型的想法适得其反。当您首先拥有一个大型模型时,您会希望插入某种现成的代码,以获得特征图的输出并将其可视化。因此,这条路线似乎不是很有趣。还要注意的是,在上面的代码中,我使用变量my_array从代码中获得了一个大小正确的张量,因此我并不真正希望以另一种形式获得输出。我的问题是把这个张量带到天体世界。我试过使用.eval()函数和.numpy()函数。顺便说一句,使用纯Tensorflow,我在做我想做的事情时有点问题,但是TF是基本的,Keras在编译时添加了一些东西,我不知道。您好,您的帮助让我按预期运行它,非常感谢。我不知道有thubs up或类似的stackoverflow系统,但请告诉我我能做什么。你肯定是在竖起大拇指@彼得,听到这个我很高兴!您可以参考堆栈溢出指南-请参阅