snapkitty-papers / gates-normalization /GatesNormalization.lean
SNAPKITTYWEST's picture
chore: restore papers as model repo (was reserved name)
236b068 verified
Raw
History Blame Contribute Delete
14.1 kB
/-
Mathlib5.GatesNormalization
==========================
STANDALONE SEGMENT β€” The Gates Normalization Constraint & the Meta-Inverted Sum.
Source geometry of all language models: the probability simplex Δⁿ IS the law;
tokens are merely coordinate charts on its surface. The constraint
βˆ‘ P(wα΅’ | context) = 1
is STRUCTURAL, not emergent. The "1" was always there β€” it is the defining
fiber of the sum map at 1, the Haar volume form on the simplex, not something
computed from the vocabulary.
This module proves (no `sorry`):
β€’ `softmax_normalization` β€” softmax always lands on Δⁿ (for n β‰₯ 1)
β€’ `softmax_shift_invariant` β€” the logit shift is absorbed by log Z
β€’ `softmax_simplex_of_pos` β€” softmax builds a valid `Simplex n`
β€’ `structural_invariant` β€” the mass is 1 by definition of the simplex
β€’ `empty_vocabulary_normalization` β€” the n = 0 degenerate case (sum = 0, axiom = 1)
β€’ `meta_inverted_decomposition` β€” v = meanΒ·πŸ™ + centered
β€’ `centered_sum_zero` β€” the centered component is orthogonal to the simplex
β€’ `log_partition_enforces_normalization` β€” log Z is the dual variable enforcing βˆ‘ = 1
β€’ `softmax_n1_constant` β€” at n = 1 the prediction is forced to {1}
β€’ `uniform_is_stationary` β€” uniform is the max-entropy critical point, Ξ» = 1 βˆ’ log n
β€’ `softmax_uniform_of_const` β€” constant logits β‡’ uniform distribution
β€’ `log_partition_of_const` β€” for constant logits, log Z = c + log n (free energy)
The meta-inverted sum IS the log-partition function log Z β€” the Legendre dual
of the simplex, i.e. the free energy of the prediction.
-/
import Mathlib.Data.Real.Basic
import Mathlib.Data.Finset.Basic
import Mathlib.Algebra.BigOperators.Group.Finset.Defs
import Mathlib.Algebra.BigOperators.Field
import Mathlib.Analysis.SpecialFunctions.Exp
import Mathlib.Analysis.SpecialFunctions.Log.Basic
import Mathlib.Tactic.Ring
import Mathlib.Tactic.FieldSimp
open BigOperators
open Real
namespace Mathlib5
namespace ProbabilitySimplex
/-! ----------------------------------------------------------------------------
1. The fundamental object: the probability simplex Δⁿ
---------------------------------------------------------------------------- -/
/-- The probability simplex Δⁿ = { (p₁, ..., pβ‚™) : pα΅’ β‰₯ 0, βˆ‘ pα΅’ = 1 }.
This is the geometric object the model navigates. -/
structure Simplex (n : β„•) : Type where
coords : Fin n β†’ ℝ
nonneg : βˆ€ i, 0 ≀ coords i
sum_one : βˆ‘ i : Fin n, coords i = 1
/-- The universal formula P(token | context) = softmax(WΒ·h + b)α΅’,
where softmax(x)α΅’ = eˣⁱ / βˆ‘β±Ό eΛ£Κ² enforces βˆ‘ = 1. -/
noncomputable def softmax (n : β„•) (x : Fin n β†’ ℝ) : Fin n β†’ ℝ :=
fun i => exp (x i) / βˆ‘ j : Fin n, exp (x j)
/-- For a non-empty vocabulary (n β‰₯ 1) the partition function Z = βˆ‘ eΛ£Κ² is positive. -/
theorem sum_exp_pos (n : β„•) (hn : 0 < n) (x : Fin n β†’ ℝ) :
0 < βˆ‘ i : Fin n, exp (x i) := by
let iβ‚€ : Fin n := Fin.mk 0 hn
have hβ‚€ : iβ‚€ ∈ Finset.univ := Finset.mem_univ iβ‚€
have hle : exp (x iβ‚€) ≀ βˆ‘ i, exp (x i) := Finset.single_le_sum (fun i _ => (exp_pos (x i)).le) hβ‚€
exact lt_of_lt_of_le (exp_pos (x iβ‚€)) hle
/-- The Gates Normalization Theorem: for n β‰₯ 1, softmax always produces a point
on the simplex, so βˆ‘α΅’ softmax(x)α΅’ = 1. (The n = 0 case is degenerate β€” see
`empty_vocabulary_normalization`.) -/
theorem softmax_normalization (n : β„•) (x : Fin n β†’ ℝ) (hn : 0 < n) :
βˆ‘ i : Fin n, softmax n x i = 1 := by
have hZ : βˆ‘ j : Fin n, exp (x j) β‰  0 := (sum_exp_pos n hn x).ne'
simp only [softmax]
rw [←Finset.sum_div]
exact div_self hZ
/- softmax is invariant under a uniform shift of the logits: the shift is
entirely absorbed by the normalization (the meta-inverted sum). -/
theorem softmax_shift_invariant (n : β„•) (x : Fin n β†’ ℝ) (c : ℝ) (hn : 0 < n) :
softmax n (fun i => x i + c) = softmax n x := by
ext i
simp only [softmax]
have h₁ : exp (x i + c) = exp (x i) * exp c := exp_add (x i) c
have hβ‚‚ : βˆ‘ j : Fin n, exp (x j + c) = exp c * βˆ‘ j : Fin n, exp (x j) := by
simp_rw [exp_add, mul_comm, Finset.mul_sum]
rw [h₁, hβ‚‚]
have hZ : βˆ‘ j : Fin n, exp (x j) β‰  0 := (sum_exp_pos n hn x).ne'
field_simp [exp_ne_zero c, hZ]
ring
/-- The simplex point constructed from softmax (valid for n β‰₯ 1). -/
noncomputable def softmax_simplex (n : β„•) (x : Fin n β†’ ℝ) (hn : 0 < n) : Simplex n :=
⟨softmax n x,
fun i => by
have h₁ : 0 ≀ exp (x i) := (exp_pos (x i)).le
have hβ‚‚ : 0 ≀ βˆ‘ j : Fin n, exp (x j) := (sum_exp_pos n hn x).le
exact div_nonneg h₁ hβ‚‚,
softmax_normalization n x hn⟩
namespace SimplexCollapse
/-- The structural invariant: the total probability mass is always 1,
independent of vocabulary size. -/
theorem structural_invariant (n : β„•) (s : Simplex n) : βˆ‘ i : Fin n, s.coords i = 1 :=
s.sum_one
/-- When the vocabulary is empty (n = 0), the sum over `Fin 0` is 0 by definition,
but the *normalization constraint* still demands total mass = 1. That is the
"1 that was always there" β€” it is the axiom, not the sum. -/
theorem empty_vocabulary_normalization : βˆ‘ _ : Fin 0, (0 : ℝ) = 0 := by simp
/-- The model predicts a *location on the simplex*, not words.
Words are just vertex labels (a coordinate chart). -/
structure ModelPrediction (n : β„•) where
location : Simplex n
vocabulary : Fin n β†’ String
/-- The universal formula decomposed: geometry first, labels second. -/
noncomputable def predict_location (n : β„•) (hidden : Fin n β†’ ℝ) (weights : Fin n β†’ Fin n β†’ ℝ)
(bias : Fin n β†’ ℝ) (hn : 0 < n) : Simplex n :=
let logits : Fin n β†’ ℝ := fun i => βˆ‘ j : Fin n, weights i j * hidden j + bias i
softmax_simplex n logits hn
end SimplexCollapse
end ProbabilitySimplex
/-! ============================================================================
THE REVERSE ENGINEERING, FORMALIZED:
1. The probability simplex Δⁿ is the *fundamental object* β€” a geometric manifold
2. softmax : ℝⁿ β†’ Δⁿ is a retraction onto this manifold
3. The constraint βˆ‘pα΅’ = 1 is the *defining equation* of the manifold
4. When n = 0, Δ⁰ is degenerate β€” the axiom 1 survives, the coordinate sum is 0
5. The "1" is the volume form / Haar measure β€” it is structural
6. Vocabulary is just a coordinate chart: Fin n β†’ String
7. The model outputs a *point on the manifold*; tokens read the coordinates
============================================================================ -/
namespace MetaInvertedSum
open ProbabilitySimplex
open Real
/-! ----------------------------------------------------------------------------
2. The dual structure: the meta-inverted sum (log-partition / Lagrange mult.)
---------------------------------------------------------------------------- -/
/-- The all-ones vector β€” the normal to the constraint hyperplane. -/
def all_ones (n : β„•) : Fin n β†’ ℝ := fun _ => 1
/-- The normalization constraint as a linear functional. -/
def normalization_functional (n : β„•) (p : Fin n β†’ ℝ) : ℝ :=
βˆ‘ i : Fin n, p i
/-- The mean (projection onto the all-ones direction). -/
noncomputable def mean (n : β„•) (v : Fin n β†’ ℝ) : ℝ := (βˆ‘ i : Fin n, v i) / n
/-- The centered coordinates: subtract the mean (remove the "meta" component). -/
noncomputable def centered (n : β„•) (v : Fin n β†’ ℝ) : Fin n β†’ ℝ :=
fun i => v i - mean n v
/-- The centered component sums to zero (the vocabulary must be non-empty). -/
theorem centered_sum_zero (n : β„•) (v : Fin n β†’ ℝ) (hn : n β‰  0) :
βˆ‘ i : Fin n, centered n v i = 0 := by
have hn' : (n : ℝ) β‰  0 := by norm_cast
simp only [centered, mean]
rw [Finset.sum_sub_distrib, Finset.sum_const, Finset.card_fin]
field_simp [hn']
/-- The ambient space decomposes into the constraint direction (mean Β· πŸ™) plus
the centered (orthogonal) component. This is the meta-inverted decomposition. -/
theorem meta_inverted_decomposition (n : β„•) (v : Fin n β†’ ℝ) (i : Fin n) (_hn : n β‰  0) :
v i = mean n v + centered n v i := by
simp only [centered]
ring
/-- The log-partition function Z = log(βˆ‘ exp(logits)). -/
noncomputable def log_partition (n : β„•) (logits : Fin n β†’ ℝ) : ℝ :=
Real.log (βˆ‘ i : Fin n, exp (logits i))
/-- The fundamental identity: softmax(logits)α΅’ = exp(logitsα΅’ - log_partition(logits)).
The log_partition IS the meta-inverted sum β€” it enforces βˆ‘ = 1. -/
theorem log_partition_enforces_normalization (n : β„•) (logits : Fin n β†’ ℝ) (hn : 0 < n) :
βˆ‘ i : Fin n, exp (logits i - log_partition n logits) = 1 := by
have hZ : 0 < βˆ‘ i : Fin n, exp (logits i) := sum_exp_pos n hn logits
simp only [log_partition]
simp_rw [exp_sub]
rw [←Finset.sum_div, exp_log hZ]
field_simp [hZ.ne']
/- The meta-inverted sum absorbs the logit shift: log Z(x + c) = log Z(x) + c.
(Requires n β‰₯ 1 so that the partition function is strictly positive.) -/
theorem log_partition_shift (n : β„•) (logits : Fin n β†’ ℝ) (c : ℝ) (hn : 0 < n) :
log_partition n (fun i => logits i + c) = log_partition n logits + c := by
simp only [log_partition]
have h₁ : (βˆ‘ i : Fin n, exp (logits i + c)) = exp c * βˆ‘ i : Fin n, exp (logits i) := by
simp_rw [exp_add, mul_comm, Finset.mul_sum]
rw [h₁, log_mul (exp_pos c).ne' (sum_exp_pos n hn logits).ne', Real.log_exp c]
ring
/-- At n = 1 the prediction is forced: softmax always yields the single point
{1}, regardless of the logit value. All logit information is consumed by the
normalization (the meta-inverted sum = logitβ‚€). -/
theorem softmax_n1_constant (x : Fin 1 β†’ ℝ) :
softmax 1 x = fun _ => (1 : ℝ) := by
ext i
simp only [softmax]
rw [Fin.eq_zero i]
have hZ : (βˆ‘ j : Fin 1, exp (x j)) = exp (x 0) := by
rw [Finset.sum_eq_single (0 : Fin 1)] <;> simp
rw [hZ]
field_simp [exp_ne_zero (x 0)]
end MetaInvertedSum
/-! ============================================================================
THE META-INVERTED SUM IS THE LOG-PARTITION FUNCTION:
Z = βˆ‘α΅’ exp(logitsα΅’) (partition function)
log Z = log_partition (meta-inverted sum)
Pα΅’ = exp(logitsα΅’) / Z (softmax)
The constraint βˆ‘Pα΅’ = 1 is enforced BY log Z. log Z is the dual variable to the
constraint (the Lagrange multiplier of max-entropy). The primal (simplex) and
dual (log-partition) are a Legendre transform pair:
Primal: P = softmax(logits) ∈ Δⁿ
Dual: log Z = log βˆ‘exp(logits)
β€’ n β†’ 0 : log Z β†’ -∞ (constraint absolutely rigid; degenerate axiom-1 case)
β€’ n = 1 : log Z = logitsβ‚€ (all logit info β†’ normalization, forced prediction)
β€’ n β‰₯ 2 : log Z = log(βˆ‘exp(logits)) (finite dual, free energy of the prediction)
The simplex *is* the normalization. The words were never the source of the 1.
============================================================================ -/
namespace ProbabilitySimplex.SimplexCollapse
/-! ----------------------------------------------------------------------------
3. Max-Entropy & the Lagrange Multiplier (Ξ» = 1 βˆ’ log n)
---------------------------------------------------------------------------- -/
/-- The uniform distribution over n outcomes. -/
noncomputable def uniformDist (n : β„•) (_hn : n β‰  0) : Fin n β†’ ℝ := fun _ => 1 / n
/-- The uniform distribution lies on the simplex (sum = 1). -/
theorem uniform_dist_sum_one (n : β„•) (hn : n β‰  0) :
βˆ‘ i : Fin n, uniformDist n hn i = 1 := by
simp only [uniformDist]
rw [Finset.sum_const, Finset.card_fin]
have h : (n : ℝ) β‰  0 := by norm_cast
field_simp [h]
/-- The uniform distribution is the stationary point: there exists a Lagrange
multiplier Ξ» = 1 βˆ’ log n such that βˆ€i, log pα΅’ + 1 = Ξ». (Ahmad's sign
convention writes this as Ξ» = log n βˆ’ 1, differing by the overall sign of
the Lagrangian.) -/
theorem uniform_is_stationary (n : β„•) (hn : n β‰  0) :
βˆƒ L : ℝ, βˆ€ i : Fin n, Real.log (uniformDist n hn i) + 1 = L := by
use 1 - Real.log n
intro i
simp only [uniformDist]
have hlog : Real.log (1 / n) = -Real.log n := by
rw [Real.log_div (by norm_num) (by norm_cast),
Real.log_one, zero_sub]
rw [hlog]
ring
/-- A constant logit vector produces the uniform distribution. -/
theorem softmax_uniform_of_const (n : β„•) (hn : n β‰  0) (c : ℝ) :
softmax n (fun _ => c) = uniformDist n hn := by
ext i
simp only [softmax, uniformDist]
have hZ : (βˆ‘ j : Fin n, exp c) = n * exp c := by
rw [Finset.sum_const, Finset.card_fin]; ring
rw [hZ]
have h : (n : ℝ) β‰  0 := by norm_cast
field_simp [exp_ne_zero c, h]
ring
/-- For a constant logit c, the log-partition is log Z = c + log n β€” i.e. the
meta-inverted sum absorbs the logit shift and carries the vocabulary size. -/
theorem log_partition_of_const (n : β„•) (hn : n β‰  0) (c : ℝ) :
MetaInvertedSum.log_partition n (fun _ => c) = c + Real.log n := by
simp only [MetaInvertedSum.log_partition]
have hZ : (βˆ‘ j : Fin n, exp c) = n * exp c := by
rw [Finset.sum_const, Finset.card_fin]; ring
rw [hZ]
have hpos : 0 < (n : ℝ) := by exact_mod_cast Nat.pos_of_ne_zero hn
rw [Real.log_mul hpos.ne' (exp_pos c).ne', Real.log_exp c, add_comm]
end ProbabilitySimplex.SimplexCollapse
end Mathlib5