You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fromtypingimportCallableimportjaximportjax.numpyasjnpfromjaxtypingimportArraydefmake_lpu_functional(f: Callable[[Array], Array], d: int, diag: bool=False) ->Callable[[Array, Array], Array]:
""" Erzeugt das Gesetz der Fehlerfortpflanzung (LPU) rein funktional über JVP/VJP. Erfüllt das Principle of Least Knowledge: Es wird kein Jacobi-Tensor allokiert. :param f: Die primale Funktion f(x) -> y. :param d: Die Anzahl der inneren Tensor-Dimensionen (Stufe der Eingabe). :param diag: True, wenn nur die Varianzen der Ausgabe berechnet werden sollen. :returns: Eine Funktion lpu(x, u) -> Ausgangs-Unsicherheitstensor. """deflpu(x: Array, u: Array) ->Array:
""" :param x: Primaler Input-Tensor. Shape: (*In_Shape) :param u: Unsicherheits-Tensor. Falls unkorreliert (u.ndim == d): Shape (*In_Shape) Falls voll-korreliert (u.ndim == 2*d): Shape (*In_Shape, *In_Shape) """in_shape=x.shape# --- FALL 1: Fehler in x sind strikt unkorreliert (u.ndim == d) ---ifu.ndim==d:
# Wir bauen die Basis der Einheitsrichtungen rein strukturell aufn_elements=x.sizeeye_flat=jnp.eye(n_elements)
eye_tensor=eye_flat.reshape(in_shape+in_shape)
# Skalierung mit den Standardabweichungen (Wurzel aus Varianz)std_dev=jnp.sqrt(u)
std_expanded=std_dev[(None,) *d+ (...,)]
V_tensors=eye_tensor*std_expanded# Shape: (*In_Shape_links, *In_Shape_rechts)defein_jvp(v_richtung):
_, jvp_erg=jax.jvp(f, (x,), (v_richtung,))
returnjvp_erg# Shape: (*Out_Shape)# d-mal vmap über die linken In_Shape-Achsenv_func=ein_jvpfor_inrange(d):
v_func=jax.vmap(v_func, in_axes=0, out_axes=0)
jvp_all=v_func(V_tensors) # Shape: (*In_Shape, *Out_Shape)# Fehlerfortpflanzung: Summe der quadrierten JVPs über die Eingangsachsenreturnjnp.sum(jvp_all**2, axis=tuple(range(d)))
# --- FALL 2: Volle Eingangs-Kovarianzmatrix (u.ndim == 2*d) ---else:
# Schritt 1: W = G * U via JVP (Vorwärtsmodus)defein_jvp(v_richtung):
_, jvp_erg=jax.jvp(f, (x,), (v_richtung,))
returnjvp_erg# vmap über die RECHTEN d Achsen von U (die Richtungsachsen)w_func=ein_jvpfor_inrange(d):
w_func=jax.vmap(w_func, in_axes=-1, out_axes=-1)
W=w_func(u) # Shape: (*In_Shape, *Out_Shape)# Schritt 2: V = W * G^T via VJP (Rückwärtsmodus)y, vjp_fun=jax.vjp(f, x)
out_rank=len(y.shape)
# Fall 2a: Nur die Ausgangs-Varianzen gewünscht (diag=True)ifdiag:
# Wir mappen das VJP über die hinteren Out_Shape-Achsen von Wv_func=vjp_funfor_inrange(out_rank):
v_func=jax.vmap(v_func, in_axes=-1, out_axes=-1)
G_W=v_func(W) # Shape: (*In_Shape, *In_Shape)# Symmetrische Reduktion auf die Ausgangsvarianzenreturnjnp.sum(G_W, axis=tuple(range(d)))
# Fall 2b: Volle Ausgangs-Kovarianzmatrix gewünschtelse:
# Wir mappen das VJP über die vorderen In_Shape-Achsen von Wv_func=vjp_funfor_inrange(d):
v_func=jax.vmap(v_func, in_axes=0, out_axes=0)
returnv_func(W) # Shape: (*Out_Shape, *Out_Shape)returnlpu# Universelle, JIT-kompilierte Batch-Verarbeitung über Achse 0@jax.jit(static_argnums=(0, 3, 4))deflpu_batched(f: Callable, d: int, batch_x: Array, batch_u: Array, diag: bool=False) ->Array:
""" Verarbeitet eine Batch von Eingaben parallel über Achse 0 analog zu Ihrer Vorlage. """returnjax.vmap(make_lpu_functional(f, d, diag), in_axes=(0, 0))(batch_x, batch_u)
Activity
[-]Implement LPU with VJP/JVP for JAX-based F/M[/-][+]LPU with VJP/JVP for JAX-based F/M[/+]heptaflar commentedon Oct 4, 2026
Google AI generated code:
[-]LPU with VJP/JVP for JAX-based F/M[/-][+]LPU with VJP/JVP[/+]heptaflar commentedon Oct 4, 2026
heptaflar commentedon Oct 4, 2026