Cuando también hay que comprobar al comprobador
Al desarrollar un modelo de IA solemos comparar una derivada calculada con una estimación obtenida al cambiar ligeramente un parámetro. Una discrepancia invita a culpar enseguida a la retropropagación. Pero el control numérico también tiene hipótesis y límites. Un paso demasiado pequeño puede empeorar la estimación y una esquina puede no tener derivada. ¿Cómo distinguir una advertencia útil de una falsa alarma?
Usaremos dos funciones escalares: seno, suave y de derivada conocida, y ReLU, una función por tramos habitual en redes neuronales. No entrenamos una red ni ejecutamos una biblioteca de diferenciación automática. El experimento expone las hipótesis de un gradient check. Las cantidades son adimensionales; el argumento 0,7 del seno está en radianes. Todos los resultados numéricos proceden del código archivado.
Una pendiente local, no una simple diferencia
La derivada mide el cambio de salida por un cambio pequeño de entrada en el límite cuando este tiende a cero. En un gráfico es la pendiente tangente. Para f escalar en x, el cociente hacia delante usa f(x+h) y f(x); el central usa puntos a ambos lados. h debe ser distinto de cero al calcular. El cociente central no define una derivada en un punto irregular: es un estimador que coincide bajo condiciones adecuadas.
Expandimos f alrededor de x para entender la precisión sin depender del gráfico. Con suficientes derivadas suaves, f(x+h)=f(x)+hf′(x)+h²f″(x)/2+h³f‴(x)/6+… . El cociente hacia delante conserva un error principal proporcional a h. Restar la expansión con −h cancela términos pares y deja un error central principal h²f‴(x)/6. Así se explica su mejor orden teórico, sin garantizar precisión en cualquier programa.
Por qué reducir h no basta
La derivación supone aritmética exacta. El ordenador evalúa f con redondeos y resta valores casi iguales. Una incertidumbre absoluta cercana a la precisión de máquina en la diferencia se divide por h. Un modelo local simplificado combina C₁h² y C₂u/h para diferencias centrales, con u como precisión relativa y constantes dependientes de función y escala. Reducir h disminuye el primer término, pero puede aumentar el segundo.
Equilibrar los órdenes sugiere h proporcional a u^(1/3) en este modelo central, tras considerar las escalas. No es un valor universal para cualquier red: ruido, redondeo, magnitudes y términos casi nulos cambian la situación. Lo práctico es inspeccionar varios pasos buscando una zona de acuerdo, sin convertir “más pequeño” en sinónimo de “más fiable”.
Seno: un control suave ejecutado
Evaluamos f(x)=sin(x) en x=0,7 con pasos de 10⁻¹ a 10⁻¹⁶. La referencia es math.cos(0.7), aproximadamente 0,7648421872844885: evaluación en doble precisión de la derivada analítica, no oráculo de precisión arbitraria. El mejor error central del barrido aparece en h=10⁻⁵, unos 1,70×10⁻¹¹. Con h=10⁻¹⁶ la estimación pasa a 1,1102230246251565, con diferencia de unos 0,34538. Aquí x+h y x−h aún difieren de x: no hace falta que los puntos coincidan para obtener un mal control.
Paso complejo: potente, pero con condiciones
Para una función con continuación analítica adecuada a los complejos puede usarse un paso imaginario ih. La expansión da f(x)+ihf′(x)−h²f″(x)/2−ih³f‴(x)/6+… . Tomar la parte imaginaria y dividir por h aproxima f′(x) con error teórico de orden h² sin restar reales cercanos. i²=−1 e Im indica la parte imaginaria. Aceptar el tipo complex no basta para validar la técnica.
Para el seno con cmath.sin en h=10⁻¹⁶ la diferencia respecto a la referencia es de unos 1,11×10⁻¹⁶. Es un buen resultado para esa función, no prueba de ausencia universal de redondeo. abs aporta un contraejemplo: en x=0,7 la derivada real de |x| es 1, pero abs(x+ih) devuelve un módulo real y pierde información imaginaria. La receta daría cero, verificado por el código. Antes deben examinarse ramas, comparaciones, conversiones a real y operaciones no analíticas.
ReLU: cuando 0,5 no es una derivada
ReLU significa Rectified Linear Unit: r(x)=max(0, x). Para x negativo salida y pendiente son cero; para x positivo la salida coincide con x y la pendiente es uno. En cero las pendientes laterales difieren y la derivada ordinaria no existe. Sin embargo, el cociente central es (h−0)/(2h)=1/2 para cualquier h positivo. Reducir el paso no lo lleva a cero ni a uno: promedia dos ramas distintas.
| h | Izquierda | Derecha | Central |
|---|---|---|---|
| 1e-1 | 0 | 1 | 0.5 |
| 1e-3 | 0 | 1 | 0.5 |
| 1e-6 | 0 | 1 | 0.5 |
La optimización no suave puede usar convenciones de subgradiente. Para esta función convexa el conjunto en cero es [0,1]. Elegir cero es una posible convención algorítmica, no afirmar que exista una derivada ordinaria igual a cero. Compararla con diferencias centrales da 0 frente a 0,5 sin demostrar por sí solo un bug. No ejecutamos autograd ni atribuimos ese resultado a una versión de un framework.

De la prueba escalar a muchos parámetros
Para una loss escalar L(theta) con d parámetros, las diferencias centrales por coordenada requieren dos evaluaciones por parámetro, unas 2d evaluaciones más el gradiente comprobado. El control direccional compara [L(theta+hv)−L(theta−hv)]/(2h) con g·v, siendo g el gradiente propuesto y v una dirección. Es más barato por dirección, pero puede omitir errores ortogonales a v. No ejecutamos aquí esa prueba multidimensional: es una extensión matemática sin resultados de red inventados.
La función evaluada debe seguir siendo la misma: aleatoriedad, actualizaciones de estado o datos distintos pueden parecer errores de derivada. Concordar en pocos puntos es evidencia local, no corrección global del modelo. Cerca de un cambio de rama hay que comprobar si la perturbación lo atraviesa; fuera de él una discrepancia estable con varios pasos sigue siendo una pista seria. Se trata de interpretar los controles, no ignorarlos.
Una respuesta útil para desarrollar IA
Un gradient check fallido no identifica por sí solo al culpable. En seno el error creció con un paso demasiado pequeño; en ReLU obtuvimos 0,5 donde no existe derivada. Son motivos diferentes para no tratar el estimador como verdad absoluta. Antes de cambiar el modelo deben explicitarse función, suavidad, paso, precisión y convención. El control se convierte en herramienta científica con ámbito de validez, no en veredicto opaco.
Fuentes y reproducibilidad
Leímos la documentación SciPy 1.18.0 de least_squares, parámetro jac, para las condiciones del paso complejo; no ejecutamos SciPy ni sus ejemplos de optimización. Nuestro código usa math y cmath de Python 3.14.0, sin aleatoriedad, y guarda los dieciséis pasos, diferencias laterales y el contraejemplo abs. Las fórmulas se derivan aquí, no son resultados de un paper o producto EL-AI. Las figuras usan Matplotlib; no se afirma rendimiento hardware ni revisión humana.
SciPy 1.18.0 — least_squares, jac.
import math
x=0.7
reference=math.cos(x)
for h in [1e-3,1e-5,1e-16]:
estimate=(math.sin(x+h)-math.sin(x-h))/(2*h)
print(h,estimate,abs(estimate-reference))
relu=lambda z:max(0.0,z)
h=1e-6
assert (relu(h)-relu(-h))/(2*h)==0.5
Código, datos e instrucciones · JSON. Cálculos didácticos ejecutados con Python 3.14.0; figuras con Matplotlib 3.11.2. Análisis asistido por IA, sin afirmar revisión por pares ni humana. Portada original ImageGen ilustrativa: no documenta personas, sedes ni instalaciones de EL-AI. Fuentes consultadas el 21 de octubre de 2026.

