Encoders#
Introduction#
Encoding input data into spike trains is one of the most important tasks in building Spiking Neural Networks (SNNs). A good encoding scheme can greatly improve the accuracy and efficiency of an SNN, while a poor one can introduce noise and reduce performance. There are several approaches to encoding, including rate coding, temporal coding, and population coding, each with its own advantages and disadvantages. Rate coding involves using the firing rate of neurons to represent the magnitude of the input, while temporal coding represents information through the precise timing of individual spikes. Population coding combines both rate and temporal coding across multiple neurons to represent complex inputs. In this SNN package, we provide various encoding techniques and tools that enable users to efficiently encode their input data into spiking events and achieve optimal performance in their neural networks.
Table of Contents#
AbstractEncoder
NullEncoder
SingleEncoder
RepeatEncoder
BernoulliEncoder
PoissonEncoder
RankOrderEncoder
Timetofirstspike
AbstractEncoder#
AbstractEncoder(ABC)
Abstract class to define encoding mechanism.
Functions#
__init__(
self,
time: int,
dt: Optional[float] = 1.0,
device: Optional[str] = "cpu",
**kwargs
) -> None
Initialize abstract encoder.
__call__(self, data: torch.Tensor) -> None
Compute the encoded tensor of the given data.
Parameters#
time(int): Length of encoded tensor.dt(float = 1.0): Simulation time step. The default is 1.0.device(str = “cpu”): The device to do the computations. The default is “cpu”.
NullEncoder#
NullEncoder(AbstractEncoder)
A null encoder which pass through of the datum that was input.
Functions#
__init__(self) -> None
Initialize null encoder.
__call__(self, data: torch.Tensor) -> torch.Tensor
Pass through of the datum that was input without any modification.
Parameters#
Note: This class doesn’t have any parameters
Example#
import torch
import synapticflow as sf
datum = torch.empty(10).uniform_(20, 100)
null_encoder = sf.NullEncoder()
encoded = null_encoder(datum)
print(encoded)
SingleEncoder#
SingleEncoder(AbstractEncoder)
Generates timing based single-spike encoding. Spike occurs earlier if the intensity of the input feature is higher. Features whose value is lower than the threshold remain silent.
Functions#
__init__(
self,
time: int,
dt: Optional[float] = 1.0,
device: Optional[str] = "cpu",
**kwargs
) -> None
Initialize single encoder with given parameters.
__call__(self, data: torch.Tensor, sparsity = 0.5) -> torch.Tensor
Generates encoded spikes with given data and sparsity.
Parameters#
time(int): Length of encoded tensor.dt(float = 1.0): Simulation time step. The default is 1.0.device(str = “cpu”): The device to do the computations. The default is “cpu”.sparsity(float = 0.5): Indicates sparsity of encoded trace.
Example#
import torch
import synapticflow as sf
datum = torch.empty(10).uniform_(20, 100)
encoder = sf.SingleEncoder(time = 10)
spikes = encoder(data= datum)
print(spikes)
sf.raster_plot(spikes, dt = 0.1)
RepeatEncoder#
RepeatEncoder(AbstractEncoder)
Repeats a tensor along a new dimension in the 0th position for int(time / dt) time steps.
Functions#
__init__(
self,
time: int,
dt: Optional[float] = 1.0,
device: Optional[str] = "cpu",
**kwargs
) -> None
Initialize repeat encoder with given parameters.
__call__(self, data: torch.Tensor) -> torch.Tensor
Generates encoded spikes with given data.
Parameters#
time(int): Length of encoded tensor.dt(float = 1.0): Simulation time step. The default is 1.0.device(str = “cpu”): The device to do the computations. The default is “cpu”.
Example#
import torch
import synapticflow as sf
datum = torch.empty(10).uniform_(20, 100)
encoder = sf.RepeatEncoder(time = 10)
spikes = encoder(data = datum)
print(spikes)
sf.raster_plot(spikes, dt = 0.1)
BernoulliEncoder#
BernoulliEncoder(AbstractEncoder)
Generates Bernoulli-distributed spike trains based on input intensity. Inputs must be non-negative. Spikes correspond to successful Bernoulli trials, with success probability equal to (normalized in [0, 1]) input value.
Functions#
__init__(
self,
time: int,
dt: Optional[float] = 1.0,
device: Optional[str] = "cpu",
**kwargs
) -> None
Initialize bernoulli encoder with given parameters.
__call__(self, data: torch.Tensor, max_prob = 1.0) -> None
Generates encoded spikes with given data and max probability.
Parameters#
time(int): Length of encoded tensor.dt(float = 1.0): Simulation time step. The default is 1.0.device(str = “cpu”): The device to do the computations. The default is “cpu”.max_prob(float = 1.0): The maximum probability in Bernoulli distribution.
Example#
import torch
import synapticflow as sf
datum = torch.empty(10).uniform_(20, 100)
encoder = sf.BernoulliEncoder(time = 10, max_prob = 0.6)
spikes = encoder(datum)
print(spikes)
sf.raster_plot(spikes, dt = 1)
PoissonEncoder#
PoissonEncoder(AbstractEncoder)
Generates Poisson-distributed spike trains based on input intensity. Inputs must be non-negative, and give the firing rate in Hz. Inter-spike intervals (ISIs) for non-negative data incremented by one to avoid zero intervals while maintaining ISI distributions.
Functions#
__init__(
self,
time: int,
dt: Optional[float] = 1.0,
device: Optional[str] = "cpu",
**kwargs
) -> None
Initialize poisson encoder with given parameters.
__call__(self, data: torch.Tensor) -> torch.Tensor
Generates encoded spikes with given data.
Parameters#
time(int): Length of encoded tensor.dt(float = 1.0): Simulation time step. The default is 1.0.device(str = “cpu”): The device to do the computations. The default is “cpu”.
Example#
import torch
import synapticflow as sf
datum = torch.empty(10).uniform_(60, 100)
encoder = sf.PoissonEncoder(time = 10, dt = 1)
spikes = encoder(data = datum)
print(spikes)
sf.raster_plot(spikes, dt = 1)
RankOrderEncoder#
RankOrderEncoder(AbstractEncoder)
Encodes data via a rank order coding-like representation. One spike per neuron, temporally ordered by decreasing intensity. Inputs must be non-negative.
Functions#
__init__(
self,
time: int,
dt: Optional[float] = 1.0,
device: Optional[str] = "cpu",
**kwargs
) -> None
Initialize rank order encoder with given parameters.
__call__(self, data: torch.Tensor) -> None
Encodes data via rank order coding with given data.
Parameters#
time(int): Length of encoded tensor.dt(float = 1.0): Simulation time step. The default is 1.0.device(str = “cpu”): The device to do the computations. The default is “cpu”.
Example#
import torch
import synapticflow as sf
datum = torch.empty(10).uniform_(20, 100)
encoder = sf.RankOrderEncoder(time = 10)
spikes = encoder(data = datum)
print(spikes)
sf.raster_plot(spikes, dt = 1)
Timeoffirstspike#
Timeoffirstspike(AbstractEncoder)
Time to first spike encoding is a neural coding strategy where the information is encoded based on the timing of the first action potential fired by a neuron. This approach is effective for representing sensory stimuli that have precise temporal features.
Functions#
__init__(
self,
time: int,
dt: Optional[float] = 1.0,
device: Optional[str] = "cpu",
**kwargs
) -> None
Initialize time of first spike encoder with given parameters.
__call__(self, data: torch.Tensor) -> None
Encodes data via time of first spike coding with given data.
Parameters#
time(int): Length of encoded tensor.dt(float = 1.0): Simulation time step. The default is 1.0.device(str = “cpu”): The device to do the computations. The default is “cpu”.
Example#
import torch
import synapticflow as sf
encoder = sf.Timetofirstspike(time=10)
spikes = encoder(datum)
print(spikes)
sf.raster_plot(spikes, dt=0.1)