Una implementación de codificación de decodificación cerebral de extremo a extremo a partir de señales MEG utilizando NeuralSet y aprendizaje profundo para predecir características lingüísticas
EPOCHS = 15 opt = torch.optim.AdamW(model.parameters(), lr=1e-3, Weight_decay=1e-4) sched = torch.optim.lr_scheduler.CosineAnnealingLR(opt, T_max=EPOCHS) loss_fn = nn.MSELoss() hist = {“tr”: []”va”: []”r”: []} def pearson(a, b): a, b = a – a.mean(), b – b.mean() return (a*b).sum() / (a.norm()*b.norm() + 1e-8) print(“\n” + “=”*64) print(f”{‘Epoch’:>5} | {‘train’:>9} | {‘val’:>9} | {‘val_r’:>7}”) print(“=”*64) para ep en el rango(EPOCHS): model.train(); tr= []
para lote en train_loader: x, y = prep(batch) loss = loss_fn(model(x), y) opt.zero_grad(); loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) opt.step(); tr.append(loss.item()) sched.step() model.eval(); va, P, T = [], [], []
con torch.no_grad(): para lote en val_loader: x, y = prep(batch); p = modelo(x) va.append(loss_fn(p, y).item()); P.append(p.cpu()); T.append(y.cpu()) P, T = torch.cat(P), torch.cat(T) r = pearson(P, T).item() hist[“tr”].append(np.mean(tr)); historia[“va”].append(np.mean(va)); historia[“r”].append(r) print(f”{ep+1:>5d} | {np.mean(tr):>9.4f} | {np.mean(va):>9.4f} | {r:>+7.3f}”) model.eval(); P, T = [], []
con torch.no_grad(): para lote en test_loader: x, y = prep(batch) P.append(model(x).cpu()); T.append(y.cpu()) P, T = torch.cat(P), torch.cat(T) test_r = pearson(P, T).item() test_mse = ((P – T) ** 2).mean().item() print(f”\nTEST | Pearson r = {test_r:+.3f} MSE = {test_mse:.3f}”) print(f”(Las señales MEG sintéticas son aleatorio por diseño: se espera una r pequeña/cero.)”) fig, ax = plt.subplots(1, 3, figsize=(15, 4)) ax[0].plot(historia[“tr”]etiqueta=”tren”); hacha[0].plot(historia[“va”]etiqueta=”val”) hacha[0].set(xlabel=”Epoch”, ylabel=”MSE”, title=”Curvas de pérdida”); hacha[0].leyenda(); hacha[0].grid(alfa=.3) hacha[1].plot(historia[“r”]color=”C2″); hacha[1].axhline(0, color=”k”, ls=”–“, alfa=.4) hacha[1].set(xlabel=”Epoch”, ylabel=”Pearson r”, title=”Correlación de validación”); hacha[1].grid(alpha=.3) m = float(max(T.abs().max(), P.abs().max())) hacha[2].scatter(T.numpy(), P.numpy(), s=10, alfa=.35) hacha[2].trama([-m, m], [-m, m]”k–“, alfa=.4) hacha[2].set(xlabel=”True (recuento de caracteres con puntuación z)”, ylabel=”Predicho”, title=f”Predicciones de prueba (r = {test_r:+.3f})”); hacha[2].grid(alfa=.3) plt.tight_layout(); plt.show() print(“\n✅ ¡Tutorial completo!”) print(f” • Estudio utilizado: {study_name}”) print(f” • Pipeline: Chain → Segmenter → SegmentDataset → DataLoader”) print(f” • Extractor personalizado: CharCount (subclase de BaseStatic)”) print(f” • Extractor incorporado: MegExtractor @ 100 Hz”) print(f” • Modelo: 1×1 conv espacial + 2 conv temporal + cabeza lineal”)