谷歌人工智能AlphaGo围棋下九段棋手代表什么?

这两天一个热闹的讨论,就是谷歌公司推出的人工智能,名叫AlphaGo,与韩国九段棋手李世石下围棋,于3月9日及今天10日连胜两局。 自从当年IBM的深蓝在国际象棋上下胜了国际象棋的世界冠军后,围棋因为运算量庞大,一直认为在是计算机难以挑战的领域。 然而自从深度神经网络技术出现后, 人工智能领域得到了巨大的发展,大众普遍会发现近几年,无论是手写输入还是语音识别都有了巨大的提升。 深度神经网络的主要提升在于,它大大提高了对深层逻辑的提取,通过海量的数据训练,可以让其不断将更复杂的逻辑规则进行识别并抽象并提取出来,然后这个抽象的结果作为一种数据结构保存下来,可以用于辨别事物。 对于类似AlphaGo这样的系统,原理上是相通的,然而真正让其得到最大提高的部分在于,它可以自己与自己进行下棋,然后不断总结更优结果,于是便能不断进行优化。 在过去的神经网络系统中,面临一个问题就是,在识别数据的时候,很容易出现识别到一半,整个网络分布就散了,于是就识别不下去了,这方面要细说就要谈到深度学习方面了,这里先不谈这个。 简单来说,AlphaGo它在围棋上取得的成就,已经超过大部分棋手了,这意味着在围棋领域,专业的九段高手也有面前败下阵来的。 有很多人说,围棋以后也没有可玩的了,因为在机器面前,人已经无还手之力了,这个说法显然是不对的。因为围棋的解集是很大的,能够构成的围棋局盘是一个天文数字,AlphaGo目前所提取的围棋规则及下法,仍然是从棋谱学习,并进行自我不断演算,然而无论如何演算,它是不可能覆盖所有的可能,只是在一个局部范围内寻找到了最优解。而这个局部范围的求解结果,极有可能在另一个角度上是错的,如果有足够多的局例对AlphaGo的下棋特点进行分析,那么人战胜AlphaGo并不难,在一些微妙的识别上,人工智能算法会很难处理。 举例来说,如果是在字符识别上,如果你把一个“2”写得模糊一些,那么对机器识别来说,它可能是“2”,也可能是“乙”,还有可能一个扭曲的“S”,亦或是其它的什么。如果有上下文的情况下,产生了会导致误导的模糊逻辑,那么要它识别出来就会很困难了。虽然理论上机器也可以联系上下文进行处理,然而现实中却不那么容易,比如机器学习中,提供的数据通常需要要规范的格式,如果是杂乱需要整理的内容,学习在对新内容的学习上会搞得一片混乱。 任何系统都一定是有BUG的。记得以前玩过下象棋的智能系统,如果是按步就班的下,难度还是很高的,然而如果走些明显很不合理的怪棋,往往系统自己就完蛋了,它们也会走一些莫名其妙的棋。像AlphaGo必然也存在这样的问题,只是体现在哪里并不清楚。 另外,既然AlphaGo能够自我进行下棋博弈进行优化,那么就说明,人工智能在自己与自己下的时候,总有一方胜一方负,如果没有的话,便不可能进行优化了。 换而言之,战胜目前状态的AlphaGo解法是一定存在的,然而这些如何应用在下棋上,又如何才能战胜,只能等棋手们去思考了。 说到人工智能,AlphaGo的局限性在于,它目前实现的智能程度确实很高,然而却是体现在仅仅下棋这个方面,如果比喻的话,AlphaGo实际上就相当于一个刻苦学习的白痴,然而因为他实在太刻苦了,所以在某一个方面掌握得就能非常精深,然而在其它方面,就完全不行了。 什么都能识别都并加以学习的人工智能,是通用人工智能,目前这样的系统还没有出现,AlphaGo同样称不上这方面好的开始,因为它的表现是在某一个专精方面的深入,而不是其它方面。当然这个也是很有意义的,利用计算机这样的工具,可以让我们更好的学习研究一些深入的知识。 如果虚心一些,那么AlphaGo这种系统的数据训练方式,对我们现实的启迪是什么?它意味着如果一个人先天不是太糟糕的情况下,后天的刻苦努力最起码可以让人在某一领域获取成就。

Read More

使用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

为什么要研究神经网络?

   有人问我,你为什么突然有兴趣研究这个了,其实答案很简单也很无奈,市面上现在没有合适的可以识别古籍毛笔字尤其是繁体的软件。太多的法本需要整理成电子文档来保存,在下一直的志愿就是以后能建立一个道教图书馆,里面放上各门各派的法本,任天下道友随意观看。    但要建立这个,需要有一个良好的识别软件,能够对古籍的文字进行提取,并且对于那些字库中不存在的讳字及符文,能够自动转换成图片,这个无论是adobe acrobat pro,ABBYY_FineReader,或是汉王 PDF OCR,中文的识别还是偏重于规则的汉字上,而在设计时也是通过内部的一定变形来进行泛化,用来识别毛笔字,尤其对于那些竖排的无标点手写古籍来说,只能说是惨不忍睹。   既然没有人做这个事,就只能自己来做了。

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