spikingjelly.activation_based.functional.layer 源代码

from __future__ import annotations

import torch


__all__ = [
    "delay_step",
    "neunorm_step",
    "synapse_filter_step",
]


[文档] def neunorm_step( in_spikes: torch.Tensor, state: torch.Tensor, weight: torch.Tensor, momentum: float, input_scale: float, ) -> tuple[torch.Tensor, torch.Tensor]: r""" **API Language** - :ref:`中文 <neunorm_step-cn>` | :ref:`English <neunorm_step-en>` ---- .. _neunorm_step-cn: * **中文** 执行一次 NeuNorm 状态转移,返回归一化输出和下一状态。函数不读取或修改 module memory。 :param in_spikes: 当前输入脉冲,shape 为 ``[N, C, H, W]`` :type in_spikes: torch.Tensor :param state: 已物化的 NeuNorm 状态,shape 为 ``[N, 1, H, W]`` :type state: torch.Tensor :param weight: 可广播到 ``in_spikes`` 的 NeuNorm 权重 :type weight: torch.Tensor :param momentum: 旧状态的系数 :type momentum: float :param input_scale: 通道求和结果的系数 :type input_scale: float :return: ``(output, state_next)`` :rtype: Tuple[torch.Tensor, torch.Tensor] ---- .. _neunorm_step-en: * **English** Run one NeuNorm state transition and return its normalized output and next state. The function does not read or mutate module memory. :param in_spikes: Current input spikes shaped ``[N, C, H, W]`` :type in_spikes: torch.Tensor :param state: Materialized NeuNorm state shaped ``[N, 1, H, W]`` :type state: torch.Tensor :param weight: NeuNorm weight broadcastable to ``in_spikes`` :type weight: torch.Tensor :param momentum: Coefficient applied to the previous state :type momentum: float :param input_scale: Coefficient applied to the channel sum :type input_scale: float :return: ``(output, state_next)`` :rtype: Tuple[torch.Tensor, torch.Tensor] .. note:: 本函数没有独立多步形式;多步执行由调用者逐步循环。 This function has no independent multi-step form; callers iterate it. """ state_next = momentum * state + input_scale * in_spikes.sum(dim=1, keepdim=True) return in_spikes - weight * state_next, state_next
[文档] def delay_step( x: torch.Tensor, queue: tuple[torch.Tensor, ...], delay_steps: int, ) -> tuple[torch.Tensor, tuple[torch.Tensor, ...]]: r""" **API Language** - :ref:`中文 <delay_step-cn>` | :ref:`English <delay_step-en>` ---- .. _delay_step-cn: * **中文** 执行 Delay 的单步显式状态转移。``queue`` 是按时间从旧到新排列的 tensor tuple。 函数返回 ``(y, queue_next)``,不原地修改输入 ``queue``。当 ``delay_steps=0`` 且 ``queue`` 为空时,输出 ``y`` 与输入 ``x`` alias;当已有 queue 被消费时,输出 ``y`` 与被弹出的 queue 元素 alias。 :param x: 当前输入张量 :type x: torch.Tensor :param queue: 当前延迟队列状态,元素为 tensor,按旧到新排列 :type queue: Tuple[torch.Tensor, ...] :param delay_steps: 延迟时间步数,必须是非负整数 :type delay_steps: int :return: ``(y, queue_next)``,其中 ``y`` 是当前输出,``queue_next`` 是下一状态 :rtype: Tuple[torch.Tensor, Tuple[torch.Tensor, ...]] :raises ValueError: ``delay_steps`` 不是非负整数时抛出 ---- .. _delay_step-en: * **English** Run one explicit Delay state transition. ``queue`` is a tuple of tensors ordered from oldest to newest. The function returns ``(y, queue_next)`` and does not mutate the input ``queue`` in place. When ``delay_steps=0`` and ``queue`` is empty, output ``y`` aliases ``x``; when an existing queue item is consumed, ``y`` aliases the popped queue item. :param x: Current input tensor :type x: torch.Tensor :param queue: Current delay-queue state with tensor elements ordered from oldest to newest :type queue: Tuple[torch.Tensor, ...] :param delay_steps: Number of delayed time steps; must be a non-negative integer :type delay_steps: int :return: ``(y, queue_next)``, where ``y`` is the current output and ``queue_next`` is the next state :rtype: Tuple[torch.Tensor, Tuple[torch.Tensor, ...]] :raises ValueError: If ``delay_steps`` is not a non-negative integer .. note:: 本函数没有独立多步形式;多步执行由调用者逐步循环。 This function has no independent multi-step form; callers iterate it. """ if not isinstance(delay_steps, int) or delay_steps < 0: raise ValueError("delay_steps must be a non-negative integer") queue_with_x = (*queue, x) if len(queue_with_x) > delay_steps: return queue_with_x[0], queue_with_x[1:] return torch.zeros_like(x), queue_with_x
[文档] def synapse_filter_step( x: torch.Tensor, out_i: torch.Tensor, reciprocal_tau: float | torch.Tensor, ) -> torch.Tensor: r""" **API Language** - :ref:`中文 <synapse_filter_step-cn>` | :ref:`English <synapse_filter_step-en>` ---- .. _synapse_filter_step-cn: * **中文** 执行 SynapseFilter 的单步显式状态转移。函数接收已物化的输出电流状态 ``out_i`` 和确定的 ``reciprocal_tau = 1 / tau``,返回下一时刻输出电流。 该函数不读取或修改 ``MemoryModule`` memory,也不原地修改 ``x`` 或 ``out_i``。 :param x: 当前输入脉冲或输入电流张量 :type x: torch.Tensor :param out_i: 已物化的当前输出电流 tensor state,shape/dtype/device 与 ``x`` 兼容 :type out_i: torch.Tensor :param reciprocal_tau: 时间常数倒数;非 learnable module 传入 ``1 / tau``, learnable module 传入 ``w.sigmoid()`` :type reciprocal_tau: float | torch.Tensor :return: 下一时刻输出电流 :rtype: torch.Tensor ---- .. _synapse_filter_step-en: * **English** Run one explicit SynapseFilter state transition. The function receives a materialized output-current state ``out_i`` and the selected ``reciprocal_tau = 1 / tau``, then returns the next output current. It does not read or mutate ``MemoryModule`` memory and does not mutate ``x`` or ``out_i`` in place. :param x: Current input spike or input-current tensor :type x: torch.Tensor :param out_i: Materialized current output-current tensor state compatible with ``x`` in shape, dtype, and device :type out_i: torch.Tensor :param reciprocal_tau: Reciprocal time constant; non-learnable modules pass ``1 / tau`` and learnable modules pass ``w.sigmoid()`` :type reciprocal_tau: float | torch.Tensor :return: Next output current :rtype: torch.Tensor .. note:: 本函数没有独立多步形式;多步执行由调用者逐步循环。 This function has no independent multi-step form; callers iterate it. """ return out_i - (1.0 - x) * out_i * reciprocal_tau + x