-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Column vector breaks observed
#4652
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
I'm unable to reproduce this error on 45cb4eb and Aesara 2.0.7. |
FWIW I just reproduced it again with 45cb4eb and Aesara 2.0.6 and 2.0.7. |
I've added your example code (verbatim) as a test in #4654, where it appears to have passed (i.e. not thrown an exception). Perhaps this is somehow related to Windows; are both of the machines you tried Windows machines? |
It does appear to be a Windows-related issue: see here. |
yes, both my machines are on Windows. |
Wrapping |
With the following test case: import aesara.printing
with pm.Model() as model:
rv = pm.Normal("x1", mu=0, sd=1, observed=np.random.normal(size=(3, 4)))
print("\n\nobserved = (3, 4) ndarray\n")
aesara.printing.debugprint([rv])
model.logp()
yobs = np.random.normal(size=(3, 1))
rv = pm.Normal("x2", mu=0, sd=1, observed=at.as_tensor_variable(yobs))
print("\n\nobserved = as_tensor_variable( (3, 1) ndarray )\n")
aesara.printing.debugprint([rv])
model.logp()
rv = pm.Normal("x3", mu=0, sd=1, observed=pm.aesaraf.pandas_to_array(yobs))
print("\n\nobserved = pandas_to_array( (3, 1) ndarray )\n")
aesara.printing.debugprint([rv])
model.logp() I get this output:
So (at least on my Windows machine) In #4667 there were also test failures with the error in the Linux containers of the CI pipeline: https://github.com/pymc-devs/pymc3/pull/4667/checks?check_run_id=2431198145#step:7:3718 So the problem can occur on Linux if the graph is produced in a certain way. |
Ill run this within the next ~8 hours when im back at my my ubuntu desktop if no one beats me to it |
Here's my versions and what I get
Aesara/PyMC Output
|
Thanks @canyon289 ,
|
This problem is caused by a difference in the default Apparently Windows defaults to This result can be reproduced in Linux as follows: import aesara.tensor as at
import aesara.tensor.random.basic as ar
size_at = at.cast([3.0, 1.0], "int64")
# or
# size_at = at.cast([at.scalar(), 1.0], "int64")
norm_at = ar.normal(0, 1, size=size_at) >>> norm_at.type
TensorType(float64, matrix)
Regardless, computing the exact broadcast pattern is nice, but it's not necessary. To fix this issue, we simply need to add a step in PyMC3 that explicitly changes the broadcast pattern of the observations so that it matches its corresponding |
I think this issue might actually be the same as pymc-devs/pytensor#390, because it only arises in situations where a Instead of a workaround that "patches" the broadcast pattern, I think we can fix this issue at the root. See my other comment. |
See my comment above; it explicitly states the connection between the two.
Likewise, my comment above mentions that determining the broadcastable dimensions exactly is not necessary for a robust solution to this problem. This is especially important given that it may not be reasonable to compute the exact broadcastable dimensions in every case. In other words, fixing pymc-devs/pytensor#390 is the actual "patch"—no matter how it's done. Instead, if we want to prevent type mismatches like these in general, we need to make sure that the |
Closed via #4700. |
Uh oh!
There was an error while loading. Please reload this page.
While working on #4625 I ran into a failure that is demoed by the following example:
Essentially passing a column vector breaks the model, whereas a matrix is fine.
Traceback
TypeError Traceback (most recent call last)
in
----> 1 test_observed_with_column_vector()
in test_observed_with_column_vector()
4 model.logp()
5 pm.Normal("x2", mu=0, sd=1, observed=np.random.normal(size=(3, 1)))
----> 6 model.logp()
e:\source\repos\pymc3\pymc3\model.py in logp(self)
264 def logp(self):
265 """Compiled log probability density function"""
--> 266 return self.model.fn(self.logpt)
267
268 @Property
e:\source\repos\pymc3\pymc3\model.py in logpt(self)
712 with self:
713 factors = [logpt_sum(var, self.rvs_to_values.get(var, None)) for var in self.free_RVs]
--> 714 factors += [logpt_sum(obs, obs.tag.observations) for obs in self.observed_RVs]
715
716 # Convert random variables into their log-likelihood inputs and
e:\source\repos\pymc3\pymc3\model.py in (.0)
712 with self:
713 factors = [logpt_sum(var, self.rvs_to_values.get(var, None)) for var in self.free_RVs]
--> 714 factors += [logpt_sum(obs, obs.tag.observations) for obs in self.observed_RVs]
715
716 # Convert random variables into their log-likelihood inputs and
e:\source\repos\pymc3\pymc3\distributions\logp.py in logpt_sum(*args, **kwargs)
366 if only the sum of the logp values is needed.
367 """
--> 368 return logpt(*args, sum=True, **kwargs)
e:\source\repos\pymc3\pymc3\distributions\logp.py in logpt(var, rv_values, jacobian, scaling, transformed, cdf, sum, **kwargs)
216 replacements.update({rv_var: rv_value, rv_value_var: rv_value})
217
--> 218 (logp_var,), _ = rvs_to_value_vars(
219 (logp_var,),
220 apply_transforms=transformed and not cdf,
e:\source\repos\pymc3\pymc3\aesaraf.py in rvs_to_value_vars(graphs, apply_transforms, initial_replacements, **kwargs)
352 return [trans_rv_value]
353
--> 354 return replace_rvs_in_graphs(graphs, transform_replacements, initial_replacements, **kwargs)
355
356
e:\source\repos\pymc3\pymc3\aesaraf.py in replace_rvs_in_graphs(graphs, replacement_fn, initial_replacements, **kwargs)
300 )
301
--> 302 fg.replace_all(replacements.items(), import_missing=True)
303
304 graphs = list(fg.outputs)
~\miniconda3\envs\pm3-dev\lib\site-packages\aesara\graph\fg.py in replace_all(self, pairs, **kwargs)
555 """Replace variables in the
FunctionGraph
according to(var, new_var)
pairs in a list."""556 for var, new_var in pairs:
--> 557 self.replace(var, new_var, **kwargs)
558
559 def attach_feature(self, feature: Feature) -> NoReturn:
~\miniconda3\envs\pm3-dev\lib\site-packages\aesara\graph\fg.py in replace(self, var, new_var, reason, verbose, import_missing)
513 print(reason, var, new_var)
514
--> 515 new_var = var.type.filter_variable(new_var, allow_convert=True)
516
517 if var not in self.variables:
~\miniconda3\envs\pm3-dev\lib\site-packages\aesara\tensor\type.py in filter_variable(self, other, allow_convert)
256 return other2
257
--> 258 raise TypeError(
259 f"Cannot convert Type {other.type} "
260 f"(of Variable {other}) into Type {self}. "
TypeError: Cannot convert Type TensorType(float64, matrix) (of Variable Rebroadcast{?,0}.0) into Type TensorType(float64, col). You can try to manually convert Rebroadcast{?,0}.0 into a TensorType(float64, col).
Versions
v3.11.1
v3.11.2
master
(d7172c0)v4
(45cb4eb)The text was updated successfully, but these errors were encountered: