使用AForge.NET中的BP神经网络库实现异或逻辑

  调试神经网络时,感觉无论怎么测试数据,收敛都非常慢,总怀疑是不是AForge.Net的BP算法有问题,所以测试一下异或逻辑,代码如下:    private static void testXOR(){             var func = new AForge.Neuro.SigmoidFunction();             var network = new AForge.Neuro.ActivationNetwork(func,2,2,1);             AForge.Neuro.Learning.BackPropagationLearning bp = new AForge.Neuro.Learning.BackPropagationLearning (network);             double input = new double;             input  = new double{ 0, 0 };             input  = new double{ 0, 1 };             input  = new double{ 1, 0 };             input  = new double{ 1, 1 };             double output = new double;             output = new double{0};             output = new double{1};             output = new double{1};             output = new double{0};             double error=1;             while(error>0.01){                 error = bp.RunEpoch(input,output);                 Console.WriteLine("error:"+error);             }             for (int i = 0; i < 4; i++) {                 var result =  network.Compute (input );                 Console.WriteLine(string.Format("output:{0},realresult:{1}",result,output));             }         }   输出结果如下:           测试了一下,只要有个隐藏层神经元为2,就足够学习到异或逻辑,而为1,很难收敛,隐藏神经元为20以上时,数值变化已经在小数点后的十几位了,也很难收敛,这说明并不是神经元越多就越好,同时增加层数时也会发现这种情况。…

Read More

单层感知器与哲学上简单思考

  无意间又翻回了单层的感知器,为了加深体会,所以又写码测试了一下,其运算速度确实很快,在使用 Threshold 激活函数的前提下,对手写的前一千个样本进行识别,识别速度极快,但是对于已经训练过的数据,效果也很一般,只有77%左右,但对于没有识别过的数据,就惨不忍睹了,几乎全错。这就是感知器的特点,它在低维的层面对进行线性可分,而遇到线性不可分的问题时,就会出现这样的情况。      这个也可以抽象到现实的哲学中,单层感知器,它就是如同在一个平面上,试图通过划线来对事物进行区域划分,并且这种划分是非此即彼的,如果有很多分类的东西混在一起时,必须要有符合目标特征的函数才能够更好的识别目标事物,而这种往往在现实中是不可能的。   如果只在极低的维度上对事情进行分类,也就是死硬派的认为,凡事非此即是彼,那么有再多的对客观事物有再正确认识,在进行教育后,也是会谬误百出,所以思考问题时只考虑某一种单一的划分条件,是不能成立的。   阴阳的认识也是如此,阴阳总是相对的,这种相对实际上就是在不同环境与条件下,对阴阳进行赋予了不同的权重,但是光仅仅是这样是不够的,如果局限在某一个单一的方面去划分,用阴阳来认识事物就难免会出现极大的问题。        像感知器这样的情况,直接根据已知事物的特征,然后判断相差多少,去不断调整认识,虽然这样有益于正确认识事物,但也会带来很强的经验主义,而经验主义的结果就是导致对于新事物难受接受,从而总是会判断错误。           大多数情况下,分类发生错误,不是说客观事物无法分类,而是分类的方法不对就会导致错误,这一点一定要明确。

Read More

深度神经网络学习:线性回归与逻辑回归

    虽然大致明白了Sparse Coding的方法,但总觉得里面有还是有滞涩之处,按师父当年的教育来说,凡是遇到有思不通的问题时,必是基础不牢。所以重习一下线性回归与逻辑回归,以加清认识。     线性回归,从概念来说其实比较简单,它抽象成几何的概念,比如一个平面上,上面有一堆点,如果能用曲线把它们全穿起来,那么这个就是一个线性问题,因为可以用曲线把它们全覆盖,而线性问题就可以通过线性回归来解决。     对于回归这个词,如果用标准术语定义是这样的:回归研究一个随机变量Y对另一个(X)或一组(X1,X2,…,Xk)变量的相依关系的统计分析方法。研究一个或 多个随机变量Y1 ,Y2 ,…,Yi与另一些变量X1、X2,…,Xk之间的关系的统计方法。又称多重回归分析。通常称Y1,Y2,…,Yi为因变量,X1、X2,…,Xk为自变量。     所谓的回归,在下的理解就是,假设有那么一条线可以覆盖所有的点,然后不断在一个平面上画啊画啊,直到找出这个曲线为止,这个过程就叫回归。     而对于数据来说,它就是试图找出数据之间的关系,尤其是找出数据之间影响的显著关系。     而回归的方法,通常就是两种,一种叫最小二乘法。     最小二乘法是法国科学家勒让德于1806年独立发现的,但因不为世人所知而默默无闻,后来高斯《天体运动论》里使用了最小二乘法,后来勒让德跟高斯还掐了一架,争执是谁发明的。     这个过程非常简单,首先假设一个目标曲线为xi,那么每次尝试画出来的就是xj,比如在0点位置,而它们间的偏差就是x0-x0。     因为这里的Xi与Xj并不是两个点,而是两个函数,所以Xi与Xj之间相关做到最小。     显然,如果把每个Xi与Xj的误差都累加起来,就是两个函数的误差,但问题这样就不好求解了,所以用它们的平方差作为误差。所以总误差判断定为: Σ(xi-xj)2     要总误差最小,当然最好是Xi与Xj相等,问题是现在本来就是要找出xi,而不断尝试画的是xj.而要求的是如何能让xj不断通过调整变成Xi。     因为第一个xj相当于随手乱画上去的一条曲线,所以把这个问题转化成:如何让Xj能更快接近Xi。    …

Read More

深度神经网络学习:AutoEncoder之Sparse Coding(稀疏编码)

  这个是一个让人感觉很神异的技术,给一堆图片,然后用软件扫描,软件就能把图片中的特征找出来,这对人来说是很轻易的事,对软件来说,最大的问题就是,怎么应该进行才可以?   写软件的技术也不是多么高科技,最终需要用到的还是人的思想,然后把思想转化成代码,从而解决现实问题,编程可以说是一个验证思路的一个绝佳途径,在下甚至以为,新时期的道士,应该个个都掌握编程的技能。   说远了。   这个给了一堆图片,然后能提取出特征,应该怎么实现?   一般的问题想要智能解决,思路是这样的:给一组输入,再给一组输出,比如天气预报,输入的就是时间,输出就是天气,然后给神经网络任意赋上一堆值,再通过数学运算,看目标结果与需要的输出数据相差有多大,然后转化成微积分的方向,计算出运算路径中应该怎么反向调整数据才能拼凑出目标结果来,然后不断重复这个计算并再拼凑的过程,最后接近目标结果,得到满意答案而确定出来的神经网络中的参数,就可以理解为特性。   但是如果是一堆图片,这个怎么处理?如何提取图片中的特征,这里不得不说,有一个很有意思的解决方案。   它是这样进行的:   1、把图片切成各种小块,并把这些小块换成数据表达   2、用神经网络去运算这些数据   但问题来了,运算的数据的输出结果是什么?   这里就是极其聪慧的一点啊,输出的结果再进行一次神经网络运算,让它能输出为输入值。   输入-》运算(编码)-》运算(解码)-》输出   然后比较输入与输出,根据差值,去调整中间的编码运算与解码运算,而至于编码与解码到底在干什么是不用管的。   反正最后输入与输出结果精度达到满意要求时,所保留的就是特征了。   为什么会这样?其实原理很简单,中间的编码层的神经网络处理,相当于去将原图进行任意的干扰,而解码层的神经网络处理,相当于将干扰后的图像进行了恢复。   而这个过程有一个有意思的地方是,因为中间出现了干扰与解干扰的过程,输出等于了输入,多次变换后,保留下来能识别到原输入的就是特征。   同样的,可以在这种思路中,多加入一个混淆器,即随机添加大量的噪音,然后再消除掉,同样可以增强神经网络的搞干扰能力,而进行了干扰处理后的这种手法得到的编码器称为Denoising AutoEncoders降噪自动编码器。   这真是一个令人惊叹的想法,而且只能在计算机上实现,传统的其它计算工具是无法实现这个的,因为它依赖大密度的运算。   那么这样就够了么?   于是这里出现一种信念,这种特性的抽象是否可以尽量的简单再简单?   损之又损,以至于无为,无为而无所不为?   这个可能吗?   于是,如果坚持相信,再复杂的东西背后都有简单的规则的话,这里就可以基于这种信念再干一件事:稀疏化      怎么做呢?因为复杂的背后总有简单的规则是不是?那么简单的规则是不是就意味着可以删减很多东西后,还只保留最核心的一些东西,就能复原绝大部分原来的信息?   既然是这样,那么就意味着,如果能找到一种,让神经网络里大部分神经元不起作用也能进行成功由输入得到输出结果时,那么就能得到这个。   所以,可以对神经元进行限制,每个神经元有一个激活值,然后规定所有的神经元的总激活值,不得超过一个数值,比如0.05,那么这样就会导致大部分神经元变成0值,而极少数神经元需要更加精准的计算出自己的权值。   那这个怎么实现?   先从源头说起,稀疏化,实际上就是寻找一组“超完备”基向量来更高效地表示样本数据。稀疏编码算法的目的就是找到一组基向量…

Read More

根据Google的AForge.NET中的源码分析BP反向传播算法原理

    Aforge.net神经网络模型中,有BP学习算法,BP算法直接使用的是激活网络类,而不是用的接口,结果导致使用BP算法,就必须要继承激活网络类来进行覆盖函数调用,而激活网络类如果进行继承的话,会有很多麻烦的事,修改网络结构或是调整算法,并不是很灵活。     在GOOGLE的这个库中,神经网络算法比较简单,其结构大体是:     网络包括多个层叠加,而层中包括神经元。     建立一个激活网络的对象,然后指出要分多少层及每层多少个神经层,默认它是三层,一层为输入,一层为输出,输入即是输入的向量,即参数的个数,而输出则是输出的结果,可以是一个或是多个。     在计算时,先是输入的数据,进入每一层,先从神经元开始计算:     1、神经元的计算:每个神经元与输入的数据,输入的数据乘以神经元自身的权重,求出总和,然后再加上一个阈值,然后把这个值用激活函数处理一下(激活就是把它转换成处处可求导的),并进行返回给层。   ActivationNeuron.cs类中的Compute函数:    public override double Compute( double input )         {             // check for corrent input vector…

Read More

道家卜卦思想与稀疏表示的联系

  在<<分享在马尔代夫的修行感悟>>一文中谈及“仔细观察海洋,在高高的天空,一样能看到海洋的波浪,这就是自然界的特点,离远了可以看到事情的整体状态,而离近了,则可以看到事物的细节状态。在同一个观察高度下,是不能既把握细节,又能把握整体的,这说明一个道理,平时在思考事物时,不但应该从高的角度去看其整体,也应该从放下足够低的姿态去了解细节,这样才能得到对事物更完整的把握。用卦来观察事物时,也是这样的,要区分清楚如何去看把握的是大势,如何去看把握的是细节,而细节与大势又有联系,因为大势的变化也由那样突出的细节组合所反映出来的,把握吉凶成败的关键在就在于能否成功识别这些内容。”   很多人有疑问,问在下,这到底是在说什么,表示不理解,更又有人说,高处看一下,低处看一下,这种道理谁都懂,这算什么体悟。   这个体悟在下描述得比较简单,如果往深了描述,恐怕一般人又是看不懂了,不过考虑到有些好学之道友,问之甚切,这里就细说一下,这是一个非常重要的道理,而这个道理,大多数人因为从来没有仔细去深入思考过,所以无法明白其深入的内涵。   先举一个例子:这个是什么?       把马赛克图片进行缩小,再看看:      在缩小后,反而可以看清这是一只大象了,这也就意味着,有些事物在模糊不清的时候,只要变化一下,使其更适合人的认识习惯后,反而会更容易理解,也就是说,有些特征要容易被识别出来,只要转换一下就行了。   但这里仅仅只是说一个放大缩小的道理?当然不是。   1995年,有两位学者,收集了一堆黑白的风景照片,然后把它们剪成了碎片,从中提取了400张出来,他们认为,在这400张碎片中,应该可以有一堆碎片,可以拼成这些近似任何一张风景照片其它碎片中的轮廓。   后来他们不断反复挑选,最后竟然发现,真的存在一组照片,可以任意组合成其它碎片的轮廓,唯一不同的仅仅只是方向而已。   这说明了一个问题:不管多少张任意复杂的图案,它都是由最简单的单元构成的,最重要的是:这些单元中,有大量是重复的。   那么这个仅仅只局限于图案?于是又有人研究发现:在声音中也存在这样的现象---只需要找出20个最基本的声音结构,它们可以合成其它的结构。   在现实世界中的事物也是一样,不同事物,也有共同基本的元素,而这些元素是相同的,同时其它的元素也是由这些元素可以合成的。   现在的问题来了,那么这些基本的元素,有没有一种快速而简单的办法可以迅速把它们找出来?   古诗有云:“远近高低各不同,只缘身在此山中”,一个事物,从不同的角度,不同的高度去看,都会得到不同的结果。   实际上技巧就在这里,第一步是先找到不同的角度,然后抽离出这些角度中不同的部分,而相同的部分抛弃。需要注意,这里与直觉相反的部分,通常一般人会尽量去选取相同的部分,不同累积,但这样很难达到“快速”的目的。   为什么,因为首先确定了一个概念:“要找出最基本可以构造成其它元素的元素”,在这个思想的指导,最基本的元素定然是不相同的,所以优先应该去找不相同的部分。   把不相同的部分找出来后,再切换角度,去划出它们的相同与不同,然后再把不相同的部分保留。如此多次之后,会发现剩下就是最基本的元素了。   基本元素之间的关系,在数学上叫作:“正交”,其它重复的大量信息叫“冗余”,而这种钩勒出来的最基本元素的组合,即是事情的最核心的轮廓,即也是事物最核心的根本的骨架所在。   事物会如何发展,如何根本不变的部分,都会在这里展现出来,这就好比树的树干,动物的骨头一样,决定的是根本上的东西。用现代一点的话,这叫找feature,而一层一层的不断找feature,并将各层的feature提出相同的部分,这些基本元素就会有“其大无外,其小无内”的性质,不同的抽象层次中,可以能够更快速的找出统一的基本元素来。     直观的说明,只要找到了基本的小元素,那么更高一层的元素,其实上都由这些小元素构成的,更有意思的是,自然界中,凡是自然的图像或是事物结构,基本的小元素数量往往很少。     而找出来的这些元素,是少而精炼的,因为其它的冗余信息都由这些信息组成而成的,它们的是一种稀疏表示,如果用数学表达,则会得到一个稀疏矩阵。     如果把这个转换成计算机算法的话,现在热门的深度神经网络的基本思想,只是在它的基础上多迭代了几层,形成了多层的抽象,从而更快速能整体找出基本的特性单元,现在国际上谷歌的数据预测,百度大数据预测,微软的数据预测等等,其实用的都是这些思路。     那么在卜卦上,会有什么不同?看卦的时候,实际上就是对符号信息的提炼,因为一个卦式就是一个太极的展示,它的包含着无数的信息,而这些信息表达的其实就是事物在不同大小、不同角度下的统一轮廓,所以只要把这些轮廓代入到具体事物中,就能推出象来。    …

Read More