Why was it needed in the first place? Given a differentiable probability distribution constructor $\theta \mapsto p(\theta)$, differentiate through $\theta \mapsto E[c(V)]$ where $V \sim p(\theta)$.
Not directly necessary for Perturbed
because we can put $c \circ f$ in the Reinforce, but necessary for regularized because $c \circ f$ is not an LP (not amenable to FW).
struct Pushforward
fixed_atoms_dist_constructor # must return a FixedAtomsProbabilityDistribution
post_processing
end
function (p::Pushforward)(theta)
dist = p.fixed_atoms_dist_constructor(theta)
return mean(p.post_processing, dist)
end
Actually it is necessary to define compute_probability_distribution
here along with its rrule
for Reinforce
https://github.com/JuliaDecisionFocusedLearning/InferOpt.jl/blob/59ab4fe21682e8c0a20bb55d4da3b4cb91f2cc0c/src/perturbed/abstract_perturbed.jl#L118-L153
The Pushforward
struct is no longer necessary then