ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 测试运行 - 借助人工尖峰神经元进行计算 通过 [James McCaffrey](https://msdn.microsoft.com/zh-cn/magazine/mt149362?author=James+McCaffrey) | 2015 年 9 月 |获取的代码: [C#](http://download.microsoft.com/download/F/A/B/FABA846E-7E6A-499F-AC79-931F1E4EACA3/Code_McCaffrey.TestRun.0915.zip)[VB](http://download.microsoft.com/download/F/A/B/FABA846E-7E6A-499F-AC79-931F1E4EACA3/VBCode_McCaffrey.TestRun.0915.zip) ![](https://box.kancloud.cn/2016-01-08_568f2a8298186.jpg) 计算机科学领域的迫切地区域计算与人工峰值状态神经元 — 模型生物神经元的行为的小型软件组件。人工峰值状态神经元是相关,又与常见的软件神经网络中人工神经元完全不同。 让我事先人工峰值状态的神经元的这种讨论不可能将立即有益于正常的日常编程任务权限声明。这将有助于您深入了解计算的未来可能是 like、 但您可能觉得人工峰值状态神经元有趣凭其自身。 若要获得有个大概了解是哪些峰值状态的神经元以及请参阅本文所述观点的最佳方法是看一下在演示程序图 1。 ![](https://box.kancloud.cn/2016-01-08_568f81ecaf54a.png)  图 1 人工峰值神经元演示的数量 该演示程序显示单个峰值状态不同,神经元的输入和输出值。有三个输入的流,有时也称为峰值火车。 每个输入的峰值火车了 16 个 0 或 1 值。三个输入的峰值火车是: ~~~ 0 0 1 0 1 0 1 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 1 1 1 0 1 1 0 1 1 1 1 0 1 0 0 0 1 1 0 1 1 1 1 1 1 ~~~ 这些 0 或 1 值从其他峰值状态的神经元表示随着时间的推移的输入。换而言之,在时间 t = 0 时,从第一个峰值定型的输入的值为 0 ;在时间 t = 1,输入是 0;t 处 = 2,输入为 1 ;等到 t = 15 时输入的值为 1。 在时间 t = 0,峰值状态的神经元接收来自所有三个流的输入,因此在 t = 0 时,完整的输入神经元是 (0,1,1);在时间 t = 1,输入是 (0,0,1);等到 t = 15 在输入 (1,1,1) 时。 演示程序的下一部分显示定义的行为的神经元的数值常量。有三个具有与每个输入火车相对应的值 (4,-2,3) 的权重。(2) 将稍后说明泄漏潜在 (1)、 (8) 中的阈值可能性、 峰值可能 (4) 和后的峰值延迟的含义。在峰值神经元的数量的上下文中,术语"可能"是指 (松散) 电气电压而不是"可能"即将。" 演示程序虽模拟 16 时间刻度。在每个时钟周期,这三个输入神经元 (活动或非活动状态) 和神经元的阶梯当前电势 (V) 的状态以及显示 0 或 1 值。请注意在时间 t = 6 神经元达到 V 潜在 = 8 和峰值到 V = 12。在后台处理的每组输入值时,是生成的输出值为 0 或 1 并保存到缓冲区。处理完所有输入的值后,演示程序将显示生成的输出峰值定型: ~~~ 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 ~~~ 此时,您很可能不太印象深刻。值 0 或 1 值的一组进入,与大量的 0 或 1 值推出。但请耐心听我,您将看到人工峰值状态神经元可帮助中的计算机和计算的基本更改所导致。 本文假定您至少具有初级编程技能,但不会假设您知道有关峰值神经元的数量的任何信息。我已编写代码演示程序虽以 C# 中,但您应能够很大的困难重构为其他语言,如 Python 或 JavaScript。演示代码将比较短,并在本文中完整地显示。完整源代码也是在随附代码下载中提供的。 ## 了解峰值状态神经元 请看图 2 中的曲线图。关系图显示电源的潜在价值 V、 蜂值从时间 t 的神经元演示 = 0 到 t = 15。有许多不同变体峰值神经元的数量。演示程序虽取决于调用存在泄漏的集成火灾峰值状态神经元的模型。 ![](https://box.kancloud.cn/2016-01-08_568f81ed091c0.png)  图 2 渗漏集成火灾蜂值神经元行为 神经元的阶梯电势往往会随着时间推移而增加。V 满足或超过为 8,由虚线,指示的峰值状态阈值时 V 值的可立即峰值 4 (峰值潜在) 上移,然后立即重置为 0。峰值状态事件发生在时间 t = 6 和 t = 13。如果发生峰值状态的事件,向输出峰值火车开,否则为 0,将发出发出一个 1。 因此,只需计算的方法 V t 的每个值吗? 在时间 t = 0 时,三个输入的值是 (0,1,1)。前面曾提到神经元的三个权重值是 (4,-2,3)。首先,输入时间权重的产品的总额被计算并添加到 V 的当前值。如果 V 假定要然后演示开头的 0: ~~~ V = V + sum    = 0 + (0)(4) + (1)(-2) + (1)(3)    = 0 + 1    = 1 ~~~ 这是集成步骤。接下来,减去泄漏值。对于演示,泄露因此 = 1: ~~~ V = V - leak    = 1 - 1    = 0 ~~~ V 的新值 = 0 不会超出阈值值为 8 因此神经元不会达到峰值,并会发出输出峰值火车到 0。接下来,在时间 t = 1,输入的值为 (0,0,1)。组合的集成和泄漏步骤提供了: ~~~ V = V + sum - leak     = 0 + (0)(4) + (0)(-2) + (1)(3) - 1     = 0 + 3 - 1     = 2 ~~~ 人工渗漏集成火灾峰值状态神经元都非常简单。请注意所有值都是整数,它结合简化设计,是指人工神经元可以高效地实现中的软件或硬件。 在 图 2, ,您可以看到了峰值事件发生在时间 t = 6。在 t = 5,V = 5 因此 t 的集成泄漏计算 = 6 是: ~~~ V = V + sum - leak     = 5 + (1)(4) + (0)(-2) + (0)(3) - 1     = 5 + 4 - 1     = 8 ~~~ 此时,V 满足阈值值为 8,因此 V 的值为 8 + 4 = 12 峰值、 的输出值为 1,将发出,然后 V 将立即重置为 0。峰值事件之后,模拟的神经元进入其中输入的值将被忽略的非活动状态。该演示设置此滞后期为 2,因此有时 t = 7,将 t = 8,V 保持为 0 而不考虑输入的值。在时间 t = 9,神经元将变为活动状态并且将恢复正常的行为。 ## 实现演示程序 与几个较小的修改为节省空间的演示程序的代码所示 图 3。若要创建演示程序,我启动了 Visual Studio 并创建一个新 C# 控制台应用程序名为项目 SpikingNeuron 中。演示程序有没有重大的 Microsoft.NET 框架依赖关系,因此,任何较新版本的 Visual Studio 将工作。 图 3 峰值神经元程序的数量 ~~~ using System; namespace SpikingNeuron {   class SpikingNeuronProgram   {     static void Main(string[] args)     {       Console.WriteLine("Begin spiking neuron demo");       int[][] inputs = new int[3][];       inputs[0] = new int[] { 0, 0, 1, 0, 1, 0, 1, 1,         1, 1, 0, 0, 1, 0, 1, 1 };       inputs[1] = new int[] { 1, 0, 1, 1, 0, 0, 0, 1,         1, 1, 0, 1, 1, 0, 1, 1 };       inputs[2] = new int[] { 1, 1, 0, 1, 0, 0, 0, 1,         1, 0, 1, 1, 1, 1, 1, 1 };       Console.WriteLine("The inputs are: ");       for (int i = 0; i < inputs.Length; ++i)         ShowVector(inputs[i], false);       Console.WriteLine("");       int[] output = new int[16];       int[] wts = new int[] { 4, -2, 3 };       Console.Write("The weights are: ");       ShowVector(wts, true);       Console.WriteLine("");       int leak = 1;       Console.WriteLine("Leak potential is: " + leak);       int v = 0; // electrical potential (voltage)       int thresh = 8; // Threshold       int spike = 4;  // Increase in v at spike       int tNext = 0; // Time when neuron is active       int latency = 2; // Inactive after spike       Console.WriteLine("Threshold is: " + thresh);       Console.WriteLine("Spike is: " + spike);       Console.WriteLine("Latency time is: " + latency);       Console.WriteLine("Starting processing\");       for (int t = 0; t < 16; ++t)       {         Console.WriteLine("----------------------");         Console.Write(" ");         Console.Write("t = ");         if (t <= 9) Console.Write(" ");         Console.Write(t + ". ");         Console.Write("Inputs = " + inputs[0][t] +           " " + inputs[1][t] +           " " + inputs[2][t]);         if (t != tNext) // Neuron not active         {           Console.Write(". Neuron is inactive. ");           Console.WriteLine("V = " + v);           output[t] = 0;         }         else // Neuron is active         {           Console.Write(". Neuron is   active. ");           int sum = 0;           for (int j = 0; j < inputs.Length; ++j)             sum += inputs[j][t] * wts[j];           v = v + sum;           v = v - leak;           if (v < 0)             v = 0;           Console.WriteLine("V = " + v);           if (v >= thresh) // Spike and reset           {             v = v + spike;             Console.WriteLine(" Spiking, V = " + v);             output[t] = 1;             v = 0;             tNext = t + 1 + latency;           }           else           {             output[t] = 0;             tNext = t + 1;           }         } // Active       } // t       Console.WriteLine("----------------------");       Console.WriteLine("Output spike train = ");       ShowVector(output, false);       Console.WriteLine("End spiking neuron demo");       Console.ReadLine();     } // Main     static void ShowVector(int[] vector, bool plus)     {       for (int i = 0; i < vector.Length; ++i)       {         if (plus == true && vector[i] >= 0)           Console.Write("+");         Console.Write(vector[i] + " ");       }       Console.WriteLine("");     }   } // Program } // ns ~~~ 模板代码加载到文本编辑器中之后,在解决方案资源管理器窗口中我将文件 Program.cs 重命名为 SpikingNeuronProgram.cs 并允许重命名类 Program 为我的 Visual Studio。我删除了源代码顶部所有不需要使用语句,离开只对顶级 System 命名空间的引用。 Main 方法中的代码首先设置输入的数据和存储缓冲区的输出值为: ~~~ int[][] inputs = new int[3][]; inputs[0] = new int[] { 0, 0, 1, 0, 1, 0, 1, 1,   1, 1, 0, 0, 1, 0, 1, 1 }; ... int[] output = new int[16]; ~~~ 以下是三个输入的流。人工峰值状态神经元可以适应任意数量的流。每个流了 16 个 0 或 1 值。输入的长度是任意的但从程序员的角度来看,您可以将每个演示输入流作为 16 位无符号值。 接下来,该演示设置定义神经元的行为的值: ~~~ int[] wts = new int[] { 4, -2, 3 }; int leak = 1; int v = 0; // Electrical potential (voltage) int thresh = 8; // Needed to fire an output spike int spike = 4;  // Increase in v at spike event int tNext = 0; // Next time when neuron is active int latency = 2; // Number t inactive after spike ~~~ 请注意 0 和 2 的输入流的权重为正数,并因此行动来增加,神经元的阶梯电势但 1 的输入流的权重为负,因此它缩短了可能。有时这些区分作为 excitatory (增加) 和 inhibitory (减少) 输入。 此处的泄漏值设置为 1。要考虑的替代方法是使泄露随机;也就是说,随机更改泄漏值之间,说,0 到 3 在每个时间刻度线。或者您可以更改要与当前可能成比例的泄漏值。您也可以考虑进行重置延迟时间段内的峰值随机值。 所有的处理时间驱动循环由控制: ~~~ for (int t = 0; t < 16; ++t) {   // Compute new V   // Spike if V >= threshold   // Emit a 0 or 1 } ~~~ 在时间循环中,演示首先检查以查看神经元是否处于非活动状态: ~~~ if (t != tNext) // Neuron is not active {   Console.Write(". Neuron is inactive. ");   Console.WriteLine("V = " + v);   output[t] = 0; } else {   // Active } ~~~ 变量 tNext 时神经元将处于活动状态的下一步的时间值。在大多数情况下,tNext 将 t + 1。非活动状态的神经元是实质上是睡眠状态时,因此,没有任何变化的电气潜力并不会大量增加可能发生。在主动神经元分支内计算电气潜在 V: ~~~ int sum = 0; for (int j = 0; j < inputs.Length; ++j)   sum += inputs[j][t] * wts[j]; v = v + sum; v = v - leak; if (v < 0) v = 0; ~~~ 此处 j 是 (0,1,2) 的输入流的索引而 t 是时间索引。例如,输入 [1] [8] 是时间 t 处的输入流 1 的 0 或 1 值 = 8。泄漏减去 V 后,所得到的值被检查以确保不会负 V。但是,在实际神经元电气潜力实际上能为负,因此,可以考虑选择是允许 V 去负。 计算 V 后,检查其值以查看是否应发生了峰值事件,如中所示 图 4。 图 4 检查是否应发生了峰值事件 ~~~ if (v >= thresh) // Spike and reset {   v = v + spike;   Console.WriteLine(" Spiking, V = " + v);   output[t] = 1;  // Fire   v = 0;   tNext = t + 1 + latency; } else // No spike {   output[t] = 0;   tNext = t + 1; } ~~~ 当峰值事件发生时,会递增 (通过在演示中的 4) V 的当前值并将其然后立即重置为 0。换而言之,未在所有使用 V 的临时锥的值。要考虑的替代方法是将不会自动重置为 V = 0。相反,您可以通过减去一定的量锥 V 值重置。例如,在时间 t = 6 在演示中,V 临时峰值从 8 到 12。如果您然后使用峰值重置值为 10,而不是从 12 重置为 0,神经元会重置从 12 为 2 上。 ## 有什么用呢? 人工峰值状态神经元是研究中,对不同组的人员用于不同的用途。Neurobiologists 尝试创建完全为了深入了解生物进程复制实际的神经元的行为的软件模型。事实证明存在泄漏集成峰值神经元模型是非常简单,并完全复制实际神经元的行为更常用于复杂的模型。 人工峰值状态神经元还充当机器学习分类系统的基础。虽然从来没有使用几十年来,人工峰值状态的神经元的网络学习了实际值模拟的神经元的人工神经网络探讨了很多。在我看来,在这一领域的研究结果不是最终并不清楚的人工峰值状态的神经元的网络是否提供任何优于传统实际值的人工神经元。仍有许多开放研究问题。 最后,人工峰值状态神经元正在用于在工作中创建一种全新方式实现计算机和编程。美国防御高级研究项目局系统的 Neuromorphic 自适应塑料可伸缩电子设备 (SyNAPSE) 项目的目标是创建可以扩展到生物级别的计算机。而不被使用传统的硬件体系结构,一些很有前景的初始设计已使用几十亿张的互连人工渗漏集成火灾峰值状态神经元。如果这些工作证明成功后,它可能可以创建几乎 inconceivably 比当前的系统功能更加强大的计算机。 * * * Dr.James McCaffrey *供职于华盛顿地区雷蒙德市沃什湾的 Microsoft Research。他参与过多个 Microsoft 产品的工作,包括 Internet Explorer 和 Bing。Scripto可通过 [jammc@microsoft.com](mailto:jammc@microsoft.com) 与 McCaffrey 取得联系。*