Módulo 7 · Grafos, cálculo e otimização
Derivadas, gradientes e a regra da cadeia
Aula 7.2 · cerca de 22 minutos
A derivada f′(x) é a taxa de variação instantânea: o quanto f muda por unidade de x. O gradiente ∇f generaliza isso para várias variáveis: é o vetor das derivadas parciais e aponta na direção de maior subida.
f′(x) = lim_{h→0} (f(x+h) − f(x)) / h
∇f(x, y) = (∂f/∂x, ∂f/∂y)
Regra da cadeia: (f ∘ g)′(x) = f′(g(x)) · g′(x)Backpropagation é só a regra da cadeia aplicada de trás para frente num grafo de computação. Cada nó sabe a derivada local, e o gradiente de quem vem depois é multiplicado por ela.
class Valor:
"""Diferenciação automática reversa em ~25 linhas (no estilo do micrograd)."""
def __init__(self, v, pais=(), locais=()):
self.v, self.grad = v, 0.0
self.pais, self.locais = pais, locais
def __add__(self, o):
return Valor(self.v + o.v, (self, o), (1.0, 1.0))
def __mul__(self, o):
return Valor(self.v * o.v, (self, o), (o.v, self.v))
def backward(self):
ordem, visto = [], set()
def topo(n):
if n not in visto:
visto.add(n)
for p in n.pais:
topo(p)
ordem.append(n)
topo(self)
self.grad = 1.0
for n in reversed(ordem):
for p, d in zip(n.pais, n.locais):
p.grad += d * n.grad # regra da cadeia
x, y = Valor(3.0), Valor(4.0)
z = x * y + x # z = xy + x
z.backward()
print(x.grad, y.grad) # 5.0 (= y + 1), 3.0 (= x)Dica: Teste gradientes com diferenças finitas: (f(x+h) − f(x−h)) / 2h, com h ≈ 1e−5. Se não bater com o gradiente analítico, há bug no backward.
Exercício 1
Derive f(x) = (3x + 1)².
Exercício 2
Qual é o gradiente de f(x, y) = x²y + y³?