Hmmm…
How is pytensor.gradient.jacobian supposed to be used? Can the variance in the w.r.t be a slice of a tensor? Indeed, perhaps I’m just slicing wrong?
After building my model (see gist for Notebook 994 in my above post), I’m trying to build out the scan function, with an inner function that - based on your guys recommendations above - I think (?) should operate on a slice of the (n, 2) matrices for f_inv_x and x.
Here f_inv_x is my mdl.y_c, and x is mdl.y. They both have shape (10, 2) for 10 observations in the model input data, so I honk the appropriate slices would be e.g.
i = 0
mdl.y_c[i] # shape (2, )
mdl.y[i] # shape (2, )
If I try this, I get a disconnected input error, so I suspect I’m slicing wrong, but dont know how to slice properly in that case
n = mdl.y_c.shape[0]
idx = pt.arange(n, dtype="int32")
i = 0
print(f'mdl.y_c[{i}]:\n', mdl.y_c[i, :].eval())
print(f'mdl.y[{i}]:\n', mdl.y[i, :].eval())
j = tg.jacobian(expression=mdl.y_c[i, :], wrt=mdl.y[i, :])
j.eval()
yields
mdl.y_c[0]:
[1.63535418 1.37195447]
mdl.y[0]:
[0.896752 7.10080497]
/Users/jon/miniforge/envs/oreum_lab/lib/python3.10/site-packages/pytensor/tensor/rewriting/elemwise.py:691: UserWarning: Optimization Warning: The Op erfcinv does not provide a C implementation. As well as being potentially slow, this also disables loop fusion.
warn(
---------------------------------------------------------------------------
DisconnectedInputError Traceback (most recent call last)
/Users/jon/workspace/oreum/oreum_lab/notebooks/994_mre_copula_with_jcd.ipynb Cell 12 line 8
5 print(f'mdl.y_c[{i}]:\n', mdl.y_c[i, :].eval())
6 print(f'mdl.y[{i}]:\n', mdl.y[i, :].eval())
----> 8 j = tg.jacobian(expression=mdl.y_c[i, :], wrt=mdl.y[i, :])
9 j.eval()
Alternatively, if I feed the w.r.t with the full non-sliced mdl.y, that seems to work albeit the returned tensor of course contains unnecessary dimensions
n = mdl.y_c.shape[0]
idx = pt.arange(n, dtype="int32")
i = 0
print(f'mdl.y_c[{i}]:\n', mdl.y_c[i, :].eval())
print(mdl.y_c[i, :].eval().shape)
print(f'mdl.y:\n', mdl.y.eval())
print(mdl.y.eval().shape)
j = tg.jacobian(expression=mdl.y_c[i, :], wrt=mdl.y)
jj = j.eval()
print(jj.shape)
print(jj[:, 0, :])
yields:
mdl.y_c[0]:
[1.63535418 1.37195447]
(2,)
mdl.y:
[[ 0.896752 7.10080497]
[ 0.99277233 20.27468766]
[ 2.50819806 0.7689727 ]
[ 1.09347164 7.5479452 ]
[ 1.07582886 5.55281411]
[ 0.91014133 21.7633982 ]
[ 1.41469134 11.23582336]
[ 0.85416985 8.77394179]
[ 0.88115079 7.74155373]
[ 0.79885203 16.73635283]]
(10, 2)
(2, 10, 2)
array([[1.00953437, 0. ],
[0. , 0.11660356]])
This final 2x2 matrix actually looks like what I want, it just looks like I have to dig into the (2, 10, 2) matrix to get it
Any thoughts on side stepping the disconnected input error?