GaussNewtonModel#
- class t3toolbox.fitting.GaussNewtonModel#
The local Gauss-Newton model of a least-squares objective at
frame, generic over the geometry.Built by a sampling-kind factory (
apply_model()/entries_model()/probe_model()), not directly. Holds the geometry, the frameframe = geometry.frame(X), the samplingkind, the measurementsample(the probe/apply vectorswwor the integer gridindex), and the data residualr = F(X) − y. The frame sweep, objective value, and gradient are cached on first use.Examples
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.manifold as t3m >>> import t3toolbox.fitting as fitting >>> np.random.seed(0) >>> x = t3.TuckerTensorTrain.randn((6, 7, 8), (2, 3, 2), (1, 2, 2, 1)) >>> ww = [np.random.randn(15, N) for N in (6, 7, 8)] # 15 samples, each a (w_1, w_2, w_3) >>> r = np.random.randn(15) # the data residual at x
On the manifold geometry the gradient
g = Π 𝒥ᵀ ris a gauged tangent andH pstays on the gauged tangent space:>>> model = fitting.apply_model(t3m.MANIFOLD, x, ww, r) >>> print(round(float(model.objective_value), 6)) 8.295196 >>> print(model.gradient.is_gauged()) True >>> p = t3m.MANIFOLD.randn(model.frame) # a gauged trial step at the model's frame >>> print(model.gn_hessian(p).is_gauged()) True
evaluate(p)is the quadratic-model value, consistent with assembling it from the cachedc/gand the Hessian action (and costs only one forward apply, not a Hessian apply):>>> hp = model.gn_hessian(p) >>> m_built = float(model.objective_value + model.gradient.corewise_inner(p) + 0.5 * p.corewise_inner(hp)) >>> bool(np.allclose(float(model.evaluate(p)), m_built)) True
The Gauss-Newton quadratic form
pᵀHp = ‖Jp‖²comes from one forward sweep (noH passembly) – the cheap step-length denominator for Cauchy / line search (alpha = g.corewise_inner(g) / gn_quadratic(g)):>>> bool(np.allclose(float(model.gn_quadratic(p)), float(p.corewise_inner(model.gn_hessian(p))))) True
The corewise geometry is the same call with a different geometry: the gradient is a tangent at the raw
(U,G,G,G)frame (a core perturbation), with no gauge projection:>>> cmodel = fitting.apply_model(t3m.COREWISE, x, ww, r) >>> print(cmodel.gradient.is_gauged()) False >>> cp = t3m.COREWISE.randn(cmodel.frame) >>> bool(np.allclose(float(cmodel.evaluate(cp)), ... float(cmodel.objective_value + cmodel.gradient.corewise_inner(cp) ... + 0.5 * cp.corewise_inner(cmodel.gn_hessian(cp))))) True
A trial step at a different frame is a structural error (the model is tied to its frame):
>>> other = t3.TuckerTensorTrain.randn((6, 7, 8), (2, 3, 2), (1, 2, 2, 1)) >>> model.gn_hessian(t3m.MANIFOLD.randn(t3m.MANIFOLD.frame(other))) Traceback (most recent call last): ValueError: trial tangent must live at the model's frame (it is at a different frame)
- geometry: t3toolbox.backend.common.typ.Any#
- kind: SamplingKind#
- sample: t3toolbox.backend.common.typ.Any#
- residual: t3toolbox.backend.common.typ.Any#
- sweep: t3toolbox.backend.common.typ.Any#
- regularizer: t3toolbox.backend.common.typ.Any = None#
Methods#
The least-squares objective at the frame, |
|
|
The gradient |
|
The linearized forward |
|
The Gauss-Newton quadratic form |
|
The Gauss-Newton Hessian action |
|
The quadratic-model value |