Custom objective for SVI example

Hi, i’m wondering what would be the most straightforward / high-level / accessible way to implement custom objectives for SVI in numpyro (reference example in pyro)

I’m trying to implement various experimental l1, l2 regularizers for SVI-based GLM.

Best i can think of rn is interfering somewhere into:

svi_state, loss = svi.stable_update(svi_state, data)
params = svi.get_params(svi_state)
# then regularize the params in some whay
# then update the params in svi state manually

it depends what you’re doing but you can add arbitrary terms to the objective via factor statement

I want to keep a state between the updates (imagine simple L2, but with different multiplier on each iteration). Which is think is challenging to do in a clean way.

Could you please give me an example, say, basic L2 (or at least something)?
This factor primitive is not particularly documented (neither in numpyro nor in pyro). Best i could find is this Custom Loss Function Implementation - #4 by fritzo and the author uses it inside the guide, not the objective per se.

the elbo is basically of the form log model_density - log guide_density.

a factor statement in the model effectively adds the given (log) factor to the model log density.

a factor statement in the guide effectively adds the given (log) factor to the guide log density.

so if you add e.g. pyro.factor('my_factor', torch.tensor(1.23)) to your model the elbo objective will be increased by 1.23.

and if you add pyro.factor('my_factor', torch.tensor(1.23)) to your guide the elbo objective will be decreased by 1.23.

Hi martinjankowiak,

Is there another way to do this differently in numpyro, such as

elbo_loss_fn = pyro.infer.Trace_ELBO().differentiable_loss

def loss_fn(data):
elbo_loss = elbo_loss_fn(model, guide, data)
x_loc = pyro.param(“x_loc”)
reg_loss = L2_regularizer(x_loc)
return elbo_loss + reg_loss

or implementing a custom loss such as in
https://pyro.ai/examples/custom_objectives.html#Example:-KL-Annealing