By GoingMyWay


2017-01-18 04:07:16 8 Comments

I have trained a binary classification model with CNN, and here is my code

model = Sequential()
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1],
                        border_mode='valid',
                        input_shape=input_shape))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=pool_size))
# (16, 16, 32)
model.add(Convolution2D(nb_filters*2, kernel_size[0], kernel_size[1]))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters*2, kernel_size[0], kernel_size[1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=pool_size))
# (8, 8, 64) = (2048)
model.add(Flatten())
model.add(Dense(1024))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))  # define a binary classification problem
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='adadelta',
              metrics=['accuracy'])
model.fit(x_train, y_train,
          batch_size=batch_size,
          nb_epoch=nb_epoch,
          verbose=1,
          validation_data=(x_test, y_test))

And here, I wanna get the output of each layer just like TensorFlow, how can I do that?

10 comments

@Mpizos Dimitris 2019-10-02 11:11:47

In case you have one of the following cases:

  • error: InvalidArgumentError: input_X:Y is both fed and fetched
  • case of multiple inputs

You need to do the following changes:

  • add filter out for input layers in outputs variable
  • minnor change on functors loop

Minimum example:

from keras.engine.input_layer import InputLayer
inp = model.input
outputs = [layer.output for layer in model.layers if not isinstance(layer, InputLayer)]
functors = [K.function(inp + [K.learning_phase()], [x]) for x in outputs]
layer_outputs = [fun([x1, x2, xn, 1]) for fun in functors]

@HashRocketSyntax 2019-10-12 03:03:27

What is meant by [x1, x2, xn, 1]? My x1 is not defined and I would like to understand what you are defining there.

@Mpizos Dimitris 2019-10-14 11:09:59

@HashRocketSyntax x1 and x2 are the inputs of the model. As stated thats incase you got 2 inputs on your model.

@Philippe Remy 2019-05-31 02:28:19

Based on all the good answers of this thread, I wrote a library to fetch the output of each layer. It abstracts all the complexity and has been designed to be as user-friendly as possible:

https://github.com/philipperemy/keract

It handles almost all the edge cases

Hope it helps!

@imanzabet 2019-05-29 21:00:50

Assuming you have:

1- Keras pre-trained model.

2- Input x as image or set of images. The resolution of image should be compatible with dimension of the input layer. For example 80*80*3 for 3-channels (RGB) image.

3- The name of the output layer to get the activation. For example, "flatten_2" layer. This should be include in the layer_names variable, represents name of layers of the given model.

4- batch_size is an optional argument.

Then you can easily use get_activation function to get the activation of the output layer for a given input x and pre-trained model:

import six
import numpy as np
import keras.backend as k
from numpy import float32
def get_activations(x, model, layer, batch_size=128):
"""
Return the output of the specified layer for input `x`. `layer` is specified by layer index (between 0 and
`nb_layers - 1`) or by name. The number of layers can be determined by counting the results returned by
calling `layer_names`.
:param x: Input for computing the activations.
:type x: `np.ndarray`. Example: x.shape = (80, 80, 3)
:param model: pre-trained Keras model. Including weights.
:type model: keras.engine.sequential.Sequential. Example: model.input_shape = (None, 80, 80, 3)
:param layer: Layer for computing the activations
:type layer: `int` or `str`. Example: layer = 'flatten_2'
:param batch_size: Size of batches.
:type batch_size: `int`
:return: The output of `layer`, where the first dimension is the batch size corresponding to `x`.
:rtype: `np.ndarray`. Example: activations.shape = (1, 2000)
"""

    layer_names = [layer.name for layer in model.layers]
    if isinstance(layer, six.string_types):
        if layer not in layer_names:
            raise ValueError('Layer name %s is not part of the graph.' % layer)
        layer_name = layer
    elif isinstance(layer, int):
        if layer < 0 or layer >= len(layer_names):
            raise ValueError('Layer index %d is outside of range (0 to %d included).'
                             % (layer, len(layer_names) - 1))
        layer_name = layer_names[layer]
    else:
        raise TypeError('Layer must be of type `str` or `int`.')

    layer_output = model.get_layer(layer_name).output
    layer_input = model.input
    output_func = k.function([layer_input], [layer_output])

    # Apply preprocessing
    if x.shape == k.int_shape(model.input)[1:]:
        x_preproc = np.expand_dims(x, 0)
    else:
        x_preproc = x
    assert len(x_preproc.shape) == 4

    # Determine shape of expected output and prepare array
    output_shape = output_func([x_preproc[0][None, ...]])[0].shape
    activations = np.zeros((x_preproc.shape[0],) + output_shape[1:], dtype=float32)

    # Get activations with batching
    for batch_index in range(int(np.ceil(x_preproc.shape[0] / float(batch_size)))):
        begin, end = batch_index * batch_size, min((batch_index + 1) * batch_size, x_preproc.shape[0])
        activations[begin:end] = output_func([x_preproc[begin:end]])[0]

    return activations

@KamKam 2019-03-29 13:00:08

Wanted to add this as a comment (but don't have high enough rep.) to @indraforyou's answer to correct for the issue mentioned in @mathtick's comment. To avoid the InvalidArgumentError: input_X:Y is both fed and fetched. exception, simply replace the line outputs = [layer.output for layer in model.layers] with outputs = [layer.output for layer in model.layers][1:], i.e.

adapting indraforyou's minimal working example:

from keras import backend as K 
inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers][1:]        # all layer outputs except first (input) layer
functor = K.function([inp, K.learning_phase()], outputs )   # evaluation function

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = functor([test, 1.])
print layer_outs

p.s. my attempts trying things such as outputs = [layer.output for layer in model.layers[1:]] did not work.

@Mpizos Dimitris 2019-10-02 11:08:06

that is not exactly correct. This is only if input layer is the first defined.

@KMunro 2019-11-20 13:31:57

Thanks, this worked for me and I just want to check I understand why, based on Mpizos' comment: my model is just 3 layers (word embeddings - BiLSTM - CRF), so I guess I had to exclude layer[0] since it's just embeddings and shouldn't have an activation, right?

@indraforyou 2017-01-18 05:28:56

You can easily get the outputs of any layer by using: model.layers[index].output

For all layers use this:

from keras import backend as K

inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers]          # all layer outputs
functors = [K.function([inp, K.learning_phase()], [out]) for out in outputs]    # evaluation functions

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = [func([test, 1.]) for func in functors]
print layer_outs

Note: To simulate Dropout use learning_phase as 1. in layer_outs otherwise use 0.

Edit: (based on comments)

K.function creates theano/tensorflow tensor functions which is later used to get the output from the symbolic graph given the input.

Now K.learning_phase() is required as an input as many Keras layers like Dropout/Batchnomalization depend on it to change behavior during training and test time.

So if you remove the dropout layer in your code you can simply use:

from keras import backend as K

inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers]          # all layer outputs
functors = [K.function([inp], [out]) for out in outputs]    # evaluation functions

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = [func([test]) for func in functors]
print layer_outs

Edit 2: More optimized

I just realized that the previous answer is not that optimized as for each function evaluation the data will be transferred CPU->GPU memory and also the tensor calculations needs to be done for the lower layers over-n-over.

Instead this is a much better way as you don't need multiple functions but a single function giving you the list of all outputs:

from keras import backend as K

inp = model.input                                           # input placeholder
outputs = [layer.output for layer in model.layers]          # all layer outputs
functor = K.function([inp, K.learning_phase()], outputs )   # evaluation function

# Testing
test = np.random.random(input_shape)[np.newaxis,...]
layer_outs = functor([test, 1.])
print layer_outs

@GoingMyWay 2017-01-18 07:18:57

sir, your answer is good, what K.function([inp]+ [K.learning_phase()], [out]) mean in your code?

@Tom 2017-10-25 09:14:10

Excellent answer, np.random.random(input_shape)[np.newaxis,...] can also be written as np.random.random(input_shape)[np.newaxis,:]

@Stav Bodik 2017-11-01 21:48:40

What is K.function ? how do it passed to GPU ( MPI ?) ? what is there behind the scene ? How it is talks with CUDA ? where is the source code ?

@Stav Bodik 2018-02-04 15:40:48

@indraforyou How do you explain that this method is much more slower then just calling model.predict ? As I understand both of them should make all the calculations on the GPU...I did tested and model.predict is much more faster in my case , any explanation please ? Thanks.

@indraforyou 2018-02-04 16:12:43

@StavBodik Model builds the predict function using K.function here, and predict uses it in the predict loop here. Predict loops over the batch size (if not set it defaults to 32) but thats to mitigate constraints on GPU memory. So i am not sure why you are observing model.predict is faster.

@Stav Bodik 2018-02-04 16:35:37

Thanks , this sounds to me like some bug in my code using the time.time() function in python...will check this out.

@Ramesh-X 2018-06-18 12:24:19

It gives this error to me ValueError("Tensor %s is not an element of this graph." % obj). Here my tensor obj is Tensor("data:0", shape=(?, 224, 224, 3), dtype=float32)

@mathtick 2019-03-15 11:21:43

Am getting this: InvalidArgumentError: S_input_39:0 is both fed and fetched. ... anyone with ideas?

@Jason 2019-08-10 23:46:31

Does anyone encounter this issue? The kernel appears to have died. It will restart automatically.

@felix Antony 2019-09-05 20:03:14

Any possibility to get the delta values in each cells in each layer? eg: Delta out, delta state, delta a, delta f, delta i ,delta o.

@HashRocketSyntax 2019-10-12 01:52:20

Error when running test = np.random.random(model.input.shape)[np.newaxis,:] error: TypeError: 'NoneType' object cannot be interpreted as an integer... i think it's because my shape is [None, 4] not [4,]?

@Daniel Möller 2017-05-09 03:07:29

Well, other answers are very complete, but there is a very basic way to "see", not to "get" the shapes.

Just do a model.summary(). It will print all layers and their output shapes. "None" values will indicate variable dimensions, and the first dimension will be the batch size.

@mathtick 2019-03-15 11:24:16

This is about the output of the layer (given inputs to the base layer) not the layer.

@blue-sky 2017-09-22 07:35:02

From https://keras.io/getting-started/faq/#how-can-i-obtain-the-output-of-an-intermediate-layer

One simple way is to create a new Model that will output the layers that you are interested in:

from keras.models import Model

model = ...  # include here your original model

layer_name = 'my_layer'
intermediate_layer_model = Model(inputs=model.input,
                                 outputs=model.get_layer(layer_name).output)
intermediate_output = intermediate_layer_model.predict(data)

Alternatively, you can build a Keras function that will return the output of a certain layer given a certain input, for example:

from keras import backend as K

# with a Sequential model
get_3rd_layer_output = K.function([model.layers[0].input],
                                  [model.layers[3].output])
layer_output = get_3rd_layer_output([x])[0]

@Dan Erez 2018-11-01 09:34:33

if I could i'd give you two ^, This way is just sooooo much more convenient when you have a bunch of inputs.

@Jiayi 2019-02-15 17:07:11

It's pretty clear from your code above but just to double check my understanding: after creating a model from an existing model(assuming it's already trained), there is no need to call set_weights on the new model. Is that correct?

@Jason 2019-03-31 17:30:02

what is the difference between layer_output = get_3rd_layer_output([X, 0])[0] and layer_output = get_3rd_layer_output([X, 1])[0] The docs mention train mode and test mode

@PedroD 2019-09-09 07:57:52

sorry, can you explain me what does this model do exactly? Do you have to train it as well? I cannot imagine any diagram to it. You add the input layer of another model, then add a random intermediary layer of that other model as output, and feed inputs to it? Why do this instead of feeding the original model and get direct access to any intermediary layer it in? Why create this extra strange model? And won't it affect the output? won't it try to learn or require training, or the layer brings its own weights pre trained from the original model?

@cannin 2017-11-12 19:45:14

From: https://github.com/philipperemy/keras-visualize-activations/blob/master/read_activations.py

import keras.backend as K

def get_activations(model, model_inputs, print_shape_only=False, layer_name=None):
    print('----- activations -----')
    activations = []
    inp = model.input

    model_multi_inputs_cond = True
    if not isinstance(inp, list):
        # only one input! let's wrap it in a list.
        inp = [inp]
        model_multi_inputs_cond = False

    outputs = [layer.output for layer in model.layers if
               layer.name == layer_name or layer_name is None]  # all layer outputs

    funcs = [K.function(inp + [K.learning_phase()], [out]) for out in outputs]  # evaluation functions

    if model_multi_inputs_cond:
        list_inputs = []
        list_inputs.extend(model_inputs)
        list_inputs.append(0.)
    else:
        list_inputs = [model_inputs, 0.]

    # Learning phase. 0 = Test mode (no dropout or batch normalization)
    # layer_outputs = [func([model_inputs, 0.])[0] for func in funcs]
    layer_outputs = [func(list_inputs)[0] for func in funcs]
    for layer_activations in layer_outputs:
        activations.append(layer_activations)
        if print_shape_only:
            print(layer_activations.shape)
        else:
            print(layer_activations)
    return activations

@devil in the detail 2017-08-01 06:24:09

Following looks very simple to me:

model.layers[idx].output

Above is a tensor object, so you can modify it using operations that can be applied to a tensor object.

For example, to get the shape model.layers[idx].output.get_shape()

idx is the index of the layer and you can find it from model.summary()

@Red Floyd 2019-06-05 20:05:42

What's wrong with this answer? Why isn't this upvoted as the top answer?

@Miladiouss 2017-03-31 08:24:19

I wrote this function for myself (in Jupyter) and it was inspired by indraforyou's answer. It will plot all the layer outputs automatically. Your images must have a (x, y, 1) shape where 1 stands for 1 channel. You just call plot_layer_outputs(...) to plot.

%matplotlib inline
import matplotlib.pyplot as plt
from keras import backend as K

def get_layer_outputs():
    test_image = YOUR IMAGE GOES HERE!!!
    outputs    = [layer.output for layer in model.layers]          # all layer outputs
    comp_graph = [K.function([model.input]+ [K.learning_phase()], [output]) for output in outputs]  # evaluation functions

    # Testing
    layer_outputs_list = [op([test_image, 1.]) for op in comp_graph]
    layer_outputs = []

    for layer_output in layer_outputs_list:
        print(layer_output[0][0].shape, end='\n-------------------\n')
        layer_outputs.append(layer_output[0][0])

    return layer_outputs

def plot_layer_outputs(layer_number):    
    layer_outputs = get_layer_outputs()

    x_max = layer_outputs[layer_number].shape[0]
    y_max = layer_outputs[layer_number].shape[1]
    n     = layer_outputs[layer_number].shape[2]

    L = []
    for i in range(n):
        L.append(np.zeros((x_max, y_max)))

    for i in range(n):
        for x in range(x_max):
            for y in range(y_max):
                L[i][x][y] = layer_outputs[layer_number][x][y][i]


    for img in L:
        plt.figure()
        plt.imshow(img, interpolation='nearest')

@Antonio Sesto 2017-07-20 11:53:43

What if the model has several inputs? How to you specify the inputs?

@Kongsea 2017-12-29 12:44:05

In this line: layer_outputs_list = [op([test_image, 1.]). Does 1. need to be 0? It seems 1 stands for training and 0 stands for testing? Isn't is?

@Vaibhav K 2019-06-14 06:11:34

This is not working for me. I have used a color image and it is giving me error : InvalidArgumentError: input_2:0 is both fed and fetched.

Related Questions

Sponsored Content

42 Answered Questions

[SOLVED] How do I merge two dictionaries in a single expression?

28 Answered Questions

[SOLVED] How do I check if a list is empty?

  • 2008-09-10 06:20:11
  • Ray Vega
  • 2558845 View
  • 3235 Score
  • 28 Answer
  • Tags:   python list

37 Answered Questions

[SOLVED] How do I check whether a file exists without exceptions?

36 Answered Questions

[SOLVED] How to get the current time in Python

  • 2009-01-06 04:54:23
  • user46646
  • 3093115 View
  • 2644 Score
  • 36 Answer
  • Tags:   python datetime time

21 Answered Questions

[SOLVED] How do I list all files of a directory?

  • 2010-07-08 19:31:22
  • duhhunjonn
  • 3778308 View
  • 3474 Score
  • 21 Answer
  • Tags:   python directory

1 Answered Questions

11 Answered Questions

[SOLVED] How do I get a substring of a string in Python?

  • 2009-03-19 17:29:41
  • Joan Venge
  • 2739197 View
  • 2010 Score
  • 11 Answer
  • Tags:   python string

25 Answered Questions

[SOLVED] How can I safely create a nested directory?

1 Answered Questions

Sponsored Content