遗传算法与深度学习实战(23)——利用遗传算法优化深度学习模型

遗传算法与深度学习实战(23)——利用遗传算法优化深度学习模型

    • 0. 前言
    • 1. 神经进化
    • 2. 使用遗传算法作为深度学习优化器
    • 小结
    • 系列链接

0. 前言

神经进化涵盖了所有用于改进深度学习的进化算法。更具体地说,神经进化用来定义应用于深度学习的特定优化模式。我们已经学习了如何将进化算法应用于超参数优化,并使用 Numpy 实现多层感知器 (multi-layer perceptron, MLP) 模型,接下来,我们使用遗传算法进行模型优化。

1. 神经进化

神经进化包括超参数优化、参数优化(权重/参数搜索)和网络优化技术。在本节中,我们将深入探讨如何应用进化方法来直接优化网络参数,从而消除通过网络进行的损失反向传播。
神经进化通常用于改进单个深度学习网络模型,也存在其他将进化应用于深度学习的方法,可以扩大搜索范围到多个模型。

2. 使用遗传算法作为深度学习优化器

在本节中,我们将多层感知器 (multi-layer perceptron, MLP) 模型中使用的深度学习 (Deep learning, DL) 优化方法从反向传播替换为神经进化优化。因此,我们完全依赖于遗传算法,而不使用任何形式的反向传播优化器(如梯度下降或 Adam)。
接下来,我们使用多层感知器 (multi-layer perceptron, MLP) 中一节中的 MLP 网络作为基本网络模型,然后使用 DEAP 实现遗传算法将训练优化过程包装起来。

(1) 首先,导入所需库,并加载数据集:

import numpy as np
import sklearn
import sklearn.datasets
import sklearn.linear_model
import matplotlib.pyplot as plt
from IPython.display import clear_outputfrom deap import algorithms
from deap import base
from deap import benchmarks
from deap import creator
from deap import toolsimport randomnumber_samples = 100 #@param {type:"slider", min:100, max:1000, step:25}
difficulty = 1 #@param {type:"slider", min:1, max:5, step:1}
problem = "circles" #@param ["classification", "blobs", "gaussian quantiles", "moons", "circles"]
number_features = 2
number_classes = 2 
middle_layer = 5 #@param {type:"slider", min:5, max:25, step:1}def load_data(problem):  if problem == "classification":clusters = 1 if difficulty < 3 else 2informs = 1 if difficulty < 4 else 2data = sklearn.datasets.make_classification(n_samples = number_samples,n_features=number_features, n_redundant=0, class_sep=1/difficulty,n_informative=informs, n_clusters_per_class=clusters)if problem == "blobs":data = sklearn.datasets.make_blobs(n_samples = number_samples,n_features=number_features, centers=number_classes,cluster_std = difficulty)if problem == "gaussian quantiles":data = sklearn.datasets.make_gaussian_quantiles(mean=None, cov=difficulty,n_samples=number_samples,n_features=number_features,n_classes=number_classes,shuffle=True,random_state=None)if problem == "moons":data = sklearn.datasets.make_moons(n_samples = number_samples)if problem == "circles":data = sklearn.datasets.make_circles(n_samples = number_samples)return datadata = load_data(problem)
X, Y = dataplt.figure("Input Data")
plt.scatter(X[:, 0], X[:, 1], c=Y, s=40, cmap=plt.cm.Spectral)

(2) 作为基线,比较 sklearn 的简单逻辑回归(分类)模型:

def show_predictions(model, X, Y, name=""):""" display the labeled data X and a surface of prediction of model """x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01), np.arange(y_min, y_max, 0.01))X_temp = np.c_[xx.flatten(), yy.flatten()]Z = model.predict(X_temp)plt.figure("Predictions " + name)plt.contourf(xx, yy, Z.reshape(xx.shape), cmap=plt.cm.Spectral)plt.ylabel('x2')plt.xlabel('x1')plt.scatter(X[:, 0], X[:, 1],c=Y, s=40, cmap=plt.cm.Spectral)clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X, Y)show_predictions(clf, X, Y, "Logistic regression")LR_predictions = clf.predict(X)
print("Logistic Regression accuracy : ", np.sum(LR_predictions == Y) / Y.shape[0])

(3) 实现 MLP 网络模型,用 Neural_Network 类中的 set_parameters 函数替换 trainback_prop 函数:

def sigmoid(x):return 1.0 / (1.0 + np.exp(-x)) ## Neural Network
class Neural_Network:def __init__(self, n_in, n_hidden, n_out):# Network dimensionsself.n_x = n_inself.n_h = n_hiddenself.n_y = n_out# Parameters initializationself.W1 = np.random.randn(self.n_h, self.n_x) * 0.01self.b1 = np.zeros((self.n_h, 1))self.W2 = np.random.randn(self.n_y, self.n_h) * 0.01self.b2 = np.zeros((self.n_y, 1))self.parameters = [self.W1, self.b1, self.W2, self.b2]def forward(self, X):""" Forward computation """self.Z1 = self.W1.dot(X.T) + self.b1self.A1 = np.tanh(self.Z1)self.Z2 = self.W2.dot(self.A1) + self.b2self.A2 = sigmoid(self.Z2)def set_parameters(self, individual):"""Sets model parameters """idx = 0for p in self.parameters:        size = p.sizesh = p.shapet = individual[idx:idx+size]t = np.array(t)t = np.reshape(t, sh)p -= pp += tidx += sizedef predict(self, X):""" Compute predictions with just a forward pass """self.forward(X)return np.round(self.A2).astype(np.int)

循环遍历模型中的参数列表,得到参数列表大小和形状,然后从个体中提取相同数量的基因。然后,构造一个新的张量并重新调整其形状以匹配原始的参数/权重张量。将原始张量与自身相减以将其归零并保持引用,然后添加新的张量。实际上,我们将个体的基因序列部分交换到张量中,然后将其作为模型内的新权重进行替换。

(4) 由于 trainback_prop 函数已经被完全移除,因此网络无法执行任何形式的常规反向传播训练。set_parameters 函数设置模型的权重/参数,我们使用遗传算法 (Genetic Algorithms, GA) 来搜索这些值。接下来,实例化 MLP 网络,将所有参数设置为 1.0,输出结果如下所示:

nn = Neural_Network(2, middle_layer, 1)
number_of_genes = sum([p.size for p in nn.parameters])
print(number_of_genes)individual = np.ones(number_of_genes)
nn.set_parameters(individual)
print(nn.parameters)show_predictions(nn, X, Y, "Neural Network")nn_predictions = nn.predict(X)
print("Neural Network accuracy : ", np.sum(nn_predictions == Y) / Y.shape[0])

预测结果

(5) 上图显示了在所有权重/参数设置为 1.0 的情况下模型的预测输出。接下来,实现 GA 算法优化网络参数:

creator.create("FitnessMax", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)def uniform(low, up, size=None):try:return [random.uniform(a, b) for a, b in zip(low, up)]except TypeError:return [random.uniform(a, b) for a, b in zip([low] * size, [up] * size)]toolbox = base.Toolbox()
toolbox.register("attr_float", uniform, -1, 1, number_of_genes)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.attr_float)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)toolbox.register("select", tools.selTournament, tournsize=5)
toolbox.register("mate", tools.cxBlend, alpha=.5)
toolbox.register("mutate", tools.mutGaussian, mu=0.0, sigma=.1, indpb=.25)

(6) 实现评估函数 evaluate(),函数返回准确率的倒数。这样我们就可以通过最小化适应度,从而最大化进化过程中个体的准确率:

def evaluate(individual):  nn.set_parameters(individual)nn_predictions = nn.predict(X)return 1/np.sum(nn_predictions == Y) / Y.shape[0], toolbox.register("evaluate", evaluate)

(7) 最后,演化种群以优化模型,使用 eaSimple() 函数训练种群。然后,比较最后一代种群的一个样本个体和当前最佳个体。通过使用提前停止,在模型性能达到提前停止条件(如果准确率达到某个值)时,停止模型优化过程。通过检查提前停止条件,代码可以在找到可接受的解决方案时立即停止:

MU = 1000 #@param {type:"slider", min:5, max:1000, step:5}
NGEN = 100 #@param {type:"slider", min:100, max:1000, step:10}
RGEN = 10 #@param {type:"slider", min:1, max:100, step:1}
CXPB = .6
MUTPB = .3random.seed(64)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)best = None
history = []for g in range(NGEN):pop, logbook = algorithms.eaSimple(pop, toolbox, cxpb=CXPB, mutpb=MUTPB, ngen=RGEN, stats=stats, halloffame=hof, verbose=False)best = hof[0] clear_output()print(f"Gen ({(g+1)*RGEN})")show_predictions(nn, X, Y, "Neural Network") nn_predictions = nn.predict(X)print("Current Neural Network accuracy : ", np.sum(nn_predictions == Y) / Y.shape[0])plt.show()nn.set_parameters(best)show_predictions(nn, X, Y, "Best Neural Network")plt.show()nn_predictions = nn.predict(X)fitness = np.sum(nn_predictions == Y) / Y.shape[0]print("Best Neural Network accuracy : ", fitness)if fitness > .99999: #stop conditionbreak

在下图中可以看到,种群演化已经演化为能够以 100% 准确率解决圆圈问题。而使用同样的 MLP 网络进行反向传播训练,在该问题上仅有 50% 的准确率。

输出结果

我们也可以使用 GA 来探索其他问题数据集,并比较该方法与简单的反向传播和梯度下降优化。可以通过完成以下问题进一步了解神经进化优化的工作原理:

  • 增加或减少样本数量,然后重新运行代码
  • 改变交叉和突变率,然后重新运行代码
  • 增加或减少中间层的大小,然后重新运行代码

小结

神经进化用来定义应用于深度学习的特定优化模式。在本节中,我们通过遗传算法优化简单 DL 网络的权重/参数,替换在误差反向传播训练过程中的所用优化器。

系列链接

遗传算法与深度学习实战(1)——进化深度学习
遗传算法与深度学习实战(2)——生命模拟及其应用
遗传算法与深度学习实战(3)——生命模拟与进化论
遗传算法与深度学习实战(4)——遗传算法(Genetic Algorithm)详解与实现
遗传算法与深度学习实战(5)——遗传算法中常用遗传算子
遗传算法与深度学习实战(6)——遗传算法框架DEAP
遗传算法与深度学习实战(7)——DEAP框架初体验
遗传算法与深度学习实战(8)——使用遗传算法解决N皇后问题
遗传算法与深度学习实战(9)——使用遗传算法解决旅行商问题
遗传算法与深度学习实战(10)——使用遗传算法重建图像
遗传算法与深度学习实战(11)——遗传编程详解与实现
遗传算法与深度学习实战(12)——粒子群优化详解与实现
遗传算法与深度学习实战(13)——协同进化详解与实现
遗传算法与深度学习实战(14)——进化策略详解与实现
遗传算法与深度学习实战(15)——差分进化详解与实现
遗传算法与深度学习实战(16)——神经网络超参数优化
遗传算法与深度学习实战(17)——使用随机搜索自动超参数优化
遗传算法与深度学习实战(18)——使用网格搜索自动超参数优化
遗传算法与深度学习实战(19)——使用粒子群优化自动超参数优化
遗传算法与深度学习实战(20)——使用进化策略自动超参数优化
遗传算法与深度学习实战(21)——使用差分搜索自动超参数优化
遗传算法与深度学习实战(22)——使用Numpy构建神经网络

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Hbase入门

目录 Hbase逻辑结构 一、基础知识 1. Hbase逻辑结构 行键(Rowkey)&#xff1a;唯一标识一行数据&#xff0c;按照字典序(row_key1 < row_key11 < rowkey2)排列.列Col&#xff1a;数据记录的一条属性列族&#xff1a;将多列划分为一类&#xff0c;视为一个列族。例如上图…

三维模型-管道-建模规范

一、阀门模型处理 Max中的阀门模型,备份之前可拆分的阀门模型。 将需要选择的阀门,合并(不打组)成一个模型。 材质在不同模型上,按照需求分好不同的材质 例如:阀门、管道,需要分成不同的材质和相对应的不同模型。 二、管道模型处理 1) 普通管道 默认展开UV ;2) 流…

golang go语言 组建微服务架构详解 - 代码基于开源框架grpc+nacos服务管理配置平台

整体介绍&#xff1a; 本文主要介绍如何用go语言 来组建微服务的框架&#xff0c;grpc服务管理 示例框架 代码由grpcnacos go sdk 组成。 grpc负责将调用序列化并传递到远端&#xff0c;nacos负责服务发现和服务管理。 grpc和nacos都是开源产品。代码复制下来就能跑。 微服…

open3d

open3d open3d用于 3D 数据处理的现代库。 简介 Open3D 是一个开源库&#xff0c;支持快速开发处理 3D 数据的软件。Open3D 前端公开了一组精心挑选的 C 和 Python 数据结构和算法。后端经过高度优化&#xff0c;并设置为并行化。Open3D 是从零开始开发的&#xff0c;具有一更…

一个轻量级RAG文本切块项目Chonkie

**Chonkie&#xff1a;**实用的RAG分块库&#xff0c;轻量级、速度快&#xff0c;可随时对文本进行分块 支持的方法 Chonkie 提供了多个分块器&#xff0c;可高效地为RAG应用程序拆分文本。以下是可用分块器的简要概述&#xff1a; TokenChunker&#xff1a;将文本分割成固定大…

如何通过AB测试找到最适合的Yandex广告内容

想要在Yandex上找到最能吸引目标受众的广告内容&#xff0c;A/B测试是一个不可或缺的步骤。通过对比不同版本的广告&#xff0c;我们可以发现哪些元素最能引起用户的共鸣。首先&#xff0c;设计两个或多个广告版本&#xff0c;确保每个版本在标题、文案、图片等关键元素上有所不…

车载空气净化器语音芯片方案

开发背景&#xff1a; 随着人们生活质量的不断提升和环保意识的日益增强&#xff0c;车内空气质量成为了广大车主关注的焦点。长时间封闭的车厢环境&#xff0c;加之城市空气污染、新车内饰材料释放的有害气体等因素&#xff0c;使得车内空气质量往往不尽如人意&#xff0c;严重…

JUC-locks锁

JUC-locks锁 1、JUC-locks锁概述2、管程模型3、ReentrantLock可重入锁3.1 ReentrantLock源码3.2 Sync静态内部类3.3 NonfairSync非公平锁3.4 FairSync公平锁 如有侵权&#xff0c;请联系&#xff5e; 如有错误&#xff0c;也欢迎批评指正&#xff5e; 1、JUC-locks锁概述 java…

如何将交叉编译配置在环境变量中

-- 将交叉编译配置到环境变量中&#xff0c;就可以直接用了 -- 环境变量 PATH -- 修改 Linux 的环境变量需要哪个文件 针对本用户修改&#xff1a; ~/.bashrc针对所有用户修改&#xff1a; /etc/profile -- 这里针对所有用户修改 sudo gedit /etc/profile-- 注意这个文件…

LeetCode-222.完全二叉树的节点个数

. - 力扣&#xff08;LeetCode&#xff09; 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都达到最大值&#xff0c;并且最下面一…

Jmeter中的配置原件(五)

17--登录配置原件/素 用途 管理登录信息&#xff1a;为测试计划中的多个请求提供统一的登录信息。简化配置&#xff1a;避免在每个请求中重复配置用户名和密码。支持多种认证方式&#xff1a;支持Basic、Digest等认证方式。 配置步骤 添加登录配置元件 右键点击线程组&#…

深度解析 ArrayList:揭开源码背后的设计与实现原理

一、ArrayList 简介 ArrayList 的底层是数组队列&#xff0c;相当于动态数组。与 Java 中的数组相比&#xff0c;它的容量能动态增长。在添加大量元素前&#xff0c;应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。 ArrayLi…

网络安全应该学什么?别被培训机构这些内容给骗了!

了解过的朋友都知道&#xff0c;网络安全内容十分丰富&#xff0c;大大小小的知识点都包含。所以有的朋友就都想学&#xff0c;尤其一些培训机构的课程大纲介绍的特别详细&#xff0c;又包含这又包含那&#xff0c;但是这些内容真的都实用吗&#xff1f;如果想系统学习&#xf…

吴恩达LLM Agent工作流Prompt设计精解

在详解和实测吴恩达4种Agentic 工作流之中&#xff0c;我测试了各种框架诸如反思、工具调用、规划、多智能体&#xff0c;在学习了其中各种Prompt设计后&#xff0c;有了一些新的认识。 对于特定的任务来说&#xff0c;没有万能的Prompt&#xff0c;只有一些通用的模式&#xf…

除了 Mock.js,前端还有更方便的 Mock 数据工具吗?

在前端开发中&#xff0c;模拟数据&#xff08;Mock Data&#xff09;是不可或缺的一部分&#xff0c;它能够帮助开发者在后端接口未完成前进行界面和逻辑的测试。而 Mock.js 是一个广泛使用的库&#xff0c;它通过简洁的语法和强大的功能&#xff0c;让前端开发者可以轻松地创…

【原创】java+ssm+mysql高校学籍管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

pytorch深度学习环境安装 + 讲解【新手版】

不知道有没有学深度学习的小伙伴在安装深度学习环境时候很头疼&#xff0c;反正我在研一时候是很头疼很头疼的一件事&#xff0c;根本搞不清楚什么显卡、显卡驱动、pytorch版本、cuda、cudnn等等等&#xff0c;这些是不是非常的头疼。 好&#xff0c;你们的救星来了。我&#x…

zabbix搭建钉钉告警流程

目录 zabbix实验规划 zabbix实验步骤 1 使用钉钉添加一个自定义的机器人 ​编辑2在zabbix-server上编写钉钉信息发送脚本&#xff0c;设置钉钉报警媒介 设置钉钉报警媒介​编辑​编辑 在添加消息模板​编辑​编辑​编辑 3设置动作条件 触发后的行为&#xff1a;重新添加一…

无人机飞手考证,地面站培训技术详解

无人机飞手考证及地面站培训技术涉及多个关键方面&#xff0c;以下是对这些方面的详细解析&#xff1a; 一、无人机飞手考证流程与要求 1. 证书类型 民用无人机驾驶员证书&#xff1a;这是国家民航局颁发的无人机操作人员资质证书&#xff0c;分为视距内驾驶员、超视距驾驶员…

高颜值的卡片折叠效果(附源码)

预览效果 源码(html部分) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>17sucai -Holiday Feature Folding Cards [Pure CSS]</title><meta charset"UTF-8"><meta name&qu…