Skip to content

English · Español

Fase 7 — Cuestionarios

🇪🇸 Espejo legible de data/quizzes/phase-07-scalar-autograd.yaml. Incluye la traza de la "diamante" (a y c apareciendo dos veces).

Fuente de verdad: data/quizzes/phase-07-scalar-autograd.yaml.


q-07-01 — ¿Por qué += y no = en la acumulación de _backward?

  1. Porque += es más rápido.
  2. Porque un nodo puede aparecer múltiples veces en el grafo (diamante); cada aparición contribuye un gradiente parcial que debe sumarse; = sobrescribe todos menos el último.
  3. Porque = rompe el topo-sort.
  4. Porque = no está implementado para floats.
Respuesta **Opción 2.** El patrón en diamante es el fallo canónico: `a` alimenta a dos hijos, ambos alimentan a la pérdida. Cada uno contribuye con un parcial. Con `=`, solo el último queda — los tests sin diamantes pasan, el test de diamante falla.

q-07-02 — ¿Por qué orden topológico inverso? (opción múltiple)

  1. Cuando se ejecuta _backward de N, lee N.grad, que debe contener ya el gradiente upstream total.
  2. El topo inverso garantiza que cada hijo de N ya se ha ejecutado, por lo que N.grad está completo.
  3. Visitar en orden directo durante el backward propaga gradientes antes de conocer los valores upstream.
  4. El topo inverso también es necesario para AD en forward-mode.
  5. El orden no importa mientras se use +=.
Respuesta **Opciones 1, 2, 3.** La opción 4 es incorrecta (forward-mode va hacia adelante). La opción 5 es la idea errónea común: incluso con `+=`, un nodo visitado demasiado pronto lee un `.grad` incompleto y propaga la magnitud equivocada a sus padres.

q-07-03 — Traza del diamante (libre)

L = (a*b + c)*(a - c) con a=2, b=3, c=4. Calcula los gradientes, muestra los dos caminos hasta ∂L/∂a.

Respuesta - **∂L/∂a** vía `(a·b + c)`: `f · b = -2 · 3 = -6`. - **∂L/∂a** vía `(a - c)`: `e · 1 = 10 · 1 = 10`. - **Suma:** `-6 + 10 = 4`. - **∂L/∂b** = `f · a = -2 · 2 = -4`. - **∂L/∂c** = `-2 + (-10) = -12`.

q-07-04 — Diferencias finitas vs PyTorch como oráculo (libre)

Respuesta Las diferencias finitas arrastran dos errores: **truncamiento** (`O(ε²)` para diferencias centradas) y **cancelación en coma flotante** (grande para ε pequeño). El ε "correcto" depende del problema; apilas tolerancias sobre tolerancias. PyTorch (o cualquier AD simbólico) computa la derivada **exacta** algebraicamente — reproducible a precisión de máquina, mejor oráculo.

q-07-05 — Necesidad de zero_grad

  1. Porque backward filtra memoria si los gradientes no se resetean.
  2. Porque backward acumula con +=; olvidar poner a cero significa que el gradiente del paso N es la suma de los pasos 1..N — el tamaño de paso efectivo crece linealmente, la pérdida diverge.
  3. Porque optimizer.step no es idempotente.
  4. Porque PyTorch lanza excepción si .grad no es None.
Respuesta **Opción 2.** El mismo `+=` que habilita el patrón en diamante también hace que los gradientes persistan entre pasos. Al paso 100, lr efectivo = 100× el lr configurado.