Spiking Neural Networks e hardware neuromorfico

Spiking Neural Networks e hardware neuromorfico

Condividi con i tuoi amici...

Il rapporto tra scienze cognitive e intelligenza artificiale è molto stretto. Abbiamo già esaminato l’argomento nell’articolo “Le scienze cognitive e l’intelligenza-artificiale”

Ora, faremo un passo in avanti per mostrare come grazie ad un modello di reti neurali più avanzato questo rapporto sia ancora più forte. Si tratta delle Spiking Neural Networks (SNN).

Le SNN rappresentano un paradigma avanzato di reti neurali artificiali, ispirato in modo più fedele al funzionamento biologico del cervello umano. A differenza delle tradizionali Artificial Neural Networks (ANN), che elaborano informazioni con operazioni matematiche continue basate su pesi e attivazioni, le SNN si basano su impulsi discreti nel tempo, detti spike, simulando l’attività dei neuroni biologici.

Nel cervello, i neuroni comunicano attraverso potenziali d’azione (spike), inviando segnali elettrici solo quando il loro potenziale di membrana supera una soglia. Le SNN riproducono questo comportamento utilizzando modelli come:

Modello di Hodgkin-Huxley
Modello Integrate-and-Fire
Modello Leaky Integrate-and-Fire (LIF)

Le Spiking Neural Networks (SNN) richiedono supporti hardware e software specifici per essere eseguite in modo efficiente, poiché il loro funzionamento basato su eventi (event-driven computation) è diverso dalle tradizionali Artificial Neural Networks (ANN). Vediamo i principali supporti:

Le SNN possono essere eseguite su hardware classico (CPU, GPU) oppure su hardware neuromorfico, progettato appositamente per imitare il funzionamento del cervello.

Le CPU e GPU tradizionali possono simulare SNN tramite software, ma l’efficienza è limitata rispetto a hardware specializzato. Le GPU (es. NVIDIA) possono accelerare alcune operazioni, ma non sono ottimizzate per i spike.

Hardware neuromorfico

L’hardware neuromorfico è una classe di processori progettati per imitare il funzionamento del cervello umano, sia in termini di struttura che di modalità di elaborazione delle informazioni. A differenza dei computer tradizionali, che eseguono calcoli basati su operazioni sequenziali e aritmetica numerica (come CPU e GPU), i sistemi neuromorfici utilizzano neuroni artificiali che comunicano tramite impulsi (spikes), come avviene nel cervello.

Il termine “neuromorfico” fu coniato da Carver Mead negli anni ’80, quando propose l’idea di realizzare circuiti elettronici che riproducessero il comportamento delle reti neurali biologiche.

Nei sistemi basati su CPU e GPU, i pesi delle reti neurali artificiali (ANN) non esistono fisicamente sotto forma di circuiti, ma sono memorizzati come numeri in memoria (RAM, VRAM, o archiviazione permanente). Quando si esegue il deep learning su una GPU NVIDIA, i pesi sono memorizzati in VRAM come matrici numeriche e vengono moltiplicati tramite operazioni tensoriali accelerate.

Nei chip neuromorfici, i pesi sinaptici che regolano la forza della connessione tra neuroni sono immagazzinati in modo fisico, attraverso diverse tecnologie.

Le memorie resistive (RRAM, memristor), per esempio utilizzano cambiamenti di resistenza per memorizzare i pesi. Le Memorie a cambiamento di fase (PCM – Phase Change Memory) memorizzano informazioni alterando lo stato fisico di materiali a base di germanio, simili a quelli usati nei CD-RW. Nei Transistor MOSFET con capacità variabile, i pesi sono rappresentati da cariche elettriche immagazzinate nei transistor. Alcuni chip usano tensioni o correnti analogiche per rappresentare i pesi. Per esempio, il chip Loihi (Intel) usa memorie resistive per le sinapsi e circuiti digitali per i neuroni, mentre BrainScaleS (Heidelberg University) usa circuiti analogici per emulare il comportamento delle sinapsi biologiche.

In questi processori l’elaborazione avviene solo quando un neurone virtuale riceve uno spike (impulso).
Questo riduce il consumo energetico rispetto alle CPU/GPU, che elaborano continuamente dati in parallelo. Invece di calcolare il gradiente come nel backpropagation delle ANN, i chip neuromorfici usano regole biologiche come la Spike-Timing-Dependent Plasticity (STDP), che modifica i pesi dinamicamente senza bisogno di grosse operazioni matematiche.

I neuroni biologici

I neuroni sono le unità fondamentali del sistema nervoso e comunicano tra loro attraverso segnali elettrici e chimici. il neurone biologico è composto da un corpo cellulare detto soma, da ramificazioni dette dendriti attarverso i quali esso riceve impulsi elettrici da altri neuroni e da un prolungamento detto assone lungo il quale il neurone può trasmettere un segnale ad altri neuroni.

L’attività dei neuroni è regolata dal potenziale di membrana, che può generare un potenziale d’azione quando supera una determinata soglia.

Il potenziale di membrana è la differenza di carica elettrica tra l’interno e l’esterno del neurone. Questa differenza è mantenuta da:

Pompe ioniche (come la pompa sodio-potassio, che trasporta Na⁺ fuori e K⁺ dentro)
Canali ionici (che permettono il passaggio selettivo di ioni)
Gradienti di concentrazione ionica (che creano differenze di carica)

Il valore del potenziale di membrana a riposo è di circa -70 mV (l’interno è più negativo rispetto all’esterno). Se il potenziale aumenta (diventa meno negativo), il neurone si avvicina alla soglia di attivazione. La soglia di attivazione è di circa -55 mV se superata, si genera un potenziale d’azione.
ISe diventa più negativo di -70 mV, il neurone diventa meno eccitabile.

Se il potenziale di membrana supera la soglia (-55 mV), si innesca un potenziale d’azione, un segnale elettrico che si propaga lungo l’assone del neurone.

Fasi del potenziale d’azione:

Depolarizzazione: i canali del sodio (Na⁺) si aprono → il Na⁺ entra nella cellula → il potenziale sale fino a ≈ +40 mV.

Ripolarizzazione: i canali del sodio si chiudono e si aprono quelli del potassio (K⁺) → il K⁺ esce → il potenziale torna negativo.

Iperpolarizzazione e ritorno al riposo: Il potenziale scende sotto -70 mV (iperpolarizzazione), poi torna a -70 mV grazie alla pompa sodio-potassio.

Propagazione del segnale: il potenziale d’azione si propaga lungo l’assone fino ai terminali sinaptici. Quando il segnale raggiunge la sinapsi, vengono rilasciati neurotrasmettitori, che attivano il neurone successivo.

Legge di Hebb

La Legge di Hebb (1949) descrive un principio fondamentale dell’apprendimento nel cervello biologico:

“Neurons that fire together, wire together”

“Se due neuroni si attivano insieme ripetutamente, la loro connessione sinaptica si rafforza.”

Se un neurone A stimola spesso un neurone B, il legame tra loro si rafforza. Se invece non si attivano insieme, la connessione si indebolisce o scompare. Questo fenomeno è noto come plasticità sinaptica ed è la base dell’apprendimento e della memoria.

L’attivazione ripetuta aumenta la produzione di neurotrasmettitori e il numero di recettori sinaptici.
Le connessioni più forti facilitano la trasmissione futura dei segnali.

Le Spiking Neural Networks (SNN) riproducono il funzionamento del cervello utilizzando modelli di potenziali di membrana, spike e plasticità sinaptica.

Ogni neurone ha un potenziale di membrana simulato. Se riceve impulsi (spikes) da altri neuroni, il suo potenziale aumenta. Se supera la soglia di attivazione, emette uno spike. Dopo lo spike, il neurone si resetta (ripolarizzazione e periodo refrattario).

La regola di plasticità usata nelle SNN è la Spike-Timing-Dependent Plasticity (STDP): Se un neurone post-sinaptico riceve uno spike subito dopo uno pre-sinaptico, la connessione si rafforza (LTP – Long-Term Potentiation). Se lo riceve con un grande ritardo, la connessione si indebolisce (LTD – Long-Term Depression).

Modello di Hodgkin-Huxley

Si è già mosrato che il neurone ha una membrana carica elettricamente che separa l’interno della cellula dall’esterno. Questa membrana ha dei canali ionici che permettono il passaggio di ioni (Na⁺, K⁺, Cl⁻), regolando il potenziale elettrico.

A riposo, l’interno della cellula è più negativo rispetto all’esterno (~ -70 mV).
Se il neurone riceve un segnale sufficiente, la membrana si depolarizza, facendo entrare ioni sodio (Na⁺).
Se la soglia viene superata (~ -55 mV), si genera un potenziale d’azione che viaggia lungo l’assone.
Il neurone poi ripolarizza, facendo uscire ioni potassio (K⁺), tornando al suo stato iniziale.

Prima che il neurone riceva uno stimolo, il suo potenziale di membrana è stabile, tipicamente intorno a -70 mV. Questo stato è detto potenziale di riposo e si mantiene grazie a un equilibrio tra le correnti ioniche.

Il potenziale di riposo è determinato da una distribuzione asimmetrica degli ioni

Più Na⁺ (sodio) all’esterno
Più K⁺ (potassio) all’interno

La membrana è selettivamente permeabile

Più permeabile al K⁺, che tende ad uscire.
Poco permeabile al Na⁺, che tende ad entrare.
Pompa Sodio-Potassio (Na⁺/K⁺-ATPasi)

Espelle 3 Na⁺ fuori e riporta 2 K⁺ dentro → mantiene la distribuzione ionica.
L’interno del neurone rimane negativo rispetto all’esterno, stabilizzando il potenziale prima dell’impulso.

C’è un gradiente di concentrazione → il Na⁺ vorrebbe entrare. La membrana lo impedisce, mantenendo l’interno negativo.

Quando la membrana supera la soglia (~ -55 mV), i canali del sodio si aprono.
Il Na⁺ entra rapidamente, rendendo l’interno positivo e innesca il potenziale d’azione.

Il modello di Hodgkin-Huxley descrive questo processo con equazioni differenziali basate sulla corrente ionica attraverso la membrana.

Hodgkin e Huxley considerarono la membrana del neurone come un circuito elettrico, dove: La membrana è come un condensatore (accumula carica). I canali ionici sono resistenze variabili (permettono il flusso di corrente). Le correnti ioniche sono guidate dalla differenza di potenziale (dovuta ai gradienti ionici tra interno ed esterno).

Il neurone viene modellato come un circuito elettrico con:

Capacità della membrana (Cm)
Correnti ioniche attraverso i canali di sodio (Na⁺), potassio (K⁺) e una corrente di “perdita” (leak, L)
Voltaggio di membrana (V) che varia nel tempo

Simulazione con Python


import numpy as np
import matplotlib.pyplot as plt

# Parametri del modello Hodgkin-Huxley
Cm = 1.0  # Capacità di membrana (µF/cm^2)
ENa = 50.0  # Potenziale di equilibrio del sodio (mV)
EK = -77.0  # Potenziale di equilibrio del potassio (mV)
EL = -54.4  # Potenziale di equilibrio della perdita (leak) (mV)

# Conduttanze massime (mS/cm^2)
gNa = 120.0  # Conduttanza massima del sodio
gK = 36.0  # Conduttanza massima del potassio
gL = 0.3  # Conduttanza della perdita

# Funzioni per i tassi di transizione di gating
def alpha_m(V): return 0.1 * (V + 40) / (1 - np.exp(-(V + 40) / 10))
def beta_m(V): return 4.0 * np.exp(-(V + 65) / 18)
def alpha_h(V): return 0.07 * np.exp(-(V + 65) / 20)
def beta_h(V): return 1 / (1 + np.exp(-(V + 35) / 10))
def alpha_n(V): return 0.01 * (V + 55) / (1 - np.exp(-(V + 55) / 10))
def beta_n(V): return 0.125 * np.exp(-(V + 65) / 80)

# Simulazione
dt = 0.01  # Passo temporale (ms)
T = 100.0  # Durata della simulazione (ms)
time = np.arange(0, T, dt)

# Inizializzazione delle variabili
V = -65.0  # Potenziale di membrana iniziale (mV)
m = alpha_m(V) / (alpha_m(V) + beta_m(V))
h = alpha_h(V) / (alpha_h(V) + beta_h(V))
n = alpha_n(V) / (alpha_n(V) + beta_n(V))

V_trace = []
I_stim = np.zeros_like(time)
I_stim[1000:3000] = 10.0  # Stimolo applicato tra 10ms e 30ms

# Loop di simulazione
for i in range(len(time)):
    # Correnti ioniche
    INa = gNa * (m ** 3) * h * (V - ENa)
    IK = gK * (n ** 4) * (V - EK)
    IL = gL * (V - EL)
    
    # Aggiornamento del potenziale di membrana
    dVdt = (I_stim[i] - (INa + IK + IL)) / Cm
    V += dVdt * dt
    
    # Aggiornamento delle variabili di gating
    dm_dt = alpha_m(V) * (1 - m) - beta_m(V) * m
    dh_dt = alpha_h(V) * (1 - h) - beta_h(V) * h
    dn_dt = alpha_n(V) * (1 - n) - beta_n(V) * n
    
    m += dm_dt * dt
    h += dh_dt * dt
    n += dn_dt * dt
    
    # Salvataggio del potenziale
    V_trace.append(V)

# Plot dei risultati
plt.figure(figsize=(10, 5))
plt.plot(time, V_trace, label='Potenziale di membrana (mV)')
plt.xlabel('Tempo (ms)')
plt.ylabel('Potenziale di membrana (mV)')
plt.title('Simulazione del modello di Hodgkin-Huxley')
plt.legend()
plt.grid()
plt.show()

Il neurone non risponde immediatamente: la depolarizzazione avviene solo dopo il superamento della soglia (~ -55 mV). Gli spike sono distinti e separati: il neurone si ripristina prima di generare un nuovo impulso. Dopo ogni picco, c’è un’iperpolarizzazione: il neurone diventa meno sensibile per un breve periodo → Periodo refrattario. L’attività è simile ai potenziali d’azione biologici, confermando la validità del modello di Hodgkin-Huxley.

Versioni semplificate del modello

Nelle Spiking Neural Networks (SNN), il modello di Hodgkin-Huxley è usato per simulare il comportamento realistico dei neuroni. Tuttavia, è computazionalmente costoso, quindi spesso si usano versioni semplificate come il modello Integrate-and-Fire (IF)

Questo modello approssima l’effetto del potenziale di membrana senza risolvere tutte le equazioni di Hodgkin-Huxley, rendendo le SNN più efficienti.

Il modello Integrate-and-Fire (IF) è uno dei modelli più semplici per descrivere il comportamento di un neurone biologico in una rete neurale spiking (SNN, Spiking Neural Network). Esso si basa sul principio che un neurone accumula potenziale di membrana in risposta agli input sinaptici fino a raggiungere una soglia, momento in cui si genera un potenziale d’azione (spike) e il potenziale viene resettato.

Simulazione con Python

import numpy as np
import matplotlib.pyplot as plt

# Parametri del modello Integrate-and-Fire
T = 200  # Tempo totale di simulazione (ms)
dt = 1   # Passo di tempo (ms)
tau_m = 10  # Costante di tempo della membrana (ms)
V_rest = -65  # Potenziale di riposo (mV)
V_th = -50  # Soglia di attivazione (mV)
V_reset = -65  # Valore di reset (mV)
R_m = 10  # Resistenza della membrana (MΩ)
I = 2  # Corrente in ingresso (nA)

# Variabili della simulazione
V = V_rest  # Potenziale iniziale
V_trace = []  # Traccia del potenziale di membrana
spike_times = []  # Lista per registrare i tempi degli spike

time = np.arange(0, T, dt)

# Simulazione del neurone IF
for t in time:
    dV = (- (V - V_rest) + R_m * I) / tau_m * dt
    V += dV
    if V >= V_th:
        V_trace.append(20)  # Picco di spike
        spike_times.append(t)
        V = V_reset
    else:
        V_trace.append(V)

# Plot della dinamica del potenziale di membrana
plt.figure(figsize=(8, 4))
plt.plot(time, V_trace, label='Potenziale di Membrana')
plt.axhline(V_th, color='r', linestyle='--', label='Soglia')
plt.xlabel('Tempo (ms)')
plt.ylabel('Potenziale (mV)')
plt.legend()
plt.title('Neurone Integrate-and-Fire')
plt.show()

# Implementazione della regola STDP
A_plus = 0.1  # Fattore di potenziamento
A_minus = 0.12  # Fattore di depressione
Tau_plus = 20  # Costante di tempo STDP
Tau_minus = 20

def stdp(delta_t):
    if delta_t > 0:
        return A_plus * np.exp(-delta_t / Tau_plus)
    else:
        return -A_minus * np.exp(delta_t / Tau_minus)

# Esempio di aggiornamento pesi con STDP
pre_spike_times = np.array([10, 50, 90, 130, 170])
post_spike_times = np.array([20, 60, 100, 140, 180])

delta_t = post_spike_times[:, None] - pre_spike_times[None, :]
weight_updates = stdp(delta_t)

# Plot della funzione STDP
plt.figure(figsize=(6, 4))
plt.plot(delta_t.flatten(), weight_updates.flatten(), 'o')
plt.axhline(0, color='k', linestyle='--')
plt.xlabel('Δt (ms)')
plt.ylabel('Δw')
plt.title('Regola STDP')
plt.show()

Il modello applicato è quello di un circuito RC in parallelo

Un circuito RC in parallelo è un circuito elettrico composto da un resistore R e un condensatore C collegati in parallelo a una sorgente di tensione. Per analizzarlo matematicamente, si usano le equazioni differenziali basate sulle leggi di Kirchhoff e sulle proprietà dei componenti.

Il circuito equivalente a un neurone nel modello IAF è costituito da:

La resistenza R rappresenta le perdite della membrana del neurone, ovvero la conduttanza delle sue perdite ioniche. È associata al canale di fuga della membrana.
La capacità C rappresenta la capacità della membrana di accumulare carica, ovvero la capacità elettrica della membrana neuronale.
La corrente I(t): rappresenta la corrente sinaptica ricevuta dal neurone, ossia il segnale in ingresso dai neuroni presinaptici.

Modello ulteriormente semplificato: il modello Integrate-and-Fire

Risorsa utile

Per un approfondimento dei concetti di dinamica neuronale impiegati nella realizzazione delle reti SNN puoi leggere anche il libro online Neuronal Dynamics: From single neurons to networks and models of cognition di Wulfram Gerstner, Werner M. Kistler, Richard Naud and Liam Paninski.