Pipeline
Dataloader
和后面网络训练是解耦的,Dataloader负责把数据读出来变成tensor,网络(继承nn.Module父类)负责把这tensor算成最后的输出。在网络传播的过程中,hook记录保留中间数据,用于display作图。
数据预处理
明确这个问题:画图,是对一张图片经过各层layer的时候画他的spike生成图像,而你生成图像需要的数据是通过hook前向传播保留下来的,你需要的只是一个样本走一次的数据,所以batch_size
要设置成1,意味着在训练或推断过程中一次处理的样本数量为1,得到iteration
=10000。然后继续设置一个sample的数量,当大于等于该sample的时候break处理即可,在这里sample_max即为1。
for i,data in enumerate(tqdm(testloader)):
if i >= args.sample_max:
break
SNN想法上的一些问题:
1、存储的形式是如同spkingjelly所说的 [T, a, b, c] 第一维是时间维度,对应着你输入的 t。所以传统的ann中走1个epoch对应着走1遍网络。在snn中1个epoch是走网络t遍。
对应着代码就要分情况讨论:
if not module in spikes:
spikes[module] = output.detach().cpu()
else:
spikes[module] = torch.cat((spikes[module], output.detach().cpu()),dim=0)
2、用切片方法取样本
neuron_number = []
layer = np.array(spikes[key].detach().cpu())
neuron_number.append("{}$\\times${}$\\times\${}".format(layer.shape[1],layer.shape[2],layer.shape[3]))
matplotlib with LaTeX
在 matplotlib 中,你可以使用 LaTeX 语法来渲染图表中的文本标签、数学符号和公式。
e.g.$\times$
neuron_number.append("{}$\\times$1$\\times$1".format(layer.shape[1]))
numpy——reshape/shape/size
detach()
方法可以帮助我们在需要处理不需要梯度信息的张量时,避免在计算图中保留不必要的计算历史。当调用 detach()
方法时,会生成一个新的张量,它与原始张量有相同的数值数据,但是不再保留梯度信息。这意味着新的张量不会被纳入到计算图中进行自动微分的计算,从而不会影响反向传播过程。
layer = np.array(value.detach().cpu())
print("layer.shape",layer.shape)
'''
激活层 : layer.shape (10, 64, 32, 32) 最外层是t
classifer: layer.shape (10, 4096)
'''
numpy.reshape 函数可以在不改变数据的条件下修改形状
layer = layer.reshape(layer.shape[0], -1) # 保留第一个维度不变,其余整合到第二个维度
'''
# print(layer.shape) (10, 512, 4, 4) ----> (10, 8192)
# print(layer.size) (10, 8192) ----> 81920
'''
layer.shape (10, 512, 4, 4)
(10, 8192)
layer.shape (10, 4096)
(10, 4096)
PS:
Matplotlib figure ‘.supxlabel’ does not work:当同一个代码在别人电脑能跑但是自己点脑跑不了时,一定是环境的问题。
- Python at least version 3.7;
- Matplotlib at least version 3.4 (pip install --upgrade matplotlib).