Conmajia

Stop stealing sheep!

导航

< 20253 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

🧬 C# 神经网络计算库和问题求解

Andrew Kirillov 著
Conmajia 译
2019 年 1 月 12 日

原文发表于 CodeProject2006 年 11 月 19 日已获作者本人授权

本文介绍了一个用于神经网络计算的 C# 库并展示了如何用这个函数库进行问题求解

全文约 3700 字建议阅读时间 8 分钟原文是 13 年前的旧文章这篇译文也是我早期学英语的习作胜在题材选的好人工智能基础研究放到今天不仅没有过时反而正是风头十足的前沿科技

这个库最终命名为 ANNTArtificial Neural Networks Technology是 AForge.NET 科学计算库 AForge.Neuro 的组成部分AForge.NET 是 Andrew Kirillov 的杰作之一主要用于计算机视觉人工智能机器学习图像处理机器人等领域

源码 251 KB

演示 181 KB

封面图源参见水印

简介

众所周知很多问题在求解时难于找到一个正式的算法这类问题有些找不到简单的传统方法解决有些甚至没有适合的解法若是应用神经网络算法则往往可以得到较为满意的结果神经网络的研究发端于 20 世纪 50 年代但在当时由于各种条件限制加之能应用处理的任务数量很少没有太大实用价值到了 70 年代随着多层神经网络反向传播算法出现这一领域又再次繁荣起来众多研究者开始探索神经网络创造了各种神经结构并用这些结构求解许多不同的问题如今神经网络广泛应用于分类识别逼近预测聚类记忆模拟等任务并且适用范围还在不断扩大

本文介绍了一个用于神经网络计算的 C# 库它实现了几种常用的神经网络结构及训练算法反向传播Kohonen 自组织映射弹性网络三角规则学习感知器学习下面是演示的几个例子

  • 分类用感知器学习算法训练的单层神经网络
  • 近似采用反向传播学习算法训练的多层神经网络
  • 时间序列预测采用反向传播学习算法训练的多层神经网络
  • 颜色聚类Kohonen 自组织映射
  • 旅行商问题弹性网络

文章开头的源码和演示文件中包含了以上内容和一些没有列出的例子

这篇文章不是讲解神经网络基础理论的入门书籍如果你一窍不通相关的理论和代码在互联网上有大把资源可用本文假设读者对神经网络已经具备了一定的了解专注于讨论用于神经网络计算的 C# 库以及如何把它应用于求解问题

使用方法

设计一个函数库重点之一是要保证它适应性强便于理解与其把几个神经网络实体杂糅到一个类里搞得一团乱麻既不好用也不好看倒不如把它们分开成几个类更便于使用和学习有些库坚持把神经元网络和学习算法组合在一起搞得很难针对同一神经网络开发其他的学习算法还有些除了在一个类里实现整个神经元网络架构外压根就没有神经元神经元层层网络之类的东西当然具体情况具体分析这种做法好不好也是存在争议的有些特定情况下并不需要或者难以将网络分层或者没有多层结构那么这些和成一堆的“大面团子”自然有它可取之处但是大多数时候把这些内容各自作为清晰的类处理不仅更简明易懂而且可以更容构建新的神经网络结构

这个库包含了 6 个主要的部分

Neuron神经元- 所有神经元的基类包含了神经元的权重输出值输入值等

Layer神经元层- 神经元的集合抽象基类

Network网络- 神经元层的集合抽象基类包含了铺铜神经网络用到的通用功能

IActivationFunction激活函数接口- 用于激活神经元的激活函数函数的输出作为神经元的权重输出

IUnsupervisedLearning无监管学习接口- 无监管学习算法的接口即系统提供输入样本而不提供期望输出

ISupervisedLearning监管学习接口- 监管学习算法的接口即系统同时提供了输入样本和期望输出

图 1 ANNT 模型

ANNT 提供了以下的神经网络结构

激活网络
一个单层或多层的神经网络网络中每个神经元将其输出作为激活函数的输出参数是其输入与阈值的加权和该网络经过监督学习算法的训练可以解决近似预测分类和识别等任务

距离网络
每个神经元将输出作为权重值和输入值之间的距离的神经网络由单层组成可作为 Kohonen 自组织映射弹性网络Hamming 网络等的基本网络

采用了不同的学习算法用于训练不同的神经网络

感知器perceptron
可以追述到 1957 年的算法适合作为首次学习的神经网络学习算法它用于单层激活网络其中每个神经元具有阈值激活功能它的应用范围很小并且限制了线性可分离数据的分类

增量规则delta rule
该算法是继感知器学习算法之后的下一步它利用激活函数的导数并且可能仅适用于单层激活网络其中每个神经元都有一个连续的激活函数而不是阈值激活函数最流行的连续激活功能是单极和双极乙状结肠功能由于该算法仅适用于一层网络因此主要局限于某些分类识别任务

反向传播back propagation
这是最流行的多层神经网络学习算法之一最早出现在 1974 年由于该算法能够训练多层神经网络其应用范围非常广泛包括逼近预测目标识别等任务

自组织映射学习self-organizing map
简称 SOM 算法Self-Organizing Map由 Kohonen 提出是公认的解决集群问题的最著名的无监督学习算法之一它将神经网络视为节点的二维映射其中每个节点可以表示一个单独的类以这种方式组织网络从而可以找到数据样本之间的相关性和相似性

弹性网络elastic net
类似于 SOM 学习算法的思想但它不将网络神经元视为节点的二维映射而是将其视为一个在学习过程中环会得到一些形状表示一个解决方案旅行商问题是这种学习算法最常见的例子之一

更多详细内容可以参考 AForge.NET 科学计算库附带的帮助文档ANNT 的相关内容可以在 AForge.Neuro 部分找到

图 2 AForge.Neuro 帮助文档

演示

分类classification

图 3 单层感知分类器演示截图

这个例子中使用了一个具有阈值激活函数的单层激活网络感知器学习算法神经元的数量等于不同数据类的数量并且每个神经元都被训练为只对某些类进行分类将一个数据样本传递给训练后的网络网络中的一个神经元应被激活产生等于 1 的输出但所有其他神经元应被停用产生等于 0 的输出数据样本的类别由激活神经元的数量决定在这种情况下如果有多个神经元激活或没有神经元激活网络就无法正确地分类显示的数据样本在二维数据样本的情况下每个神经元的权重和阈值代表一条线将一个类与所有其他类分开

// 准备学习数据
double[][] input = new double[samples][];
double[][] output = new double[samples][];

// 生成感知器
ActivationNetwork network = new ActivationNetwork( new ThresholdFunction( ), 
                                                   2, classesCount );
// 生成训练器
PerceptronLearning teacher = new PerceptronLearning( network );
// 设置学习速率
teacher.LearningRate = learningRate;
// 循环
while ( ... )
{
    // 运行学习程序
    double error = teacher.RunEpoch( input, output );
    ...
}

尽管这个网络结构很简单但还是可以用于很多分类识别任务唯一的限制是它只能区分线性可分离的数据

逼近approximation

图 4 多层神经网络逼近演示截图

这个例子演示了使用反向传播算法训练的多层神经网络该算法应用于函数的逼近问题假设只知道有限数量点上的函数值但是要计算其他点上的函数这些点在 minmax X 的范围内在训练阶段对网络进行训练以产生正确的函数值训练完成后网络用于计算训练过程中网络不可用的其他函数值

// 准备学习数据
double[][] input = new double[samples][];
double[][] output = new double[samples][];

// 生成多层神经网络
ActivationNetwork    network = new ActivationNetwork(
    new BipolarSigmoidFunction( sigmoidAlphaValue ),
    1, neuronsInFirstLayer, 1 );
// 生成训练器
BackPropagationLearning teacher = new BackPropagationLearning( network );
// 设置学习速率和动量
teacher.LearningRate = learningRate;
teacher.Momentum     = momentum;
// 循环
while ( ... )
{
    // 运行学习程序
    double error = teacher.RunEpoch( input, output ) / samples;
    ...
}

这种多层神经网络结构不仅可以用于二维函数的逼近还可以处理任意维的函数但是别忘了网络层和神经元的数量以及像 sigmoid α 值这样的参数可能会极大地影响学习速度网络的某些错误设置可能会导致无法学习任何内容所以小心点尝试更多的实验

时间序列预测time series prediction

图 5 多层神经网络时间序列预测演示截图

该个例子演示了一种具有反向传播学习算法但应用于时间序列预测的多层神经网络时间序列预测问题是一个非常重要和非常普遍的问题许多研究人员在该领域尝试了许多不同的算法和方法这个问题最受欢迎的领域之一是交易预测如果你能预测股票的未来价值或货币兑换率并且做得很好那么你就可能成为一个有钱人在训练阶段向网络提供一定数量的时间序列先前值并训练网络预测时间序列的下一个值训练样本越多预测模型就越好另外一个非常重要的参数是窗口大小即历史中有多少值用于预测未来的值窗口越大你有可能得到更好的模型但也可能得不到这取决于时间序列并且需要实验但是更大的窗口意味着会减少所需的培训样本量因此这是矛盾的需要进行折衷处理

演示代码与上一个例子相同只更改了准备学习数据的过程

颜色聚类color clusterization

图 6 Kohonen 自组织映射颜色聚类演示截图

这是一个非常简单的示例演示了 Kohonen 自组织映射的组织过程创建了一个由 10000 个随机初始化权重的神经元组成的方形 SOM 网络每个神经元有三个权重它们被解释为用于可视化的 RGB因此网络的初始可视化将显示某种嘈杂的彩色图在学习过程中随机的颜色被一个接一个地选择并传递给网络的输入重复学习迭代神经网络以这样的方式组织自己在可视化过程中它不再像一幅随机的图片但它得到了某种结构——颜色近似 RGB 调色板也更近似 Kohonen 映射

// 设置神经元权重随机范围
Neuron.RandRange = new DoubleRange( 0, 255 );
// 创建网络
DistanceNetwork network = new DistanceNetwork( 3, 100 * 100 );
// 创建学习算法
SOMLearning trainer = new SOMLearning( network );
// 输入
double[] input = new double[3];
// 循环
while ( ... )
{
    // 更新学习速率和半径
    // ...

    // 准备网络输入
    input[0] = rand.Next( 256 );
    input[1] = rand.Next( 256 );
    input[2] = rand.Next( 256 );

    // 运行学习迭代
    trainer.Run( input );
    
    ...
}

这个例子里你会发现神经网络总是创建不同的图片而观察这些图产生的过程是很有趣的你甚至可以用它们来做个屏保

你也可以用其他对象来代替颜色这些对象可以用特征的实值向量描述在学习过程中将这些特征向量传递到 Kohonen 映射中它们将自动进行组织训练完成后就可以查看二维图并根据其特征发现哪些对象相似且彼此接近

旅行商问题traveling salesman problem

图 7 弹性网络解决旅行商问题演示截图

旅行商问题证明了弹性网络的应用弹性网络在自组织概念上与 SOM 相似但在神经网络的解释上有所不同SOM 将神经网络解释为节点的二维映射而弹性网络将其解释为节点环在训练阶段将特征向量逐一呈现给网络使网络得到某种形状这代表了一种解决方案TSP 问题的情况下每个神经元都有两个权重表示 (x, y) 坐标在训练阶段任意城市的坐标逐一传递到网络的输入端网络以这样的方式组织其权重使其代表旅行社的路径

// 设置随机范围
Neuron.RandRange = new DoubleRange( 0, 1000 );
// 生成网络
DistanceNetwork network = new DistanceNetwork( 2, neurons );
// 生成学习算法
ElasticNetworkLearning trainer = new ElasticNetworkLearning( network );
// 输入
double[] input = new double[2];
// 循环
while ( ... )
{
    // 设置网络输入
    int currentCity = rand.Next( citiesCount );
    input[0] = map[currentCity, 0];
    input[1] = map[currentCity, 1];

    // 运行训练迭代
    trainer.Run( input );
    ...
}

这种方法的缺点是它不能提供精确的解——神经元的权重可能接近但是不等于城市坐标这种方法的另一个缺点是城市太多时效率下降但是该方法仍不失为神经网络应用的一个很好的证明

结论

上面的五个例子表明ANNT 库是灵活的可重用的并且很容易用于不同的任务尽管由于神经网络体系结构及学习算法种类繁多仍有许多工作要做但是ANNT 可以用于许多不同的问题并且可以扩展以解决更多的问题我希望这个库不仅对我接下来的研究工作有用而且其他不同的研究人员也能从中有所收获

历史版本

  • [12.01.2019] 译文首次发表
  • [19.11.2006] 原文首次发表

许可

本文以及任何相关的源代码和文件都是根据 GNU通用公共许可证GPLv3授权的

关于作者


Andrew Kirillov来自英国🇬🇧目前就职于 IBM


  1. Perceptron, Wikipedia ↩︎

  2. Delta Rule, Wikipedia ↩︎

  3. Back Propagation, Wikipedia ↩︎

  4. Self-Organizing Map, Wikipedia ↩︎

  5. Elastic Net Tutorial, Andrei Cimponeriu, Oct. 12, 1999 ↩︎

  6. 一种常用的非线性激活函数其表达式为σ(x)=11+ex.sigmoid 的缺点在于当输入非常大或者非常小时容易饱和饱和后神经元梯度趋于 0即容易导致神经元“死亡” ↩︎

  7. 时间序列预测法其实是一种回归预测方法属于定量预测其基本原理是;一方面承认事物发展的延续性运用过去时间序列的数据进行统计分析推测出事物的发展趋势另一方面充分考虑到偶然因素影响而产生的随机性为了消除随机波动的影响利用历史数据进行统计分析并对数据进行适当处理进行趋势预测 ↩︎

posted on2019-01-12   Conmajia  阅读(2252)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示