Unable to get hidden layer activation of ANN - python

I am using python2 and i'm trying to get the activations of hidden layer. I am using the following code which is giving me an error:
get_activations = theano.function([my_model.layers[0].input], my_model.layers[0].get_output(train=False),
allow_input_downcast=True)
When I run the code it says:
AttributeError: 'Dense' object has no attribute 'get_output'
I have tried to use my_model.layers[0].output which also does not work correctly.
What should I do to get the activations from a layer given?

attribute get_output is only defined for old versions of keras (0.3). It no longer exists in version 1.0.
see new syntax (keras doc FAQ)
something like
get_activations = K.function([model.layers[0].input], [model.layers[1].output])
should work since the hidden layer is the second layer in your model (i.e. model.layers[1])

Related

Attribute Error: 'Embedding' object has no attribute 'embeddings' - TensorFlow & Keras

Okay so I have a keras model that I fully ran and then saved the weights with this line:
model.save_weights("rho_beta_true_tf", save_format="tf")
Then in another file I build just the model and then I load the weights from the model I ran above using this line:
model_build.load_weights("rho_beta_true_tf")
When I then go to call some of the attributes everything displays correctly except when I try to run this line:
model_build.stimuli.embeddings
or
model_build.stimuli.embeddings.numpy()[0]
I get an attribute error saying:
AttributeError: 'Embedding' object has no attribute 'embeddings'
This line is supposed to return a tensor and if I call any other attributes so far it works so I am not sure if it just can't find the tensors or if the problem is something else. Could someone please help me figure out how to solve this attribute Error?
Try using .get_weights():
model_build.stimuli.get_weights()
Turns out that because I had saved the weights in tf format I had to follow this step in the tensor flow documentation:
For user-defined classes which inherit from tf.keras.Model, Layer instances must be assigned to object attributes, typically in the constructor.
So then the line
build_model.stimuli.embedding(put the directory path to your custom embedding layer here)
worked!

Keras concatenate is not defined when loading the model

In one of my lambda layers, I used from keras.layers import concatenate to concatenate two tensors and it worked without any problem during training and I successfully saved the model files.
However, when I'm loading the model, it throws me this error:
NameError: name 'concatenate' is not defined
Does anyone know what might be wrong? I've imported concatenate before I load the model.
The lambda layer looks like this:
def concat_l1_l2(vests):
l1, l2 = vests
l1 = K.l2_normalize(l1, axis=-1)
l2 = K.l2_normalize(l2, axis=-1)
return concatenate([l1, l2])
I had the same issue when loading a model from a json file, try the following line (it worked for me):
from keras.layers import concatenate
model_from_json(model_file, custom_objects={'concatenate': concatenate})
Maybe the following will solve your problem.
Try to pass your costum function to the load function of keras, i.e.
load(model_path,{"concat_l1_l2":concat_l1_l2})

Using custom tensorflow ops in keras

I am having a script in tensorflow which contains the custom tensorflow ops. I want to port the code to keras and I am not sure how to call the custom ops within keras code.
I want to use tensorflow within keras, so the tutorial I found so far is describing the opposite to what I want: https://blog.keras.io/keras-as-a-simplified-interface-to-tensorflow-tutorial.html.
I also read about Lambda layers that can wrap arbitrary custom function, yet I did not see an example for tf.ops.
If you could provide code snippet with a simplest example how to do that I would be very grateful. For example assuming the tf.ops as:
outC = my_custom_op(inA, inB)
---EDIT:
Similar problem has been described in here - essentially calling this custom op in keras, however I cannot grasp the solution how to apply it on another example that I want, for instance this one. This custom tf op is first compiled (for gpu) and then so far used within tensorflow as here, see # line 40. It is clear for me how to use a custom (lambda) function wrapped in Lambda layer, what I would like to understand is how to use the compiled custom ops, if I use keras.
You can wrap arbitrary tensorflow functions in a keras Lambda layer and add them to your model. Minimal working example from this answer:
import tensorflow as tf
from keras.layers import Dense, Lambda, Input
from keras.models import Model
W = tf.random_normal(shape=(128,20))
b = tf.random_normal(shape=(20,))
inp = Input(shape=(10,))
x = Dense(128)(inp)
# Custom linear transformation
y = Lambda(lambda x: tf.matmul(x, W) + b, name='custom_layer')(x)
model = Model(inp, y)

How do the same function for pytorch expand_as in keras

pytorch code:
att_h = att_h.unsqueeze(1).expand_as(att)
att_h shape is (10,512)
att shape is (10,196,512)
Keras code:
K.expand_dims(att_h, 1).expand_as(att)
Got error:
'Tensor' object has no attribute 'expand_as'
Not sure how to do the same thing in keras.
There isn't any inbuilt function in Keras as such. But you can achieve the same result using : np.reshape.
So you can :
K.expand_dims(att_h,1).reshape(att.shape)

What is a `"Python"` layer in caffe?

Caffe has a layer type "Python".
For instance, this layer type can be used as a loss layer.
On other occasions it is used as an input layer.
What is this layer type?
How can this layer be used?
Prune's and Bharat's answers gives the overall purpose of a "Python" layer: a general purpose layer which is implemented in python rather than c++.
I intend this answer to serve as a tutorial for using "Python" layer.
A Tutorial for "Python" layer
what is a "Python" layer?
Please see the excellent answers of Prune and Bharat.
Pre-requisite
In order to use 'Python" layer you need to compile caffe with flag
WITH_PYTHON_LAYER := 1
set in 'Makefile.config'.
How to implement a "Python" layer?
A "Python" layer should be implemented as a python class derived from caffe.Layer base class. This class must have the following four methods:
import caffe
class my_py_layer(caffe.Layer):
def setup(self, bottom, top):
pass
def reshape(self, bottom, top):
pass
def forward(self, bottom, top):
pass
def backward(self, top, propagate_down, bottom):
pass
What are these methods?
def setup(self, bottom, top): This method is called once when caffe builds the net. This function should check that number of inputs (len(bottom)) and number of outputs (len(top)) is as expected.
You should also allocate internal parameters of the net here (i.e., self.add_blobs()), see this thread for more information.
This method has access to self.param_str - a string passed from the prototxt to the layer. See this thread for more information.
def reshape(self, bottom, top): This method is called whenever caffe reshapes the net. This function should allocate the outputs (each of the top blobs). The outputs' shape is usually related to the bottoms' shape.
def forward(self, bottom, top): Implementing the forward pass from bottom to top.
def backward(self, top, propagate_down, bottom): This method implements the backpropagation, it propagates the gradients from top to bottom. propagate_down is a Boolean vector of len(bottom) indicating to which of the bottoms the gradient should be propagated.
Some more information about bottom and top inputs you can find in this post.
Examples
You can see some examples of simplified python layers here, here and here.
Example of "moving average" output layer can be found here.
Trainable parameters
"Python" layer can have trainable parameters (like "Conv", "InnerProduct", etc.).
You can find more information on adding trainable parameters in this thread and this one. There's also a very simplified example in caffe git.
How to add a "Python" layer in a prototxt?
See Bharat's answer for details.
You need to add the following to your prototxt:
layer {
name: 'rpn-data'
type: 'Python'
bottom: 'rpn_cls_score'
bottom: 'gt_boxes'
bottom: 'im_info'
bottom: 'data'
top: 'rpn_labels'
top: 'rpn_bbox_targets'
top: 'rpn_bbox_inside_weights'
top: 'rpn_bbox_outside_weights'
python_param {
module: 'rpn.anchor_target_layer' # python module name where your implementation is
layer: 'AnchorTargetLayer' # the name of the class implementation
param_str: "'feat_stride': 16" # optional parameters to the layer
}
}
How to add a "Python" layer using pythonic NetSpec interface?
It's very simple:
import caffe
from caffe import layers as L
ns = caffe.NetSpec()
# define layers here...
ns.rpn_labels, ns.rpn_bbox_targets, \
ns.rpn_bbox_inside_weights, ns.rpn_bbox_outside_weights = \
L.Python(ns.rpn_cls_score, ns.gt_boxes, ns.im_info, ns.data,
name='rpn-data',
ntop=4, # tell caffe to expect four output blobs
python_param={'module': 'rpn.anchor_target_layer',
'layer': 'AnchorTargetLayer',
'param_str': '"\'feat_stride\': 16"'})
How to use a net with a "Python" layer?
Invoking python code from caffe is nothing you need to worry about. Caffe uses boost API to call python code from compiled c++.
What do you do need to do?
Make sure the python module implementing your layer is in $PYTHONPATH so that when caffe imports it - it can be found.
For instance, if your module my_python_layer.py is in /path/to/my_python_layer.py then
PYTHONPATH=/path/to:$PYTHONPATH $CAFFE_ROOT/build/tools/caffe train -solver my_solver.prototxt
should work just fine.
How to test my layer?
You should always test your layer before putting it to use.
Testing the forward function is entirely up to you, as each layer has a different functionality.
Testing the backward method is easy, as this method only implements a gradient of forward it can be numerically tested automatically!
Check out test_gradient_for_python_layer testing utility:
import numpy as np
from test_gradient_for_python_layer import test_gradient_for_python_layer
# set the inputs
input_names_and_values = [('in_cont', np.random.randn(3,4)),
('in_binary', np.random.binomial(1, 0.4, (3,1))]
output_names = ['out1', 'out2']
py_module = 'folder.my_layer_module_name'
py_layer = 'my_layer_class_name'
param_str = 'some params'
propagate_down = [True, False]
# call the test
test_gradient_for_python_layer(input_names_and_values, output_names,
py_module, py_layer, param_str,
propagate_down)
# you are done!
Special Notice
It is worth while noting that python code runs on CPU only. Thus, if you plan to have a Python layer in the middle of your net you will see a significant degradation in performance if you plan on using GPU. This happens because caffe needs to copy blobs from GPU to CPU before calling python layer and then copy back to GPU to proceed with the forward/backward pass.
This degradation is far less significant if the python layer is either an input layer or the topmost loss layer.
Update: On Sep 19th, 2017 PR #5904 was merged into master. This PR exposes GPU pointers of blobs via the python interface.
You may access blob._gpu_data_ptr and blob._gpu_diff_ptr directly from python at your own risk.
Very simply, it's a layer in which you provide the implementation code, rather than using one of the pre-defined types -- which are all backed by efficient functions.
If you want to define a custom loss function, go ahead: write it yourself, and create the layer with type Python. If you have non-standard input needs, perhaps some data-specific pre-processing, no problem: write it yourself, and create the layer with type Python.
Python layers are different from C++ layers which need to be compiled, their parameters need to be added to the proto file and finally you need to register the layer in layer_factory. If you write a python layer, you don't need to worry about any of these things. Layer parameters can be defined as a string, which are accessible as a string in python. For example: if you have a parameter in a layer, you can access it using 'self.param_str', if param_str was defined in your prototxt file. Like other layers, you need to define a class with the following functions:
Setup - Initialize your layer using parameters obtained from layer variables
Forward - What would be input and output of a layer
Backward - Given the prediction and gradients from the next layer, compute the gradients for the previous layer
Reshape - Reshape your blob if needed
Prototxt example:
layer {
name: 'rpn-data'
type: 'Python'
bottom: 'rpn_cls_score'
bottom: 'gt_boxes'
bottom: 'im_info'
bottom: 'data'
top: 'rpn_labels'
top: 'rpn_bbox_targets'
top: 'rpn_bbox_inside_weights'
top: 'rpn_bbox_outside_weights'
python_param {
module: 'rpn.anchor_target_layer'
layer: 'AnchorTargetLayer'
param_str: "'feat_stride': 16"
}
}
Here, name of the layer is rpn-data, bottom and top are input and output details of the layer respectively. python_param defines what are the parameters of the Python layer. 'module' specifies what is the file name of your layer. If the file called 'anchor_target_layer.py' is located inside a folder called 'rpn', the parameter would be 'rpn.anchor_target_layer'. The 'layer' parameter is the name of your class, in this case it is 'AnchorTargetLayer'. 'param_str' is a parameter for the layer, which contains a value 16 for the key 'feat_stride'.
Unlike C++/CUDA layers, Python layers do not work in a multi-GPU setting in caffe as of now, so that is a disadvantage of using them.

Categories