Differentiate through optimization problems
mainMPAX is differentiable via unrolled differentiation. This allows you to integrate mathematical programming directly into the backpropagation process of neural networks. You can use jax.custom_vjp or jax.custom_jvp to define custom forward and backward passes for loss functions that depend on optimization results.
import jax
import jax.numpy as jnp
@jax.custom_vjp
def pso_fun(pred_cost, true_cost, true_sol, true_obj):
sol, obj = batch_optimize(2*pred_cost - true_cost)
loss = -obj + 2 * jnp.sum(pred_cost * true_sol, axis=1) - true_obj
loss = jnp.mean(loss)
return loss, sol
def spo_fwd(pred_cost, true_cost, true_sol, true_obj):
loss, sol = pso_fun(pred_cost, true_cost, true_sol, true_obj)
return loss, (sol, true_sol)
def spo_bwd(res, g):
sol, true_sol = res
grad = 2 * (true_sol - sol)
# No gradients needed for true_cost, true_sol, or true_obj
return grad * g, None, None, None
pso_fun.defvjp(spo_fwd, spo_bwd)