Open youlingforever0328 opened 1 year ago
在pytorch中实现autograd function时,有几个输入就要返回几个梯度,由于v是前向传播的输入,因此grad_v也一定需要成为反向传播的输出
v_seq
是可能参与loss计算的,所以在SJ框架里面也给它计算了梯度
如果你把神经元设计成 输入: v[-1], x_seq 输出: v[T-1], s_seq
在这种情况下你就只需要回传grad_v而不是grad_v_seq了。但在这种情况下无法获取到中间的v_seq并进行某些计算,比如v_seq参与计算损失
在pytorch中实现autograd function时,有几个输入就要返回几个梯度,由于v是前向传播的输入,因此grad_v也一定需要成为反向传播的输出
v_seq
是可能参与loss计算的,所以在SJ框架里面也给它计算了梯度
所以说如果输出的v_seq并未参与计算的话,损失对v_seq的导数是0对吗? 比如在"编写CUPY神经元"这一教程最后的损失是只用了spike对其求和,并没有用到v_seq, 所以我发现损失对v_seq的导数都是0.那么这个时候在反向传播公式里面 中的L对v_t的导数这一项都是0是吗?关于这块还不是很懂,想请教下作者
aL/aV是0(V不直接参与loss计算),但dL/dV不是0(V通过S参与loss计算)
aL/aV是0(V不直接参与loss计算),但dL/dV不是0(V通过S参与loss计算)
也就是说,上述公式里aL/aV[t]这一项,无论是v_seq有没有参与损失计算,都是一直存在的吗,并且若v_seq没有参与损失计算,那么就无法通过pytorch中autograd function显式得到aL/aV[t](我自己打印出来都是0),只能通过自己在底层反向传播时手动求出aL/aV[t]是这样吗(通过V和S的关系递推)
是的
作者您好,我想请教一个问题 在教程里关于自定义CUPY神经元的部分 class CUPYIFNode(base.MemoryModule): def init(self, v_threshold: float = 1., v_reset: float or None = 0., surrogate_function: Callable = surrogate.Sigmoid(), detach_reset: bool = False): super().init() self.v_threshold = v_threshold self.v_reset = v_reset self.surrogate_function = surrogate_function self.detach_reset = detach_reset self.step_mode = 'm' if v_reset is not None: self.register_memory('v', v_reset) else: self.register_memory('v', 0.)
CUPYIFNode的输出只有spike_seq,然后他被用来计算loss(在教程里是直接对spike_seq求和),然后反向传播,这个loss的计算并没有用到v_seq,那么请问为什么教程里提到损失会对v_seq有梯度呢?可能我学的还不够深入,不太明白这里loss是只用spike_seq计算的,为什么loss对v_seq会有梯度【grad_v_seq】呢?因为我自己用cuda实现了一个类似的过程,其中loss对v_seq的梯度都是0,不太明白为什么,还请多多指教 @staticmethod def backward(ctx, grad_spike_seq: torch.Tensor, grad_v_seq: torch.Tensor):