Can not update a subset of shared tensor variable

2019-05-22 01:13发布

问题:

I have the following code:

import theano.tensor as T

Words = theano.shared(value = U, name = 'Words')
zero_vec_tensor = T.vector()
zero_vec = np.zeros(img_w, dtype = theano.config.floatX)
set_zero = theano.function([zero_vec_tensor], updates=[(Words, T.set_subtensor(Words[0,:], zero_vec_tensor))])

Which is compiling fine (where U is a numpy array of dtype float64).

To prevent future type error I want to cast my shared tensor Words into float32 (or theano.config.floatX which is equivalent as I have set floatX to float32 in the config file).

I so add Words = T.cast(Words, dtype = theano.config.floatX) and then I get the following error:

TypeError: ('update target must be a SharedVariable', Elemwise{Cast{float32}}.0).

I do not understand why. According to this question, using set_subtensor should allow me to update a subset of the shared variable.

How can I cast my shared tensor while being able to update it?

回答1:

The problem is that you are trying to update a symbolic variable, not a shared variable.

U = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64)
Words = theano.shared(value=U, name='Words')
zero_vec_tensor = T.vector()
set_zero = theano.function([zero_vec_tensor], updates=[(Words, T.set_subtensor(Words[0, :], zero_vec_tensor))])

works fine because the thing you are updating, Words is a shared variable.

U = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64)
Words = theano.shared(value=U, name='Words')
Words = T.cast(Words, dtype = theano.config.floatX)
zero_vec_tensor = T.vector()
set_zero = theano.function([zero_vec_tensor], updates=[(Words, T.set_subtensor(Words[0, :], zero_vec_tensor))])

does not work because now Words is no longer a shared variable, it is a symbolic variable that, when executed, will compute a cast the values in the shared variable to theano.config.floatX.

The dtype of a shared variable is determined by the value assigned to it. So you probably just need to change the type of U:

U = np.array([[1, 2, 3], [4, 5, 6]], dtype=theano.config.floatX)

Or cast it using numpy instead of symbolically:

U = np.dtype(theano.config.floatX).type(U)