Optional parameter to theano function

368 views Asked by At

I have a function f in theano which takes two parameters, one of them optional. When I call the function with the optional parameter being None the check inside f fails. This script reproduces the error:

import theano
import theano.tensor as T
import numpy as np

# function setup
def f(b, c=None):
    if c is not None:
        return (c*b).mean()
    else:
        return b.mean()

y = T.vector()
c = T.vector()
ins = [y,c]
tfn = theano.function(ins, f(y,c), allow_input_downcast=True, mode=None)

# eval function
first = np.array([1])
second = np.array([2])
second = None
res = tfn(first, second)
print res

Fails with the error message

ValueError: expected an ndarray, not None
Apply node that caused the error: Elemwise{mul,no_inplace}(<TensorType(float64, vector)>, <TensorType(float64, vector)>)
Inputs types: [TensorType(float64, vector), TensorType(float64, vector)]
Inputs shapes: ['No shapes', (1,)]
Inputs strides: ['No strides', (8,)]
Inputs values: [None, array([ 1.])]

Backtrace when the node is created:
  File "test_theano.py", line 14, in f
    return (c*b).mean()

It makes sense that c has no input shapes nor input strides. But I wonder why the if check inside f does not seem to work.

How can I make the check inside f work such that the optional parameter c is handled correctly?

2

There are 2 answers

1
Daniel Renshaw On BEST ANSWER

Theano does not support optional parameters. By specifying the function's input parameters as ins=[y,c] you are telling Theano that the function has two 1-dimensional (vector) parameters. As far as Theano is concerned, both are mandatory. When you try to pass None in for c Theano checks that the types of the values you pass in match the types declared when you compiled the function (i.e. two vectors) but clearly None is not a vector so this exception is raised.

A solution is to compile two Theano functions, one that accepts just one parameter and the other that accepts both. You could even use your existing Python function f for both.

0
nouiz On

I'm going to try a more complete response.

1) the condition "c is not None" is run only once when you build the graph. As c is a symbolic variable, the else path will always be executed. If you want to execution condition at run time see this documentation page:

http://deeplearning.net/software/theano/tutorial/conditions.html

2) Theano have a special Type for None. But I do not recommand that you use it. It is not useful most of the time and it is not documented. So don't use it until you get more familiar with Theano.

3) The other answer that tell to use 2 functions will work.

4) In that simple case, you could pass a vector of the right size with only one instead of None. That would also work, but be slower.