Internal noise analysis in Spiking Neural Networks. Covers noise sources (channel, synaptic, threshold), propagation mechanisms, and effects on SNN dynamics. Distinguishes additive vs multiplicative noise regimes and their impacts on computation. Activation: SNN, internal noise, spiking neural networks, noise analysis, neuromorphic
A comprehensive analysis of internal noise in spiking neural networks, examining how noise originates from biological sources (channel noise, synaptic variability, threshold fluctuations), propagates through network layers, and affects computation. Distinguishes between additive and multiplicative noise regimes and provides frameworks for characterizing and quantifying noise in both biological and artificial spiking systems.
Internal noise arises from multiple biological mechanisms:
import numpy as np
class NoisyLIFNeuron:
"""
Leaky Integrate-and-Fire neuron with configurable internal noise.
"""
def __init__(self, tau_m=20e-3, v_rest=-65e-3, v_thresh=-50e-3,
noise_type='additive', noise_std=1e-3):
self.tau_m = tau_m
self.v_rest = v_rest
self.v_thresh = v_thresh
self.v_reset = v_rest
self.noise_type = noise_type
self.noise_std = noise_std
self.v_membrane = v_rest
def step(self, input_current, dt=1e-3):
# LIF membrane dynamics
dv = (-(self.v_membrane - self.v_rest) + input_current * 1e6) / self.tau_m * dt
# Internal noise
if self.noise_type == 'additive':
# State-independent: dV = f(V)dt + sigma*dW
noise = np.random.normal(0, self.noise_std)
elif self.noise_type == 'multiplicative':
# State-dependent: dV = f(V)dt + g(V)*dW
noise = np.random.normal(0, self.noise_std * abs(self.v_membrane - self.v_rest))
else:
noise = 0
self.v_membrane += dv + noise
if self.v_membrane >= self.v_thresh:
self.v_membrane = self.v_reset
return True
return False
def characterize_noise_regime(spike_times):
"""
Determine noise regime from spike train statistics.
- Additive noise: CV approx 1 (Poisson-like), Fano factor approx 1
- Multiplicative noise: CV != 1, Fano factor != 1
- Sub-Poisson: CV < 1 (regular firing)
- Super-Poisson: CV > 1 (bursty firing)
"""
isi = np.diff(spike_times)
if len(isi) < 2:
return {'CV': np.nan, 'fano_factor': np.nan}
cv = np.std(isi) / np.mean(isi)
# Fano factor from spike counts in windows
window = 0.1
counts = []
for t in np.arange(spike_times[0], spike_times[-1] - window, window):
counts.append(np.sum((spike_times >= t) & (spike_times < t + window)))
fano = np.var(counts) / (np.mean(counts) + 1e-10)
return {'CV': cv, 'fano_factor': fano}