遗传算法与深度学习实战——生命模拟与进化论

遗传算法与深度学习实战——生命模拟与进化论

    • 0. 前言
    • 1. 模拟进化
      • 1.1 代码实现
      • 1.2 代码改进
    • 2. 达尔文进化论
    • 3. 自然选择和适者生存
      • 3.1 适者生存
      • 3.2 进化计算中的生物学
    • 小结
    • 系列链接

0. 前言

生命模拟通过计算机模拟生物体的基本特征、遗传机制、环境互动等,试图模拟和理解生物的演化过程。我们已经学习了如何实现简单的生命模型,为了进一步提升生命模拟需要模拟进化,接下来,通过借鉴达尔文的进化论,构建升级版的生命模拟。

1. 模拟进化

在本节中,我们重用了简单生命模型的大部分代码,并对其进行修改,以模拟进化或细胞传递遗传特征的能力。在本节中,我们不再使用单一特征 strength,而是分配了三个新特征,标记为 abc。除此之外,我们还将健康特征替换为更通用的术语——适应度 (fitness)。

1.1 代码实现

(1) 更新 create_cell 函数,该函数需要接受两个输入细胞来生成一个后代。例如,在模拟开始时,没有父代细胞,则为细胞的特征设置随机值;而在有父代细胞时,子代细胞的每个特征为父代双亲特征的平均值,这种平均机制只是创建子代特征值的一种方式:

import random
import time
import matplotlib.pyplot as plt
from livelossplot import PlotLossesMUTATE_RNG = 5
MUTATE_RATE = 10def clamp(num, min_value, max_value):return max(min(num, max_value), min_value)def create_cell(parent1, parent2):if parent1 is None or parent2 is None:return dict(fitness = 0,a = random.randint(1, 100),b = random.randint(1, 100),c = random.randint(1, 100)) else:    return dict(fitness = 0,a = (parent1["a"] + parent2["a"])/2,b = (parent1["b"] + parent2["b"])/2,c = (parent1["c"] + parent2["c"])/2,) 

(2) 更新 reproduce 函数,首先,按适应度对父代细胞进行排序,然后选择前一半作为父代(选择过程),然后循环遍历所选择的父代两次(假设每个父代双亲有两个孩子),随机选择两个父代双亲进行繁殖,然后将这两个父母传递给 create_cell 函数,使用两个父母的特征获得一个新的子代。最后,通过 mutate 函数对细胞执行突变(有多种选择父代的方式,我们将在后续的学习中看到更多选择方式):

def reproduce(cells): parents = sorted(cells, key=lambda d: d['fitness'])[int(len(cells)/2):]    children = [] for i in range(len(parents)*2):mates = random.sample(parents, 2) children.append(create_cell(mates[0], mates[1]))return mutate(children)

(3) mutate 函数能够随机修改子代特征,通过使用此函数来模拟物理世界中生物体(细胞)可能发生的突变,以获取超越父母的特征。突变是进化的关键因素,也是地球上所有高级生命形式的根源:

def mutate(cells):for cell in cells:if random.randint(1,100) < MUTATE_RATE:cell["a"] = clamp(cell["a"] + random.randint(-MUTATE_RNG, MUTATE_RNG), 1, 100)cell["b"] = clamp(cell["b"] + random.randint(-MUTATE_RNG, MUTATE_RNG), 1, 100)cell["b"] = clamp(cell["b"] + random.randint(-MUTATE_RNG, MUTATE_RNG), 1, 100)      return cells

(4) 更新 evaluate 函数,使用一个简单的方程来评估特征 abc 的值,并输出细胞的适应度。该函数在特征 a 上的权重为 2,在特征 b 上的权重为一个负值,而特征 c 权重为 1。进化生命模拟的目标是优化这些特征,以获取高适应度个体。更高的适应度增加了繁殖的可能性,将鼓励更多优秀特征的传递:

def birth(offspring):return [create_cell(None, None) for i in range(offspring)]def evaluate(cells):for cell in cells:cell["fitness"] = 2 * cell["a"] - cell["b"] + cell["c"]return cells

删除 death 函数,专注于 reproduce 函数。之所以这样做,是因为我们简单地假设在繁殖后,所有的父母都不会进一步保留;因此,无需考虑细胞死亡的情况。因此,我们不再关心种群数量的增长,而是关注种群的繁衍。这个假设简化了模拟的过程我们的过程,当然,我们也可以模拟多代之间的繁殖,保留父代中的优秀个体。

(5) 最后,更新 run_generation 函数,函数首先调用 evaluate 函数,更新细胞的适应度。接下来,调用 reproduce 函数产生下一代繁殖种群。之后,再次调用 evaluate 函数更新新一代的适应度值:

def run_generation(cells):  cells = evaluate(cells)cells = reproduce(cells) cells = evaluate(cells)
return cellsgenerations = 25 #@param {type:"slider", min:1, max:25, step:1}
initial_offspring = 10 #@param {type:"slider", min:10, max:1000, step:1}
mutation_rate = 10 #@param {type:"slider", min:1, max:100, step:1}
mutation_range = 20 #@param {type:"slider", min:1, max:100, step:1}MUTATE_RNG = mutation_range
MUTATE_RATE = mutation_rate
cells = birth(initial_offspring)groups = {'Generation': ['population','avg_fitness'], 'Attrributes' : ["avg_a", "avg_b", "avg_c"]}
liveloss = PlotLosses(groups=groups)history = {}
for i in range(generations):  cells = run_generation(cells)  history["population"] = len(cells)   history["avg_fitness"] = sum([cell["fitness"] for cell in cells])/(len(cells)+1)history["avg_a"] = sum([cell["a"] for cell in cells])/(len(cells)+1) history["avg_b"] = sum([cell["b"] for cell in cells])/(len(cells)+1) history["avg_c"] = sum([cell["c"] for cell in cells])/(len(cells)+1) liveloss.update(history)liveloss.send()

代码输出如下图所示。可以看到,与上一节的模拟相比,适应度显著提高,但人口始终保持为 10 个。并且特征 abc 都得到了明显的优化,特征 a 的值明显增加,特征 b 的值明显减少,这是由于我们在适应度方程中定义的特征权重导致的结果。

模拟结果

通过将进化的概念添加到生命模拟中,可以看到适应度和特征优化之间的强相关性,使得修改后的模拟更加健壮和可扩展。事实上,进化的概念是整个进化算法类的基础。

1.2 代码改进

可以通过完成以下问题进一步理解上示生命模拟过程:

  • 修改 evaluate 函数中的适应度计算方法,重新运行模拟过程观察不同权重的优化结果
  • 在细胞中添加一个新特征 d,并相应修改相关代码
  • 将突变率 MUTATE_RATE 改为介于 01 之间的值,更改后重新运行代码,观察突变对细胞进化的影响

2. 达尔文进化论

从达尔文提出自然选择概念和理论开始,对地球上的生命如何通过遗传学分享和传递选择特征的好奇驱使我们不断探索进化理论。
达尔文于 1859 年发表了《物种起源》,这一开创性的作品颠覆了自然科学,并成为许多自然和生物科学的基础。达尔文将自然选择理论描述为:“导致所有有机生命进步的一般法则,即繁殖、突变,令强者生存、弱者死亡。”
根据这一法则,达尔文构建了他的进化理论,认为生命需要通过将更成功的特征传递给后代来繁衍。虽然他未理解细胞有丝分裂和遗传学过程,但他确实总结了多个物种中特征的选择性传递。直到 1865 年,孟德尔通过观察豌豆植物的七个特征,提出了基因遗传理论。
孟德尔使用特征来描述我们现在称为基因的东西。近 30 年后,他的工作才得到认可,遗传学领域就此诞生,此后,基因学快速发展,包括基因治疗、转基因技术等。

3. 自然选择和适者生存

3.1 适者生存

“适者生存”常常被用来定义进化和进化计算,但这个术语是由早期的自然学家赫伯特·斯宾塞首次提出的。但斯宾塞忽略了一个事实:生存只是变化的结果。达尔文很好地解释了这个概念:“生存下来的不是最强壮或最聪明的,而是对变化最敏感的物种。”进化不是发展最强壮或最适合的物种,而是能够最好地适应变化的物种。这意味着,在实际应用中,虽然我们专注于开发能产生最佳适应度的算法,我们真正的目标是发展进化性变化。
在计算中,通过应用进化性变化,确保不仅是最适合或最优秀的个体能够得以生存,这意味着需要确保种群不仅是最好的,而且是最具多样性的。鼓励多样性的种群通常能够更快地解决问题。

3.2 进化计算中的生物学

进化计算借鉴了生物学和进化理论。与神经网络将深度学习 ( Deep learning, DL) 与大脑进行类比一样,并非所有概念都完全等价。在多数情况下,能够使用类似或匹配生物学等效的概念,但为了便于理解,这些生物学概念已经被大幅简化。

小结

生命模拟利用计算机模拟来模拟生命体的行为、生长和进化过程。这些模拟可以基于简单的规则和算法,通过模拟生物个体的互动和繁殖,探索复杂系统如何从简单规则中产生出自组织和复杂性。在本节中,通过借鉴达尔文的进化论,构建了升级版的生命模拟。

系列链接

遗传算法与深度学习实战——进化深度学习
遗传算法与深度学习实战——生命模拟及其应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/392907.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF 依赖属性 IsHitTestVisible

IsHitlTestVisible 仅影响本身的元素&#xff08;含内部包含的子元素&#xff09;&#xff0c;不影响父元素效果&#xff0c;且事件会传递到父元素。 Eg&#xff1a; 如父元素有click事件&#xff0c; 子元素设置了IsHitTestVisiblefalse&#xff0c; 当鼠标单击这个子元素时&…

Android 埋点信息分析——内存篇

源码基于&#xff1a;Android U 0. 前言 在前一篇《Android statsd 埋点简析》一文中简单剖析了Android 埋点采集、传输的框架&#xff0c;本文在其基础对埋点信息进行解析&#xff0c;来看下Android 中埋下的内存信息有哪些。 1. 通过代码剖析google 埋点内容 1.1 PROCESS_M…

BootStrap前端面试常见问题

在前端面试中&#xff0c;关于Bootstrap的问题通常围绕其基本概念、使用方式、特性以及实际应用等方面展开。以下是一些常见的问题及其详细解答&#xff1a; 1. Bootstrap是哪家公司研发的&#xff1f; 回答&#xff1a;Bootstrap是由Twitter的Mark Otto和Jacob Thornton合作…

脊髓损伤小伙伴的活力重启秘籍! 让我们一起动起来,拥抱不一样的精彩生活✨

Hey小伙伴们~&#x1f44b; 今天咱们来聊聊一个超级重要又温暖的话题——脊髓损伤后的锻炼大法来啦&#xff01;&#x1f389; 记住&#xff0c;无论遇到什么挑战&#xff0c;我们都要像打不死的小强一样&#xff0c;活力满满地面对每一天&#xff01;&#x1f4aa; 首先&#…

2024实验班选拔考试(热身赛)

比赛传送门 邀请码&#xff1a;2024wksyb A. 简单的数列问题 签到&#xff0c;记得开long long。 #include<bits/stdc.h> #define rep(i,a,b) for (int ia;i<b;i) #define per(i,a,b) for (int ia;i>b;--i) #define se second #define fi first #define endl …

【C#语音文字互转】.NET的TTS文本转语音合成

官方文档给出环境为Visual Studio 2017及以上&#xff1b;C#SDK为.NET4.8及以上 本文章环境介绍&#xff1a; Visual Studio 2022&#xff1b;C#SDK为.NET6.0 语音转文字请移步&#xff1a;【C#语音文字互转】C#语音转文字&#xff08;方法一&#xff09; 一. 启动 Visual Stud…

【OceanBase系列】—— OceanBase应急三板斧

作者&#xff1a; 花名&#xff1a;洪波&#xff0c; OceanBase 数据库解决方案架构师 目前随着OceanBase数据库越来越流行&#xff0c;社区已经有很多用户在生产环境使用了OceanBase&#xff0c;也有不少用户的核心业务用到了OceanBase数据库&#xff0c;在使用OceanBase数据库…

新址·新征程|美创科技北京中心喜迎乔迁

7月30日&#xff0c;北京暴雨倾城 连绵大雨和隆隆雷声 却像是在为一场新征程洗礼 这一天&#xff0c;我们迎来了重要的时刻 ——美创科技北京中心搬新家啦&#xff01; 新址&#xff1a;北京市海淀区庚坊国际大厦6层 喜迎新址&#xff0c;一场简单但喜气盈盈、温馨十足的乔…

【Python学习手册(第四版)】学习笔记16-函数基础

个人总结难免疏漏&#xff0c;请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。 本文主要介绍Python中函数的基本概念&#xff0c;作用域以及参数传递&#xff0c;函数语法以及def和return语句的操作&#xff0c;函数调用表达式的行为&#xff…

Delphi5实现DLL的编写、调用

效果图 显式跟隐式调用差不多的&#xff0c;就重新画了窗体&#xff0c;画的有点粗糙。 DLL文件 DLL文件是一种包含了可执行代码的库文件&#xff0c;但它不能独立运行&#xff0c;必须由其他程序&#xff08;如EXE文件&#xff09;显式或隐式地加载并调用。DLL文件通常用于实…

全国地铁路线及站点SHP数据

数据是GIS的血液&#xff01; 我们在《126M全球手机基站SHP数据分享》一文中&#xff0c;为你分享过全球手机基站分布数据。 现在再为你分享全国地铁轻轨路线与站点SHP数据&#xff0c;你可以在文末查看该数据的领取方法。 全球地铁路线及站点数据 截至2023年12月31日&…

LAVIS在Mac,M1PRO芯片下的安装实战

LAVIS在Mac,M1PRO芯片下的安装实战 契机 ⚙ 本地想装个图片理解的大模型&#xff0c;看了下blip2感觉比较合适&#xff0c;macos安装的时候有点坑需要注意下&#xff0c;但是最终也无法使用mps加速&#xff0c;比较蛋疼。这里记录下安装步骤。 安装 LAVIS/projects/blip2 a…

【研发日记】Matlab/Simulink技能解锁(十二)——Stateflow中的两种状态机嵌套对比

文章目录 前言 项目背景 两级状态机 函数状态机 分析和应用 总结 参考资料 前言 见《【研发日记】Matlab/Simulink技能解锁(七)——两种复数移相算法》 见《【研发日记】Matlab/Simulink技能解锁(八)——分布式仿真》 见《【研发日记】Matlab/Simulink技能解锁(九)——基…

数据结构(其四)--特殊矩阵的存储

目录 11.特殊矩阵的压缩存储 &#xff08;1&#xff09;.一维数组的储存结构 &#xff08;2&#xff09;.二维数组的存储结构 &#xff08;3&#xff09;.普通矩阵的存储 &#xff08;4&#xff09;.特殊矩阵的压缩存储 i.对称矩阵 ii.三角矩阵 iii.三对角矩阵 iiii.稀疏矩…

Java多商户新零售超市外卖商品系统

解锁新零售奥秘&#xff0c;多商户外卖超市商品系统大揭秘&#xff01; &#x1f31f; 开篇&#xff1a;新零售时代的浪潮 在这个日新月异的数字化时代&#xff0c;新零售已悄然成为商业变革的新风口。想象一下&#xff0c;足不出户就能逛遍全城商家&#xff0c;心仪商品一键…

力扣——238.移动零

题目 思路 利用双指针&#xff0c;先找到第一个为0的地方指向&#xff0c;指针2指向下一个&#xff0c;指针1之前是已经处理好的数据&#xff0c;指针2进行遍历&#xff0c;遇到非零则与指针1数据交换&#xff0c;然后指针1。 代码 class Solution { public:void moveZeroes(…

离心机转子适配器容量转换器的作用

离心机转子是离心机的核心部件&#xff0c;离心机中的所有系统都配置为保证转子在一定条件下安全运行。转子不仅直接影响分离效果&#xff0c;而且也是离心机技术中的主要承力部件&#xff0c;对离心机的安全性极为重要。 简而言之&#xff0c;离心机可分为两部分&#xff1a;…

Java Web——第二天

什么是JavaScript? JavaScript(简称:JS) 是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互 JavaScript和Java是完全不同的语言&#xff0c;不论是概念还是设计。但是基础语法类似 JavaScript在1995年由 Brendan Eich 发明&#xff0c;…

【MySQL】索引概念解析

1.什么是索引&#xff1f; MySQL中的索引是一种数据结构&#xff0c;用于帮助MySQL数据库管理系统快速查询数据。索引的主要目的是提高数据检索的速度&#xff0c;减少数据库系统需要扫描的数据量。 优点&#xff1a; 索引可以极大的提高数据检索效率&#xff0c;降低数据库…

C语言——预处理和指针

C语言——预处理和指针 预处理宏宏定义宏的作用域带参的宏 文件包含条件编译 指针指针的概念指针的定义 预处理 编程的流程分为&#xff1a;编辑、编译、运行、调试四个阶段&#xff1b; 预处理属于编译阶段&#xff0c;编译过程又可以分为&#xff1a;预处理、编译、汇编、链…