ValueError: Can't apply Jacobian with a quadratic objective
mr-mikmik opened this issue · 2 comments
Hi all,
I am trying to get gradients on a QP solution, but I am having the following error: ValueError: Can't apply Jacobian with a quadratic objective.
This is the trace:
File python3.8/site-packages/cvxpylayers/torch/cvxpylayer.py:286, in _CvxpyLayerFn.<locals>._CvxpyLayerFnFn.backward(ctx, *dvars)
284 grad = [[] for _ in range(len(param_order))]
285 for i in range(ctx.batch_size):
--> 286 del_param_dict = compiler.apply_param_jac(
287 dcs[i], -dAs[i], dbs[i])
288 for j, p in enumerate(param_order):
289 grad[j] += [to_torch(del_param_dict[p.id],
290 ctx.dtype, ctx.device).unsqueeze(0)]
File python3.8/site-packages/cvxpy/reductions/dcp2cone/cone_matrix_stuffing.py:222, in ParamConeProg.apply_param_jac(self, delc, delA, delb, active_params)
214 """Multiplies by Jacobian of parameter mapping.
215
216 Assumes delA is sparse.
(...)
219 A dictionary param.id -> dparam
220 """
221 if self.P is not None:
--> 222 raise ValueError("Can't apply Jacobian with a quadratic objective.")
224 if active_params is None:
225 active_params = {p.id for p in self.parameters}
using cvxpy 1.4.1
and cvxpylayers 0.0.1
I need help understanding why it does not work with quadratic objectives. Any insights will be much appreciated.
Thank you.
Just for reference, this is the form of my program:
where cp.Variable
, cp.Parameter
.
For context, the goal is to optimize via the backpropagated gradients a set of parameters that produce
Can confirm this issue persists with the latest stable of cvxpy & cvxpylayers. The relevant change commited by @SteveDiamond made it into v1.3.0 and above.
I tried 1.2.5 and it seemed to have worked in my case, namely
>>> import tensorflow as tf
>>> import cvxpy as cp
>>> from cvxpylayers.tensorflow import CvxpyLayer
>>> y = cp.Variable(2, pos=True)
>>> b = cp.Parameter(2, pos=True)
>>> S = cp.Parameter((2, 2), PSD=True)
>>> constraints = [y >= 0, cp.log(y) @ b >= 1]
>>> objective = cp.Minimize(cp.sum_squares(S @ y))
>>> problem = cp.Problem(objective, constraints)
>>> cvxpylayer = CvxpyLayer(problem, parameters=[S, b], variables=[y])
>>> problem.is_dpp()
True
>>> Sigma = tf.constant([[1, 0.5], [0.5, 1]])
>>> b_t = tf.Variable([0.4, 0.6])
>>>
>>> with tf.GradientTape() as tape:
... y_s, = cvxpylayer(Sigma, b_t)
... m = tf.reduce_sum(tf.square(y_s))
>>> tape.gradient(m, b_t)
<tf.Tensor: shape=(2,), dtype=float64, numpy=array([-27.85296513, -30.29720541])>
>>>