Search code examples
pythonpickletheano

Saving and Loading theano variables


I am using a theano variable to define a function. Then I save the variable. When I load the variable theano does not recognize it as being the same variable used before.

This code:

import theano
import theano.tensor as T
from theano.misc.pkl_utils import dump,load
x = T.scalar('x')
y = x**2

f = file('temp','wb')
dump(x,f)
f.close()
del x

f = file('temp','rb')
x=load(f)
f.close()

F=theano.function([x],y)
print F(2)

Generates the error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 699, in runfile
    execfile(filename, namespace)
  File "C:\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 74, in execfile
    exec(compile(scripttext, filename, 'exec'), glob, loc)
  File "C:/Users/jpiabrantes/Desktop/untitled6.py", line 28, in <module>
    F=theano.function([x],y)
  File "C:\Anaconda2\lib\site-packages\theano\compile\function.py", line 320, in function
    output_keys=output_keys)
  File "C:\Anaconda2\lib\site-packages\theano\compile\pfunc.py", line 479, in pfunc
    output_keys=output_keys)
  File "C:\Anaconda2\lib\site-packages\theano\compile\function_module.py", line 1776, in orig_function
    output_keys=output_keys).create(
  File "C:\Anaconda2\lib\site-packages\theano\compile\function_module.py", line 1415, in __init__
    self._check_unused_inputs(inputs, outputs, on_unused_input)
  File "C:\Anaconda2\lib\site-packages\theano\compile\function_module.py", line 1553, in _check_unused_inputs
    i.variable, err_msg))
theano.compile.function_module.UnusedInputError: theano.function was asked to create a function computing outputs given certain inputs, but the provided input variable at index 0 is not part of the computational graph needed to compute the outputs: x.
To make this error into a warning, you can pass the parameter on_unused_input='warn' to theano.function. To disable it completely, use on_unused_input='ignore'.

I also tried to Save/Load using cPickle with the same results.


Solution

  • When you load x from pickle, you get a copy of x, not the original x. Pickle is a serialization protocol. For its nature, the identity of objects cannot be guaranteed to be the same.

    You must also consider that pickle is meant to be used to dump/load data across different Python processes, not within the same process (I do not see any benefit in using pickle in your code).

    What you should do is dumping and loading x together with y:

    dump((x, y), f)
    x, y = load(f)
    

    Pickle can guarantee that the dumped x is "linked" to the dumped y (and, consequently, the loaded x is "linked" to the loaded y).