遗传算法与深度学习实战(15)——差分进化详解与实现

遗传算法与深度学习实战(15)——差分进化详解与实现

    • 0. 前言
    • 1. 差分进化
      • 1.1 基本原理
      • 1.2 差分进化基本流程
    • 2. 使用差分进化逼近复杂和不连续函数
    • 小结
    • 系列链接

0. 前言

深度学习 (Deep learning, DL) 系统通常可以被简单的视为凸函数逼近器,函数逼近并不仅局限于 DL。进化计算 (Evolutionary Computation, EC) 包含了多种方法,不仅限于连续解,还可以解决不连续解。差分进化 (Differential Evolution, DE) 是一种专注于连续和不连续解的函数逼近方法,但该方法并不是基于微积分,而是依赖于减少优化解的差异。在本节中,我们将使用 DE 来逼近已知的连续多项式解,以及不连续和复杂函数。当我们需要将 DLEC 结合解决问题时,DE 是一个行之有效的方法。

1. 差分进化

1.1 基本原理

相比遗传算法 (Genetic Algorithms, GA) 与遗传编程,差分进化 (Differential Evolution, DE) 与粒子群优化 (Particle Swarm Optimization, PSO) 更相似。在差分进化中,我们维护一个个体种群,每个个体具有相等的向量大小。与 PSO 类似,个体是长期存在的,不会产生后代,但它们的组件向量会通过与其他随机个体的差异比较来进行修改,以生成新的更好的个体。

1.2 差分进化基本流程

下图显示了差分进化的基本工作流程。在该图的起始处,从一组较大的个体种群中随机选择三个个体。然后,使用这三个个体来修改每个索引值上的目标 Y,方法是将第一个个体 a 的值加到个体 bc 之间的比例差异上。评估生成的个体 Y 的适应度,如果该值更好,则用新的个体 Y 替换该个体。

差分进化

这种方法在不连续函数上如此有效的原因是计算个体维度差异。与通常需要混合结果(如在 DL 中)或概括结果(如在遗传进化中)的正常优化函数不同,差分进化进行了分量级的差异化。
DL 中,我们使用梯度优化方法在训练期间反向传播误差,这是一个全局优化问题。差分进化将优化提取为数值的分量级差异,因此不受全局方法的限制。这意味着差分进化可以用于逼近不连续或复杂的函数。

2. 使用差分进化逼近复杂和不连续函数

在本节中,我们继续使用在进化策略一节中使用的三个问题:多项式、绝对值和阶跃函数。

(1) 为了比较,我们首先使用差分进化解决多项式函数逼近问题。由于绝对值和分段函数更复杂,需要更多时间来运行,因此我们还需要修改最长运行时间超参数(将 MAX_TIME 的值从 5 秒更改为 100):

import random
import array
import time

import numpy as np

from deap import base
from deap import benchmarks
from deap import creator
from deap import tools

import matplotlib.pyplot as plt
from IPython.display import clear_output

NDIM = 6
CR = 0.25
F = 1  
MU = 300
NGEN = 1000  
GEN_OUTPUT = 25
MAX_TIME = 5

通过设置不同函数,重新运行代码,能够解决不同函数逼近问题。例如,为了更好的进行比较,将 MAX_TIME 更改为 100 秒,将目标函数设置为 step (分段函数)。下图显示了使用差分进化 (Differential Evolution, DE) 和进化策略 (Evolutionary Strategies, ES) 方法逼近 step 函数的差异,可以看到,DE 方法的性能比 ES 方法要好 10 倍以上,这与差分方法有关;另一方面,ES 的直方图服从正态分布,而 DE 的分布类似于狭窄的柯西分布。

结果对比

(2) 接下来,编写 creatortoolbox 设置代码。对于 toolbox,注册一个类型为 float 的属性,初始值为 -3+3,类似于遗传进化中的基因。然后,定义类型为 float 且大小为 NDIM (维度数)的个体。注册一个使用 random 方法选择三个元素的 select 函数,用于选择三个个体 (abc) 来应用差分算法。

creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", array.array, typecode='d', fitness=creator.FitnessMin)

toolbox = base.Toolbox()
toolbox.register("attr_float", random.uniform, -3, 3)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, NDIM)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("select", tools.selRandom, k=3)

equation_form = "polynomial" #@param ["polynomial", "abs", "step"]

X_START = -5
X_END = 5
X_STEP = 0.5

def equation(x):
    if equation_form == "polynomial":
        return (2*x + 3*x**2 + 4*x**3 + 5*x**4 + 6*x**5 + 10) 
    elif equation_form == "abs":    
        return abs(x)
    else:    
        return np.where(x>1, 1, 0)     

X = np.array([x for x in np.arange(X_START, X_END, X_STEP)])
Y = equation(X)
data = list(zip(X, Y))

plt.scatter(X,Y)

import csv
with open('data.csv', 'w') as f:      
    # using csv.writer method from CSV package
    write = csv.writer(f)      
write.writerows(data)

def pred(ind, x):    
    y_ = 0.0    
    for i in range(1,NDIM):
        y_ += ind[i-1]*x**i    
    y_ += ind[NDIM-1]       
    return y_

def fitness(ind, data):    
    mse = 0.0    
    for x, y in data:        
        y_ = pred(ind, x)
        mse += (y - y_)**2        
    return mse/len(data),

# fitness eval
toolbox.register("evaluate", fitness, data=data)

def plot_fitness(g, best, pop, logbook):
    Y_ = np.array([pred(best, x) for x in X])
    clear_output()
    print(f"Generation {g}, Best {best}") 
    print(logbook.stream)
    fits = [f.fitness.values[0] for f in pop]  
    plt.hist(fits)
    plt.show()
    plt.scatter(X,Y)
    plt.plot(X,Y_, 'r')
    plt.show()

(3) 运行训练过程,代码中有两个 for 循环——第一个循环迭代代数次,第二个循环遍历每个个体。在内部循环中,我们首先对个体进行采样 (abc),然后克隆个体作为目标 Y。然后,我们对个体的向量进行随机索引采样,并使用交叉概率值 (CR) 确定是否计算可能的差异。最后,检查新个体是否具有更好的适应度,如果是,则用新个体替换旧个体:

pop = toolbox.population(n=MU);
hof = tools.HallOfFame(1)
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg", np.mean)
stats.register("std", np.std)
stats.register("min", np.min)
stats.register("max", np.max)

logbook = tools.Logbook()
logbook.header = "gen", "evals", "std", "min", "avg", "max"

# Evaluate the individuals
fitnesses = toolbox.map(toolbox.evaluate, pop)
for ind, fit in zip(pop, fitnesses):
    ind.fitness.values = fit

record = stats.compile(pop)
logbook.record(gen=0, evals=len(pop), **record)
print(logbook.stream)
start = time.time()
for g in range(1, NGEN):
    for k, agent in enumerate(pop):
        a,b,c = toolbox.select(pop)
        y = toolbox.clone(agent)
        index = random.randrange(NDIM)
        for i, value in enumerate(agent):
            if i == index or random.random() < CR:
                y[i] = a[i] + F*(b[i]-c[i])
        y.fitness.values = toolbox.evaluate(y)
        if y.fitness > agent.fitness:
            pop[k] = y       
    hof.update(pop)    
    record = stats.compile(pop)
    logbook.record(gen=g, evals=len(pop), **record)
    if (g+1) % GEN_OUTPUT == 0:
        plot_fitness(g, hof[0], pop, logbook) 
        end = time.time()
        if end-start > MAX_TIME:
            break

print("Best individual is ", hof[0], hof[0].fitness.values[0])

输出结果如下所示:

Generation 224, Best Individual('d', [30.623428393852492, 9.95572994067285, -0.111135397356243, 4.814033796899285, 6.145782841353448, -15.520563507441928])
200	300  	12101.9    	1204.96	14070.8    	105171     
201	300  	12097.2    	1204.96	14038.9    	105171     
202	300  	12075      	1204.96	13995.6    	105171     
203	300  	11617      	1204.96	13748.1    	105171     
204	300  	11572.5    	1204.96	13707.8    	105171     
205	300  	10211.7    	1204.96	13305.5    	80207      
206	300  	10213.3    	1204.96	13298.9    	80207      
207	300  	10210.2    	1204.96	13190.8    	80207      
208	300  	10193.8    	1204.96	13046.2    	80207      
209	300  	10153.5    	1204.96	12928.7    	80207      
210	300  	9831.04    	1204.96	12818.5    	65199.8    
211	300  	9731.12    	1204.96	12725      	65199.8    
212	300  	9386.74    	1204.96	12482.3    	65199.8    
213	300  	9351.17    	1099.93	12338      	65199.8    
214	300  	9269.36    	1099.93	12217.7    	65199.8    
215	300  	9304.61    	1099.93	12113.3    	64891      
216	300  	9300.13    	1099.93	12020.8    	64891      
217	300  	9263.16    	1099.93	11888.1    	64891      
218	300  	9276.17    	1099.93	11794.4    	64891      
219	300  	9291.6     	1099.93	11732.7    	64891      
220	300  	9310.43    	1099.93	11694.6    	64891      
221	300  	9299.04    	1099.93	11622      	64891      
222	300  	9281.38    	1099.93	11508.5    	64891      
223	300  	9274.25    	1099.93	11461.3    	64891      
224	300  	9178.1     	1099.93	11391.1    	64891      

Best individual is  Individual('d', [30.623428393852492, 9.95572994067285, -0.111135397356243, 4.814033796899285, 6.145782841353448, -15.520563507441928]) 1099.9285908060874

通过更改数据准备中的函数类型,我们可以在绝对值或分段函数上使用差分进化,还可以尝试调整超参数,查看它们对使用 ESDE 逼近函数的影响。通过完成以下问题进一步理解差分进化的基本概念:

  • 修改超参数,然后重新运行,观察能否改善不连续函数逼近的性能
  • 比较 ESDE 对于各种函数的函数逼近结果。

小结

差分进化 (Differential Evolution, DE) 和进化策略 (Evolutionary Strategies, ES) 都为连续问题提供了优秀的函数逼近器,对于不连续问题,通常最好应用 DE,因为它不受全局空间中逐渐逼近的限制。在本节中,我们对 EC 进行了扩展,并介绍了差分进化方法,用于解决新颖或复杂的问题。

系列链接

遗传算法与深度学习实战(1)——进化深度学习
遗传算法与深度学习实战(2)——生命模拟及其应用
遗传算法与深度学习实战(3)——生命模拟与进化论
遗传算法与深度学习实战(4)——遗传算法(Genetic Algorithm)详解与实现
遗传算法与深度学习实战(5)——遗传算法中常用遗传算子
遗传算法与深度学习实战(6)——遗传算法框架DEAP
遗传算法与深度学习实战(7)——DEAP框架初体验
遗传算法与深度学习实战(8)——使用遗传算法解决N皇后问题
遗传算法与深度学习实战(9)——使用遗传算法解决旅行商问题
遗传算法与深度学习实战(10)——使用遗传算法重建图像
遗传算法与深度学习实战(11)——遗传编程详解与实现
遗传算法与深度学习实战(12)——粒子群优化详解与实现
遗传算法与深度学习实战(13)——协同进化详解与实现
遗传算法与深度学习实战(14)——进化策略详解与实现

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Linux]从零开始的网站搭建教程

一、谁适合本次教程 学习Linux已经有一阵子了&#xff0c;相信大家对LInux都有一定的认识。本次教程会教大家如何在Linux中搭建一个自己的网站并且实现内网访问。这里我们会演示在Windows中和在Linux中如何搭建自己的网站。当然&#xff0c;如果你没有Linux的基础&#xff0c;这…

python画图|自制渐变柱状图

在前述学习过程中&#xff0c;我们已经通过官网学习了如何绘制渐变的柱状图及其背景。 掌握一门技能的最佳检验方式就是通过实战&#xff0c;因此&#xff0c;本文尝试做一些渐变设计。 前述学习记录可查看链接&#xff1a; Python画图|渐变背景-CSDN博客 【1】柱状图渐变 …

ArcGIS共享数据的最佳方法(不丢可视化、标注等各类显示信息一样带)

今天我们介绍一下ArcGIS数据共享的几个小妙招 我们时常要把数据发给对方&#xff0c;特别是很多新手朋友要将shp发给对方时只是发送了shp后缀的文件&#xff0c;却把shp的必要组成文件dbf、shx等等给落下了。 还有很多朋友给图层做好了符号化标注&#xff0c;但是数据一发给别…

详解调用钉钉AI助理消息API发送钉钉消息卡片给指定单聊用户

文章目录 前言准备工作1、在钉钉开发者后台创建一个钉钉企业内部应用&#xff1b;2、创建并保存好应用的appKey和appSecret&#xff0c;后面用于获取调用API的请求token&#xff1b;3、了解AI助理主动发送消息API&#xff1a;4、应用中配置好所需权限&#xff1a;4.1、权限点4.…

OkHttp 详细使用步骤,以及异步请求和同步请求

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。 &#x1f60a; 座右铭&#xff1a;不…

python编程开发“人机猜拳”游戏

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

Arduino UNO R3自学笔记6 之 Arduino引脚(IO)功能介绍

注意&#xff1a;学习和写作过程中&#xff0c;部分资料搜集于互联网&#xff0c;如有侵权请联系删除。 前言&#xff1a;Ardunio UNO R3有很多引脚&#xff0c;接下来主要介绍它们都可以用做什么。 从上图不难看出开发板引脚也不是有多少&#xff0c;分类来看也就以下种类型&…

翻译:Recent Event Camera Innovations: A Survey

摘要 基于事件的视觉受到人类视觉系统的启发&#xff0c;提供了变革性的功能&#xff0c;例如低延迟、高动态范围和降低功耗。本文对事件相机进行了全面的调查&#xff0c;并追溯了事件相机的发展历程。它介绍了事件相机的基本原理&#xff0c;将其与传统的帧相机进行了比较&am…

大数据-154 Apache Druid 架构与原理详解 基础架构、架构演进

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

最大正方形 Python题解

最大正方形 题目描述 在一个 n m n\times m nm 的只包含 0 0 0 和 1 1 1 的矩阵里找出一个不包含 0 0 0 的最大正方形&#xff0c;输出边长。 输入格式 输入文件第一行为两个整数 n , m ( 1 ≤ n , m ≤ 100 ) n,m(1\leq n,m\leq 100) n,m(1≤n,m≤100)&#xff0c;接…

[Linux]开发环境搭建

RPM和YUM 安装JDK 安装Tomcat 安装IDEA 安装MySql

2-109 基于matlab-GUI的BP神经网络

基于matlab-GUI的BP神经网络&#xff0c;10种不同分布的数据样本&#xff0c;9种不同的激活函数&#xff0c;可更改升级网络结构参数&#xff0c;对比各种方法参数下的训练测试效果&#xff0c;实时显示预测过程。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&…

以Flask为基础的虾皮Shopee“曲线滑块验证码”识别系统部署

以Flask为基础的虾皮Shopee“曲线滑块验证码”识别系统部署 一、验证码类型二、简介三、Flask应用 一、验证码类型 验证码类型&#xff1a;此类验证码存在两个难点&#xff0c;一是有右侧有两个凹槽&#xff0c;二是滑块的运动轨迹不是直线的&#xff0c;而是沿着曲线走的&…

AI驱动TDSQL-C Serverless 数据库技术实战营-与AI的碰撞

目录 一、简介 二、实验介绍 三、结果展示 四、实操指导 4.1 系统设计 4.2 环境搭建&#xff08;手把手教程&#xff09; 4.3 应用构建 4.4 效果展示 4.5 踩坑避雷总结 五、清理资源 5.1 删除TDSQL-C Serverless 5.2 删除 HAI 算力 六、实验总结归纳 一、简介 本…

SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS

一、本地上传 概念&#xff1a;将前端上传的文件保存到自己的电脑 作用&#xff1a;前端上传的文件到后端&#xff0c;后端存储的是一个临时文件&#xff0c;方法执行完毕会消失&#xff0c;把临时文件存储到本地硬盘中。 1、导入文件上传的依赖 <dependency><grou…

用于高频交易预测的最优输出LSTM

用于高频交易预测的最优输出LSTM J.P.Morgan的python教程 Content 本文提出了一种改进的长短期记忆&#xff08;LSTM&#xff09;单元&#xff0c;称为最优输出LSTM&#xff08;OPTM-LSTM&#xff09;&#xff0c;用于实时选择最佳门或状态作为最终输出。这种单元采用浅层拓…

Elasticsearch:使用 LLM 实现传统搜索自动化

作者&#xff1a;来自 Elastic Han Xiang Choong 这篇简短的文章是关于将结构化数据上传到 Elastic 索引&#xff0c;然后将纯英语查询转换为查询 DSL 语句&#xff0c;以使用特定过滤器和范围搜索特定条件。完整代码位于此 Github repo 中。 首先&#xff0c;运行以下命令安装…

Apache POI 2024/10/2

导入Apache POI的maven坐标 通过POI向Excel文件写入文件内容 package com.sky.test;import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.File; import java.…

【C++并发入门】opencv摄像头帧率计算和多线程相机读取(下):完整代码实现

前言 高帧率摄像头往往应用在很多opencv项目中&#xff0c;今天就来通过简单计算摄像头帧率&#xff0c;抛出一个单线程读取摄像头会遇到的问题&#xff0c;同时提出一种解决方案&#xff0c;使用多线程对摄像头进行读取。上一期&#xff1a;【C并发入门】摄像头帧率计算和多线…

1.5 测试用例

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 测试用例介绍2 测试用例编写3 案例分析4 执行测试用例 前言 测试用例的设计和编制是软件活动中最重要的工作。本文详细讲解了测试用例的基本概念以及如何编写测试用例。 本篇文…