遗传算法的有趣实践

源码

先放上我的源码链接:
https://github.com/AIjugg/Genetic_Algorithm.git

自己思考加纯手写的代码,有兴趣的同学可以拿去玩玩

前言

生物进化是一个有趣的话题,人是怎么从人猿进化到的人,长颈鹿的脖子为什么这么长,猫和老虎为什么一个这么大一个这么小只?

有个人在19世纪就对这些问题感到了浓厚的兴趣,1859年,《物种起源》出版,标志着生物学进入了新的阶段。

生物进化是怎么进行的

学过生物进化论的同学应该知道,进化的核心是自然选择,进化其实是被动的,自然选择对物种做了筛选,保留下了适宜生存的基因,也就是适者生存。

适者生存,现代的生物进化论将适者生存修改为了适者繁衍。

举个🌰,在远古时期,树越长越高,于是短颈鹿吃不到🍃活不下去了,只剩下长颈鹿,经过一代代的繁衍,它们的脖子越来越长。

遗传算法的由来

在20世纪60年代,有人提出将进化论的思想应用到计算机运算中;70年代有人成功运用到了运算中;到了80年代,被Goldberg归纳总结,形成了基本框架。

这便是遗传算法的问世过程。

遗传算法的重要概念与步骤

在学习遗传算法前,我们首先得学习几个概念。


种群
一个生物个体是完不成繁衍进化的,需要众多个体组成一个团体,这个团体称为种群。

附上百度百科的定义:种群(population)指同一时间生活在一定自然区域内,同种生物的所有个体。种群是进化的基本单位,同一种群的所有生物共用一个基因库。


适应度(fitness)

适应度是用来衡量个体对环境适应的能力,一般适应度越高,越适应这个环境。


交叉(crossover)

其实就是生物的交配。父代交叉得到子代。


变异(mutation)

父代交叉得到的子代,其基因有概率发生一定的变化,这种变化有可能是有利的,也可能是有害的。变异是种群多样化的重要一环。

选择(selection)
其实就是淘汰。从群体中选择优胜的个体,淘汰劣质个体的操作叫选择。

流程图

遗传算法流程图

实际应用

在《遗传算法原理及应用》一书中指出,遗传算法是一种自适应全局优化概率搜索算法。我们可以用来做数据拟合、生产规划等,遗传算法的流程跟神经网络的算法很像……


这里我举一个有趣的实例:图像拟合。

之前在网上看到这么一张图片👇
在这里插入图片描述

这是怎么实现的?一度令我非常困惑,后来得知这是用遗传算法拟合得到的,于是我开始爬遗传算法的坑。


有想了解遗传算法的同学,可以去我的git上下电子书《遗传算法原理及应用》


实践

目标图

在这里插入图片描述

拟合图

在这里插入图片描述
上述图片都是我的拟合结果图,数字表示迭代轮次,可见越到后面越接近原图。

浅谈代码原理

问题分析

首先我们需要思考图像拟合这个问题,如何应用遗传算法,我们先用进化论的思维去思考这个问题。


个体:遗传算法中,我们首先需要有个个体,在这里,我们的个体就是一张图片。


基因:有了个体之后,需要明确个体内部需要改变的是什么,也就是基因。

基因是个体内部,发生改变的最小单元,我们知道图片是由像素点构成的,那么我们可以把每个像素点看做是一个基因,那么100*100的图片就是 100*100的像素点。

但这好像太多了,计算起来非常繁琐……上面的蒙娜丽莎图给了我启发,我考虑到可以用半透明的多边形组合成图片,在遗传算法中,个体的基因数量是保持不变的,所以我们的半透明多边形数量也是一直保持不变的(之前这点也令我非常困惑,蒙娜丽莎的拟合图中多边形的数量似乎是变化的)。

适应度 :用来衡量个体适应环境的能力,在我们当前的场景下,可以用图片相似度来表示。用数学公式表示也非常简单,把图片当作矩阵,那么计算出矩阵之间的欧氏距离即可。

我之前的代码就是这么计算适应度的,但后来我发现python里有现成的图片相似度计算方法,于是我直接调用了。


种群:在我们这里,种群自然就是指图片数量了。由于我们的运算是占用cpu内存的,根据cpu计算能力,选择一个合适的种群数量是非常重要的。

种群迭代:我认为种群迭代的概念也是非常重要的,当每次选择父代生成子代,再淘汰一部分适应度低的个体后,算是完成了一轮种族的迭代。


交叉:两个图片要怎么交叉呢?我的做法是,按照顺序,随机选中父本或母本的基因出来,作为子代的基因,按照概率而言,子代一半的基因来自父本,一半来自母本。


变异: 在我的代码中,变异只发生在生成子代时,子代的极少部分基因会发生变异(多边形的某个点坐标变化、或者多边形的颜色发生改变),随着种族的迭代,这种变异改变的特性会越来越小(坐标变化幅度变小、颜色也只会小幅改变)。当然这只是我的经验之谈,在我的实践中就是如此,从常理来想,这样也是合理的,因为到后期我们已经逼近了某个极值点了(局部最优)。


选择:我们每次进行种群迭代时,需要选择,首先计算出每个个体的适应度,根据适应度高低做排行,适应度越高的个体,获得交叉的概率越高(被我戏称为优先交配权),生成子代后,再做一次适应度计算和排行,适应度最低的个体将被无情淘汰。


遇到的有趣的问题

经过非常非常久的反复实践,我遇到了许多有趣的问题,我有时在想,这些问题会不会也是生物进化中的问题呢?

再一次感叹造物主的伟大。


没有变异的繁衍

当我在最初做代码调试时,并没有写变异的代码,在我的认知中,不变异也可以使得种群不断进化,只不过进化速度慢一些罢了。

实际上真的是这样吗?

不,经过几百轮的迭代后,每个个体的适应度都一样了,也就是说种群中的每个个体基因都一模一样😲!


经过打印调试,我发现了一个有趣的现象,由于适应度最高的个体拥有优先交叉权,于是他可以把自己一半的基因传递给子代,而往往他的子代适应度也不会低,于是也拥有较高的交叉权。
经过短短几百轮的迭代,就会出现一个神奇的现象,种群中适应度最高的两个个体,适应度居然一模一样了(基因也一模一样)。而且一旦出现这个现象,那么整个种群被同化就是瞬间的事儿了👻~

我在想,也许我们国人的许多基因是一样的,因为不管是人猿时代还是开启智慧后的五千年,我们也在不断做着选择淘汰。

同时可以看出变异对于一个种群是多么的重要,没有变异,种群就会进化停滞。变异是种群多样化的重要一环。


变异速度

如果一直保持同一变异速度,且变异概率一直很小或很大,都很难快速得到适应度高的个体。

对此我是用爬山来理解的,身处群山中,我想要登顶最高的山峰,如果我的步幅太小,我很可能以为这座山就是最高的山;如果我的步幅非常大,我又可能错过了最高的山;

当然大家要切记,遗传算法并不是求全局最优的算法,它是求局部最优的算法。

纯变异

其实我很早就实践过纯变异版本的遗传算法,我发现压根就不需要交叉,靠每个个体的纯变异,也可以得到一个适应度很高的个体。

这是不是说明,如果一种生命可以自我变异,那么就不需要繁衍了(当然还得有无限寿命才行)。


基因数量是不是越高越好

我个人浅薄的理解是 “是的”,基因越多,个体的表现越充分,能表达的东西越多,比如这个实践中,150个多边形拟合的图片比100个多边形拟合的图片更加细腻。

但由于我们计算资源是有限的,所以基因数量差不多就得了……

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值