-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Implied dimensions of RVs are not broadcasted by dims or observed #5993
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
Comments
Looks like with pm.Model(coords=coords) as model:
mu = np.zeros((10, 1))
# mu = np.zeros((10, 7)) # this works
x = pm.Normal("x", mu=mu, dims=("dim1", "dim2"))
samples = pm.sample_prior_predictive() fails with ValueError: conflicting sizes for dimension 'dim2': length 1 on the data but length 7 on coordinate 'dim2' TracebackTraceback (most recent call last):
File "/Users/benedikt/code/pymc/nb_examples/issue_5993.py", line 15, in <module>
samples = pm.sample_prior_predictive()
File "/Users/benedikt/code/pymc/pymc/sampling.py", line 2267, in sample_prior_predictive
return pm.to_inference_data(prior=prior, **ikwargs)
File "/Users/benedikt/code/pymc/pymc/backends/arviz.py", line 591, in to_inference_data
).to_inference_data()
File "/Users/benedikt/code/pymc/pymc/backends/arviz.py", line 522, in to_inference_data
**self.priors_to_xarray(),
File "/Users/benedikt/code/pymc/pymc/backends/arviz.py", line 471, in priors_to_xarray
else dict_to_dataset(
File "/Users/benedikt/miniforge3/envs/pymc-dev/lib/python3.10/site-packages/arviz/data/base.py", line 307, in dict_to_dataset
data_vars[key] = numpy_to_data_array(
File "/Users/benedikt/miniforge3/envs/pymc-dev/lib/python3.10/site-packages/arviz/data/base.py", line 254, in numpy_to_data_array
return xr.DataArray(ary, coords=coords, dims=dims)
File "/Users/benedikt/miniforge3/envs/pymc-dev/lib/python3.10/site-packages/xarray/core/dataarray.py", line 402, in __init__
coords, dims = _infer_coords_and_dims(data.shape, coords, dims)
File "/Users/benedikt/miniforge3/envs/pymc-dev/lib/python3.10/site-packages/xarray/core/dataarray.py", line 152, in _infer_coords_and_dims
raise ValueError(
ValueError: conflicting sizes for dimension 'dim2': length 1 on the data but length 7 on coordinate 'dim2' I can also create a random variable with a shape that's inconsistent with the shape of the x = pm.Normal("x", dims=("dim1", "dim2"), shape=(2, 2)) How about resolving this by using the following logic if
Perhaps this could be implemented in |
@bherwerth I like your idea for the fix. |
I had a closer look at the code and I see that there already is a logic in place for resizing RVs based on pymc/pymc/distributions/distribution.py Lines 263 to 269 in c8db06b
However, it seems pymc/pymc/distributions/shape_utils.py Line 525 in c8db06b
To address this issue, we would need a resize also when
When reading the code in pymc/pymc/distributions/distribution.py Line 356 in c8db06b
|
This is not an easy problem. The test case should also cover the case where the with pm.Model() as pmodel:
dat = pm.MutableData(
"dat",
np.ones((10, 7)),
dims=("dim1", "dim2")
)
dlength_1 = pmodel.dim_lengths["dim1"]
dlength_2 = pmodel.dim_lengths["dim2"]
mu = np.zeros((10, 1))
x = pm.Normal("y", mu=mu, dims=("dim1", "dim2"))
y = pm.Normal("x", mu=mu, shape=(dlength_1, dlength_2))
print(x.eval().shape)
print(y.eval().shape) |
This indeed looks like a more involved task. The current resize logic extends dimensions to the left, and I don't see a quick way to adapt it to cover broadcasting from Would you agree in principle that it would make sense to determine |
At this point the main reason for the additional resize is the There might be additional reasons for the resize related to |
I think it's reasonable to take the shape from dims (if shape isn't provided). Happy to remove ellipsis as well. I don't see why observed would conflict with any of this. |
I think something similar happens with observed as brought up (but a bit unrelated to the original issue in #5992) |
Thanks for explaining and clarifying the reason for the additional resize.
I understood @michaelosthege's suggestion to drop the ellipsis to apply if we wanted to condense the resize steps into a single one. I raised the question of why there are two resize steps when reading the code in Coming back to the original suggestion of inferring if dims is not None and "shape" not in kwargs:
dims = convert_dims(dims)
if len(dims) > 0 and dims[-1] != Ellipsis and all([d in model.dim_lengths for d in dims]):
kwargs["shape"] = tuple(model.dim_lengths[d] for d in dims) That is, we would only infer
If you agree with this proposal, I can add a test case and create a PR. |
Just to give the big picture, the problem is that we wrongly assumed that dims cannot provide new shape information for dimensions that are already implied by the parameters. So we simply created an RV and then only looked at dims for dimensions that were missing on the left for resizing. However, we need to resize all dimensions because dims may broadcast the dimensions implied by the parameters as well. This is equally true to resize from observed I think. |
this ☝️ The code snippet @bherwerth posted looks fine on the first glance, but to systematically fix this we also have to consider the case where there's a mix of already-known and not-yet-known And ultimately we have to update our decision of what is the intended behavior:
One solution to clean up this behavior-mess could be to replace IMO we should thoroughly think this through before touching it. As a general advice to everybody: The best way to avoid shape issues (like the one this issue originally was about) is to not rely on "smart" broadcasting, but do all broadcasts/resizes intentionally. |
About precedence: size/shape > dims > observed Because they go from more flexible to more inflexible. Size/shape can be an arbitrary symbolic expression, dims and observed are usually static but can be resized, and observed is a bit more implicit and restricted to likelihoods. |
The dims argument is not respected when a random variable is created with parameters that broadcast to the desired output dimensions:
The text was updated successfully, but these errors were encountered: