TAGS :Viewed: 5 - Published at: a few seconds ago

[ theano T.switch(): if tensor is empty strange behaviour ]

i want to check if vector A is empty: return [0] else: return A

import theano
import theano.tensor as T

A = T.ivector()

out = T.switch( T.eq(A.size, 0), [0], A )

f = theano.function([A], out)

print f([1])
print f([])

this prints:

[ 1 ]
[]

the conditional statement by itself works, it only returns 1 if A is empty.

Answer 1


This is because theano.tensor.switch operates differently to theano.ifelse.ifelse.

theano.tensor.switch operates element-wise. The three arguments need to have the same shape, or be broadcastable to the same shape. T.eq(A.size, 0) will always be a scalar and the true value, [0] is a vector with a single element so both will be broadcast to the shape of A. The case of A == [] is undoubtedly odd and I don't know if it is by design; Theano appears to be "broadcasting" the scalar and single entry vector to the empty vector.

The solution is to switch to theano.ifelse.ifelse:

A = tt.ivector()
out = theano.ifelse.ifelse(
    tt.eq(A.size, 0), tt.unbroadcast(tt.zeros((1,), dtype=A.dtype), 0), A)
f = theano.function([A], out)
print f([])
print f([1])
print f([1, 2])

As desired, this prints

[0]
[1]
[1 2]

Note that the two possible ifelse output values (the value if the comparison is true and the value if the comparison is false) must have identical types, hence the convoluted method for constructing a zeros vector with a single entry.