spikingjelly.clock_driven.encoding package

Module contents

class spikingjelly.clock_driven.encoding.BaseEncoder[源代码]

基类:torch.nn.modules.module.Module

所有编码器的基类。编码器将输入数据(例如图像)编码为脉冲数据。

forward(x)[源代码]
参数

x – 要编码的数据

返回

编码后的脉冲,或者是None

将x编码为脉冲。少数编码器(例如ConstantEncoder)可以将x编码成时长为1个dt的脉冲,在这种情况下,本函数返回编码后的脉冲。

多数编码器(例如PeriodicEncoder),都是把x编码成时长为n个dt的脉冲out_spike,out_spike.shape=[n, *]。

因此编码一次后,需要调用n次step()函数才能将脉冲全部发放完毕,第index次调用step()会得到out_spike[index]。

step()[源代码]
返回

1个dt的脉冲

多数编码器(例如PeriodicEncoder),编码一次x,需要经过多步仿真才能将数据输出,这种情况下则用step来获取每一步的数据。

reset()[源代码]
返回

None

将编码器的所有状态变量设置为初始状态。对于有状态的编码器,需要重写这个函数。

training: bool
class spikingjelly.clock_driven.encoding.PeriodicEncoder(out_spike)[源代码]

基类:spikingjelly.clock_driven.encoding.BaseEncoder

参数

out_spike – shape=[T, *],PeriodicEncoder会不断的输出out_spike[0], out_spike[1], …, out_spike[T-1], out_spike[0], out_spike[1], …

给定out_spike后,周期性的输出out_spike[0], out_spike[1], …, out_spike[T-1]的编码器。

forward(x)[源代码]
参数

x – 输入数据,实际上并不需要输入数据,因为out_spike在初始化时已经被指定了

返回

调用step()后得到的返回值

step()[源代码]
返回

out_spike[index]

初始化时index=0,每调用一次,index则自增1,index为T时修改为0。

set_out_spike(out_spike)[源代码]
参数

out_spike – 新设定的out_spike,必须是torch.bool

返回

None

重新设定编码器的输出脉冲self.out_spike为out_spike。

reset()[源代码]
返回

None

重置编码器的状态变量,对于PeriodicEncoder而言将索引index置0即可。

training: bool
class spikingjelly.clock_driven.encoding.LatencyEncoder(max_spike_time, function_type='linear', device='cpu')[源代码]

基类:spikingjelly.clock_driven.encoding.BaseEncoder

参数
  • max_spike_time – 最晚(最大)脉冲发放时间

  • function_type – ‘linear’或’log’

  • device – 数据所在设备

延迟编码,刺激强度越大,脉冲发放越早。要求刺激强度已经被归一化到[0, 1]。

脉冲发放时间 \(t_i\) 与刺激强度 \(x_i\) 满足:

type=’linear’
\[t_i = (t_{max} - 1) * (1 - x_i)\]
type=’log’
\[t_i = (t_{max} - 1) - ln(\alpha * x_i + 1)\]

\(\alpha\) 满足:

\[(t_{max} - 1) - ln(\alpha * 1 + 1) = 0\]

这导致此编码器很容易发生溢出,因为

\[\alpha = e^{t_{max} - 1} - 1\]

\(t_{max}\) 较大时 \(\alpha\) 极大。

示例代码:

x = torch.rand(size=[3, 2])
max_spike_time = 20
le = encoding.LatencyEncoder(max_spike_time)

le(x)
print(x)
print(le.spike_time)
for i in range(max_spike_time):
    print(le.step())
forward(x)[源代码]
参数

x – 要编码的数据,任意形状的tensor,要求x的数据范围必须在[0, 1]

将输入数据x编码为max_spike_time个时刻的max_spike_time个脉冲。

step()[源代码]
返回

out_spike[index]

初始化时index=0,每调用一次,index则自增1,index为max_spike_time时修改为0。

reset()[源代码]
返回

None

重置LatencyEncoder的所有状态变量(包括spike_time,out_spike,index)为初始值0。

training: bool
class spikingjelly.clock_driven.encoding.PoissonEncoder[源代码]

基类:spikingjelly.clock_driven.encoding.BaseEncoder

泊松频率编码,输出脉冲可以看作是泊松流,发放脉冲的概率即为刺激强度,要求刺激强度已经被归一化到[0, 1]。

示例代码:

pe = encoding.PoissonEncoder()
x = torch.rand(size=[8])
print(x)
for i in range(10):
    print(pe(x))
forward(x)[源代码]
参数

x – 要编码的数据,任意形状的tensor,要求x的数据范围必须在[0, 1]

将输入数据x编码为脉冲,脉冲发放的概率即为对应位置元素的值。

training: bool
class spikingjelly.clock_driven.encoding.GaussianTuningCurveEncoder(x_min, x_max, tuning_curve_num, max_spike_time, device='cpu')[源代码]

基类:spikingjelly.clock_driven.encoding.BaseEncoder

参数
  • x_min – float,或者是shape=[M]的tensor,表示M个特征的最小值

  • x_max – float,或者是shape=[M]的tensor,表示M个特征的最大值

  • tuning_curve_num – 编码每个特征使用的高斯函数(调谐曲线)数量

  • max_spike_time – 最大脉冲发放时间,所有数据都会被编码到[0, max_spike_time - 1]范围内的脉冲发放时间

  • device – 数据所在设备

Bohte S M, Kok J N, La Poutre H. Error-backpropagation in temporally encoded networks of spiking neurons[J]. Neurocomputing, 2002, 48(1-4): 17-37.

高斯调谐曲线编码,一种时域编码方法。

首先生成tuning_curve_num个高斯函数,这些高斯函数的对称轴在数据范围内均匀排列,对于每一个输入x,计算tuning_curve_num个 高斯函数的值,使用这些函数值线性地生成tuning_curve_num个脉冲发放时间。

待编码向量是M维tensor,也就是有M个特征。

1个M维tensor会被编码成shape=[M, tuning_curve_num]的tensor,表示M * tuning_curve_num个神经元的脉冲发放时间。

需要注意的是,编码一次数据,经过max_spike_time步仿真,才能进行下一次的编码。

示例代码:

x = torch.rand(size=[3, 2])
tuning_curve_num = 10
max_spike_time = 20
ge = encoding.GaussianTuningCurveEncoder(x.min(0)[0], x.max(0)[0], tuning_curve_num=tuning_curve_num, max_spike_time=max_spike_time)
ge(x)
for i in range(max_spike_time):
    print(ge.step())
forward(x)[源代码]
参数

x – 要编码的数据,shape=[batch_size, M]

将输入数据x编码为脉冲。

step()[源代码]
返回

out_spike[index]

初始化时index=0,每调用一次,index则自增1,index为max_spike_time时修改为0。

reset()[源代码]
返回

None

重置GaussianTuningCurveEncoder的所有状态变量(包括spike_time,out_spike,index)为初始值0。

training: bool
class spikingjelly.clock_driven.encoding.IntervalEncoder(T_in, shape, device='cpu')[源代码]

基类:spikingjelly.clock_driven.encoding.BaseEncoder

参数
  • T_in – 脉冲发放的间隔

  • shape – 输出形状

  • device – 输出脉冲所在的设备

每隔 T_in 个步长就发放一次脉冲的编码器。

step()[源代码]
reset()[源代码]
training: bool
class spikingjelly.clock_driven.encoding.WeightedPhaseEncoder(phase, period, device='cpu')[源代码]

基类:spikingjelly.clock_driven.encoding.BaseEncoder

参数
  • phase (int) – 一个周期内用于编码的相数

  • device (str) – 输出脉冲所在的设备

Kim J, Kim H, Huh S, et al. Deep neural networks with weighted spikes[J]. Neurocomputing, 2018, 311: 373-386.

带权的相位编码,一种基于二进制表示的编码方法。

将输入按照二进制各位展开,从高位到低位遍历输入进行脉冲编码。相比于频率编码,每一位携带的信息量更多。编码相位数为 \(K\) 时,可以对于处于区间 \([0, 1-2^{-K}]\) 的数进行编码。以下为原始论文中的示例:

Phase (K=8)

1

2

3

4

5

6

7

8

Spike weight \(\omega(t)\)

2-1

2-2

2-3

2-4

2-5

2-6

2-7

2-8

192/256

1

1

0

0

0

0

0

0

1/256

0

0

0

0

0

0

0

1

128/256

1

0

0

0

0

0

0

0

255/256

1

1

1

1

1

1

1

1

forward(x)[源代码]
参数

x – 要编码的数据,shape=[batch_size, *]

将输入数据x编码为一个周期内的脉冲。

step()[源代码]
reset()[源代码]
training: bool