从老版本迁移
本教程作者: fangwei123456
新版的SpikingJelly改动较大,使用老版本SpikingJelly的用户若想迁移到新版本,则需要阅读此教程。SpikingJelly的版本升级尽可能前向兼容,因此用户无需做出太多代码上的修改,即可轻松迁移到新版本。
推荐老版本用户也阅读新版本的教程 基本概念。
“老版本SpikingJelly”均指的是版本号 <=0.0.0.0.12
的SpikingJelly。
子包重命名
新版的SpikingJelly对子包进行了重命名,与老版本的对应关系为:
老版本 |
新版本 |
---|---|
clock_driven |
activation_based |
event_driven |
timing_based |
单步多步模块和传播模式
<=0.0.0.0.12
的老版本SpikingJelly,在默认情况下所有模块都是单步的,除非其名称含有前缀 MultiStep
。而新版的SpikingJelly,则不再使用前缀对单步和多步模块进行区分,取而代之的是同一个模块,拥有单步和多步两种步进模式,使用 step_mode
进行控制。具体信息可以参见 基本概念。
因而在新版本中不再有单独的多步模块,取而代之的则是融合了单步和多步的统一模块。例如,在老版本的SpikingJelly中,若想使用单步LIF神经元,是按照如下方式:
from spikingjelly.clock_driven import neuron
lif = neuron.LIFNode()
在新版本中,所有模块默认是单步的,所以与老版本的代码几乎相同,除了将 clock_driven
换成了 activation_based
:
from spikingjelly.activation_based import neuron
lif = neuron.LIFNode()
在老版本的SpikingJelly中,若想使用多步LIF神经元,是按照如下方式:
from spikingjelly.clock_driven import neuron
lif = neuron.MultiStepLIFNode()
在新版本中,单步和多步模块进行了统一,因此只需要指定为多步模块即可:
from spikingjelly.activation_based import neuron
lif = neuron.LIFNode(step_mode='m')
在老版本中,若想分别搭建一个逐步传播和逐层传播的网络,按照如下方式:
import torch
import torch.nn as nn
from spikingjelly.clock_driven import neuron, layer, functional
with torch.no_grad():
T = 4
N = 2
C = 4
H = 8
W = 8
x_seq = torch.rand([T, N, C, H, W])
# step-by-step
net_sbs = nn.Sequential(
nn.Conv2d(C, C, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(C),
neuron.IFNode()
)
y_seq = functional.multi_step_forward(x_seq, net_sbs)
# y_seq.shape = [T, N, C, H, W]
functional.reset_net(net_sbs)
# layer-by-layer
net_lbl = nn.Sequential(
layer.SeqToANNContainer(
nn.Conv2d(C, C, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(C),
),
neuron.MultiStepIFNode()
)
y_seq = net_lbl(x_seq)
# y_seq.shape = [T, N, C, H, W]
functional.reset_net(net_lbl)
而在新版本中,由于单步和多步模块已经融合,可以通过 spikingjelly.activation_based.functional.set_step_mode
对整个网络的步进模式进行转换。在所有模块使用单步模式时,整个网络就可以使用逐步传播;所有模块都使用多步模式时,整个网络就可以使用逐层传播:
import torch
import torch.nn as nn
from spikingjelly.activation_based import neuron, layer, functional
with torch.no_grad():
T = 4
N = 2
C = 4
H = 8
W = 8
x_seq = torch.rand([T, N, C, H, W])
# the network uses step-by-step because step_mode='s' is the default value for all modules
net = nn.Sequential(
layer.Conv2d(C, C, kernel_size=3, padding=1, bias=False),
layer.BatchNorm2d(C),
neuron.IFNode()
)
y_seq = functional.multi_step_forward(x_seq, net)
# y_seq.shape = [T, N, C, H, W]
functional.reset_net(net)
# set the network to use layer-by-layer
functional.set_step_mode(net, step_mode='m')
y_seq = net(x_seq)
# y_seq.shape = [T, N, C, H, W]
functional.reset_net(net)