如何用遗传算法进化出一只聪明的小鹦鹉,赶紧来get一下
问题
现在有一些样本数据,如下表所示。你是否能找到其中的规律,然后计算出新样本的output是多少?
乍一看,规律似乎并不明显。
仔细看,可能会发现其中的规律:output=input1+input2/2,因此问号处的值应该是13。
现在,我们想让一只小鹦鹉来做这个事情。这当然不是现实中的小鹦鹉,而是我们用代码写的小鹦鹉。
小鹦鹉
小鹦鹉要想解出上面的题目,必须会“思考”。这里的思考,我们可以理解为:具有将input转换成output的能力。我们选择神经网络作为鹦鹉的大脑。
神经网络
我们知道,人脑中有无数个神经元,神经元之间通过轴突连接。当某个神经元接收到足够多的信号后,就会被“触发”。而被“触发”的神经元会发送信号到临近的神经元,临近的神经元接收到足够的信号后,又会被“触发”。这样的过程被称之为“思考”。
我们可以用程序模拟这个过程。为了简化,这里只使用一层网络。我们给每个轴突(连接神经元的线)设置一个权重,每一个input乘以相应的轴突权重会得出一个值,然后对这些值再求和,得出output。即output=input1*w1+input2*w2+input3*w3
这就是一个简单的“大脑”。大脑是否聪明,取决于[w1,w2,w3]的值的组合。如果这三个权重值能够满足提出的问题,那它就是“聪明”的,否则就是“笨”的。于是,刚才的问题就转换成:如何找到一组“聪明”的权重组合。
对于文章开头的问题,我们已经知道,[w1=1,w2=1,w3=0]这种组合是最好的。那,如何生成这样的“大脑”呢?
上帝之手
现在,我们可以扮演上帝的角色,随性的创造物种。假设我们创造了一只鹦鹉,它的脑子就是一个有3个权重的神经网络。这只鹦鹉只会做上面的题(但不一定能做好)。它的大脑是随机生成的,假设他的权重组合为[0.5,0.3,1.2]。
此时,这只鹦鹉就可以用大脑去“思考”上面的问题了。它会先看样本数据,从样本1开始看。这只鹦鹉根据input算出来的output是:0.5*5+0.3*8+1.2*7=13.3,而样本给出的output是9。于是它的误差(error1)是13.3-9=4.3。同样,还可以知道这只鹦鹉计算其它样本时的误差,它们分别是:
我们知道,鹦鹉计算得越准(误差越小),就越聪明。因此,我们可以给鹦鹉的智商设定一个计算方法:
根据这个公式,可以算出这只鹦鹉的智商(intelligence)为9.15。
我们再随机创建第二只鹦鹉。假设它的大脑的神经网络权重组合为[0.8,0.7,0.1]。
根据同样的方法,可以算出它的智商为35.65。它比第一支鹦鹉“聪明”!
进化
种群
我们可以创建一个鹦鹉种群,这个种群里有若干只鹦鹉,比如有100只。每个鹦鹉的智商也各不相同。下一步就是让这个种群进行自我进化。
进化
物竞天择、适者生存!大自然的这个法则,让地球上的物种不断进化,诞生了越来越高级的物种,乃至出现了我们人类。我们的这个鹦鹉种群也可以通过进化变得越来越聪明。
种群中的鹦鹉比拼的是智商。每一次比拼,我们把低智商的鹦鹉淘汰掉,把高智商鹦鹉留下来。然后,让留下来的鹦鹉繁衍下一代,这样它们和下一代的个体会组成一个新群体。然后再来一次全员智商比拼,再把低智商鹦鹉淘汰掉,高智商留下。留下的鹦鹉再次繁殖。这样不断迭代,经过若干代的筛选后,最后留下的就是特别聪明的鹦鹉。
在最后留下来的鹦鹉中,找到最聪明的那个。让它去“思考”文章开头提到的问题,它会给出一个不错的答案!
繁衍
现实中的鹦鹉是双性繁殖,那是长期进化的结果。我们的鹦鹉还很原始,只能单性繁殖:)
繁殖的方式是把自己复制一份,再做一次“基因突变”。所谓“基因突变”就是对神经网络的权重进行微调。比如有一只鹦鹉,它的大脑神经网络是[2, 3, 3.5],它繁衍的某一个后代可能是[2, 3.01, 3.5]或[1.98, 3, 3.5]等。
这样,后代基本保留了父代智商,又做了微调。这种微调可能是正向的(更聪明),也可能是负向的(更笨)。
代码
运行
运行结果
新样本中的output应该是13,进化出来的鹦鹉给出的答案是12.97060759,已经相当接近!
它的大脑[0.99293629, 0.498883, 0.00599333]与最优解[1,1,0]非常接近!
这就是自然选择的力量!
让我们向大自然的规则致敬!
原文:https://my.oschina.net/stanleysun/blog/1857599