Skip to content

Latest commit

 

History

History
138 lines (100 loc) · 5.63 KB

File metadata and controls

138 lines (100 loc) · 5.63 KB

stoppower

tests PyPI DOI

Dimensionar la ventana de un criterio de detención por análisis de potencia, en vez de elegirla por costumbre.

pip install stoppower

El problema

Casi todo el mundo decide que un modelo "convergió" comparando dos o tres evaluaciones y aflojando la tolerancia cuando la detección falla. Eso ataca el término equivocado. En el caso medido (Zenodo 10.5281/zenodo.21630279), la ganancia total de detección se descompone en 7.0× por alargar la ventana y solo 1.31× por cambiar el estadístico. La tolerancia casi no mueve la aguja.

Peor: cuando la relación señal-ruido cae por debajo de 1, ninguna tolerancia recupera la decisión. El error tipo I y el tipo II dejan de poder separarse.

La regla

Para n evaluaciones equiespaciadas, el error estándar de la pendiente OLS decrece como n^(-3/2), contra n^(-1/2) del simple promediado:

EE(b) = σ · sqrt( 12 / (n(n² − 1)) )
b*   ≥ (z_α + z_β) · EE(b)

Uso

from stoppower import window_for, sigma_from_pilot, evaluate, prereg_text, pts

# 1) ¿Qué ventana necesito para no pasar por alto 1 punto de accuracy cada 2500 pasos?
plan = window_for(b_star=pts(1.0), sigma=0.0082, eval_every=500)
print(plan)      # -> n=11 evaluaciones = 5000 pasos

# 2) ¿Qué potencia tiene la ventana que ya uso?
from stoppower import power_of
power_of(pts(1.0), sigma=0.0082, n=3, eval_every=500)     # -> 0.097

# 3) Decidir con datos
evaluate(steps, accs, b_star=pts(1.0))
stoppower design --b-star 0.01 --sigma 0.0082 --eval-every 500 --prereg
stoppower power  --b-star 0.01 --sigma 0.0082 --n 3 --eval-every 500
stoppower check  historial.csv --b-star 0.01 --span 5000 10000

Un caso real, de punta a punta

Historial de validación de un modelo entrenado 10 000 pasos, evaluando cada 500. La pregunta es si en el tramo final sigue mejorando o ya se puede cortar.

$ stoppower check historial.csv --b-star 0.01 --span 5000 10000
  sigma estimada en el tramo 5000-10000: 0.010593
INDECIDIBLE · pendiente +0.006424 por 2500 pasos (IC95 [-0.003474, +0.01632])
  t=1.27 p=0.1017 · n=11 evaluaciones · potencia=0.63 para b*=0.01
  ! potencia 0.63 < 0.8: con esta ventana no se puede afirmar convergencia,
    solo que no se detectó mejora. Alargá la ventana antes de concluir.

El criterio de dos puntos habría dicho "convergió". Acá el veredicto es indecidible, con el número al lado: la ventana no tiene potencia para sostener esa afirmación.

Y si en vez del tramo estable se le pide toda la corrida, avisa antes de responder:

$ stoppower check historial.csv --b-star 0.01 --span 500 10000
  ! el ruido cambia 7.4x dentro de la ventana (sigma=0.06951 en la 1ª mitad vs
    0.009344 en la 2ª, más alto al principio): la ecuación supone ruido constante.
    Acortá la ventana o corrésela al régimen estable.

Tres cosas que lo distinguen de copiar la fórmula

1. σ se estima en el tramo, no sobre toda la corrida. El ruido de validación no es constante. Medido sobre 8 semillas de un mismo modelo:

paso 500 1000 1500 2000 2500 5000 7500
SD entre semillas .101 .073 .038 .010 .014 .009 .011

Un factor 9. Quien meta una σ global en la ecuación se equivoca por un factor grande, y por eso acá el tramo es un argumento obligatorio. homoscedasticity_check avisa cuando el supuesto de ruido constante no se sostiene ni siquiera dentro de la ventana:

! el ruido cambia 7.4x dentro de la ventana (sigma=0.0695 en la 1ª mitad vs 0.0093 en la 2ª):
  la ecuación supone ruido constante. Acortá la ventana o corrésela al régimen estable.

2. No confunde "no detecté mejora" con "convergió". evaluate devuelve converged=None cuando la potencia no alcanza, en vez de dar un falso verde:

INDECIDIBLE · pendiente +0.0064 por 2500 pasos (IC95 [-0.0035, +0.0163])
  t=1.27 p=0.1017 · n=11 evaluaciones · potencia=0.63 para b*=0.01
  ! potencia 0.63 < 0.8: no se puede afirmar convergencia, solo que no se detectó mejora.

3. Escupe el párrafo pre-registrable. prereg_text(plan) da el texto con σ, su procedencia, el nivel, la potencia y la ventana resultante — para pegar en el protocolo antes de ver los datos.

Cómo estimar σ sin circularidad

situación función
el conjunto de validación se remuestrea sigma_floor(p, n_val) — cota analítica, sin entrenar
conjunto fijo, tenés un piloto sigma_from_pilot(steps, values, span=(desde, hasta))
tenés varias semillas corridas sigma_from_runs(runs, at_index=...)

Fijar una ventana a partir de un piloto no es lo mismo que recalibrar una tolerancia después de ver los resultados: se fija el diseño, no el veredicto.

Alcance

Sin dependencias (solo la biblioteca estándar). No entrena, no toca tu bucle, no decide por vos. No modela el efecto del hardware: está medido que cambiar de backend aporta 0.53× la variación entre semillas en régimen tardío, despreciable frente a lo que ya se reporta.

Cita

Speranza, M. R. (2026). Stopping criteria below the signal-to-noise floor: window length, not tolerance, governs convergence detection in architecture comparisons. 10.5281/zenodo.21630279

MIT.