Follow-up split out of #454 (layer G). #454 landed the gradient for the asymmetric/non-Gaussian noise families Laplace and Student-t (scalar data-fit gradient + estimated-scale columns) and deferred negative-binomial, which is gated with a pointed GradientNotSupported message pointing here.
Why deferred
NegBinomial's default centering is the median (ADR-0031), realized by inverting a continuous CDF for the mean that places the median at the prediction — a bounded brentq root-find in noise/negative_binomial.py::_mean_for_median. So ∂data_fit/∂pred needs implicit differentiation through the root-find:
∂mean/∂pred = −(∂gap/∂pred) ÷ (∂gap/∂mu), gap(mu) = betainc(r, target+1, r/(r+mu)) − 0.5
∂gap/∂pred is the derivative of the regularized incomplete beta w.r.t. its second parameter (target+1, where target = max(pred, 0)), which is not elementary (it brings in digamma / a numerically-evaluated parameter derivative of betainc). That is the gnarly part #454 set aside; the issue text explicitly allowed shipping only one of {neg_bin, student_t} as the second FD oracle, and student_t was the lower-risk choice.
Scope
- Implement
NegBinomial.d_data_fit_d_prediction for MEAN centering (clean: ∂mean/∂pred = 1, ∂data_fit/∂mean = r(mean−obs)/(mean(r+mean))) and MEDIAN centering (the implicit-diff above).
- Generalize the estimated-scale column to the dispersion
r (neg_bin_dynamic's r__FREE): NegBinomial's PMF is self-normalizing, so there is no separable normalizer — the whole ∂data_fit/∂r lives in the data fit.
- Lift the NegBinomial clause of
LikelihoodObjective._require_gradient_supported.
- FD acceptance oracle on a small count net (mirroring the Laplace/Student-t oracles in
tests/test_gradient_assembly.py).
Edition-2 only, additive, opt-in — same conventions as the rest of #385.
Follow-up split out of #454 (layer G). #454 landed the gradient for the asymmetric/non-Gaussian noise families Laplace and Student-t (scalar data-fit gradient + estimated-scale columns) and deferred negative-binomial, which is gated with a pointed
GradientNotSupportedmessage pointing here.Why deferred
NegBinomial's default centering is the median (ADR-0031), realized by inverting a continuous CDF for the mean that places the median at the prediction — a bounded
brentqroot-find innoise/negative_binomial.py::_mean_for_median. So∂data_fit/∂predneeds implicit differentiation through the root-find:∂gap/∂predis the derivative of the regularized incomplete beta w.r.t. its second parameter (target+1, wheretarget = max(pred, 0)), which is not elementary (it brings in digamma / a numerically-evaluated parameter derivative ofbetainc). That is the gnarly part #454 set aside; the issue text explicitly allowed shipping only one of {neg_bin, student_t} as the second FD oracle, and student_t was the lower-risk choice.Scope
NegBinomial.d_data_fit_d_predictionfor MEAN centering (clean:∂mean/∂pred = 1,∂data_fit/∂mean = r(mean−obs)/(mean(r+mean))) and MEDIAN centering (the implicit-diff above).r(neg_bin_dynamic'sr__FREE): NegBinomial's PMF is self-normalizing, so there is no separable normalizer — the whole∂data_fit/∂rlives in the data fit.LikelihoodObjective._require_gradient_supported.tests/test_gradient_assembly.py).Edition-2 only, additive, opt-in — same conventions as the rest of #385.