v0.1.0 · Reproducing Zozoulenko et al. (2026)
Pure NumPy · No runtime deps
Second-order boosting,
regularized to convergence.
A faithful, dependency-free reproduction of
Gradient Regularized Newton Boosting Trees — the algorithm
that turns Newton's second-order signal into a globally convergent
boosting iteration. Vanilla Newton diverges. GRN converges.
Reproduced from experiments/wine_charbonnier.py
λk = λbase + √(M · ||gk||H)
Reproducing & extending
139
Test cases covering identities & edge cases
4
Analytic losses with known M0
0
Runtime dependencies beyond NumPy
6
Mathematical guarantees, byte-faithful
Overview
The second-order story,
written cleanly.
A reference implementation of Newton boosting you can actually read,
with no C extensions, no framework lock-in, and no mystery in the
iteration. Every closed-form in the paper has a name, a test, and
a diagnostic.
01
Newton's signal
Use the Hessian — without losing the loss.
Gradient boosting uses first-order signal. Newton boosting uses the curvature. Faster convergence per iteration, but unstable: unregularized Newton can diverge when the Hessian is non-constant.
02
Adaptive regularization
One scalar that learns with you.
GRN replaces the static λ with λk = λbase + √(M · ||gk||H), where M = M0 · √N. The Hessian-Lipschitz constant M0 is analytic for four standard losses.
03
Global convergence
Provably converging iterations.
Proposition 5.1 of the paper guarantees global convergence. The implementation ships with Hilbert-space diagnostics to verify Θk, γk, and Lemma 4.2 on every trained model.
Algorithms
Two engines. One elegant difference.
Vanilla Newton boosting (Algorithm 1) and Gradient Regularized Newton
boosting (Algorithm 2) share everything — loss, tree builder,
diagnostics — except a single line that changes the entire
convergence behaviour.
Vanilla Newton Boosting
Static λ
Algorithm 1. Uses a fixed λbase at every iteration. On
losses with non-constant Hessians — e.g. Charbonnier or
cross-entropy — the iteration can diverge.
for k = 1, 2, …, K:
g_k, h_k = ∇L(F_k), H(F_k)
f_k = NewtonTree(g_k, h_k, λ_base)
F_{k+1} = F_k + η · f_k
Recommended
Gradient Regularized Newton
Adaptive λk
Algorithm 2. λk scales with the gradient norm
(Proposition 5.1). The iteration converges —
steadily and provably.
for k = 1, 2, …, K:
g_k, h_k = ∇L(F_k), H(F_k)
λ_k = λ_base + √(M·||g_k||_H)
f_k = NewtonTree(g_k, h_k, λ_k)
F_{k+1} = F_k + η · f_k
Closed-form leaf
w = -Σg / (Σh + λ)
Algorithm 1, line 4 — exact, no gradient descent on leaves.
Exact Newton gain
½[ G²_L/(H_L+λ) + … − G²/(H+λ) ]
Used for greedy split selection; closed form, no approximations.
Lipschitz M0
M0 ∈ {0, ¼, 1}
Analytic Hessian-Lipschitz constants for MSE, BCE/CCE and Charbonnier.
Capabilities
Everything the paper promises,
nothing you don't need.
A focused surface area: six core APIs, four losses, three engines. Built
for clarity, not for benchmarks on big data.
Newton tree learner
Closed-form leaves & splits.
Exact greedy splits with closed-form leaf weights and exact Newton gain. No gradient descent on leaves, no approximations.
Multi-class boosting
K-class softmax output.
Vector-valued tree leaves share split structure across classes. Block Hessians diag(p) − ppᵀ extracted to per-class diagonals.
Four analytic losses
MSE, Charbonnier, BCE, CCE.
Each loss ships with its analytic Hessian-Lipschitz constant M₀ ∈ {0, ¼, 1}, ready to plug into Proposition 5.1.
Hilbert-space diagnostics
Verify the paper on your model.
Exact Newton direction f = -g/(h+λ), cosine angle Θₖ, weak gradient edge γₖ, and Lemma 4.2 — all numerically checked.
Pure NumPy
No C extensions. No frameworks.
A single runtime dependency. Optional extras: scikit-learn for datasets, matplotlib for the experiment plots.
139 tests
Correctness, identities, edge cases.
Every closed-form in the paper has a test. Mathematical identities are checked numerically, byte-faithful to the formulas.
Mathematical guarantees
Six identities. One implementation.
Every closed-form in the paper maps to a test. The library is
byte-faithful to Zozoulenko et al. (2026); see
docs/fidelity.md for the
section-by-section report.
01
Verified
Closed-form leaf weight
w = -Σg / (Σh + λ)
Algorithm 1, line 4. Each leaf's weight is the exact Newton step on its share of the loss.
02
Verified
Exact Newton gain
½[ G²_L/(H_L+λ) + G²_R/(H_R+λ) − G²/(H+λ) ]
Used to rank candidate splits greedily, with no approximation.
03
Verified
Adaptive λₖ (Proposition 5.1)
λₖ = λ_base + √(M · ||gₖ||_H)
With M = M₀ · √N and ||gₖ||_H = ||gₖ|| / √N, matching the paper's notation.
04
Verified
Lemma 4.2 identities
λ||f|| ≤ ||g||, ||f||²_K = -⟨g, f⟩
Verified numerically per iteration by verify_lemma_4_2.
05
Verified
Analytic M₀ (Appendix A)
MSE = 0 · Charbonnier = 1 · BCE/CCE = ¼
Hessian-Lipschitz constants, hard-coded per loss — no estimation step.
06
Verified
Multi-class block Hessian
diag(p) − p pᵀ
Extracted to per-class diagonals for the K-class Newton tree builder.
Developer experience
A scikit-learn feel,
without the framework.
Familiar .fit / .predict surface,
strict type hints, mypy-clean, and four short lines to a paper-faithful
training run.
~ python
vanilla_regression.py
import numpy as np
from grnbt import VanillaNewtonBoosting, MSELoss
rng = np.random.default_rng(42)
X = rng.standard_normal((500, 8))
y = X[:, 0] + 0.5 * X[:, 1] ** 2 + 0.1 * rng.standard_normal(500)
model = VanillaNewtonBoosting(
loss=MSELoss(),
n_estimators=100,
learning_rate=0.1,
max_depth=4,
)
model.fit(X, y)
preds = model.predict(X)
print(f"final loss: {model.history['loss'][-1]:.6f}")
grn_charbonnier.py
from grnbt import (
GradientRegularizedNewtonBoosting,
CharbonnierLoss,
)
model = GradientRegularizedNewtonBoosting(
loss=CharbonnierLoss(),
n_estimators=100,
learning_rate=1.0,
max_depth=4,
lam_base=1e-3,
)
model.fit(X, y)
multiclass_softmax.py
from grnbt import (
MultiClassNewtonBoosting,
CategoricalCrossEntropyLoss,
)
logits = np.stack([X[:, 0], -X[:, 0] + X[:, 1], X[:, 2]], axis=1)
y = np.argmax(logits, axis=1)
model = MultiClassNewtonBoosting(
loss=CategoricalCrossEntropyLoss(n_classes=3),
n_estimators=100,
learning_rate=0.1,
max_depth=3,
n_classes=3,
)
model.fit(X, y)
probs = model.predict_proba(X) # (n, 3), rows sum to 1
Three experiment scripts reproduce Figures 1, 2 and the hyperparameter
ablations from Zozoulenko et al. (2026). Machine-readable artifacts
written to experiments/.
Paper Figure 1 · Wine Quality (Charbonnier)
Three engines, one plot, three behaviours.
Vanilla Newton diverges. The static-high-λ baseline plateaus biased. GRN's adaptive λₖ converges — steadily and provably.
Vanilla · divergesGRN · convergesStatic · plateau
Paper Figure 2 · Higgs (BCE)
Diagnostics you can plot.
Record the cosine angle Θₖ and weak gradient edge γₖ per iteration. Verify Lemma 4.2 numerically on a trained model.
ΘₖγₖLemma 4.2
Hyperparameter ablations
108 configurations × 3 seeds.
Loss × engine × η × depth × λ_base grid, written to a tidy CSV. Aggregate with one line of pandas.
324 runsCSV output
When to use GRNBT
Designed for research,
not for production scale.
GRNBT is the right tool when clarity matters more than throughput. For
big-data production workloads, prefer a system built for it.
Verifying theory
Run experiments that reproduce Figures 1 and 2 of the paper. Trace every identity numerically.
Teaching Newton boosting
Use it in a graduate ML seminar. Every line maps to a closed-form on the projector slide.
Starting a research fork
Drop in a custom loss with its analytic M₀, swap in your own tree, and run.
API surface
A short list.
A long reach.
Three engines, four losses, two tree learners, four diagnostics —
everything you need to reproduce the paper and explore beyond it.
If you use this implementation in your research, please cite the
accompanying preprint. The library is reproduction code only; the
paper contents remain the property of the original authors.
citation.bib
@article{zozoulenko2026grnbt,
title = {Gradient Regularized Newton Boosting Trees
with Global Convergence},
author = {Zozoulenko, Nikita and
Falkowski, Daniel and
Cass, Thomas and
Gonon, Lucien},
journal = {Preprint (arXiv id verification pending)},
year = {2026}
}
v0.1.0 · MIT
Read the paper.
Run the code.
A faithful, dependency-free reference implementation of Newton's
second-order boosting — regularized, proven, and ready to inspect.