Tempotron介绍

首先介绍一下Tempotron这个监督算法,想要用SNN去解决一个分类问题,有三个步骤:
1、考虑如何将样本编码成和时间相关的脉冲序列。
2、如何构建一个神经元的模型。
3、确定一个学习算法,用于训练样本。
Tempotron方法提出:神经元后突触膜电位是所有与之相连的上一层脉冲输入的加权和。膜电位计算公式为:
在这里插入图片描述
其中K函数是一个kernel函数,它代表的是每一个传入脉冲的贡献值。它的公式为:
在这里插入图片描述
画成图像为:
在这里插入图片描述
其中 taum和taus是控制整个K(t)图像大致形状的参数,是个超参数。V0的作用是个归一化的作用。看到这,我产生了一个疑问,我们都知道在创建的神经网络中,它的时间都是一层一层往下延伸的,所以这个ti?是什么意思。
到这,我们还缺少一个参数w,在训练时我们通常根据随机化去产生一个初始权重矩阵,那么在训练的时候我们是怎么根据误差来更新权重?脉冲神经元只有两种状态,一个是发放,一个是不发放,转移到数字上就是0和1,如果在一个时间步骤内,我们只能产生一个脉冲。那么我们就可以得出一个规则,**如果我们的目标它要求是输出1,可是我们输出了0,那么我们就可以使权重变大,如果我们要求是输出0,但是它输出了1,那么我们就可以使脉冲减小。**这就是Tempotron的学习规则,所以它是监督学习然后我们只要得到一个△w公式就可以了。
在这里插入图片描述
λ是一个控制变化幅度的系数,类似与学习率。K就是上面的kernel函数,tmax是指在一个时间窗口内该输出层神经元达到电压最大值的时间。

接下去进入代码部分
代码地址:https://github.com/ajaykarpur/tempotron-classifier
那我们就从编码开始吧,具体的图片处理的,就去源码看好了。

def encode(self):
   data_array = np.array(self.image)#data).reshape((28,28))
   edges = canny(data_array, sigma=3)    #提取边缘
   def linear_mapping(data): # using principal components analysis
      pca = decomposition.PCA(n_components=784)  #主成分分析
      pca.fit(data)  #训练
      mapping = pca.transform(data)  #将原始数据转化成训练好后的数据
      return mapping
   # encoded = linear_mapping(edges)
   encoded = np.array(edges).reshape(784)    #这是平铺成一维数据
   # encoded = []
   # for d in self.data:
   #  if (d > 45):
   #     encoded.append(1)
   #  else:
   #     encoded.append(0)
   return encoded

这一段就是编码的程序,他是先对图像进行canny提取边缘处理。在它注释掉的代码里面还有进行主成分分析的处理,不过这不是我们训练的关键。

下面这是Tempotron的神经元封装。

class Tempotron(object):
   def __init__(self, length, Cm=4.9, Vreset=-63., Vthresh=-55., Vrest=-58., V0=2.12, Erev=-80., El=-58., gl=.02):
      self.Vreset = float(Vreset) # mV   
      self.Vthresh = float(Vthresh) # mV 阈值
      self.Vrest = float(Vrest) # mV 静息
      self.V0 = float(V0)    #归一化数值
      self.Erev = float(Erev) # mV
      self.El = float(El) # mV
      self.gl = float(gl) # uS
      self.length = length
      # self.Rm = 1/gl
      # self.taum = Cm*self.Rm
      self.tau = 15 # in ms
      self.taus = self.tau/4
      self.weights = [random.random()]*length # initialize with randomly assigned weights


   def __PSP(self, t):       #kernel函数
      return self.V0*(m.exp(-t/self.tau) - m.exp(-t/self.taus))


   def V(self, t):       #膜电位计算函数
      return self.weights[t]*(self.__PSP(t) + self.Vrest)


   def __cost(self, t):
      Vthresh = self.Vthresh
      spike = data[t]       #脉冲 输入值
      tmax = self.length - 1 #最后一个值
      if (spike == 1):   #
         return Vthresh - self.V(tmax)
      elif (spike == 0):
         return self.V(tmax) - Vthresh

   def __syn_update(self, t, maxsize=.00008): #maxsize就是学习率值 这个就是权重更新值
      tmax = self.length - 1
      return maxsize*self.__PSP(tmax - t)


   def train(self, data): #权重更新 这里居然只有增加的,
      for t, d in enumerate(data):
         self.weights[t] += self.__syn_update(t)


   def test(self, data):
      for t, d in enumerate(data):
         if (abs(self.V(t)) > abs(self.Vthresh)):
            return 1
      return 0
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值