Giter Site home page Giter Site logo

braincog-x / brain-cog Goto Github PK

View Code? Open in Web Editor NEW
392.0 16.0 62.0 3.29 MB

Brain-inspired Cognitive Intelligence Engine (BrainCog) is a brain-inspired spiking neural network based platform for Brain-inspired Artificial Intelligence and simulating brains at multiple scales. The long term goal of BrainCog is to provide a comprehensive theory and system to decode the mechanisms and principles of human intelligence and its evolution, and develop artificial brains for brain-inspired conscious living AI in future Human-AI symbiotic Society.

Home Page: http://www.brain-cog.network/

License: Apache License 2.0

Python 100.00%
brain-inspired-computation brain-simulations computational-neuroscience spiking-neural-networks brain-inspired-ai

brain-cog's Introduction

BrainCog


BrainCog is an open source spiking neural network based brain-inspired cognitive intelligence engine for Brain-inspired Artificial Intelligence and brain simulation. More information on BrainCog can be found on its homepage http://www.brain-cog.network/

The current version of BrainCog contains at least 18 functional spiking neural network algorithms (including but not limited to perception and learning, decision making, knowledge representation and reasoning, motor control, social cognition, etc.) built based on BrainCog infrastructures, and BrainCog also provide brain simulations to drosophila, rodent, monkey, and human brains at multiple scales based on spiking neural networks at multiple scales. More detail in http://www.brain-cog.network/docs/

BrainCog is a community based effort for spiking neural network based artificial intelligence, and we welcome any forms of contributions, from contributing to the development of core components, to contributing for applications.

./figures/logo.jpg

BrainCog provides essential and fundamental components to model biological and artificial intelligence.

image

Our paper has been accepted by Patterns recently. If you use BrainCog in your research, the following paper can be cited as the source for BrainCog.

@article{Zeng2023,
  doi = {10.1016/j.patter.2023.100789},
  url = {https://doi.org/10.1016/j.patter.2023.100789},
  year = {2023},
  month = jul,
  publisher = {Cell Press},
  pages = {100789},
  author = {Yi Zeng and Dongcheng Zhao and Feifei Zhao and Guobin Shen and Yiting Dong and Enmeng Lu and Qian Zhang and Yinqian Sun and Qian Liang and Yuxuan Zhao and Zhuoya Zhao and Hongjian Fang and Yuwei Wang and Yang Li and Xin Liu and Chengcheng Du and Qingqun Kong and Zizhe Ruan and Weida Bi},
  title = {{BrainCog}: A spiking neural network based,  brain-inspired cognitive intelligence engine for brain-inspired {AI} and brain simulation},
  journal = {Patterns}
}

Brain-Inspired AI

BrainCog currently provides cognitive functions components that can be classified into five categories:

  • Perception and Learning
  • Knowledge Representation and Reasoning
  • Decision Making
  • Motor Control
  • Social Cognition
  • Development and Evolution
  • Safety and Security

mt

mt

Brain Simulation

BrainCog currently include two parts for brain simulation:

  • Brain Cognitive Function Simulation
  • Multi-scale Brain Structure Simulation

bmbm10s

bm10s

bh10s

The anatomical and imaging data is used to support our simulation from various aspects.

Software-Hardware Codesign

BrainCog currently provides hardware acceleration for spiking neural network based brain-inspired AI.

bh10s

Resources

Publications Using BrainCog

BrainCog Data Engine

Requirements:

  • python == 3.8
  • CUDA toolkit == 11.
  • numpy >= 1.21.2
  • scipy >= 1.8.0
  • h5py >= 3.6.0
  • torch >= 1.10
  • torchvision >= 0.12.0
  • torchaudio >= 0.11.0
  • timm >= 0.5.4
  • matplotlib >= 3.5.1
  • einops >= 0.4.1
  • thop >= 0.0.31
  • pyyaml >= 6.0
  • loris >= 0.5.3
  • pandas >= 1.4.2
  • tonic
  • pandas >= 1.4.2
  • xlrd == 1.2.0

Install

Install Online

  1. You can install braincog by running:

    pip install braincog

  2. Also, install from github by running:

    pip install git+https://github.com/braincog-X/Brain-Cog.git

Install locally

  1. If you are a developer, it is recommanded to download or clone braincog from github.

    git clone https://github.com/braincog-X/Brain-Cog.git

  2. Enter the folder of braincog

    cd Brain-Cog

  3. Install braincog locally

    pip install -e .

Example

  1. Examples for Image Classification
cd ./examples/Perception_and_Learning/img_cls/bp 
python main.py --model cifar_convnet --dataset cifar10 --node-type LIFNode --step 8 --device 0
  1. Examples for Event Classification
cd ./examples/Perception_and_Learning/img_cls/bp 
python main.py --model dvs_convnet --node-type LIFNode --dataset dvsc10 --step 10 --batch-size 128 --act-fun QGateGrad --device 0 

Other BrainCog features and tutorials can be found at http://www.brain-cog.network/docs/

BrainCog Assistant

Please add our BrainCog Assitant via wechat and we will invite you to our wechat developer group. image

Maintenance

This project is led by

1.Brain-inspired Cognitive Intelligence Lab, Institute of Automation, Chinese Academy of Sciences http://www.braincog.ai/

2.Center for Long-term Artificial Intelligence (CLAI) http://long-term-ai.center/

brain-cog's People

Contributors

adamgallas avatar agnes233 avatar annaoliver avatar bing88b avatar craree avatar fancyssc avatar fenghuihhhh avatar floyedshen avatar jinyu-fan avatar lczd avatar lqnankai avatar lxbeatles avatar ppx-hub avatar precola avatar qingluyichen avatar sunbaby01 avatar sunyinqian avatar tianlonglee avatar tiger0044 avatar wyw-cas avatar xdusponge avatar yizeng-ai avatar zyx-cas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

brain-cog's Issues

UserWarning: Overwriting wide_resnet101_2 in registry with braincog.model_zoo.resnet.wide_resnet101_2. This is because the name being registered conflicts with an existing name. Please check if this is not expected.

'from braincog.base.node import LIFNode' I ran this import then this log appears:

"/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:461: UserWarning: Overwriting resnet18 in registry with braincog.model_zoo.resnet.resnet18. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def resnet18(pretrained=False, **kwargs):
/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:474: UserWarning: Overwriting resnet34 in registry with braincog.model_zoo.resnet.resnet34. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def resnet34(pretrained=False, **kwargs):
/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:486: UserWarning: Overwriting resnet50 in registry with braincog.model_zoo.resnet.resnet50. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def resnet50(pretrained=False, **kwargs):
/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:491: UserWarning: Overwriting resnet101 in registry with braincog.model_zoo.resnet.resnet101. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def resnet101(pretrained=False, **kwargs):
/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:497: UserWarning: Overwriting resnet152 in registry with braincog.model_zoo.resnet.resnet152. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def resnet152(pretrained=False, **kwargs):
/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:503: UserWarning: Overwriting resnext50_32x4d in registry with braincog.model_zoo.resnet.resnext50_32x4d. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def resnext50_32x4d(pretrained=False, **kwargs):
/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:511: UserWarning: Overwriting resnext101_32x8d in registry with braincog.model_zoo.resnet.resnext101_32x8d. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def resnext101_32x8d(pretrained=False, **kwargs):
/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:519: UserWarning: Overwriting wide_resnet50_2 in registry with braincog.model_zoo.resnet.wide_resnet50_2. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def wide_resnet50_2(pretrained=False, **kwargs):
/Users/khang/Documents/F-Brain-Cog/braincog/model_zoo/resnet.py:526: UserWarning: Overwriting wide_resnet101_2 in registry with braincog.model_zoo.resnet.wide_resnet101_2. This is because the name being registered conflicts with an existing name. Please check if this is not expected.
def wide_resnet101_2(pretrained=False, **kwargs):"

This is all the packages existing in my environment conda

"conda list

packages in environment at /Users/khang/miniconda3/envs/braincog:

Name Version Build Channel

absl-py 2.1.0 pypi_0 pypi
audioread 3.0.1 pypi_0 pypi
braincog 0.2.7.19 dev_0
ca-certificates 2024.3.11 hca03da5_0
cachetools 5.3.3 pypi_0 pypi
certifi 2024.2.2 pypi_0 pypi
cffi 1.16.0 pypi_0 pypi
charset-normalizer 3.3.2 pypi_0 pypi
contourpy 1.1.1 pypi_0 pypi
cycler 0.12.1 pypi_0 pypi
decorator 5.1.1 pypi_0 pypi
deprecated 1.2.14 pypi_0 pypi
dv 1.0.12 pypi_0 pypi
einops 0.7.0 pypi_0 pypi
expelliarmus 1.1.12 pypi_0 pypi
filelock 3.13.3 pypi_0 pypi
flatbuffers 24.3.25 pypi_0 pypi
fonttools 4.50.0 pypi_0 pypi
fsspec 2024.3.1 pypi_0 pypi
google-auth 2.29.0 pypi_0 pypi
google-auth-oauthlib 1.0.0 pypi_0 pypi
grpcio 1.62.1 pypi_0 pypi
h5py 3.10.0 pypi_0 pypi
huggingface-hub 0.22.2 pypi_0 pypi
idna 3.6 pypi_0 pypi
importlib-metadata 7.1.0 pypi_0 pypi
importlib-resources 6.4.0 pypi_0 pypi
importrosbag 1.0.4 pypi_0 pypi
jinja2 3.1.3 pypi_0 pypi
joblib 1.3.2 pypi_0 pypi
kiwisolver 1.4.5 pypi_0 pypi
lazy-loader 0.3 pypi_0 pypi
libcxx 14.0.6 h848a8c0_0
libffi 3.4.4 hca03da5_0
librosa 0.10.1 pypi_0 pypi
llvmlite 0.41.1 pypi_0 pypi
lz4 4.3.3 pypi_0 pypi
markdown 3.6 pypi_0 pypi
markupsafe 2.1.5 pypi_0 pypi
matplotlib 3.7.5 pypi_0 pypi
mpmath 1.3.0 pypi_0 pypi
msgpack 1.0.8 pypi_0 pypi
ncurses 6.4 h313beb8_0
networkx 3.1 pypi_0 pypi
numba 0.58.1 pypi_0 pypi
numpy 1.24.4 pypi_0 pypi
oauthlib 3.2.2 pypi_0 pypi
openssl 3.0.13 h1a28f6b_0
packaging 24.0 pypi_0 pypi
pandas 2.0.3 pypi_0 pypi
pbr 6.0.0 pypi_0 pypi
pillow 10.3.0 pypi_0 pypi
pip 23.3.1 py38hca03da5_0
platformdirs 4.2.0 pypi_0 pypi
pooch 1.8.1 pypi_0 pypi
protobuf 5.26.1 pypi_0 pypi
pyasn1 0.6.0 pypi_0 pypi
pyasn1-modules 0.4.0 pypi_0 pypi
pycparser 2.22 pypi_0 pypi
pygame 2.5.2 pypi_0 pypi
pyparsing 3.1.2 pypi_0 pypi
python 3.8.19 hb885b13_0
python-dateutil 2.9.0.post0 pypi_0 pypi
pytz 2024.1 pypi_0 pypi
pyyaml 6.0.1 pypi_0 pypi
readline 8.2 h1a28f6b_0
requests 2.31.0 pypi_0 pypi
requests-oauthlib 2.0.0 pypi_0 pypi
rsa 4.9 pypi_0 pypi
safetensors 0.4.2 pypi_0 pypi
scikit-learn 1.3.2 pypi_0 pypi
scipy 1.10.1 pypi_0 pypi
seaborn 0.13.2 pypi_0 pypi
setuptools 68.2.2 py38hca03da5_0
six 1.16.0 pypi_0 pypi
soundfile 0.12.1 pypi_0 pypi
soxr 0.3.7 pypi_0 pypi
sqlite 3.41.2 h80987f9_0
sympy 1.12 pypi_0 pypi
tensorboard 2.14.0 pypi_0 pypi
tensorboard-data-server 0.7.2 pypi_0 pypi
thop 0.1.1-2209072238 pypi_0 pypi
threadpoolctl 3.4.0 pypi_0 pypi
timm 0.9.16 pypi_0 pypi
tk 8.6.12 hb8d0fd4_0
tonic 1.4.3 pypi_0 pypi
torch 2.2.2 pypi_0 pypi
torchaudio 2.2.2 pypi_0 pypi
torchvision 0.17.2 pypi_0 pypi
tqdm 4.66.2 pypi_0 pypi
typing-extensions 4.10.0 pypi_0 pypi
tzdata 2024.1 pypi_0 pypi
urllib3 2.2.1 pypi_0 pypi
werkzeug 3.0.2 pypi_0 pypi
wheel 0.41.2 py38hca03da5_0
wrapt 1.16.0 pypi_0 pypi
xz 5.4.6 h80987f9_0
zipp 3.18.1 pypi_0 pypi
zlib 1.2.13 h5a0b063_0
zstd 1.5.5.1 pypi_0 pypi"

I don't know what the log means so I wonder if there is something wrong.
Thank you in advance

learing rule

how can I use different learning rule(such as LTDP) in a classical conv model ?
(I think the unsupervisedSTDP example script is quite different others)

some readme files may need to be modified

examples/Perception_and_Learning/img_cls/bp/readme

The path may need to be changed to "cd examples/Perception_and_Learning/img_cls/bp"

cd examples/img_cls/bp

QGate->QGateGrad

python main.py --model dvs_convnet --node-type LIFNode --dataset dvsc10 --step 10 --batch-size 128 --act-fun QGate --device 0

python main.py --model dvs_convnet --node-type LIFNode --dataset dvsc10 --step 10 --batch-size 128 --act-fun QGateGrad --device 0

name 'tonic' is not defined

Any Papers on These?

Import class name error

An error occurred while I was running brainSimMaq.py

/Brain-Cog/examples/Multiscale_Brain_Structure_Simulation/MacaqueBrain$ python3 brainSimMaq.py

ImportError: cannot import name 'IFNodev1' from 'braincog.base.node.node'

There is another issue, when I run /Brain-Cog/examples/Multiscale_Brain_Structure_Simulation/Mouse_brain/Mouse_model.py, cannot find ./mouse.mat

Please secure your website with HTTPS

Good afternoon!

I've read your paper and am interested in your project, but noticed that the website you link to where you host the documentation for BrainCog is HTTP and does not have a certificate.

Please consider setting up HTTPS. It is free and only takes a few minutes using a free service. There is also more than one site that comes up on google identical to yours. Without HTTPS it is difficult to ensure authenticity.

https://blog.cloudflare.com/how-to-make-your-site-https-only/

Thanks! I look forward to seeing more.

使用BrainCog模拟RMSNorm,最终输出为nan

class SNN_RMSNorm(nn.Module):
    def __init__(self, max_length = 128, hidden_size=4096,node=LIAFNode, threshold=0.5, eps=1e-6):
        super().__init__()
        self.eps = eps
        self.rms_neuron = node(act_fun='LeakyReLU', threshold=threshold)
        self.weight_neuron = node(act_fun='ReLU', threshold=threshold)
        self.weight = nn.Parameter(torch.ones(hidden_size,hidden_size))
        self.rms_connection = CustomLinear(torch.ones(1,hidden_size))
        self.weight_connection = CustomLinear(self.weight)

    def forward(self, x):
        x_sqr = x ** 2
        x_rms = x_sqr.mean(-1, keepdim=True)
        s_rms = self.rms_neuron(self.rms_connection(x_rms))
        rms_out = torch.rsqrt(s_rms + self.eps)
        s_scale = self.weight_neuron(self.weight_connection(rms_out))
        return s_scale

class RMSNorm(torch.nn.Module):
    def __init__(self, dim: int, eps: float = 1e-6):
        """
        Initialize the RMSNorm normalization layer.

        Args:
            dim (int): The dimension of the input tensor.
            eps (float, optional): A small value added to the denominator for numerical stability. Default is 1e-6.

        Attributes:
            eps (float): A small value added to the denominator for numerical stability.
            weight (nn.Parameter): Learnable scaling parameter.

        """
        super().__init__()
        self.eps = eps
        self.weight = nn.Parameter(torch.ones(dim))

    def _norm(self, x):
        """
        Apply the RMSNorm normalization to the input tensor.

        Args:
            x (torch.Tensor): The input tensor.

        Returns:
            torch.Tensor: The normalized tensor.

        """
        return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)

    def forward(self, x):
        """
        Forward pass through the RMSNorm layer.

        Args:
            x (torch.Tensor): The input tensor.

        Returns:
            torch.Tensor: The output tensor after applying RMSNorm.

        """
        output = self._norm(x.float()).type_as(x)
        return output * self.weight

以上为我定义的SNN化RMSNorm和原始RMSNorm函数,以下为SNN_RMSNorm前向传播的输出,虽然维度shape经过我的处理达到了一致,但是输出如下:

tensor([[[nan, nan, nan,  ..., nan, nan, nan],
         [nan, nan, nan,  ..., nan, nan, nan],
         [nan, nan, nan,  ..., nan, nan, nan],
         ...,
         [nan, nan, nan,  ..., nan, nan, nan],
         [nan, nan, nan,  ..., nan, nan, nan],
         [nan, nan, nan,  ..., nan, nan, nan]],

        [[nan, nan, nan,  ..., nan, nan, nan],
         [nan, nan, nan,  ..., nan, nan, nan],
         [nan, nan, nan,  ..., nan, nan, nan],
         ...,
         [nan, nan, nan,  ..., nan, nan, nan],
         [nan, nan, nan,  ..., nan, nan, nan],
         [nan, nan, nan,  ..., nan, nan, nan]]], device='cuda:0',
       grad_fn=<StackBackward0>)
torch.Size([2, 128, 4096])

以下为全部代码:

from torchvision import transforms
from PIL import Image
import torch
import torch.nn as nn
import torch.nn.functional as F
from timm.models.layers import trunc_normal_, DropPath
from timm.models.registry import register_model
from timm.models.vision_transformer import _cfg
from spikingjelly.clock_driven.neuron import MultiStepLIFNode, MultiStepParametricLIFNode
from transformers import CLIPProcessor, CLIPModel
from accelerate import Accelerator
from dataclasses import dataclass
from typing import Optional, Tuple

import fairscale.nn.model_parallel.initialize as fs_init
from fairscale.nn.model_parallel.layers import ColumnParallelLinear, ParallelEmbedding, RowParallelLinear

import numpy as np
import os
import sys
from torch.nn import Parameter
import abc
from abc import ABC
from einops import rearrange, repeat

accelerator = Accelerator()


@dataclass
class ModelArgs:
    dim: int = 4096
    n_layers: int = 32
    n_heads: int = 32
    n_kv_heads: Optional[int] = None
    vocab_size: int = -1  # defined later by tokenizer
    multiple_of: int = 256  # make SwiGLU hidden layer size multiple of large power of 2
    ffn_dim_multiplier: Optional[float] = None
    norm_eps: float = 1e-5

    max_batch_size: int = 32
    max_seq_len: int = 2048


class CustomLinear(nn.Module):
    """
    用户自定义连接 通常stdp的计算
    """

    def __init__(self, weight, mask=None):
        super().__init__()

        self.weight = nn.Parameter(weight, requires_grad=True)
        self.mask = mask

    def forward(self, x: torch.Tensor):
        """
        :param x:输入 x.shape = [N ]
        """
        #
        # ret.shape = [C]

        return x.matmul(self.weight)

    def update(self, dw):
        """
        :param dw:权重更新量
        """
        with torch.no_grad():
            if self.mask is not None:
                dw *= self.mask
            self.weight.data += dw


class STDP(nn.Module):
    """
    STDP learning rule
    """

    def __init__(self, node, connection, decay=0.99):
        """
        :param node:node神经元类型实例如IFNode LIFNode
        :param connection:连接 类的实例 里面只能有一个操作
        """
        super().__init__()

        self.node = node
        self.connection = connection
        self.trace = None
        self.decay = decay

    def forward(self, x):
        """
        计算前向传播过程
        :return:s是脉冲 dw更新量
        """
        x = x.clone().detach()
        i = self.connection(x)
        with torch.no_grad():
            s = self.node(i)

            i.data += s - i.data
            trace = self.cal_trace(x)
            x.data += trace - x.data

        dw = torch.autograd.grad(
            outputs=i, inputs=self.connection.weight, grad_outputs=i)

        return s, dw

    def cal_trace(self, x):
        """
        计算trace
        """
        if self.trace is None:
            self.trace = Parameter(x.clone().detach(), requires_grad=False)
        else:
            self.trace *= self.decay
            self.trace += x
        return self.trace.detach()

    def reset(self):
        """
        重置
        """
        self.trace = None


def heaviside(x):
    return (x >= 0.).to(x.dtype)


class quadratic_gate(torch.autograd.Function):
    """
    使用 quadratic_gate 作为代理梯度函数
    对应的原函数为:

    .. math::
        g(x) =
        \\begin{cases}
        0, & x < -\\frac{1}{\\alpha} \\\\
        -\\frac{1}{2}\\alpha^2|x|x + \\alpha x + \\frac{1}{2}, & |x| \\leq \\frac{1}{\\alpha}  \\\\
        1, & x > \\frac{1}{\\alpha} \\\\
        \\end{cases}

    反向传播的函数为:

    .. math::
        g'(x) =
        \\begin{cases}
        0, & |x| > \\frac{1}{\\alpha} \\\\
        -\\alpha^2|x|+\\alpha, & |x| \\leq \\frac{1}{\\alpha}
        \\end{cases}

    """

    @staticmethod
    def forward(ctx, x, alpha):
        if x.requires_grad:
            mask_zero = (x.abs() > 1 / alpha)
            grad_x = -alpha * alpha * x.abs() + alpha
            grad_x.masked_fill_(mask_zero, 0)
            ctx.save_for_backward(grad_x)
        return x.gt(0.).float()

    @staticmethod
    def backward(ctx, grad_output):
        grad_x = None
        if ctx.needs_input_grad[0]:
            grad_x = grad_output * ctx.saved_tensors[0]
        return grad_x, None


class SurrogateFunctionBase(nn.Module):
    """
    Surrogate Function 的基类
    :param alpha: 为一些能够调控函数形状的代理函数提供参数.
    :param requires_grad: 参数 ``alpha`` 是否需要计算梯度, 默认为 ``False``
    """

    def __init__(self, alpha, requires_grad=True):
        super().__init__()
        self.alpha = nn.Parameter(
            torch.tensor(alpha, dtype=torch.float),
            requires_grad=requires_grad)

    @staticmethod
    def act_fun(x, alpha):
        """
        :param x: 膜电位的输入
        :param alpha: 控制代理梯度形状的变量, 可以为 ``NoneType``
        :return: 激发之后的spike, 取值为 ``[0, 1]``
        """
        raise NotImplementedError

    def forward(self, x):
        """
        :param x: 膜电位输入
        :return: 激发之后的spike
        """
        return self.act_fun(x, self.alpha)


'''
    sigmoid surrogate function.
'''


class QGateGrad(SurrogateFunctionBase):
    def __init__(self, alpha=2., requires_grad=False):
        super().__init__(alpha, requires_grad)

    @staticmethod
    def act_fun(x, alpha):
        return quadratic_gate.apply(x, alpha)


class relu_like(torch.autograd.Function):
    @staticmethod
    def forward(ctx, x, alpha):
        if x.requires_grad:
            ctx.save_for_backward(x, alpha)
        return heaviside(x)

    @staticmethod
    def backward(ctx, grad_output):
        grad_x, grad_alpha = None, None
        x, alpha = ctx.saved_tensors
        if ctx.needs_input_grad[0]:
            grad_x = grad_output * x.gt(0.).float() * alpha
        if ctx.needs_input_grad[1]:
            grad_alpha = (grad_output * F.relu(x)).sum()
        return grad_x, grad_alpha


class RoundGrad(nn.Module):
    def __init__(self, **kwargs):
        super(RoundGrad, self).__init__()
        self.act = nn.Hardtanh(-.5, 4.5)

    def forward(self, x):
        x = self.act(x)
        return x.ceil() + x - x.detach()


class backeigate(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input):
        ctx.save_for_backward(input)
        return input.gt(0.).float()

    @staticmethod
    def backward(ctx, grad_output):
        input, = ctx.saved_tensors
        grad_input = grad_output.clone()
        temp = abs(input) < 0.5
        return grad_input * temp.float()


class BackEIGateGrad(SurrogateFunctionBase):
    def __init__(self, alpha=2., requires_grad=False):
        super().__init__(alpha, requires_grad)

    @staticmethod
    def act_fun(x, alpha):
        return backeigate.apply(x)


class ei(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input):
        ctx.save_for_backward(input)
        return torch.sign(input).float()

    @staticmethod
    def backward(ctx, grad_output):
        input, = ctx.saved_tensors
        grad_input = grad_output.clone()
        temp = abs(input) < 0.5
        return grad_input * temp.float()


class BaseNode(nn.Module, abc.ABC):
    """
    神经元模型的基类
    :param threshold: 神经元发放脉冲需要达到的阈值
    :param v_reset: 静息电位
    :param dt: 时间步长
    :param step: 仿真步
    :param requires_thres_grad: 是否需要计算对于threshold的梯度, 默认为 ``False``
    :param sigmoid_thres: 是否使用sigmoid约束threshold的范围搭到 [0, 1], 默认为 ``False``
    :param requires_fp: 是否需要在推理过程中保存feature map, 需要消耗额外的内存和时间, 默认为 ``False``
    :param layer_by_layer: 是否以一次性计算所有step的输出, 在网络模型较大的情况下, 一般会缩短单次推理的时间, 默认为 ``False``
    :param n_groups: 在不同的时间步, 是否使用不同的权重, 默认为 ``1``, 即不分组
    :param mem_detach: 是否将上一时刻的膜电位在计算图中截断
    :param args: 其他的参数
    :param kwargs: 其他的参数
    """

    def __init__(self,
                 threshold=.5,
                 v_reset=0.,
                 dt=1.,
                 step=8,
                 requires_thres_grad=False,
                 sigmoid_thres=False,
                 requires_fp=False,
                 layer_by_layer=False,
                 n_groups=1,
                 *args,
                 **kwargs):

        super(BaseNode, self).__init__()
        self.threshold = Parameter(torch.tensor(
            threshold), requires_grad=requires_thres_grad)
        self.sigmoid_thres = sigmoid_thres
        self.mem = 0.
        self.spike = 0.
        self.dt = dt
        self.feature_map = []
        self.mem_collect = []
        self.requires_fp = requires_fp
        self.v_reset = v_reset
        self.step = step
        self.layer_by_layer = layer_by_layer
        self.groups = n_groups
        self.mem_detach = kwargs['mem_detach'] if 'mem_detach' in kwargs else False
        self.requires_mem = kwargs['requires_mem'] if 'requires_mem' in kwargs else False

    @abc.abstractmethod
    def calc_spike(self):
        """
        通过当前的mem计算是否发放脉冲,并reset
        :return: None
        """

        pass

    def integral(self, inputs):
        """
        计算由当前inputs对于膜电势的累积
        :param inputs: 当前突触输入电流
        :type inputs: torch.tensor
        :return: None
        """

        pass

    def get_thres(self):
        return self.threshold if not self.sigmoid_thres else self.threshold.sigmoid()

    def rearrange2node(self, inputs):
        if self.groups != 1:
            if len(inputs.shape) == 4:
                outputs = rearrange(
                    inputs, 'b (c t) w h -> t b c w h', t=self.step)
            elif len(inputs.shape) == 2:
                outputs = rearrange(inputs, 'b (c t) -> t b c', t=self.step)
            else:
                raise NotImplementedError

        elif self.layer_by_layer:
            if len(inputs.shape) == 4:
                outputs = rearrange(
                    inputs, '(t b) c w h -> t b c w h', t=self.step)
            elif len(inputs.shape) == 3:
                outputs = rearrange(
                    inputs, '(t b) n c -> t b n c', t=self.step)
            elif len(inputs.shape) == 2:
                outputs = rearrange(inputs, '(t b) c -> t b c', t=self.step)
            else:
                raise NotImplementedError

        else:
            outputs = inputs

        return outputs

    def rearrange2op(self, inputs):
        if self.groups != 1:
            if len(inputs.shape) == 5:
                outputs = rearrange(inputs, 't b c w h -> b (c t) w h')
            elif len(inputs.shape) == 3:
                outputs = rearrange(inputs, ' t b c -> b (c t)')
            else:
                raise NotImplementedError
        elif self.layer_by_layer:
            if len(inputs.shape) == 5:
                outputs = rearrange(inputs, 't b c w h -> (t b) c w h')
            elif len(inputs.shape) == 4:
                outputs = rearrange(inputs, ' t b n c -> (t b) n c')
            elif len(inputs.shape) == 3:
                outputs = rearrange(inputs, ' t b c -> (t b) c')
            else:
                raise NotImplementedError

        else:
            outputs = inputs

        return outputs

    def forward(self, inputs):
        """
        torch.nn.Module 默认调用的函数,用于计算膜电位的输入和脉冲的输出
        在```self.requires_fp is True``` 的情况下,可以使得```self.feature_map```用于记录trace
        :param inputs: 当前输入的膜电位
        :return: 输出的脉冲
        """

        if self.layer_by_layer or self.groups != 1:
            inputs = self.rearrange2node(inputs)

            outputs = []
            for i in range(self.step):

                if self.mem_detach and hasattr(self.mem, 'detach'):
                    self.mem = self.mem.detach()
                    self.spike = self.spike.detach()
                self.integral(inputs[i])

                self.calc_spike()

                if self.requires_fp is True:
                    self.feature_map.append(self.spike)
                if self.requires_mem is True:
                    self.mem_collect.append(self.mem)
                outputs.append(self.spike)
            outputs = torch.stack(outputs)

            outputs = self.rearrange2op(outputs)
            return outputs
        else:
            if self.mem_detach and hasattr(self.mem, 'detach'):
                self.mem = self.mem.detach()
                self.spike = self.spike.detach()
            self.integral(inputs)
            self.calc_spike()
            if self.requires_fp is True:
                self.feature_map.append(self.spike)
            if self.requires_mem is True:
                self.mem_collect.append(self.mem)
            return self.spike

    def n_reset(self):
        """
        神经元重置,用于模型接受两个不相关输入之间,重置神经元所有的状态
        :return: None
        """
        self.mem = self.v_reset
        self.spike = 0.
        self.feature_map = []
        self.mem_collect = []

    def get_n_attr(self, attr):

        if hasattr(self, attr):
            return getattr(self, attr)
        else:
            return None

    def set_n_warm_up(self, flag):
        """
        一些训练策略会在初始的一些epoch,将神经元视作ANN的激活函数训练,此为设置是否使用该方法训练
        :param flag: True:神经元变为激活函数, False:不变
        :return: None
        """
        self.warm_up = flag

    def set_n_threshold(self, thresh):
        """
        动态设置神经元的阈值
        :param thresh: 阈值
        :return:
        """
        self.threshold = Parameter(torch.tensor(
            thresh, dtype=torch.float), requires_grad=False)

    def set_n_tau(self, tau):
        """
        动态设置神经元的衰减系数,用于带Leaky的神经元
        :param tau: 衰减系数
        :return:
        """
        if hasattr(self, 'tau'):
            self.tau = Parameter(torch.tensor(
                tau, dtype=torch.float), requires_grad=False)
        else:
            raise NotImplementedError


class LIFNode(BaseNode):
    """
    Leaky Integrate and Fire
    :param threshold: 神经元发放脉冲需要达到的阈值
    :param v_reset: 静息电位
    :param dt: 时间步长
    :param step: 仿真步
    :param tau: 膜电位时间常数, 用于控制膜电位衰减
    :param act_fun: 使用surrogate gradient 对梯度进行近似, 默认为 ``surrogate.AtanGrad``
    :param requires_thres_grad: 是否需要计算对于threshold的梯度, 默认为 ``False``
    :param sigmoid_thres: 是否使用sigmoid约束threshold的范围搭到 [0, 1], 默认为 ``False``
    :param requires_fp: 是否需要在推理过程中保存feature map, 需要消耗额外的内存和时间, 默认为 ``False``
    :param layer_by_layer: 是否以一次性计算所有step的输出, 在网络模型较大的情况下, 一般会缩短单次推理的时间, 默认为 ``False``
    :param n_groups: 在不同的时间步, 是否使用不同的权重, 默认为 ``1``, 即不分组
    :param args: 其他的参数
    :param kwargs: 其他的参数
    """

    def __init__(self, threshold=0.5, tau=2., act_fun=QGateGrad, *args, **kwargs):
        super().__init__(threshold, *args, **kwargs)
        self.tau = tau
        if isinstance(act_fun, str):
            act_fun = eval(act_fun)
        self.act_fun = act_fun(alpha=2., requires_grad=False)
        # self.threshold = threshold
        # print(threshold)
        # print(tau)

    def integral(self, inputs):
        self.mem = self.mem + (inputs - self.mem) / self.tau

    def calc_spike(self):
        self.spike = self.act_fun(self.mem - self.threshold)
        self.mem = self.mem * (1 - self.spike.detach())


class LIAFNode(BaseNode):
    """
    Leaky Integrate and Analog Fire (LIAF), Reference: https://ieeexplore.ieee.org/abstract/document/9429228
    与LIF相同, 但前传的是膜电势, 更新沿用阈值和膜电势
    :param act_fun: 前传使用的激活函数 [ReLU, SeLU, LeakyReLU]
    :param threshold_related: 阈值依赖模式,若为"True"则 self.spike = act_fun(mem-threshold)
    :note that BaseNode return self.spike, and here self.spike is analog value.
    """

    def __init__(self, spike_act=BackEIGateGrad(), act_fun="SELU", threshold=0.5, tau=2., threshold_related=True, *args, **kwargs):
        super().__init__(threshold, *args, **kwargs)
        if isinstance(act_fun, str):
            act_fun = eval("nn." + act_fun + "()")
        self.tau = tau
        self.act_fun = act_fun
        self.spike_act = spike_act
        self.threshold_related = threshold_related

    def integral(self, inputs):
        self.mem = self.mem + (inputs - self.mem) / self.tau

    def calc_spike(self):
        if self.threshold_related:
            spike_tmp = self.act_fun(self.mem - self.threshold)
        else:
            spike_tmp = self.act_fun(self.mem)
        self.spike = self.spike_act(self.mem - self.threshold)
        self.mem = self.mem * (1 - self.spike)
        self.spike = spike_tmp


class SNN_RMSNorm(nn.Module):
    def __init__(self, max_length = 128, hidden_size=4096,node=LIAFNode, threshold=0.5, eps=1e-6):
        super().__init__()
        self.eps = eps
        self.rms_neuron = node(act_fun='LeakyReLU', threshold=threshold)
        self.weight_neuron = node(act_fun='ReLU', threshold=threshold)
        self.weight = nn.Parameter(torch.ones(hidden_size,hidden_size))
        self.rms_connection = CustomLinear(torch.ones(1,hidden_size))
        self.weight_connection = CustomLinear(self.weight)

    def forward(self, x):
        x_sqr = x ** 2
        x_rms = x_sqr.mean(-1, keepdim=True)
        s_rms = self.rms_neuron(self.rms_connection(x_rms))
        rms_out = torch.rsqrt(s_rms + self.eps)
        s_scale = self.weight_neuron(self.weight_connection(rms_out))
        return s_scale

About your code on CIFAR10-DVS

Dear author,
We recently executed your code on CIFAR10-DVS and had some issues. You don't seem to be splitting your dataset into training and test sets. Furthermore, when we loaded the data downloaded from the url provided in the code, an error occurred, "ValueError: String size must be a multiple of the element size", which means that there mighe be some errors in the code while processing the dataset.
We would be grantful for any response or help.
Kinds regard.
image
48e2f6d1dc33c4e30402f233b428580

Incomplete `algorithms` subpackage for the `Social_Cognition/FOToM` project

The ToM_decisionN1 and ToM_decision01 cannot be identified due to the missing files tomN1.py and tom01.py in the algorithms subpackage for the Social_Cognition/FOToM project

# ./examples/Social_Cognition/FOToM/main.py
from algorithms.tomN1 import ToM_decisionN1 # missing
from algorithms.tom01 import ToM_decision01 # missing
from algorithms.tom11 import ToM_decision11
$ ls ./examples/Social_Cognition/FOToM/algorithms
__init__.py  maddpg.py  tom11.py  ToM_class.p

Multiscale_Brain_Structure_Simulation Errors under Windows

Hello,

I have tried to run the brain models with Python 3.9, 3.10, and 3.11 under "Multiscale_Brain_Structure_Simulation" models like "HumanBrain", "MouseBrain", and "" and am getting errors like this.

---- Human Brain ----

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\HumanBrain> python .\human_brain.py
torch.Size([3442000, 2])
Traceback (most recent call last):
  File "D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\HumanBrain\human_brain.py", line 185, in <module>
    model = brain(syn, weight, neuron_model, p_neuron, dt, device)
  File "D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\HumanBrain\human_brain.py", line 46, in __init__
    self.neurons = HHNode(p_neuron, dt, device)
TypeError: __init__() missing 1 required positional argument: 'type_index'

---- Mouse Brain ----

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\MouseBrain> python .\mouse_brain.py
torch.Size([52238965, 2])
Traceback (most recent call last):
  File "D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\MouseBrain\mouse_brain.py", line 186, in <module>
    model = brain(syn, weight, neuron_model, p_neuron, dt, device)
  File "D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\MouseBrain\mouse_brain.py", line 47, in __init__
    self.neurons = aEIF(p_neuron, dt, device)
TypeError: __init__() missing 1 required positional argument: 'type_index'

---- MacaqueBrain ----

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\MacaqueBrain> python .\macaque_brain.py
torch.Size([38960200, 2])
Traceback (most recent call last):
  File "D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\MacaqueBrain\macaque_brain.py", line 185, in <module>
    model = brain(syn, weight, neuron_model, p_neuron, dt, device)
  File "D:\BrainCog\examples\Multiscale_Brain_Structure_Simulation\MacaqueBrain\macaque_brain.py", line 47, in __init__
    self.neurons = aEIF(p_neuron, dt, device)
TypeError: __init__() missing 1 required positional argument: 'type_index'

Any thoughts?
Thanks

问题,PermissionError: [Errno 13] Permission denied: '/data' 权限不足,已经设置超级管理员

(pytorch38) huo@DESKTOP-0F2SLL8:/mnt/d/pywork/Brain-Cog-main/examples/Perception_and_Learning/img_cls/bp$ python main.py --model dvs_convnet --node-type LIFNode --dataset dvsc10 --step 10 --batch-size 128 --act-fun QGateGrad --device 0
Traceback (most recent call last):
File "main.py", line 1068, in
main()
File "main.py", line 364, in main
output_dir = get_outdir(output_base, 'train', exp_name)
File "/home/huo/anaconda3/envs/pytorch38/lib/python3.8/site-packages/timm/utils/summary.py", line 16, in get_outdir
os.makedirs(outdir)
File "/home/huo/anaconda3/envs/pytorch38/lib/python3.8/os.py", line 213, in makedirs
makedirs(head, exist_ok=exist_ok)
File "/home/huo/anaconda3/envs/pytorch38/lib/python3.8/os.py", line 213, in makedirs
makedirs(head, exist_ok=exist_ok)
File "/home/huo/anaconda3/envs/pytorch38/lib/python3.8/os.py", line 213, in makedirs
makedirs(head, exist_ok=exist_ok)
[Previous line repeated 1 more time]
File "/home/huo/anaconda3/envs/pytorch38/lib/python3.8/os.py", line 223, in makedirs
mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/data'

``

What typical GPU is used?

Hello,

Can you please tell me what is the typical GPU cards that you are using and their specification?

On this machine, I have a RTX 3060 Ti with 8GB memory but it does not seem to be enough to run your Unsupervised STDP-based spiking neural network and I keep running out of memory on the GPU.

https://github.com/BrainCog-X/Brain-Cog/tree/main/examples/Perception_and_Learning/UnsupervisedSTDP

I am working my way through the wonder Brain Cog code and examples. This project show the most promise that I have found for truly developing a full virtual brain simulation that will hopefully be able to learn incrementally and online. I have investigated MANY other solutions and one that had good potential was the SOINN by Hasegawa that uses unsupervised learning to incrementally learn.

Also, I am wondering if you have considered adding Liquid time-constant Networks (LTCs) which are supposed to be a significant improvement over classic RNN's in that they evolve and self-adjust to optimal solutions.

https://github.com/raminmh/liquid_time_constant_networks

PAPER: https://arxiv.org/abs/2006.04439

Thanks and have a great day

About STDP code implementation

Hi!
I'm reading STDP code in braincog.base.learningrule.
But it seems like the way to implement the STDP is not the same as the formula (9) in the Braincog thesis.

`class STDP(nn.Module):
"""
STDP learning rule
"""

def __init__(self, node, connection, decay=0.99):
    """
    :param node:node神经元类型实例如IFNode LIFNode
    :param connection:连接 类的实例 里面只能有一个操作
    """
    super().__init__()

    self.node = node
    self.connection = connection
    self.trace = None
    self.decay = decay

def forward(self, x):
    """
    计算前向传播过程
    :return:s是脉冲 dw更新量
    """
    x = x.clone().detach()
    i = self.connection(x)
    with torch.no_grad():
        s = self.node(i)

        i.data += s - i.data
        trace = self.cal_trace(x)
        x.data += trace - x.data

    dw = torch.autograd.grad(outputs=i, inputs=self.connection.weight, grad_outputs=i)

    return s, dw

def cal_trace(self, x):
    """
    计算trace
    """
    if self.trace is None:
        self.trace = Parameter(x.clone().detach(), requires_grad=False)
    else:
        self.trace *= self.decay
        self.trace += x
    return self.trace.detach()

def reset(self):
    """
    重置
    """
    self.trace = None`

I have some doubts, specifically,

  1. there is no Δt in the code, how to calculate W(Δt)?
  2. the 'trace' seems like unused in the forward pass, what does 'trace' mean in the code?
  3. the STDP is a unsupervised learning rule, but the dw is calculate by torch.autograd.grad, how it works and why use that?

Thanks for your time!

There is a problem with your instance program. Please solve it

root@I104ba06b4a00701fdf:/hy-tmp/Brain-Cog-master/examples/Perception_and_Learning/img_cls/bp# python main.py --model dvs_convnet --node-type LIFNode --dataset dvsc10 --step 10 --batch-size 128 --act-fun QGateGrad --device 0
Training with a single process on 1 GPUs.
learning rate is 0.000625
Model dvs_convnet created, param count: 7532826
AMP not enabled. Training in float32.
Scheduled epochs: 610
Traceback (most recent call last):
File "main.py", line 1069, in
main()
File "main.py", line 578, in main
loader_train, loader_eval, mixup_active, mixup_fn = eval('get_%s_data' % args.dataset)(
File "/usr/local/lib/python3.8/dist-packages/braincog/datasets/datasets.py", line 544, in get_dvsc10_data
train_dataset = tonic.datasets.CIFAR10DVS(os.path.join(DATA_DIR, 'DVS/DVS_Cifar10'), transform=train_transform)
File "/usr/local/lib/python3.8/dist-packages/tonic/datasets/cifar10dvs.py", line 87, in init
self.download()
File "/usr/local/lib/python3.8/dist-packages/tonic/dataset.py", line 34, in download
download_and_extract_archive(
File "/usr/local/lib/python3.8/dist-packages/tonic/download_utils.py", line 322, in download_and_extract_archive
download_url(url, download_root, filename, md5)
File "/usr/local/lib/python3.8/dist-packages/tonic/download_utils.py", line 118, in download_url
url = _get_redirect_url(url, max_hops=max_redirect_hops)
File "/usr/local/lib/python3.8/dist-packages/tonic/download_utils.py", line 62, in _get_redirect_url
with urllib.request.urlopen(
File "/usr/lib/python3.8/urllib/request.py", line 222, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.8/urllib/request.py", line 531, in open
response = meth(req, response)
File "/usr/lib/python3.8/urllib/request.py", line 640, in http_response
response = self.parent.error(
File "/usr/lib/python3.8/urllib/request.py", line 569, in error
return self._call_chain(*args)
File "/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
result = func(*args)
File "/usr/lib/python3.8/urllib/request.py", line 649, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.