Reputation: 469
I tried to take cfiar data set and to try to get the feature map of every output giving as an input one of the test images.
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
# Normalize pixel values to be between 0 and 1
train_images, test_images = train_images / 255.0, test_images / 255.0
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck']
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels))
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
layer_input = test_images[0]
for i in range(len(model.layers)):
get_layer_output = K.function(inputs = model.layers[i].input, outputs = model.layers[i].output)
print(get_layer_output(layer_input))
layer_input = model.layers[i].output
My feeling is that i misunderstand something regarding how to set the input and also how to take the output during the prediction.
Upvotes: 2
Views: 948
Reputation: 111
You can use following python script to draw feature maps of the neural network.
import tensorflow as tf
import cv2
import numpy as np
# use 'model' as your model name
# change 224 image size to your model input image size
layer_names = [layer.name for layer in model.layers]
layer_outputs = [layer.output for layer in model.layers[1:]]
feature_map_model = tf.keras.models.Model(inputs=model.input, outputs=layer_outputs)
img = cv2.imread("path/to/image/image.jpg")
img = cv2.resize(img, (224,224))
img = np.array([img])/255.0
feature_maps = feature_map_model.predict(img, verbose=0)
for layer_name, feature_map in zip(layer_names, feature_maps):
if len(feature_map.shape) == 4:
k = feature_map.shape[-1]
size=feature_map.shape[1]
image_belt = np.zeros((size, size * k))
for i in range(k):
feature_image = feature_map[0, :, :, i]
feature_image-= feature_image.mean()
feature_image/= feature_image.std ()
feature_image*= 64
feature_image+= 128
feature_image= np.clip(feature_image, 0, 255).astype('uint8')
image_belt[:, i * size : (i + 1) * size] = feature_image
scale = 20. / k
plt.figure( figsize=(scale * k, scale) )
plt.title ( layer_name )
plt.grid ( False )
plt.imshow( image_belt, aspect='auto')
Upvotes: 1
Reputation: 1836
You should set the input to model.layers[0].input
if you are using Sequential
model.
First, expand the dimensionality of the Test Input to include the Batch_Size:
layer_input = test_images[0]
plt.imshow(layer_input) # Plot Test Image
layer_input = tf.expand_dims(layer_input,0) # Add prefix of Batch Size
print(layer_input.shape) # Prints : (1, 32, 32, 3)
Output:
Modified code for plotting:
for i in range(len(model.layers)):
get_layer_output = K.function(inputs = model.layers[0].input, outputs = model.layers[i].output)
get_1_output = get_layer_output(layer_input)
# print(get_1_output.shape) << Use this to check if the Output shape matches the shape of Model.summary()
if get_1_output.ndim == 4: # Check for Dimensionality to plot ONE feature map (Batch size, Length, Width
plt.imshow(get_1_output[0][:,:,:3]) # Plots the output of Conv2D and MaxPooling
else:
print(get_1_output) # If not Image, ie. Array, print the Values
plt.show()
Output:
I hope I answered your question.
Upvotes: 2