-
Notifications
You must be signed in to change notification settings - Fork 258
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
MultiStepLIFNode等神经元的阈值是可训练的吗?或者有什么方法可以把阈值变成一个可训练的参数吗 #371
Comments
pytorch版本的神经元比较容易实现,用 |
cupy版本的神经元可以通过把backend改为torch来实现吗?然后再用nn.parameter来包装 |
可以 |
nn.parameter的输入必须是tensor,但阈值是float,我包装了一下,但是发现在训练过程中阈值并没有被训练,代码如下: |
改成
|
这样改会报错 |
那就需要你继承一下MultiStepLIFNode,改一下init函数 |
这是我继承了MultiStepLIFNode类,并修改了init函数得到的MultiStepLIFNode2;
这是使用MultiStepLIFNode2的部分,可以看到v_threshold已经变成了nn.Parameter型,但是训练后我发现阈值还是没有变化,请问这有什么问题吗? |
另外请问下,有训练阈值的先例吗? |
训练阈值的文章挺多的,两年前就有了 |
好的,感谢! |
输出为
|
提供最小的复现你问题的代码和框架版本,不要以图片的形式放代码 |
抱歉,给您带来不便,现重新整理问题如下:
以下是在model里用到MultiStepLIFNode2的地方,所使用的框架版本是0.0.0.0.12:
这里MultiStepLIFNode2的阈值已经有了梯度,但经过训练发现,该阈值并没有改变,不知道是哪里的问题?阶跃函数在反向传播的过程中已经替换为sigmoid函数,损失函数对阈值求导按理说梯度不会是0? |
from spikingjelly.clock_driven.neuron import *
class MultiStepLIFNode(LIFNode): #篇幅原因只粘贴了部分forward函数
def __init__(self, tau: float = 2., decay_input: bool = True, v_threshold: float = 1.,
v_reset: float = 0., surrogate_function: Callable = surrogate.Sigmoid(),
detach_reset: bool = False, backend='torch', lava_s_cale=1 << 6):
super().__init__(tau, decay_input, v_threshold, v_reset, surrogate_function, detach_reset)
self.register_memory('v_seq', None)
check_backend(backend)
self.backend = backend
self.lava_s_cale = lava_s_cale
def forward(self, x_seq: torch.Tensor):
assert x_seq.dim() > 1
# x_seq.shape = [T, *]
if self.backend == 'torch':
spike_seq = []
self.v_seq = []
for t in range(x_seq.shape[0]):
spike_seq.append(super().forward(x_seq[t]).unsqueeze(0))
self.v_seq.append(self.v.unsqueeze(0))
spike_seq = torch.cat(spike_seq, 0)
self.v_seq = torch.cat(self.v_seq, 0)
return spike_seq
class MultiStepLIFNode2(MultiStepLIFNode): #继承MultiStepLIFNode
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
v_threshold = self.v_threshold
del self.v_threshold
self.v_threshold = nn.Parameter(torch.as_tensor(v_threshold))
x_seq = torch.rand([8, 4], requires_grad=True)
net = MultiStepLIFNode2()
print(net)
print('threshold =', net.v_threshold)
optimier = torch.optim.SGD(net.parameters(), lr=0.1)
net(x_seq).sum().backward()
print(net.v_threshold.grad)
print('threshold.grad =', net.v_threshold)
optimier.step()
print('after bp, threshold =', net.v_threshold) 上面的代码是可以对阈值进行梯度下降的了。 我查了一下代码,在12版本中阈值被视作memory的一部分:
因此必须先调用 |
ok,十分感谢您的帮助! |
如果有问题的话可以再重新打开此issue |
你好,如果我堆叠几层,之前层是不是也会被del |
No description provided.
The text was updated successfully, but these errors were encountered: