Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
849 views
in Technique[技术] by (71.8m points)

keras - How to set weights for Convolution2D?

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.]]]]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...