11.10-11.17学习周报

摘要

本周学习了脉冲神经网络的相关概念,了解了脉冲神经网络的原理,理解了膜电位和突触的工作过程,能够自己手动搭建一个脉冲神经网络来实现一些小实验。

Abstract

This week, I learned the relevant concepts of spiking neural networks, understood the principles of spiking neural networks, understood the working process of membrane potentials and synapses, and was able to manually build a spiking neural network to achieve some small experiments.

一.什么是SNN?

脉冲神经网络(Spiking Neural Networks,简称SNNs)是一种模拟生物大脑神经元行为的计算模型,它通过模拟神经元发放脉冲(或称为尖峰)的方式来传递信息。与传统的人工神经网络不同,SNNs在信息处理上更加接近生物神经系统的工作方式。

1.SNN的优势

生物可塑性:SNNs能够模拟生物大脑的可塑性,即通过学习改变神经元间连接的强度。
事件驱动:SNNs仅在输入发生变化时才发放脉冲,这种事件驱动的特性使得它们在处理动态视觉和听觉信息时非常高效。
高能效:SNNs在理论上能够实现更高的能效,因为它们只在必要时发放脉冲,而不是持续地处理信息。
时间编码:SNNs能够利用脉冲的精确时间信息,这为处理时间序列数据提供了一种强大的工具。

2.SNN的局限

训练难度:SNNs的训练算法相比传统神经网络更为复杂,需要特定的学习规则(如STDP)。
计算资源:虽然理论上SNNs具有高能效,但目前的硬件平台尚未能完全发挥其潜力。
理论发展:SNNs的理论基础尚在发展中,对于如何最有效地设计和训练SNNs仍有许多未知。
SNN的结构和工作原理
SNN的基本单元是脉冲神经元,它们通过发放脉冲(或称为尖峰)来传递信息。每个神经元的输出不是连续的信号,而是一个离散的脉冲序列。这些脉冲的发放时间和频率携带了编码的信息。

SNN中的神经元通常通过突触连接,突触的权重决定了神经元间信息传递的强度和效率。

3.ANN神经元概要

•计算方法:ANN中的神经元通过非线性激活函数处理输入和权重的乘积累加
•通信方式:ANN神经元使用高精度和连续值编码的激活值进行相互通信。
•信息传播:ANN仅在空间域(layer by layer)传播信息。
SNN神经元概要

•结构与行为:SNN神经元在结构上与ANN神经元相似,但通过脉冲(Spike)而非连续激活值进行交流。
•通信方式:SNN神经元之间的交流通过二进制事件(脉冲)进行。
•膜电位更新:SNN神经元的膜电位更新遵循微分方程,涉及时间步长、常数、膜电位、输出峰值、静息电位、重置电位和输入突触的权重。
•脉冲发放条件:
a.当膜电位超过阈值时,神经元发放脉冲,输出电位置为1,膜电位回归到重置电位。
b.当膜电位低于阈值时,神经元不发放脉冲,输出电位保持为0。
•信息传播:SNN不仅在空间域中传播信息,时间域中的历史也对当前状态产生影响。
•信号稀疏性:由于只有膜电位超过阈值时才激发尖峰信号,SNN的信号通常是稀疏的。

二、手动搭建SNN

这里我用snn模拟了信息在人脑传递的过程。
1.首先我们要定义神经元,膜电位,以及达到膜电位以后所触发的脉冲事件。因为信息传递的时候会造成能量损失,我们将输入时的能量提到最高,定义好损失值和膜电位,如果下一个神经元的脉冲能量达不到膜电位就无法触发脉冲事件。达到膜电位触发脉冲事件以后会将能量传递到下一个神经元,当前神经元的能量就会归0。

import torch
import torch.nn as nn
import numpy as np
import logging
import time

class Sprikeneuron:#定义神经元
    def __init__(self,id,threshold=60.0,reset_voltage=0.0):
        self.id=id#神经元id
        self.threshold=threshold#定义阈值,膜电位达到阈值的时候触发脉冲
        self.reset_voltage=reset_voltage#达到阈值激活后充值膜电压
        self.membrane_potential = 0.0  # 初始膜电位为 0
        self.energy = 100.0  # 初始能量值为 1.0
        self.log = []  # 记录神经元活动的日志列表

    def receive_input(self,input):#接收外部输入,提高膜电位
        self.membrane_potential+=input
        if self.membrane_potential>=self.threshold:#触发条件:达到阈值
            self.fire_pulse()  # 触发脉冲
            self.membrane_potential = self.reset_voltage  # 重置膜电位到设定的重置电压

    def fire_pulse(self):
        #触发脉冲事件
        event = {  # 记录脉冲事件的详细信息
            "neuron_id": self.id,  # 神经元 ID
            "activation_time": time.time(),  # 当前时间戳,记录脉冲发生的时间
            "energy_loss": 10  # 每次脉冲损失的能量(这里假设是 10)
        }
        self.log.append(event)
        self.energy -= 10  # 每次触发脉冲时,神经元的能量减少 0.05
        # 将脉冲事件写入日志文件
        logging.info(f"Neuron {self.id} fired a pulse. Energy loss: 10.0. Remaining energy: {self.energy:.2f}.")

    def recover_energy(self):
        self.energy+=10

2.定义好了神经元以后开始搭建神经网络。脉冲神经网络有多个神经元组成。在这里我加入了对句子的拆分和处理。将句子的每个单词用空格进行分割,用哈希函数为每个单词分配id,将每个单词存储到神经元中,若在这个过程中传递能量达不到膜电位,就会造成单词的缺失或者说遗忘。

from Sprike_neuron import Sprikeneuron
import time
import numpy as np
import logging

class Sprikenetwork:
    def __init__(self):
        self.neurons=[]
        self.time_step=0

    def add_neuron(self,neuron):#将脉冲神经元加入脉冲神经网络
        self.neurons.append(neuron)

    def process_sentence(self,sentence):#处理句子转为对神经元的刺激
        words=sentence.split()#将句子用空格分割成单词列表
        logging.info(f"Processing sentence: {sentence}")
        for word in words:
            neuron_id=hash(word)%len(self.neurons)#通过哈希函数为每个单词分配神经元id
            neuron=self.neurons[neuron_id]#根据id获取对应神经元
            input=100.0#生成电流
            neuron.receive_input(input)  # 将输入电流传递给神经元,模拟神经元的激活



    def log_events(self):
        # 输出网络中所有神经元的日志事件
        for neuron in self.neurons:  # 遍历网络中的每个神经元
            for event in neuron.log:  # 遍历神经元的日志
                print(event)  # 打印日志信息
                logging.info(f"Neuron {event['neuron_id']} fired at {event['activation_time']}. Energy loss: {event['energy_loss']:.2f}.")

3.最后创建神经元和神经网络,输入句子,并将执行结果存放在日志中。

from Sprike_neuron import Sprikeneuron
from Sprike_network import Sprikenetwork
import logging

# 配置日志记录器
logging.basicConfig(
    filename='spiking_neuron_network.log',  # 日志文件名
    level=logging.DEBUG,  # 设置日志记录的级别为 DEBUG
    format='%(asctime)s - %(levelname)s - %(message)s',  # 日志格式
)

network = Sprikenetwork() # 创建一个新的脉冲神经网络对象
for i in range(10):  # 创建 10 个神经元
    neuron=Sprikeneuron(id=i)
    network.add_neuron(neuron)

network.process_sentence("Hello world this is a test")  # 处理输入的句子,刺激相应的神经元
network.log_events()  # 打印网络中所有神经元的日志事件

在这里插入图片描述
在这里插入图片描述

总结

本周学习脉冲神经网络的相关内容,下周将复习之前学过的相关内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值