how to get data from within Keras model for visualisation?

懵懂的女人 提交于 2019-12-24 07:34:07

问题


I am using Tensorflow 1.12 which has Keras integrated together with Python 3.6.x

I wish to use Keras for its simplicity of model building, but also would like to use data on the intermediate layer for visualization of feature maps and kernels to better understand how machine learning works(even though this is admittedly not so evident)

I am using the mnist data base and a very basic Keras model to try to do what I want to do.

Here is the code

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

The above sets up the dataset and the model Next I define my session for Tensorflow and do the training.

This all works fine but now I want to get my data for the, as example, the first layer out as ideally a numpy array on which I can do the visualization.

My model.layers[0].output gives me a Tensor of (?,25,25,32) as expected and now I try to do a eval() and thenafter a .numpy() method to get my result.

The error message is

You must feed a value for placeholder tensor 'conv2d_6_input' with dtype float and shape [?,28,28,1]

I am looking for help on how to get my data (32 feature maps of 25x25 pixels) out as numpy array for visualization.

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()

回答1:


First of all, you must note that getting the output of a model or a layer only makes sense when you feed the input layers with some data. You get the model something (i.e. input data), you get something in return (i.e. output or feature map or activation map). That's why it would produce the following error:

You must feed a value for placeholder tensor 'conv2d_6_input'

You haven't fed the baby, so it would cry :)

Now, the idea of building a new Keras model is counterproductive. When you have a large model in the first place, one would like to plug in some kind of ready-made code that can get the output of the feature maps and visualize them. So this route seems not really interesting.

I think you are mistakenly thinking that when you construct a new model out of the layers of another model, a whole new model is cloned. That's not the case since the parameters of the layers would be shared.

Concretely, what you are looking for can be achieved like this:

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)`

All the parameters of viz_conv are shared with model and they have not been copied either. Under the hood they are using the same weight Tensors.

Alternatively, you could define a backend function to do this:

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])

This has been covered in Keras documentation and I highly recommend to read that as well.



来源:https://stackoverflow.com/questions/53419127/how-to-get-data-from-within-keras-model-for-visualisation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!