-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Column vector breaks observed
#4652
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 |
(The default value for integers leads to a Cast operation that destroys broadcast information.)
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. |
The new test case triggers the issue independent of the default intX.
The new test case triggers the issue independent of the default intX.
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. |
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: