← Back to list

Code Snippets That Can Change AI in Neurosciences

Rey Rad — Neuroscience & AI Research

Rey Rad · 2026-05-14 20:35 · 0 claps · 6.1 min read
#neuroscience #ai #neurotechnology #science #neurotech
Open on Medium ↗
Wiki topics: AI · AI · General NEU · Neuroscience 🔬 · Science · General 🐾 · Pets & Animals

Code Snippets That Can Change AI in Neurosciences

Rey Rad — Neuroscience & AI Research

“The most powerful instrument for studying the brain is no longer a microscope or an MRI — it’s a well-crafted for loop."

Neuroscience is drowning in data. A single recording session with a modern Neuropixels probe can generate gigabytes of neural signals. A connectomics dataset from a cubic millimetre of cortex contains millions of synapses. A resting-state fMRI session yields a 4D tensor that no human can intuitively parse.

The field is being transformed not just by AI models, but by specific, targeted pieces of code, algorithms that decode brain states, detect spikes in noise, model consciousness, or simulate entire neural circuits. What follows is a curated collection of the most consequential code concepts in modern computational neuroscience, each with a working snippet and an explanation of why it matters.

1. Neural Spike Sorting with Clustering

⬆ High Impact — electrophysiology

Before you can analyze what neurons are “saying,” you need to isolate individual neurons from a raw electrode signal, a process called spike sorting. Modern approaches use unsupervised ML to cluster waveform shapes. This snippet uses UMAP + HDBSCAN, the gold standard pairing.

import numpy as np
import umap
import hdbscan
from scipy.signal import butter, filtfilt

# Bandpass filter raw electrode signal (300–3000 Hz)
def bandpass(signal, fs=30000, low=300, high=3000):
    b, a = butter(4, [low/(fs/2), high/(fs/2)], btype='band')
    return filtfilt(b, a, signal)

# Extract spike waveforms around threshold crossings
def extract_spikes(filtered, threshold_sigma=5, window=64):
    thresh = -threshold_sigma * np.median(np.abs(filtered) / 0.6745)
    crossings = np.where(np.diff((filtered < thresh).astype(int)) == 1)[0]
    waveforms = []
    for c in crossings:
        if c + window < len(filtered):
            waveforms.append(filtered[c:c + window])
    return np.array(waveforms)

# Dimensionality reduction → clustering → unit assignment
def sort_spikes(waveforms):
    reducer = umap.UMAP(n_components=2, random_state=42)
    embedding = reducer.fit_transform(waveforms)

    clusterer = hdbscan.HDBSCAN(min_cluster_size=30, min_samples=5)
    labels = clusterer.fit_predict(embedding)

    return labels, embedding

# Usage
raw = np.load('electrode_trace.npy')
filtered = bandpass(raw)
waveforms = extract_spikes(filtered)
unit_labels, projection = sort_spikes(waveforms)
print(f"Found {len(set(unit_labels)) - 1} putative neurons")

Why does this change things?

  • Manual spike sorting took hours per recording session. This pipeline runs in seconds and scales to hundreds of channels simultaneously — enabling large-scale population coding studies that were previously impossible.

2. Brain State Decoder with an LSTM

⬆ High Impact — BCI · decoding

Brain-Computer Interfaces (BCIs) depend on real-time decoding of neural population activity. Long Short-Term Memory networks are particularly well-suited because neural activity in the past 500ms of firing rates predicts what a subject will do next. This snippet decodes intended movement direction from motor cortex activity.

import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset

class NeuralDecoder(nn.Module):
    def __init__(self, input_dim, hidden_dim=128, output_dim=2):
        super().__init__()
        self.lstm = nn.LSTM(input_dim, hidden_dim,
                            num_layers=2, batch_first=True,
                            dropout=0.3)
        self.norm  = nn.LayerNorm(hidden_dim)
        self.head  = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        out, _ = self.lstm(x)          # (batch, time, hidden)
        out    = self.norm(out[:, -1]) # last timestep
        return self.head(out)           # predict (vx, vy)

# X: (trials, timesteps, neurons)  Y: (trials, 2) velocity
X = torch.tensor(spike_rates, dtype=torch.float32)
Y = torch.tensor(velocities,  dtype=torch.float32)

model     = NeuralDecoder(input_dim=X.shape[2])
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3)
loss_fn   = nn.MSELoss()

for epoch in range(100):
    pred = model(X)
    loss = loss_fn(pred, Y)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    if epoch % 10 == 0:
        print(f"Epoch {epoch} | Loss: {loss.item():.4f}")

Why does this change things?

  • This architecture underpins modern neuroprosthetics. When trained on population activity from the motor cortex, it achieves R² > 0.85 for continuous cursor control, giving paralyzed patients the ability to type or control robotic arms in real time.

3. Functional Connectivity with Partial Correlation

Medium–High Impact — fMRI · connectomics

fMRI data lets us ask: which brain regions talk to each other? Partial correlation controls for indirect connections, so we don’t mistake A→C→B for A→B. The resulting graph is the functional connectome, and its topology predicts cognitive ability, disease state, and even personality.

import numpy as np
from sklearn.covariance import GraphicalLassoCV
import networkx as nx
import matplotlib.pyplot as plt

# roi_ts: (time_points, n_ROIs) - parcellated BOLD signal
def build_functional_connectome(roi_ts, threshold=0.2):
    # Graphical LASSO estimates sparse precision (partial corr) matrix
    estimator = GraphicalLassoCV(alphas=10, cv=5)
    estimator.fit(roi_ts)

    precision = estimator.precision_
    n = precision.shape[0]

    # Convert precision to partial correlations
    partial_corr = np.zeros_like(precision)
    for i in range(n):
        for j in range(n):
            if i != j:
                partial_corr[i, j] = (
                    -precision[i, j] /
                    np.sqrt(precision[i, i] * precision[j, j])
                )

    # Build graph, threshold weak edges
    G = nx.from_numpy_array(np.abs(partial_corr) * (np.abs(partial_corr) > threshold))
    print(f"Graph density: {nx.density(G):.3f}")
    print(f"Modularity:    {nx.community.modularity(G, nx.community.greedy_modularity_communities(G)):.3f}")
    return G, partial_corr

G, pcorr = build_functional_connectome(roi_ts)

4. Integrate-and-Fire Neuron Simulation

◈ Foundational — computational modeling

Before fitting data to a black-box model, neuroscientists build mechanistic models grounded in biophysics. The Leaky Integrate-and-Fire (LIF) neuron is the workhorse; it captures the threshold-firing logic of a real neuron in just a handful of differential equations.

import numpy as np
import matplotlib.pyplot as plt

# LIF parameters
tau_m  = 20e-3   # membrane time constant (s)
V_rest = -70e-3  # resting potential (V)
V_th   = -50e-3  # spike threshold (V)
V_reset= -80e-3  # post-spike reset (V)
R_m    = 10e6    # membrane resistance (Ω)
dt     = 1e-4    # timestep (s)
T      = 0.5     # simulation duration (s)

t      = np.arange(0, T, dt)
V      = np.full_like(t, V_rest)
spikes = []

# Sinusoidal input current (simulates oscillating input)
I_ext = 2e-9 * (1 + np.sin(2 * np.pi * 8 * t))  # 8 Hz theta

for i in range(1, len(t)):
    dV = (-(V[i-1] - V_rest) + R_m * I_ext[i]) / tau_m
    V[i] = V[i-1] + dV * dt

    if V[i] >= V_th:
        V[i]  = V_reset
        spikes.append(t[i])

print(f"Firing rate: {len(spikes)/T:.1f} Hz")
print(f"Spike times (first 5): {[f'{s*1000:.1f}ms' for s in spikes[:5]]}")

Why does this change things?

When scaled to networks of thousands of LIF neurons, this code can simulate an entire cortical column — generating predictions about population dynamics, oscillations, and how anesthetics affect consciousness. It’s the backbone of large-scale brain simulators like NEST and Brian2.

5. EEG Microstates & Consciousness Markers

⬆ High Impact — consciousness · clinical

EEG microstates are quasi-stable topographic configurations of scalp potentials that last ~80ms. They are the “atoms of thought” — and their transitions encode cognitive and affective states. This snippet extracts microstates via modified k-means, used in consciousness research and Graves’ disease-related autoimmune encephalopathy work.

import numpy as np
from sklearn.preprocessing import normalize

def extract_microstates(eeg, n_states=4, max_iter=500):
    """Modified polarity-invariant k-means for EEG microstates.
    eeg: (n_channels, n_timepoints)
    """
    # Normalize frames to unit norm (polarity-invariant)
    frames = normalize(eeg.T)  # (n_tp, n_ch)

    # Initialize cluster centers from GFP peaks
    gfp = np.std(eeg, axis=0)
    peak_idx = np.argsort(gfp)[-n_states * 10:]
    np.random.shuffle(peak_idx)
    centers = frames[peak_idx[:n_states]]

    for _ in range(max_iter):
        # Assign each frame to nearest microstate (polarity-invariant)
        corr    = np.abs(frames @ centers.T)
        labels  = np.argmax(corr, axis=1)

        new_centers = np.zeros_like(centers)
        for k in range(n_states):
            mask = labels == k
            if mask.any():
                # Flip signs to align polarity
                segment     = frames[mask]
                signs       = np.sign(segment @ centers[k])
                new_centers[k] = normalize((signs[:, np.newaxis] * segment).mean(axis=0, keepdims=True))[0]

        if np.allclose(centers, new_centers, atol=1e-6):
            break
        centers = new_centers

    duration_ms = np.array(
        [np.sum(labels == k) for k in range(n_states)]
    ) / eeg.shape[1] * 1000

    return labels, centers, duration_ms

labels, maps, durations = extract_microstates(eeg_data)
print(f"Mean duration per state (ms): {durations.round(1)}")

6. Graph Neural Network on Connectomes

⬆ High Impact — neurological disease prediction

The brain is a graph. Graph Neural Networks (GNNs) can directly operate on brain connectivity graphs, classifying patients by disease state or predicting cognitive scores. This snippet builds a Graph Convolutional Network on functional connectome data — applicable to Alzheimer’s detection, ALS staging, and autoimmune encephalitis profiling.

import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv, global_mean_pool
from torch_geometric.data import Data

class BrainGNN(torch.nn.Module):
    def __init__(self, node_features=1, n_classes=2):
        super().__init__()
        self.conv1 = GCNConv(node_features, 64)
        self.conv2 = GCNConv(64, 128)
        self.conv3 = GCNConv(128, 64)
        self.fc    = torch.nn.Linear(64, n_classes)
        self.bn1   = torch.nn.BatchNorm1d(64)
        self.bn2   = torch.nn.BatchNorm1d(128)

    def forward(self, data):
        x, edge_index, batch = data.x, data.edge_index, data.batch

        x = F.elu(self.bn1(self.conv1(x, edge_index)))
        x = F.dropout(x, p=0.3, training=self.training)
        x = F.elu(self.bn2(self.conv2(x, edge_index)))
        x = F.elu(self.conv3(x, edge_index))

        x = global_mean_pool(x, batch)  # graph-level representation
        return F.log_softmax(self.fc(x), dim=1)

# Build graph from functional connectivity matrix
def connectome_to_graph(fcm, threshold=0.3):
    adj = (fcm > threshold).float()
    edges = adj.nonzero(as_tuple=False).t().contiguous()
    node_feats = fcm.mean(dim=1, keepdim=True)  # mean connectivity as node feature
    return Data(x=node_feats, edge_index=edges)

model = BrainGNN(node_features=1, n_classes=2)
print(model)

Why does this change things?

Unlike CNNs or Transformers applied to flattened connectivity matrices, GNNs respect the brain's graph topology — they understand that the hippocampus communicates directly with the entorhinal cortex, not through every other region. This leads to more interpretable, biologically meaningful disease classifiers.

Summary

Six Domains, One Convergence

Each snippet above represents a category of transformation. Together, they form a complete computational neuroscience stack — from raw signals all the way to clinical insights.

The brain is a computational system.

Code is the new microscope.

These snippets are starting points. The real work is in validating them against biological ground truth, adapting them to your dataset, and asking questions the model can’t ask for you. The code doesn’t think — but it does let you think faster, at scale, in dimensions the human eye will never reach.

neuroscience #AI #Neurotech #ArtificialIntelligence


메타데이터
post_id
f5d2d2c5d29f
slug
code-snippets-that-can-change-ai-in-neurosciences-f5d2d2c5d29f
url
https://medium.com/@rh.h.rad/code-snippets-that-can-change-ai-in-neurosciences-f5d2d2c5d29f
canonical_url
https://medium.com/@rh.h.rad/code-snippets-that-can-change-ai-in-neurosciences-f5d2d2c5d29f
author_url
https://medium.com/@rh.h.rad
status
ok
fetched_at
2026-06-15 20:49:13