Coder Social home page Coder Social logo

philipperemy / keract Goto Github PK

View Code? Open in Web Editor NEW
1.0K 34.0 187.0 4.33 MB

Layers Outputs and Gradients in Keras. Made easy.

License: MIT License

Python 100.00%
keras keras-neural-networks keras-tutorials keras-visualization deep-learning visualize-activations mnist multi-inputs machine-learning

keract's Introduction

Keract: Keras Activations + Gradients

Downloads Downloads Keract CI

Tested with Tensorflow 2.9, 2.10, 2.11, 2.12, 2.13, 2.14 and 2.15 (Nov 17, 2023).

pip install keract

You have just found a way to get the activations (outputs) and gradients for each layer of your Tensorflow/Keras model (LSTM, conv nets...).

Important Note: The nested models are not well supported. The recent versions of Tensorflow made it extremely tricky to extract the layer outputs reliably. Please refer to the example section to see what is possible.

API

Get activations (nodes/layers outputs as Numpy arrays)

keract.get_activations(model, x, layer_names=None, nodes_to_evaluate=None, output_format='simple', nested=False, auto_compile=True)

Fetch activations (nodes/layers outputs as Numpy arrays) for a Keras model and an input X. By default, all the activations for all the layers are returned.

  • model: Keras compiled model or one of ['vgg16', 'vgg19', 'inception_v3', 'inception_resnet_v2', 'mobilenet_v2', 'mobilenetv2', ...].
  • x: Numpy array to feed the model as input. In the case of multi-inputs, x should be of type List.
  • layer_names: (optional) Single name of a layer or list of layer names for which activations should be returned. It is useful in very big networks when it is computationally expensive to evaluate all the layers/nodes.
  • nodes_to_evaluate: (optional) List of Keras nodes to be evaluated.
  • output_format: Change the output dictionary key of the function.
    • simple: output key will match the names of the Keras layers. For example Dense(1, name='d1') will return {'d1': ...}.
    • full: output key will match the full name of the output layer name. In the example above, it will return {'d1/BiasAdd:0': ...}.
    • numbered: output key will be an index range, based on the order of definition of each layer within the model.
  • nested: If specified, will move recursively through the model definition to retrieve nested layers. Recursion ends at leaf layers of the model tree or at layers with their name specified in layer_names. For example a Sequential model in another Sequential model is considered nested.
  • auto_compile: If set to True, will auto-compile the model if needed.

Returns: Dict {layer_name (specified by output_format) -> activation of the layer output/node (Numpy array)}.

Example

import numpy as np
from tensorflow.keras import Input, Model
from tensorflow.keras.layers import Dense, concatenate
from keract import get_activations

# model definition
i1 = Input(shape=(10,), name='i1')
i2 = Input(shape=(10,), name='i2')

a = Dense(1, name='fc1')(i1)
b = Dense(1, name='fc2')(i2)

c = concatenate([a, b], name='concat')
d = Dense(1, name='out')(c)
model = Model(inputs=[i1, i2], outputs=[d])

# inputs to the model
x = [np.random.uniform(size=(32, 10)), np.random.uniform(size=(32, 10))]

# call to fetch the activations of the model.
activations = get_activations(model, x, auto_compile=True)

# print the activations shapes.
[print(k, '->', v.shape, '- Numpy array') for (k, v) in activations.items()]

# Print output:
# i1 -> (32, 10) - Numpy array
# i2 -> (32, 10) - Numpy array
# fc1 -> (32, 1) - Numpy array
# fc2 -> (32, 1) - Numpy array
# concat -> (32, 2) - Numpy array
# out -> (32, 1) - Numpy array

Display the activations you've obtained

keract.display_activations(activations, cmap=None, save=False, directory='.', data_format='channels_last', fig_size=(24, 24), reshape_1d_layers=False)

Plot the activations for each layer using matplotlib

Inputs are:

  • activations: dict - a dictionary mapping layers to their activations (the output of get_activations)
  • cmap: (optional) string - a valid matplotlib colormap to be used
  • save: (optional) bool - if True the images of the activations are saved rather than being shown
  • directory: (optional) string - where to store the activations (if save is True)
  • data_format: (optional) string - one of "channels_last" (default) or "channels_first".
  • reshape_1d_layers: (optional) bool - tries to reshape large 1d layers to a square/rectangle.
  • fig_size: (optional) (float, float) - width, height in inches.

The ordering of the dimensions in the inputs. "channels_last" corresponds to inputs with shape (batch, steps, channels) (default format for temporal data in Keras) while "channels_first" corresponds to inputs with shape (batch, channels, steps).

Display the activations as a heatmap overlaid on an image

keract.display_heatmaps(activations, input_image, directory='.', save=False, fix=True, merge_filters=False)

Plot heatmaps of activations for all filters overlayed on the input image for each layer

Inputs are:

  • activations: a dictionary mapping layers to their activations (the output of get_activations).
  • input_image: numpy array - the image that was passed as x to get_activations.
  • directory: (optional) string - where to store the heatmaps (if save is True).
  • save: (optional) bool - if True the heatmaps are saved rather than being shown.
  • fix: (optional) bool - if True automated checks and fixes for incorrect images will be ran.
  • merge_filters: (optional) bool - if True one heatmap (with all the filters averaged together) is produced for each layer, if False a heatmap is produced for each filter in each layer

Get gradients of weights

keract.get_gradients_of_trainable_weights(model, x, y)
  • model: a keras.models.Model object.
  • x: Numpy array to feed the model as input. In the case of multi-inputs, x should be of type List.
  • y: Labels (numpy array). Keras convention.

The output is a dictionary mapping each trainable weight to the values of its gradients (regarding x and y).

Get gradients of activations

keract.get_gradients_of_activations(model, x, y, layer_name=None, output_format='simple')
  • model: a keras.models.Model object.
  • x: Numpy array to feed the model as input. In the case of multi-inputs, x should be of type List.
  • y: Labels (numpy array). Keras convention.
  • layer_name: (optional) Name of a layer for which activations should be returned.
  • output_format: Change the output dictionary key of the function.
    • simple: output key will match the names of the Keras layers. For example Dense(1, name='d1') will return {'d1': ...}.
    • full: output key will match the full name of the output layer name. In the example above, it will return {'d1/BiasAdd:0': ...}.
    • numbered: output key will be an index range, based on the order of definition of each layer within the model.

Returns: Dict {layer_name (specified by output_format) -> grad activation of the layer output/node (Numpy array)}.

The output is a dictionary mapping each layer to the values of its gradients (regarding x and y).

Persist activations to JSON

keract.persist_to_json_file(activations, filename)
  • activations: activations (dict mapping layers)
  • filename: output filename (JSON format)

Load activations from JSON

keract.load_activations_from_json_file(filename)
  • filename: filename to read the activations from (JSON format)

It returns the activations.

Examples

Examples are provided for:

  • keras.models.Sequential - mnist.py
  • keras.models.Model - multi_inputs.py
  • Recurrent networks - recurrent.py

In the case of MNIST with LeNet, we are able to fetch the activations for a batch of size 128:

conv2d_1/Relu:0
(128, 26, 26, 32)

conv2d_2/Relu:0
(128, 24, 24, 64)

max_pooling2d_1/MaxPool:0
(128, 12, 12, 64)

dropout_1/cond/Merge:0
(128, 12, 12, 64)

flatten_1/Reshape:0
(128, 9216)

dense_1/Relu:0
(128, 128)

dropout_2/cond/Merge:0
(128, 128)

dense_2/Softmax:0
(128, 10)

We can visualise the activations. Here's another example using VGG16:

cd examples
pip install -r examples-requirements.txt
python vgg16.py


A cat.


Outputs of the first convolutional layer of VGG16.

Also, we can visualise the heatmaps of the activations:

cd examples
pip install -r examples-requirements.txt
python heat_map.py

Limitations / Ways of improvement

In some specific cases, Keract does not handle well some models that contain submodels. Feel free to fork this repo and propose a PR to fix it!

Citation

@misc{Keract,
  author = {Philippe Remy},
  title = {Keract: A library for visualizing activations and gradients},
  year = {2020},
  publisher = {GitHub},
  journal = {GitHub repository},
  howpublished = {\url{https://github.com/philipperemy/keract}},
}

Contributors

keract's People

Contributors

daniyalmaroufi avatar dependabot-preview[bot] avatar dsblank avatar gis-puppetmaster avatar philipperemy avatar qwertpi avatar stochastic13 avatar thomasdebrunner avatar zhhongzhi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keract's Issues

Clarification on the returned shape for the gradients

In regards to the output of get_gradients_of_activations vs get_gradients_of_trainable_weights:

I have a Conv2D layer with 16 (5,5) filters and padding = 'same', which accepts input of dimension (batch_size, 96, 96, 10).
Let's say I am using a batch of 2 inputs (x.shape = (2, 96, 96, 10)) vs a batch of a single input (x.shape = (1, 96, 96, 10)).
So the shapes returned by the three functions are as such:

get_activations: (2, 96, 96, 16), (1, 96, 96, 16)
get_gradients_of_activations: (2, 96, 96, 16), (1, 96, 96, 16)
get_gradients_of_trainable_weights - kernel: (5, 5, 10, 16), (5, 5, 10, 16)
get_gradients_of_trainable_weights - bias: (16,), (16,)

So, am I right in assuming that trainable_weights gradients are averaged over all the training examples, but the activation gradients are individually returned for each input sample?

Also, activation gradients are not the gradients of the activation function, are they? Because then they'd be used to backpropagate and be included in the gradients for trainable_weights?

Using keract with flow_from_directory() and datagenerators?

Is there a way to use keract with flow from directory and datagenerators?

def plot_images_from_layers(model_path):
model = load_model(model_path)
activations = get_activations(model, x, "fc1")

I have a trained model, I would like to see what "fully connected layers" and "convolutional layers" see. I don't have "x" input array, but I use generators/flow_from directory functions. Is there a way how to use keract?

visualize VGG16 activations

Can this library visualize activations for VGG16, or any of the other pretrained models in Keras?

For example, if I run the code below I get the following error:

AssertionErrorTraceback (most recent call last)
<ipython-input-5-2e2d97d61734> in <module>
----> 1 keract.display_activations(activations)

/usr/local/lib/python3.5/dist-packages/keract/keract.py in display_activations(activations)
     58     """
     59     for name, activation_map in activations.items():
---> 60         assert activation_map.shape[0] == 1, 'One image at a time to visualize.'
     61         print('Displaying activation map [{}]'.format(name))
     62         shape = activation_map.shape

AssertionError: One image at a time to visualize.
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.vgg16 import preprocess_input
from keras.applications.vgg16 import decode_predictions
from keras.applications.vgg16 import VGG16
model = VGG16()

from PIL import Image
import requests
from io import BytesIO
import numpy as np

url='https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Gatto_europeo4.jpg/250px-Gatto_europeo4.jpg'
response = requests.get(url)
image = Image.open(BytesIO(response.content))
image = image.crop((0,0,244,244))
image.save('cat.jpg')

image = load_img('cat.jpg', target_size=(224, 224))
image = img_to_array(image)
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
image = preprocess_input(image)
yhat = model.predict(image)
label = decode_predictions(yhat)
label = label[0][0]
print('{} ({})'.format(label[1], label[2]*100))

import keract
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
activations = keract.get_activations(model, image)
keract.display_activations(activations)

edit: looks like it works, but there might be an issue with the display_activations function.

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(12, 12))

rows = 8
columns = 8

first = activations.get('block1_conv1/Relu:0')

for i in range(1, columns*rows +1):
    img = first[0,:,:,i-1]
    fig.add_subplot(rows, columns, i)
    plt.imshow(img)
    plt.axis('off')
plt.show()

first

Why are all the layers skipped?

I followed one of the examples on the repoistory. Here is the keract code I am using and below you can see the error. Why are the layers being skipped? Do I need to change the number of filters to 1 for all my convolutions? How does that make sense?

import keract
activations = keract.get_activations(model, x_training)
first = activations.get('conv2d_1/Relu:0')
keract.display_activations(activations, save=True)

OUTPUT
input_1:0 (256, 256, 1) -> Skipped. First dimension is not 1.
conv2d_1/Relu:0 (89, 256, 256, 64) -> Skipped. First dimension is not 1.
conv2d_2/Relu:0 (89, 256, 256, 64) -> Skipped. First dimension is not 1.
max_pooling2d_1/MaxPool:0 (89, 128, 128, 64) -> Skipped. First dimension is not 1.
conv2d_3/Relu:0 (89, 128, 128, 128) -> Skipped. First dimension is not 1.
conv2d_4/Relu:0 (89, 128, 128, 128) -> Skipped. First dimension is not 1.
max_pooling2d_2/MaxPool:0 (89, 64, 64, 128) -> Skipped. First dimension is not 1.
conv2d_5/Relu:0 (89, 64, 64, 256) -> Skipped. First dimension is not 1.
conv2d_6/Relu:0 (89, 64, 64, 256) -> Skipped. First dimension is not 1.
max_pooling2d_3/MaxPool:0 (89, 32, 32, 256) -> Skipped. First dimension is not 1.
conv2d_7/Relu:0 (89, 32, 32, 512) -> Skipped. First dimension is not 1.
conv2d_8/Relu:0 (89, 32, 32, 512) -> Skipped. First dimension is not 1.
dropout_1/cond/Merge:0 (89, 32, 32, 512) -> Skipped. First dimension is not 1.
max_pooling2d_4/MaxPool:0 (89, 16, 16, 512) -> Skipped. First dimension is not 1.
conv2d_9/Relu:0 (89, 16, 16, 1024) -> Skipped. First dimension is not 1.
conv2d_10/Relu:0 (89, 16, 16, 1024) -> Skipped. First dimension is not 1.
dropout_2/cond/Merge:0 (89, 16, 16, 1024) -> Skipped. First dimension is not 1.
up_sampling2d_1/ResizeNearestNeighbor:0 (89, 32, 32, 1024) -> Skipped. First dimension is not 1.
conv2d_11/Relu:0 (89, 32, 32, 512) -> Skipped. First dimension is not 1.
concatenate_1/concat:0 (89, 32, 32, 1024) -> Skipped. First dimension is not 1.
conv2d_12/Relu:0 (89, 32, 32, 512) -> Skipped. First dimension is not 1.
conv2d_13/Relu:0 (89, 32, 32, 512) -> Skipped. First dimension is not 1.
up_sampling2d_2/ResizeNearestNeighbor:0 (89, 64, 64, 512) -> Skipped. First dimension is not 1.
conv2d_14/Relu:0 (89, 64, 64, 256) -> Skipped. First dimension is not 1.
concatenate_2/concat:0 (89, 64, 64, 512) -> Skipped. First dimension is not 1.
conv2d_15/Relu:0 (89, 64, 64, 256) -> Skipped. First dimension is not 1.
conv2d_16/Relu:0 (89, 64, 64, 256) -> Skipped. First dimension is not 1.
up_sampling2d_3/ResizeNearestNeighbor:0 (89, 128, 128, 256) -> Skipped. First dimension is not 1.
conv2d_17/Relu:0 (89, 128, 128, 128) -> Skipped. First dimension is not 1.
concatenate_3/concat:0 (89, 128, 128, 256) -> Skipped. First dimension is not 1.
conv2d_18/Relu:0 (89, 128, 128, 128) -> Skipped. First dimension is not 1.
conv2d_19/Relu:0 (89, 128, 128, 128) -> Skipped. First dimension is not 1.
up_sampling2d_4/ResizeNearestNeighbor:0 (89, 256, 256, 128) -> Skipped. First dimension is not 1.
conv2d_20/Relu:0 (89, 256, 256, 64) -> Skipped. First dimension is not 1.
concatenate_4/concat:0 (89, 256, 256, 128) -> Skipped. First dimension is not 1.
conv2d_21/Relu:0 (89, 256, 256, 64) -> Skipped. First dimension is not 1.
conv2d_22/Relu:0 (89, 256, 256, 64) -> Skipped. First dimension is not 1.
conv2d_23/Relu:0 (89, 256, 256, 2) -> Skipped. First dimension is not 1.
conv2d_24/Sigmoid:0 (89, 256, 256, 1) -> Skipped. First dimension is not 1.

Cannot find a way to feed a single image to InceptionV3

My InceptionV3 layer has an input of [?, 250, 150, 3]. If I call get_activations() with an x of shape (250, 150, 3), Keras will complaint that you need 4 dimensions, not 3.
Fair enough, the model needs a dynamic batch dimension (wait, wasn't supposed to use that dimension for training only?).

But if I go for a reshape like np.reshape(image, (1,250, 150, 3)) the error becomes:

InvalidArgumentError:  You must feed a value for placeholder tensor 'input_4' with dtype float and shape [?,250,150,3]
	 [[node input_4 (defined at /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3009) ]] [Op:__inference_keras_scratch_graph_83846]

Function call stack:
keras_scratch_graph

What's that about?

Learning phase 0 and 1.

Thanks a lot for sharing!
One simple issue,

Learning phase. 1 = Test mode (no dropout or batch normalization)

However, I found in Keras (2.0.2)
The learning phase flag is a bool tensor (0 = test, 1 = train)
And in practice I set the flag to 0 will get same output for same samples.

Keras Applications VGG16 has no attribute '_feed_targets'

I'm trying to use transfer learning of VGG16, but when I run get_activations got AttributeError.

Traceback (most recent call last):
  File "rpn.py", line 16, in <module>
    activations = get_activations(feature_model, img_array)
  File "/home/tiago/.pyenv/versions/3.6.7/envs/mnist/lib/python3.6/site-packages/keract/keract.py", line 38, in get_activations
    activations = _evaluate(model, layer_outputs, x, y=None)
  File "/home/tiago/.pyenv/versions/3.6.7/envs/mnist/lib/python3.6/site-packages/keract/keract.py", line 6, in _evaluate
    symb_inputs = (model._feed_inputs + model._feed_targets + model._feed_sample_weights)
AttributeError: 'Model' object has no attribute '_feed_targets'
import numpy

from keras.applications import vgg16
from keras.preprocessing.image import load_img, img_to_array

from keract import get_activations, display_activations

img = load_img('eight.png')
img_array = img_to_array(img)
img_array = numpy.expand_dims(img_array, axis=0)

# last vgg16 conv2d layer returns (None, None, None, 512)
feature_model = vgg16.VGG16(include_top=False, input_shape=(600, 800, 3))
result = feature_model.predict(img_array)

activations = get_activations(feature_model, img_array)
display_activations(activations)

Handle cycles in the network

I am getting this error:

Traceback (most recent call last): File "/Users/pedro/PycharmProjects/OOVconverter/visualize_drd.py", line 20, in <module> activations = get_activations(model, x) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/keract/keract.py", line 77, in get_activations activations = _evaluate(model, layer_outputs, x, y=None) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/keract/keract.py", line 24, in _evaluate return f(x_ + y_ + sample_weight_) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", line 2715, in __call__ return self._call(inputs) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", line 2671, in _call session) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py", line 2623, in _make_callable callable_fn = session._make_callable_from_options(callable_opts) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1471, in _make_callable_from_options return BaseSession._Callable(self, callable_options) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1425, in __init__ session._session, options_ptr, status) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 528, in __exit__ c_api.TF_GetCode(self.status.status)) tensorflow.python.framework.errors_impl.InvalidArgumentError: retro_word_2:0 is both fed and fetched. Exception ignored in: <bound method BaseSession._Callable.__del__ of <tensorflow.python.client.session.BaseSession._Callable object at 0x1c3ab2ba20>> Traceback (most recent call last): File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1455, in __del__ self._session._session, self._handle, status) File "/Users/pedro/.conda/envs/OOVconverter/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 528, in __exit__ c_api.TF_GetCode(self.status.status)) tensorflow.python.framework.errors_impl.InvalidArgumentError: No such callable handle: 140697188192368

I understand that it is related to this:
https://github.com/keras-team/keras/issues/10372

But i am not sure how to add the change!

What do the different color and axis value mean.

Hi @philipperemy,
I tried your tool, its very interesting to observe the activation-map. But I am facing one issue, i dont understand what the different colors mean. I have the below activation-map.

screenshot from 2018-05-26 17-55-25
Is there some kind of reference I can refer to for different colors, generating in future.
Also i dont understand what values on x-axis and y-axis mean.
My test data contains - [[12345, 12345, 12345, 12345, 12345]]
Predicted Output - [[12345.001 12345.021 12345. 12344.999 12345.041]]

Any help is appreciated.

Can't run predictions after using get_activations()

After calling the get_activations to print out the shapes of my activation layers, I'm unable to train my model or make any predictions.

I get the following error:

tensorflow/core/framework/op_kernel.cc:1273] OP_REQUIRES failed at resource_variable_ops.cc:449 : Not found: Resource localhost/embedding/embeddings/N10tensorflow3VarE does not exist

When trying to run predict:

tensorflow.python.framework.errors_impl.FailedPreconditionError: Error while reading resource variable batch_normalization_2/moving_mean from Container: localhost. This could mean that the variable was uninitialized. Not found: Container localhost does not exist. (Could not find resource: localhost/batch_normalization_2/moving_mean)
         [[{{node batch_normalization_2/cond/FusedBatchNorm_1/ReadVariableOp}} = ReadVariableOp[dtype=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:GPU:0"](batch_normalization_2/cond/FusedBatchNorm_1/ReadVariableOp/Switch)]]
         [[{{node lambda_4/strided_slice/_17}} = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_397_lambda_4/strided_slice", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

When I don't run get_activations(), my code runs normally.

NameError: name 'k' is not defined

Hi,

I've been getting below issue trying to visualize activation heatmaps . I can't seem to understand why, since as I understand is just the channels_last format from keras backend.

I can see that in below line of keract.py the K is capital and in data_format = k.image_data_format() is not?

import keras.backend as K

I didn't have an issue with display_activations and first meets what display_heatmaps requires as input.

Am I missing something?

first = np.array(activations.get('bAct-1/Relu:0'))
keract.display_activations(activations, save=False)
first.shape, k.image_data_format()
((1, 20, 40, 8), 'channels_last')
keract.display_heatmaps(activations, first, save=False)

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-74-ebed9f04da1c> in <module>()
----> 1 keract.display_heatmaps(activations, first, save=False)

~/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/keract/keract.py in display_heatmaps(activations, input_image, directory, save, fix)
    194     import math
    195 
--> 196     data_format = k.image_data_format()
    197     if fix:
    198         # fixes common errors made when passing the image

NameError: name 'k' is not defined

DV

Trying to apply heatmap on multi_gpu model

from keras.preprocessing.image import array_to_img
from PIL import Image
%matplotlib inline

x, y = gen_test.next()
image = x[1]
plt.imshow(image)
# the image is plotted successfully
from keract import get_activations
import numpy as np

images = np.array([image])
print(images.shape)
activations = get_activations(dmodel_parallel, images, dmodel_parallel.layers[-1].name)
# prints (1, 256, 256, 3)
from keract import display_heatmaps
display_heatmaps(activations, images)
# gives the error: activation_9_1/concat:0 (1, 2) -> Skipped. 2D Activations.

my model

def create_model():
    m = Sequential()
    
    m.add(Conv2D(32,(3, 3), activation='relu', padding = 'same', input_shape=(None,None,3)))    
    m.add(Conv2D(32, (3, 3), activation='relu'))
    m.add(MaxPooling2D(pool_size=(2, 2)))
    m.add(Dropout(0.2))
    
    m.add(Conv2D(64,(3, 3), activation='relu', padding = 'same'))  
    m.add(Conv2D(64,(3, 3), activation='relu', padding = 'same', strides = 2))    
    m.add(MaxPooling2D(pool_size=(2, 2)))
    m.add(Dropout(0.5))
    
    m.add(Conv2D(64,(3, 3), activation='relu', padding = 'same'))    
    m.add(Conv2D(64,(3, 3), activation='relu', padding = 'same'))
    m.add(Conv2D(64,(3, 3), activation='relu', padding = 'same', strides = 2))    
    m.add(MaxPooling2D(pool_size=(2, 2)))
    m.add(Dropout(0.5))    
    
    m.add(Conv2D(64,(3, 3), padding = 'same'))
    m.add(Activation('relu'))
    m.add(Conv2D(64,(1, 1),padding='valid'))
    m.add(Activation('relu'))
    m.add(Conv2D(2, (1, 1), padding='valid'))

    m.add(GlobalAveragePooling2D())
    return m

model = create_model()
model.add(Activation('softmax'))

model = multi_gpu_model(model, gpus=[0,1])
model.compile(optimizer="adam",
    loss="categorical_crossentropy", 
    metrics=["accuracy"])

Here's the shape of the activations:
array([[0.9661835 , 0.03381654]], dtype=float32)

OOM when trying to get activations for large image

I realize this is a memory issue, but I was wondering if you have any ideas as to how I can circumvent the issue. When I run predictions on large images I cut them into smaller tiles and reassemble them afterwards, but I have trouble seeing how to properly do that with the data structure delivered by keract.get_activations().

Visualizing activations in RNN while generating network output.

Hi, I might be missing something but I don`t quite see how I could record activations of layers while simultaneously using my network for predictions.

What I am trying to do is something like the pictures at the end of this blog http://karpathy.github.io/2015/05/21/rnn-effectiveness/ that are obviously generated using some sort of snapshots of activation.

Basically, when creating the desired sequence I would like to track the activations while feeding the last generated output of the network as next input. However, the get_activations function seems to discard the network output (or at least I don't see where is it explicitly generated).

Is there some way how I could add the network output to the return value? Your tool seems to be pretty straightforward so I am asking instead of trying to hack something from scratch myself :)

Thanks for help!

TypeError: Invalid shape (1, 64, 64, 3) for image data

Hi, i am new to keras applications. i try to display heatmaps but getting this error.

Traceback (most recent call last):

File "", line 3, in
display_heatmaps(activations, image, save=False)

File "C:\Users\ts1\Anaconda3\envs\tfenvnew\lib\site-packages\keract\keract.py", line 162, in display_heatmaps
axes.flat[i].imshow(input_image / 255.0)

File "C:\Users\ts1\Anaconda3\envs\tfenvnew\lib\site-packages\matplotlib_init_.py", line 1589, in inner
return func(ax, *map(sanitize_sequence, args), **kwargs)

File "C:\Users\ts1\Anaconda3\envs\tfenvnew\lib\site-packages\matplotlib\cbook\deprecation.py", line 369, in wrapper
return func(*args, **kwargs)

File "C:\Users\ts1\Anaconda3\envs\tfenvnew\lib\site-packages\matplotlib\cbook\deprecation.py", line 369, in wrapper
return func(*args, **kwargs)

File "C:\Users\ts1\Anaconda3\envs\tfenvnew\lib\site-packages\matplotlib\axes_axes.py", line 5660, in imshow
im.set_data(X)

File "C:\Users\ts1\Anaconda3\envs\tfenvnew\lib\site-packages\matplotlib\image.py", line 683, in set_data
.format(self._A.shape))

TypeError: Invalid shape (1, 64, 64, 3) for image data

Display of Dense Layers

Is there a better way to display dense layers to be more visually appealing?
dense
All the other layers are visually clear but the layer of 256 nodes is hard to interpret. Is there a way to reshape the visualization? Or do I need to add a reshape layer to the model?
cnn
This is the model I'm using:
model

Calling get_activations in a loop causing problems

Hopefully someone can point me in the right direction.
I'm using get_activations to do some computations on different layer's output and do something with the result. The workflow is like:

model = VGG16()
model.compile(...)
for item in list:
load_img
get_activations(model, img)
# do stuff with activation layers

each time I loop through takes longer and longer. I've narrowed it down to the get_activations call that is causing the issue. It takes more time each iteration to get the activations. What is a workaround here?

python 2.7 compatibility

import keract

File "/apps/software/python/python-2.7.15/lib/python2.7/site-packages/keract/init.py", line 1, in
from keract.keract import *
File "/apps/software/python/python-2.7.15/lib/python2.7/site-packages/keract/keract.py", line 5
def _evaluate(model: Model, nodes_to_evaluate, x, y=None):
^
SyntaxError: invalid syntax

LSTM Activations- Cell, Input Gate, Output Gate and Forget Gate

Hey, awesome work with this repo!
In an LSTM network you have neurons acting as cells, some acting as input gates, some as output gates and some as forget gates. Do you know if it is possible to get the activation values with Keras for all of them? I guess the output of Keract by now is the resulting Cell Unit activation.

If you could point me to the right part of the code I can also implement the needed changes on my own in a separate Pull Request.

Does not work for multi-inputs

    m = get_multi_inputs_model()
    m.compile(optimizer='adam',
              loss='binary_crossentropy')

    inp_a = np.random.uniform(size=(100, 10))
    inp_b = np.random.uniform(size=(100, 10))
    inp_o = np.random.randint(low=0, high=2, size=(100, 1))
    m.fit([inp_a, inp_b], inp_o)

    from read_activations import *

    get_activations(m, [inp_a[0:1], inp_b[0:1]], print_shape_only=True)

Running heat_map.py: 'NoneType' object has no attribute 'shape'

Hello @philipperemy!
I'm currently facing the following issue: when running heat_map.py I'm getting the following error:

Traceback (most recent call last):
  File "/home/misha/Desktop/dev-anna/15sof/shot_detection/src/scripts/heat_map.py", line 31, in <module>
    activations = keract.get_activations(model, image)
  File "/home/misha/anaconda3/envs/conda-py3/lib/python3.6/site-packages/keract/keract.py", line 77, in get_activations
    activations = _evaluate(model, layer_outputs, x, y=None)
  File "/home/misha/anaconda3/envs/conda-py3/lib/python3.6/site-packages/keract/keract.py", line 23, in _evaluate
    x_, y_, sample_weight_ = model._standardize_user_data(x, y)
  File "/home/misha/anaconda3/envs/conda-py3/lib/python3.6/site-packages/keras/engine/training.py", line 1487, in _standardize_user_data
    in zip(y, sample_weights, class_weights, self._feed_sample_weight_modes)]
  File "/home/misha/anaconda3/envs/conda-py3/lib/python3.6/site-packages/keras/engine/training.py", line 1486, in <listcomp>
    for (ref, sw, cw, mode)
  File "/home/misha/anaconda3/envs/conda-py3/lib/python3.6/site-packages/keras/engine/training.py", line 540, in _standardize_weights
    return np.ones((y.shape[0],), dtype=K.floatx())
AttributeError: 'NoneType' object has no attribute 'shape'

Library versions are as follows:

keract==2.5.4
Keras==2.1.6
tensorflow-gpu==1.9.0

Could you please advise what might be the problem?

Use keract on GPU

Hello !

I have used keract to get the activation of the layers of my model on CPU, it works good !

Now, I work on GPU (GeForce GTX 1080) .
To explain breifly : I install tensorflow gpu in a conda environment.
I train my model and now I want to get the activation of the layer for some images in my test dataset.

So, this is my model :

Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 224, 224, 3)       0         
_________________________________________________________________
conv1_1 (Conv2D)             (None, 224, 224, 64)      1792      
_________________________________________________________________
conv1_2 (Conv2D)             (None, 224, 224, 64)      36928     
_________________________________________________________________
pool1 (MaxPooling2D)         (None, 112, 112, 64)      0         
_________________________________________________________________
conv2_1 (Conv2D)             (None, 112, 112, 128)     73856     
_________________________________________________________________
conv2_2 (Conv2D)             (None, 112, 112, 128)     147584    
_________________________________________________________________
pool2 (MaxPooling2D)         (None, 56, 56, 128)       0         
_________________________________________________________________
conv3_1 (Conv2D)             (None, 56, 56, 256)       295168    
_________________________________________________________________
conv3_2 (Conv2D)             (None, 56, 56, 256)       590080    
_________________________________________________________________
conv3_3 (Conv2D)             (None, 56, 56, 256)       590080    
_________________________________________________________________
pool3 (MaxPooling2D)         (None, 28, 28, 256)       0         
_________________________________________________________________
conv4_1 (Conv2D)             (None, 28, 28, 512)       1180160   
_________________________________________________________________
conv4_2 (Conv2D)             (None, 28, 28, 512)       2359808   
_________________________________________________________________
conv4_3 (Conv2D)             (None, 28, 28, 512)       2359808   
_________________________________________________________________
pool4 (MaxPooling2D)         (None, 14, 14, 512)       0         
_________________________________________________________________
conv5_1 (Conv2D)             (None, 14, 14, 512)       2359808   
_________________________________________________________________
conv5_2 (Conv2D)             (None, 14, 14, 512)       2359808   
_________________________________________________________________
conv5_3 (Conv2D)             (None, 14, 14, 512)       2359808   
_________________________________________________________________
pool5 (MaxPooling2D)         (None, 7, 7, 512)         0         
_________________________________________________________________
flatten (Flatten)            (None, 25088)             0         
_________________________________________________________________
fc6 (Dense)                  (None, 4096)              102764544 
_________________________________________________________________
fc6/relu (Activation)        (None, 4096)              0         
_________________________________________________________________
fc7 (Dense)                  (None, 4096)              16781312  
_________________________________________________________________
fc7/relu (Activation)        (None, 4096)              0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 4096)              0         
_________________________________________________________________
predictions (Dense)          (None, 253)               1036541   
=================================================================
Total params: 135,297,085
Trainable params: 135,036,925
Non-trainable params: 260,160
_________________________________________________________________

I use the function :

layers_activations = keract.get_activations(model, df_sparse1.reshape(df_sparse1.shape[0],224,224,3))

And then I get this error :

  File "<ipython-input-5-d581d0114ebd>", line 1, in <module>
    layers_activations = keract.get_activations(model, sparse1.reshape(sparse1.shape[0],224,224,3)) #177

  File "C:\Users\renoult\AppData\Local\Continuum\anaconda3\envs\tf_gpu\lib\site-packages\keract\keract.py", line 38, in get_activations
    activations = _evaluate(model, layer_outputs, x, y=None)

  File "C:\Users\renoult\AppData\Local\Continuum\anaconda3\envs\tf_gpu\lib\site-packages\keract\keract.py", line 9, in _evaluate
    return f(x_ + y_ + sample_weight_)

  File "C:\Users\renoult\AppData\Local\Continuum\anaconda3\envs\tf_gpu\lib\site-packages\keras\backend\tensorflow_backend.py", line 2715, in __call__
    return self._call(inputs)

  File "C:\Users\renoult\AppData\Local\Continuum\anaconda3\envs\tf_gpu\lib\site-packages\keras\backend\tensorflow_backend.py", line 2675, in _call
    fetched = self._callable_fn(*array_vals)

  File "C:\Users\renoult\AppData\Roaming\Python\Python36\site-packages\tensorflow\python\client\session.py", line 1439, in __call__
    run_metadata_ptr)

  File "C:\Users\renoult\AppData\Roaming\Python\Python36\site-packages\tensorflow\python\framework\errors_impl.py", line 528, in __exit__
    c_api.TF_GetCode(self.status.status))

ResourceExhaustedError: OOM when allocating tensor with shape[55,64,224,224] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
	 [[{{node conv1_1/convolution}} = Conv2D[T=DT_FLOAT, data_format="NCHW", dilations=[1, 1, 1, 1], padding="SAME", strides=[1, 1, 1, 1], use_cudnn_on_gpu=true, _device="/job:localhost/replica:0/task:0/device:GPU:0"](conv1_1/convolution-0-TransposeNHWCToNCHW-LayoutOptimizer, conv1_1/kernel/read)]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

EDIT : I have tried your example "mnisp.py" and I have the same error message !
Do you know where this problem come from ?

( As a last resort, I will install tensorflow cpu in a new environment but I really want to understand the problem).

Thank you in advance,

Kind regards ! :)

Sonia Mai.

Visualize features into a CNN+LSTM for video classification

Hi to all,
The network on which I am working aims to classify video sequences composed by 30 frames. Each sequence is labelled with 1 of the 4 classes considered, let's say: [0,1,2,3].
I want to use a CNN feature extraction module, then feed all the features of each image in an LSTM to predict the class. So we are talking about transfer learning: in my example the CNN is InceptionV3.
The idea is to let the last 10 layers trainable (no limits on choosing the trainable layers). I would like to visualize the features through this network. Here the simple code:
`
from keras.applications.inception_v3 import InceptionV3
from keras.layers import Dense, LSTM, TimeDistributed, Dropout
video = Input(shape=(30,299,299,3))
inc = InceptionV3(
weights='imagenet',
include_top=False,
input_shape=(299, 299, 3)
)
cnn_out = GlobalAveragePooling2D()(inc.output)
cnn = Model(inputs=inc.input, outputs=cnn_out)
for layer in cnn.layers:
layer.trainable=False
encoded_frames = TimeDistributed(cnn)(video)
encoded_sequence = LSTM(128, activation='relu', return_sequences=False, kernel_initializer=he_uniform(), bias_initializer='zeros', dropout=0.5)(encoded_frames)
hidden_layer = Dense(1024, activation='relu')(encoded_sequence)
outputs = Dense(4, activation="softmax")(hidden_layer)
model = Model(inputs=[video], outputs=outputs)

adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)
model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy'])
`
You can try the network with any random frame generator, assign random class to each sequence.
First doubt: In the summary of the network any layer of inception appear, since INC is considered as submodel, or nested model. How can i choose which layer consider as feature visualization?
It seems that the TD wrapper just not consider the layers, or the network, before itself. Is that a correct behavior?
Second: Is your package, in general, applicable to such a network? I would like to have an 'attention map' (I know is not) for each of the frame considered, even if the classification is done per series (return_sequences=False). Is that make sense?

Thank you very much for the help

Error: TypeError: Invalid dimensions for image data

Hi @philipperemy , I am trying to visualize my activations but this error showed up:
slow_conv1/add:0 (1, 2, 112, 112, 64) Traceback (most recent call last): File "vis.py", line 107, in <module> keract.display_activations(activations) File "C:\Users\xxx\Envs\krtf\lib\site-packages\keract\keract.py", line 111, in display_activations hmap = axes.flat[i].imshow(img, cmap=cmap) File "C:\Users\xxx\Envs\krtf\lib\site-packages\matplotlib\__init__.py", line 1810, in inner return func(ax, *args, **kwargs) File "C:\Users\xxx\Envs\krtf\lib\site-packages\matplotlib\axes\_axes.py", line 5494, in imshow im.set_data(X) File "C:\Users\xxx\Envs\krtf\lib\site-packages\matplotlib\image.py", line 638, in set_data raise TypeError("Invalid dimensions for image data") TypeError: Invalid dimensions for image data

I am working with 3D conv, is it compatible with your lib? Thanks (again)!

Error of placeholder tensor in _evaluate function

Hi,
First, thanks for this great work !
I'm trying to use your repo but I have an error of placeholder shape in _evaluate function.

I have created a sequential model based-on VGG16 to perform binary classification:

vgg_model = applications.VGG16(weights=None, include_top=False, input_shape=(224, 224, 3))
model = keras.models.Sequential()
model.add(vgg_model)
model.add(Flatten(input_shape=model.output_shape[1:]))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.75))
model.add(Dense(1, activation='sigmoid, name='Output_Classification'))

I have no probleme during training and when I predict new data.

But when I want to visualize convolution filter I have an issue:

Traceback (most recent call last):
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 2016.3\helpers\pydev\pydevd.py", line 1596, in
globals = debugger.run(setup['file'], None, None, is_module)
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 2016.3\helpers\pydev\pydevd.py", line 974, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 2016.3\helpers\pydev_pydev_imps_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "//Nt-nas/2019/L'Oreal/MED/Etude/Codes/VGG16_VisualizeFeatureMap.py", line 178, in
keract.get_activations(model, img, layer_dict=layer_dict)
File "C:\Python35\lib\site-packages\keract\keract.py", line 83, in get_activations
activations = evaluate(model, layer_outputs, x, y=None)
File "C:\Python35\lib\site-packages\keract\keract.py", line 25, in evaluate
return f(x
+ y
+ sample_weight_)
File "C:\Python35\lib\site-packages\keras\backend\tensorflow_backend.py", line 2715, in call
return self._call(inputs)
File "C:\Python35\lib\site-packages\keras\backend\tensorflow_backend.py", line 2675, in _call
fetched = self._callable_fn(*array_vals)
File "C:\Python35\lib\site-packages\tensorflow\python\client\session.py", line 1382, in call
run_metadata_ptr)
File "C:\Python35\lib\site-packages\tensorflow\python\framework\errors_impl.py", line 519, in exit
c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'input_1' with dtype float and shape [?,224,224,3]
[[Node: input_1 = Placeholderdtype=DT_FLOAT, shape=[?,224,224,3], _device="/job:localhost/replica:0/task:0/device:CPU:0"]]

The image I want to predict is the same as your vgg16.py file, so for me I think the shape is correct.

I used the following version:
keras 2.2.4
tensorflow 1.10.0
keract 2.6.2

Can you help me to fix it ?

Get activations while training

Hello, is there a way to get activations/outputs of a layer during training of neural network?
Thanks for any suggestions.

TypeError: can only concatenate list (not "NoneType") to list

I'm getting the following error when trying to use the example you gave for keract:

Traceback (most recent call last):
  File "new.py", line 139, in <module>
    activations = get_activations(model, test_volumes_mri)
  File ".../.local/lib/python3.7/site-packages/keract/keract.py", line 80, in get_activations
    activations = _evaluate(model, layer_outputs, x, y=None)
  File ".../.local/lib/python3.7/site-packages/keract/keract.py", line 27, in _evaluate
    return f(x_ + y_ + sample_weight_)
TypeError: can only concatenate list (not "NoneType") to list

The code (just the part that crashes. The model itself compiles, trains and evaluates just fine):

from keract import get_activations,display_activations,display_heatmaps,get_gradients_of_trainable_weights,get_gradients_of_activations
activations = get_activations(model, test_volumes_mri)
display_activations(activations, cmap="gray", save=True)
display_heatmaps(activations, input_image, save=True)
get_gradients_of_trainable_weights(model, test_volumes_mri, images_groundtruth)
get_gradients_of_activations(model, test_volumes_mri, images_groundtruth)

apply to RNNs?

Thanks for implementing this! Have you tested your package with recurrent nets? Naively applying your package to an RNN returned some error message and I am trying to understand it... But never mind if this is specifically designed for feedforward nets!

Version Compatibility Problem : great amount of memory consuming and Keract running slowly

The problem is caused by environment below in Windows10 :

  • tensorflow-gpu 1.15.0
  • keras 2.3.1
  • GTX 1080 ti
  • CUDA 10.0 with Cudnn 7.6.4

everything is OK but when I use the keract function get_activations(model, x, y), my memory comsuming reaching nearly 40GB and no any result, warning or error is given, though I just use one example for testing. I have tried keract with version 3.1.0 and 2.9.5, but both of them came with same problem.

But it works well in keract 3.0.2, keras 2.3.1 with tensorflow 2.0.0 in CPU mode. Does it caused by the the GPU mode? Or any other things like the version compatibility? Thanks.

Is there any way of reversing an activation map from Keract or set values of classes?

sigmoid_activation_output_compared_with_predicted

I am working with the U-net neural network for image segmentation (i.e. binary classification at every pixel). I feed a test image (top), then I get a prediction out by the network (bottom left) and then I used the keract display_activations function on the last convolution of the network with sigmoid activation (borrom right), I get an activation map, with yellow colour for a value of 1 assigned for white pixel and blue colour for a value of 0 assigned for black pixels. If I am interested in having my black pixels to be classified as being in class 1 (therefore yellow colour), is there any way to set this in Keract as to change the current behaviour? I am not sure if this is Keract specific question, but did not find solutions elsewhere. Any advice would be appreciated.

About the attributes of Keras Model

When I try to run recurrent.py, some errors I got are like:

Traceback (most recent call last): File "recurrent.py", line 37, in <module> utils.print_names_and_shapes(keract.get_activations(model, x_train)) File "D:\python3\lib\site-packages\keract-2.5.1-py3.6.egg\keract\keract.py", line 77, in get_activations File "D:\python3\lib\site-packages\keract-2.5.1-py3.6.egg\keract\keract.py", line 6, in _evaluate AttributeError: 'Sequential' object has no attribute '_is_compiled'

and

Traceback (most recent call last): File "recurrent.py", line 37, in <module> utils.print_names_and_shapes(keract.get_activations(model, x_train)) File "D:\python3\lib\site-packages\keract-2.5.1-py3.6.egg\keract\keract.py", line 77, in get_activations File "D:\python3\lib\site-packages\keract-2.5.1-py3.6.egg\keract\keract.py", line 22, in _evaluate AttributeError: 'Sequential' object has no attribute '_feed_targets'

And I checked the Keract.py, found that the codes used many attributes of the Keras Model that seems to be excluded from the keras 2.0.9 and tensorflow 1.4.0.
like
model._is_compiled, model._feed_inputs and model._feed_targets.

Should I use a specific version of keras or tensorflow to solve these issues?

Inner layer processing

Error the_input:0 is both fed and fetched.

act = get_activations(loaded_model, img)

image
How can I transfer inner layers if this does not work?
[layer.name for layer in loaded_model.get_layer('efficientnet-b0').layers]

_standardize_user_data may return None for sample_weights

The tensorflow branch the keras engine was modified such that model._standardize_user_data will now return None instead of an empty list when sample_weights are not defined.

Although the code states:

    Returns:
      A tuple of 3: inputs (arrays or dicts, depending on whether `x` was a dict
      or not), target arrays, sample-weight arrays.
      If the model's input and targets are symbolic, these lists are empty
      (since the model takes no user-provided data, instead the data comes
      from the symbolic inputs/targets).

The following commit seems to have changed the default sample weights return from [] to None.

tensorflow/tensorflow@41abdd1

This in turn causes the list add operation in the following return statement to fail:

def _evaluate(model: Model, nodes_to_evaluate, x, y=None):
   [...]
    x_, y_, sample_weight_ = model._standardize_user_data(x, y)
    return f(x_ + y_ + sample_weight_)

IndexError with multiple inputs

Thank you for your work! display_activations is work ,but i got the following error with display_heatmaps():

Traceback (most recent call last):
  File "/home/sipl-dl/.vscode/extensions/ms-python.python-2019.10.41019/pythonFiles/ptvsd_launcher.py", line 43, in <module>
    main(ptvsdArgs)
  File "/home/sipl-dl/.vscode/extensions/ms-python.python-2019.10.41019/pythonFiles/lib/python/old_ptvsd/ptvsd/__main__.py", line 432, in main
    run()
  File "/home/sipl-dl/.vscode/extensions/ms-python.python-2019.10.41019/pythonFiles/lib/python/old_ptvsd/ptvsd/__main__.py", line 316, in run_file
    runpy.run_path(target, run_name='__main__')
  File "/home/sipl-dl/anaconda3/envs/keras/lib/python3.6/runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "/home/sipl-dl/anaconda3/envs/keras/lib/python3.6/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/home/sipl-dl/anaconda3/envs/keras/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/sipl-dl/code/streamer/attention_map_CAM3.py", line 100, in <module>
    main()
  File "/home/sipl-dl/code/streamer/attention_map_CAM3.py", line 97, in main
    validate(image_shape=image_shape, class_limit=None)
  File "/home/sipl-dl/code/streamer/attention_map_CAM3.py", line 89, in validate
    display_heatmaps(activations, imgx, save=False)
  File "/home/sipl-dl/anaconda3/envs/keras/lib/python3.6/site-p
```ackages/keract/keract.py", line 226, in display_heatmaps
    img = acts[0, :, :, i]
IndexError: too many indices for array

and my code is :

    model = load_model('multi3_cgru_0527 22:39 69.83.h5',custom_objects={'categorical_focal_loss_fixed':categorical_focal_loss_fixed})
    model.summary()
    img_path1 = 'data/attention/video/v1 - 48of99-0001.png'
    img_path2= 'data/attention/audio/v1-48of99chunk0.png'
    img_path3='data/attention/flow/frame_00001.png'

    img1 = image.load_img(img_path1, target_size=(299, 299)) 
    img2 = image.load_img(img_path2, target_size=(299, 299)) 
    img3 = image.load_img(img_path3, target_size=(299, 299)) 
    x1= image.img_to_array(img1) 
    x2= image.img_to_array(img2) 
    x3 = image.img_to_array(img3) 
    x1 = np.expand_dims(x1, axis=0)
    x2 = np.expand_dims(x2, axis=0) 
    x3 = np.expand_dims(x3, axis=0)  
    x=[x1,x2,x3]


    activations = get_activations(model, x, layer_name='concatenate_3')
    print(activations)
    imgx = image.load_img(img_path1)
    imgx = np.array(imgx)
    imgx = np.expand_dims(imgx, axis=0) 
    display_heatmaps(activations, imgx, save=False)

Thank you!

Discovering the input(s) that maximizes activation of each CNN filter

This isn't an issue; rather an enquiry.

Any guidance as to how would one would use your library to find the inputs that maximize each layer/filter?

The first thought that comes to mind is to send random inputs through and measure the activations, but that doesn't feel very efficient.

Issue with a Keras model created with a custom function

Hi, thanks for your excellent work!

I am finding an issue with a code I am working on. I made a custom function to create a Sequential model using ImageDataGenerator class and then pass on a suitable input vector along with the model to your get_activations function but it throws up an error.

Please allow me to describe the problem clearly.
Here are my custom functions (here is my repo)

def train_CNN(train_directory,target_size=(256,256), 
              classes=None,batch_size=128,num_classes=2,
              num_epochs=20,verbose=0):
    """
    Trains a conv net for the flowers dataset with a 5-class classifiction output
    Also provides suitable arguments for extending it to other similar apps
    
    Arguments:
            train_directory: The directory where the training images are stored in separate folders.
                            These folders should be named as per the classes.
            target_size: Target size for the training images. A tuple e.g. (200,200)
            classes: A Python list with the classes 
            batch_size: Batch size for training
            num_epochs: Number of epochs for training
            num_classes: Number of output classes to consider
            verbose: Verbosity level of the training, passed on to the `fit_generator` method
    Returns:
            A trained conv net model
    
    """
    from tensorflow.keras.preprocessing.image import ImageDataGenerator
    import tensorflow as tf
    from tensorflow.keras.optimizers import RMSprop
    
    # ImageDataGenerator object instance with scaling
    train_datagen = ImageDataGenerator(rescale=1/255)

    # Flow training images in batches using the generator
    train_generator = train_datagen.flow_from_directory(
            train_directory,  # This is the source directory for training images
            target_size=target_size,  # All images will be resized to 200 x 200
            batch_size=batch_size,
            # Specify the classes explicitly
            classes = classes,
            # Since we use categorical_crossentropy loss, we need categorical labels
            class_mode='categorical')
    
    input_shape = tuple(list(target_size)+[3])
    
    # Model architecture
    model = tf.keras.models.Sequential([
    # Note the input shape is the desired size of the image 200x 200 with 3 bytes color
    # The first convolution
    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=input_shape),
    tf.keras.layers.MaxPooling2D(2, 2),
    # The second convolution
    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # The third convolution
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # The fourth convolution
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # The fifth convolution
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    # Flatten the results to feed into a dense layer
    tf.keras.layers.Flatten(),
    # 512 neuron in the fully-connected layer
    tf.keras.layers.Dense(512, activation='relu'),
    # Output neurons for `num_classes` classes with the softmax activation
    tf.keras.layers.Dense(num_classes, activation='softmax')
    ])
    
    # Optimizer and compilation
    model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop(lr=0.001),
              metrics=['acc'])
    
    # Total sample count
    total_sample=train_generator.n
    
    # Training
    model.fit_generator(
        train_generator, 
        steps_per_epoch=int(total_sample/batch_size),  
        epochs=num_epochs,
        verbose=verbose)
    
    return model

And one for preprocessing a random test image from the disk,

def preprocess_image(img_path,model=None,rescale=255,resize=(256,256)):
    """
    Preprocesses a given image for prediction with a trained model, with rescaling and resizing options
    
    Arguments:
            img_path: The path to the image file
            rescale: A float or integer indicating required rescaling. 
                    The image array will be divided (scaled) by this number.
            resize: A tuple indicating desired target size. 
                    This should match the input shape as expected by the model
    Returns:
            img: A processed image.
    """
    from keras.preprocessing.image import img_to_array, load_img
    import cv2
    import numpy as np
    
    assert type(img_path)==str, "Image path must be a string"
    assert type(rescale)==int or type(rescale)==float, "Rescale factor must be either a float or int"
    assert type(resize)==tuple and len(resize)==2, "Resize target must be a tuple with two elements"
    
    img = load_img(img_path)
    img = img_to_array(img)
    img = img/float(rescale)
    img = cv2.resize(img,resize)
    if model!=None:
        if len(model.input_shape)==4:
            img = np.expand_dims(img,axis=0)
        
    return img

What is the utility of these? With these custom functions, I can train a conv net with just two lines of code and then test any random image. Such as,

train_directory = "../Data/101_ObjectCategories/"

model_caltech101 = train_CNN(train_directory=train_directory,
                             classes=['crab','cup','brain','camera','chair'],batch_size=4,
                             num_epochs=20,num_classes=5,verbose=1)**

and then,

img_path = '../Data/101_ObjectCategories/Test_images/crab-1.jpg'
img = preprocess_image(img_path)
model_caltech101.predict(img)

I wrote an article on this, see here.

Now, I just want to apply the same process with your activation package. I want to,

  • build a model using my train_CNN function
  • process a random image using my preprocess_image function
  • then pass on my model and the image as a x input to your function
train_directory = "../Data/101_ObjectCategories/"

model_caltech101 = train_CNN(train_directory=train_directory,
                             classes=['crab','cup','brain','camera','chair'],batch_size=4,
                             num_epochs=20,num_classes=5,verbose=1)

img_path = '../Data/101_ObjectCategories/Test_images/crab-1.jpg'
x = preprocess_image(img_path=img_path,model=model_caltech101)

from keract import get_activations
activations = get_activations(model_caltech101, x)

When I do that, I get this error,

---------------------------------------------------------------------------
FailedPreconditionError                   Traceback (most recent call last)
<ipython-input-6-c0594bb3700d> in <module>
      1 from keract import get_activations
----> 2 activations = get_activations(model_caltech101, x)

c:\users\tirth\docume~1\personal\datasc~2\python~1\tf-gpu\lib\site-packages\keract\keract.py in get_activations(model, x, layer_name)
     78     input_layer_outputs, layer_outputs = [], []
     79     [input_layer_outputs.append(node) if 'input_' in node.name else layer_outputs.append(node) for node in nodes]
---> 80     activations = _evaluate(model, layer_outputs, x, y=None)
     81     activations_dict = OrderedDict(zip([output.name for output in layer_outputs], activations))
     82     activations_inputs_dict = OrderedDict(zip([output.name for output in input_layer_outputs], x))

c:\users\tirth\docume~1\personal\datasc~2\python~1\tf-gpu\lib\site-packages\keract\keract.py in _evaluate(model, nodes_to_evaluate, x, y)
     25     f = K.function(symb_inputs, nodes_to_evaluate)
     26     x_, y_, sample_weight_ = model._standardize_user_data(x, y)
---> 27     return f(x_ + y_ + sample_weight_)
     28 
     29 

c:\users\tirth\docume~1\personal\datasc~2\python~1\tf-gpu\lib\site-packages\keras\backend\tensorflow_backend.py in __call__(self, inputs)
   2713                 return self._legacy_call(inputs)
   2714 
-> 2715             return self._call(inputs)
   2716         else:
   2717             if py_any(is_tensor(x) for x in inputs):

c:\users\tirth\docume~1\personal\datasc~2\python~1\tf-gpu\lib\site-packages\keras\backend\tensorflow_backend.py in _call(self, inputs)
   2673             fetched = self._callable_fn(*array_vals, run_metadata=self.run_metadata)
   2674         else:
-> 2675             fetched = self._callable_fn(*array_vals)
   2676         return fetched[:len(self.outputs)]
   2677 

c:\users\tirth\docume~1\personal\datasc~2\python~1\tf-gpu\lib\site-packages\tensorflow\python\client\session.py in __call__(self, *args, **kwargs)
   1437           ret = tf_session.TF_SessionRunCallable(
   1438               self._session._session, self._handle, args, status,
-> 1439               run_metadata_ptr)
   1440         if run_metadata:
   1441           proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

c:\users\tirth\docume~1\personal\datasc~2\python~1\tf-gpu\lib\site-packages\tensorflow\python\framework\errors_impl.py in __exit__(self, type_arg, value_arg, traceback_arg)
    526             None, None,
    527             compat.as_text(c_api.TF_Message(self.status.status)),
--> 528             c_api.TF_GetCode(self.status.status))
    529     # Delete the underlying status object from memory otherwise it stays alive
    530     # as there is a reference to status from this from the traceback due to

FailedPreconditionError: Error while reading resource variable conv2d_4/bias from Container: localhost. This could mean that the variable was uninitialized. Not found: Container localhost does not exist. (Could not find resource: localhost/conv2d_4/bias)
	 [[{{node conv2d_4/BiasAdd/ReadVariableOp}}]]
	 [[{{node max_pooling2d_1/MaxPool}}]]

Please see if you can reproduce this and help in any way. We can collaborate to recreate the issue if needed.

Thanks!

error of image size in vgg16.py

When I run python vgg16.py I get:

ValueError: Cannot feed value of shape (1, 1, 224, 224, 3) for Tensor 'input_1:0', which has shape '(?, 224, 224, 3)'

How to remove this error ?

AttributeError when using on mobilenet transfer learned model

When attempting to use keract to get the activations of a CNN given an image I get the error AtributeError: Layer mobilenet_1.00_224 has multiple inbound nodes, hence the notion of "layer output" is ill-defined. Use get_output_at(node_index) instead

Output of model.summary:

Layer (type)                 Output Shape              Param    
=================================================================
mobilenet_1.00_224 (Model)   (None, 7, 7, 1024)        3228864   
_________________________________________________________________
flatten_1 (Flatten)          (None, 50176)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 2)                 100354    
=================================================================

Full traceback:

Traceback (most recent call last):
  File "viz.py", line 43, in <module>
    activations = keract.get_activations(model, img)
  File "/usr/local/lib/python3.5/dist-packages/keract/keract.py", line 34, in get_activations
    nodes = [layer.output for layer in model.layers if layer.name == layer_name or layer_name is None]
  File "/usr/local/lib/python3.5/dist-packages/keract/keract.py", line 34, in <listcomp>
    nodes = [layer.output for layer in model.layers if layer.name == layer_name or layer_name is None]
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/base_layer.py", line 813, in output
    ' has multiple inbound nodes, '
AttributeError: Layer mobilenet_1.00_224 has multiple inbound nodes, hence the notion of "layer output" is ill-defined. Use `get_output_at(node_index)` instead.

Code defining model in my separate training code:

mn=mobilenet.MobileNet(weights='imagenet', include_top=False, input_shape=shape)

model = Sequential()
model.add(mn)
model.add(Flatten())
model.add(Dense(2, activation='softmax'))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.