Using theano scan with pymc3

Hi!
I have a external function i need to run in a loop to accumulate some values.
this function i need to loop through has a number of pymc3 variables defined in it.
So it does something like

def func(pymc3-rvs-args):
    do some deterministic operations on these variables

As of now i am doing this in a standard python loop, and the theano graph looks like a monster. I was therefore planning to use a theano.scan function instead. I am trying something along the lines of:

with pm.Model() as model:
    def fn(x,y,n): # n is a random variable, x a vector of numbers
            return x*n

        n = pm.Normal('n').get_test_val
        s_x = T.ivector()
        v_sum = theano.shared(np.int32(0))
       

        s_y, update_sum = theano.scan(
            fn,
            sequences = [s_x],
            outputs_info = [v_sum],
            non_sequences=n)

        res_ = s_y[-1]
        fn = theano.function([s_x,n], res_, updates=update_sum)

I cant seem to make this work.
Am I on the right track here?

you dont need theano.function([s_x,n], res_, updates=update_sum) - just get res_ (it’s already a tensor) and plug that into downstream compuations

1 Like

hi @junpenglao, thank you once more for getting back to me!!
I have done some modifications but i am still not able to include my “scan-function” in the sampling process.

I have written a scan-function, where n should be a normally distributed pymc3 variable:

def fn(x,y,n): 
         return x*n 

def scan(x,n):
        v_sum = T.as_tensor_variable(np.float64())
        s_y, update_sum = theano.scan(
            fn=fn,
            sequences = [x],
            outputs_info = [v_sum],
            non_sequences=n
        )
        return s_y

I then defined the pymc3 model calling the scan function as:

with pm.Model() as model:
    x = T.ivector()
    x_ =  [1,1,1]
    x.tag.test_value  = x_

    n = pm.Normal('n')
    s = scan(x,n)
    s_det = pm.Deterministic('s',s)
    print(s) # =0
    trace = pm.sample()

in the hope that my s would have shape (len(x),n_samples), in other words that s would be included in the sampling process.

If i include comment out s_det, i get just a single value, and if i run with s_det, i get an error of the following type. I have not been able to find a solution to this … hope you are able to help me.

Input 0 of the graph (indices start from 0), used to compute Subtensor{int64::}(<TensorType(int32, vector)>, Constant{0}), was not provided and not given a value. Use the Theano flag exception_verbosity='high', for more information on this error.

The input missing is referring to x. I would rewrite your model into something like below:

# x = T.ivector()
# x_ =  [1,1,1]
# x.tag.test_value  = x_
x = np.asarray([1,1,1])
with pm.Model() as model:
    n = pm.Normal('n')
    s = scan(x,n)
    s_det = pm.Deterministic('s',s)
    trace = pm.sample()
1 Like