Search code examples
pythontheano

change theano shared variable do not effect the value of internal


i have a little problem with shared variable. codes as below:

np_array = numpy.ones(2, dtype='float32')
s_true = theano.shared(np_array,borrow=True)
np_array+=1.
print s_true.get_value()#[ 2.  2.] change np_array will change s_true

i can understand the above. but reverse can't work,as below:

np_array = numpy.ones(2, dtype='float32')
s_true = theano.shared(np_array,borrow=True)
s_true+=1.0
print s_true.eval()   #[ 2.  2.]
np_array  #array([ 1.,  1.], dtype=float32) **change s_true will not change np_array**

however,the below work:

s_true = theano.shared(np_array,borrow=True)
v_true=s_true.get_value(borrow=True,return_internal_type=True)
v_true+=1.0
print s_true.get_value() #[ 2.  2.] **change v_true will change s_true**  
np_array #array([ 2.,  2.], dtype=float32) **change v_true will change np_array**

i cannot understand the logic of shared variable, hope to get help


Solution

  • Answered on theano-users mailing list.

    A shared variable wraps a piece of memory but there is no guarantee that only the piece of memory used to initialize the shared variable will be used throughout the computation.

    borrow=True should be thought of as a hint rather than an explicit instruction to be followed in all cases.

    In the first example the shared variable wraps the initial numpy array because borrow=True. Changing the numpy array thus changes the contents of the shared variable. But this should not be relied upon and is poor practice for Theano programming.

    In the second example s_true+=1.0 is a symbolic expression. It does not actually change any state in memory other than making s_true point at an object representing the expression rather than the shared variable. print s_true.eval() shows the result of executing the symbolic computation but that does not change the shared variable. The only "approved" ways to change the contents of a shared variable are via shared_var.set_value(...) or via the updates=... mechanism of theano.function(...). Changing the backing store, as in the first example, will sometimes work but not always and should generally be avoided.

    The third example is just a more roundabout way of doing the first example so is again bad practice.

    This page in the documentation may help.