import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import entropy
1. Configurar Seed para Reprodutibilidade
np.random.seed(42)
2. Gerar Amostras Iniciais (Dados Reais no Manifold)
Simulamos dois clusters de dados "estruturados"
n_samples = 1000
data_0 = np.concatenate([
np.random.normal(loc=-2, scale=0.5, size=(n_samples // 2, 2)),
np.random.normal(loc=2, scale=0.5, size=(n_samples // 2, 2))
])
3. Agendamento de Ruído (Schedule)
timesteps = 50
betas = np.linspace(0.01, 0.1, timesteps) # Fração de ruído por passo
Listas para armazenar estados e entropia
history = [data_0]
entropies = []
def calculate_entropy(data):
# Calculamos um histograma 2D para estimar a distribuição de probabilidade
hist, _ = np.histogramdd(data, bins=30, range=[[-10, 10], [-10, 10]], density=True)
return entropy(hist.flatten() + 1e-12) # Adicionamos pequeno valor para evitar log(0)
4. Executar o Forward Process (Cadeia de Markov)
current_data = data_0
for t in range(timesteps):
noise = np.random.normal(size=current_data.shape)
# x_t = sqrt(1-beta)*x_{t-1} + sqrt(beta)*noise
current_data = np.sqrt(1 - betas[t]) * current_data + np.sqrt(betas[t]) * noise
history.append(current_data)
entropies.append(calculate_entropy(current_data))
5. Visualização
fig, axs = plt.subplots(1, 4, figsize=(20, 5))
steps_to_show = [0, 10, 25, 49]
for i, step in enumerate(steps_to_show):
axs[i].scatter(history[step][:, 0], history[step][:, 1], alpha=0.5, s=10)
axs[i].set_title(f"Timestep {step}\nEntropia: {calculate_entropy(history[step]):.2f}")
axs[i].set_xlim(-8, 8); axs[i].set_ylim(-8, 8)
plt.tight_layout()
plt.show()
Gráfico da Entropia ao longo do tempo
plt.figure(figsize=(8, 4))
plt.plot(entropies, color='red', lw=2)
plt.title("Aumento da Entropia (Desordem) no Forward Process")
plt.xlabel("Timestep (t)")
plt.ylabel("Entropia Estimada")
plt.grid(True)
plt.show()