brendanhasz / probflow

A Python package for building Bayesian models with TensorFlow or PyTorch
http://probflow.readthedocs.io
MIT License
171 stars 17 forks source link

predictive_interval gives an error #15

Closed gerardcelio closed 4 years ago

gerardcelio commented 4 years ago

I am following the tutorial on DenseRegression (using the same versions of packages) but using my own data, when I try to do model.predictive_interval(x_test, ci=0.95), it outputs the following error:


InvalidArgumentError Traceback (most recent call last)

in ----> 1 model.predictive_interval(xx_test, ci=0.95) ~/proc_optim/opt_env/lib/python3.6/site-packages/probflow/models.py in predictive_interval(self, x, ci, side, n) 956 for samples in ``x``. Doesn't return this if ``side='lower'``. 957 """ --> 958 return self._intervals(self.predictive_sample, x, side, ci=ci, n=n) 959 960 ~/proc_optim/opt_env/lib/python3.6/site-packages/probflow/models.py in _intervals(self, fn, x, side, ci, n) 903 def _intervals(self, fn, x, side, ci=0.95, n=1000): 904 """Compute intervals on some type of sample""" --> 905 samples = fn(x, n=n) 906 if side == 'lower': 907 return np.percentile(samples, 100*(1.0-ci), axis=0) ~/proc_optim/opt_env/lib/python3.6/site-packages/probflow/models.py in predictive_sample(self, x, n) 346 """ 347 with Sampling(n=n, flipout=False): --> 348 return self._sample(x, lambda x: x.sample(), ed=0) 349 350 ~/proc_optim/opt_env/lib/python3.6/site-packages/probflow/models.py in _sample(self, x, func, ed, axis) 320 samples += [func(self())] 321 else: --> 322 samples += [func(self(O.expand_dims(x_data, ed)))] 323 return np.concatenate(to_numpy(samples), axis=axis) 324 ~/proc_optim/opt_env/lib/python3.6/site-packages/probflow/applications.py in __call__(self, x) 248 return Normal(m_preds, s_preds) 249 else: --> 250 return Normal(self.network(x), self.std()) 251 252 ~/proc_optim/opt_env/lib/python3.6/site-packages/probflow/applications.py in __call__(self, x) 194 x = to_tensor(x) 195 for i in range(len(self.layers)): --> 196 x = self.layers[i](x) 197 x = self.activations[i](x) 198 return x ~/proc_optim/opt_env/lib/python3.6/site-packages/probflow/modules.py in __call__(self, x) 199 # Without Flipout 200 else: --> 201 return x @ self.weights() + self.bias() 202 203 ~/proc_optim/opt_env/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py in binary_op_wrapper(x, y) ~/proc_optim/opt_env/lib/python3.6/site-packages/tensorflow/python/util/dispatch.py in wrapper(*args, **kwargs) ~/proc_optim/opt_env/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py in matmul(a, b, transpose_a, transpose_b, adjoint_a, adjoint_b, a_is_sparse, b_is_sparse, name) ~/proc_optim/opt_env/lib/python3.6/site-packages/tensorflow/python/ops/gen_math_ops.py in batch_mat_mul_v2(x, y, adj_x, adj_y, name) ~/proc_optim/opt_env/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in raise_from_not_ok_status(e, name) ~/proc_optim/opt_env/lib/python3.6/site-packages/six.py in raise_from(value, from_value) InvalidArgumentError: cannot compute BatchMatMulV2 as input #1(zero-based) was expected to be a double tensor but is a float tensor [Op:BatchMatMulV2]
brendanhasz commented 4 years ago

Hi! Sorry for the late reply. From that error message I'd guess that your test data (xx_test) has a float64 datatype, but probflow's default datatype is float32 (and so all the weight and bias parameters were float32 tensors), so TensorFlow threw a hissy fit when it tried to do an operation with two tensors of different datatypes.

Assuming your xx_test is a numpy array, this should work:

lb, ub = model.predictive_interval(xx_test.astype('float32'), ci=0.95)

Alternatively you could change the default datatype used by probflow to be float64 (though I figure variational inference is already super noisy as it is, so do we really need all that extra precision? Thus the choice of a default datatype of float32. I.e. I'd gently discourange this 2nd option both because it's more complicated and because it's probably wicked overkill haha):

# x_train, y_train, and x_test are all float64

# Set the default datatype used by probflow
# note that this must be done before initializing and fitting  the model
pf.set_datatype(tf.dtypes.float64)

model = DenseRegression([1, 32, 32, 1])
model.fit(x_train, y_train)
lb, ub = model.predictive_interval(x_test, ci=0.95)

And sorry, I definitely should have included a discussion of datatypes and how to set the default datatype in the user guide, but I hadn't gotten around to it 😬 I've added it here!

Hope that helps!

gerardcelio commented 4 years ago

Works like a charm, thanks!