Search code examples
pythonneural-networktheano

Theano: this shared variable already has an update expression


Is there any way to define more than one update on the same share variable when calling theano.function()?

Example:

updates = []
updates.append([(self.W, self.W - 1)])
updates.append([(self.W, self.W - 2)])
train = th.function(inputs=[index], outputs=[cost], updates=updates)

will throw the error this shared variable already has an update expression:

ignore_bug_before` to at least "0.7".
  tolerate_inplace_aliasing=tolerate_inplace_aliasing)
Traceback (most recent call last):
  File "ae.py", line 340, in <module>
    main()
  File "ae.py", line 315, in main
    ae.train(n_epochs=n_epochs, mini_batch_size=100, learning_rate=0.002, train_data= train_sentence_embeddings, test_data= test_sentence_embeddings)
  File "ae.py", line 97, in train
    givens={x:self.X[index:index+mini_batch_size,:]})
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function.py", line 266, in function
    profile=profile)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 489, in pfunc
    no_default_updates=no_default_updates)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 198, in rebuild_collect_shared
    (store_into, update_d[store_into]))
ValueError: ('this shared variable already has an update expression', (W, DimShuffle{1,0}.0))

I was interested in doing so as I have weight matrix that I need to update in such a way that different parts of it has a different update (which I do it using set_subtensor).


Solution

  • As explained in this thread on the theano-users mailing list...

    You need to chain the set_subtensors so that you only end up with a single entry for the whole tensor in the updates list.

    For example (code not like original because original does not actually include set_subtensor anywhere):

    new_w = self.W
    new_W = theano.tensor.set_subtensor(new_W[0], -1)
    new_W = theano.tensor.set_subtensor(new_W[1], -2)
    updates = [(self.W, new_W)]
    train = theano.function(inputs=[index], outputs=[cost], updates=updates)