Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set weights for Convolution2D?

Tags:

keras

I would like to set the weights of a Convolution2D layer:

conv = Convolution2D(conv_out_size, window_size, embedding_size,
                     border_mode='same',
                     activation='relu',
                     weights=weights,
                     name='conv_{:d}'.format(i))(in_x)

but I am not sure what's expected here. I've tried several thing but most of the time I get

ValueError: You called `set_weights(weights)` on layer "conv_0" with a  weight list of length 1, but the layer was expecting 2 weights. 

Not sure what this exactly means.

like image 679
Stefan Falk Avatar asked Feb 13 '17 19:02

Stefan Falk


People also ask

What is convolution2d layer?

Description. A 2-D convolutional layer applies sliding convolutional filters to 2-D input. The layer convolves the input by moving the filters along the input vertically and horizontally and computing the dot product of the weights and the input, and then adding a bias term.

How does CNN decide number of filters?

More than 0 and less than the number of parameters in each filter. For instance, if you have a 5x5 filter, 1 color channel (so, 5x5x1), then you should have less than 25 filters in that layer. The reason being is that if you have 25 or more filters, you have at least 1 filter per pixel.

How do you define Conv2D?

Keras Conv2D is a 2D Convolution Layer, this layer creates a convolution kernel that is wind with layers input which helps produce a tensor of outputs.

What is Conv1D used for?

Conv1D class. 1D convolution layer (e.g. temporal convolution). This layer creates a convolution kernel that is convolved with the layer input over a single spatial (or temporal) dimension to produce a tensor of outputs. If use_bias is True, a bias vector is created and added to the outputs.


1 Answers

You should pass a numpy array to your convolutional layer through the set_weights method.

Remember that the weights of a convolutional layer are not only the weights of each individual filter, but also the bias. So if you want to set your weights you need to add an extra dimension.

For example, if you want to set a 1x3x3 filter with all weights zero except for the central element, you should make it:

w = np.asarray([ 
    [[[
    [0,0,0],
    [0,2,0],
    [0,0,0]
    ]]]
    ])

And then set it.

For a code you could run:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import numpy as np
np.random.seed(1234)
from keras.layers import Input
from keras.layers.convolutional import Convolution2D
from keras.models import Model
print("Building Model...")
inp = Input(shape=(1,None,None))
output   = Convolution2D(1, 3, 3, border_mode='same', init='normal',bias=False)(inp)
model_network = Model(input=inp, output=output)
print("Weights before change:")
print (model_network.layers[1].get_weights())
w = np.asarray([ 
    [[[
    [0,0,0],
    [0,2,0],
    [0,0,0]
    ]]]
    ])
input_mat = np.asarray([ 
    [[
    [1.,2.,3.],
    [4.,5.,6.],
    [7.,8.,9.]
    ]]
    ])
model_network.layers[1].set_weights(w)
print("Weights after change:")
print(model_network.layers[1].get_weights())
print("Input:")
print(input_mat)
print("Output:")
print(model_network.predict(input_mat))

Try changing the central element in the convolutional fillter (2 in the example).

What the code does:

At first build a model.

inp = Input(shape=(1,None,None))
output   = Convolution2D(1, 3, 3, border_mode='same', init='normal',bias=False)(inp)
model_network = Model(input=inp, output=output)

Print your original weights (initialized with normal distribution, init='normal' )

print (model_network.layers[1].get_weights())

Create your desired weight tensor w and some input input_mat

w = np.asarray([ 
    [[[
    [0,0,0],
    [0,2,0],
    [0,0,0]
    ]]]
    ])
input_mat = np.asarray([ 
    [[
    [1.,2.,3.],
    [4.,5.,6.],
    [7.,8.,9.]
    ]]
    ])

set your weights and print them

model_network.layers[1].set_weights(w)
print("Weights after change:")
print(model_network.layers[1].get_weights())

Finally, use it to generate output with predict (predict automatically compiles your model)

print(model_network.predict(input_mat))

Example Output:

Using Theano backend.
Building Model...
Weights before change:
[array([[[[ 0.02357176, -0.05954878,  0.07163535],
         [-0.01563259, -0.03602944,  0.04435815],
         [ 0.04297942, -0.03182618,  0.00078482]]]], dtype=float32)]
Weights after change:
[array([[[[ 0.,  0.,  0.],
         [ 0.,  2.,  0.],
         [ 0.,  0.,  0.]]]], dtype=float32)]
Input:
[[[[ 1.  2.  3.]
   [ 4.  5.  6.]
   [ 7.  8.  9.]]]]
Output:
[[[[  2.   4.   6.]
   [  8.  10.  12.]
   [ 14.  16.  18.]]]]
like image 84
maz Avatar answered Nov 18 '22 14:11

maz