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

news2024/12/26 23:27:05

遗传算法与深度学习实战(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_output

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

import random

number_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 2
        informs = 1 if difficulty < 4 else 2
        data = 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 data

data = load_data(problem)
X, Y = data

plt.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() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, 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 dimensions
        self.n_x = n_in
        self.n_h = n_hidden
        self.n_y = n_out
        
        # Parameters initialization
        self.W1 = np.random.randn(self.n_h, self.n_x) * 0.01
        self.b1 = np.zeros((self.n_h, 1))
        self.W2 = np.random.randn(self.n_y, self.n_h) * 0.01
        self.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.b1
        self.A1 = np.tanh(self.Z1)
        self.Z2 = self.W2.dot(self.A1) + self.b2
        self.A2 = sigmoid(self.Z2)

    def set_parameters(self, individual):
      """Sets model parameters """
      idx = 0
      for p in self.parameters:        
        size = p.size
        sh = p.shape
        t = individual[idx:idx+size]
        t = np.array(t)
        t = np.reshape(t, sh)
        p -= p
        p += t
        idx += size
    
    def 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 = .3

random.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 condition
        break

在下图中可以看到,种群演化已经演化为能够以 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.coloradmin.cn/o/2239424.html

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

相关文章

Kubernetes 核心组件调度器(Scheduler)

文章目录 一&#xff0c;调度约束1.Kubernetes的基本构建块和最小可调度单元pod创建过程&#xff08;工作机制&#xff0c;重点&#xff09;1.1list-watch 组件List-Watch 的优点List-Watch 的应用场景List-Watch 的挑战与优化 2.调度过程(重点)2.1调度过程&#xff1a;2.2Kube…

STM32WB55RG开发(3)----生成 BLE 程序连接手机APP

STM32WB55RG开发----3.生成 BLE 程序连接手机APP 概述硬件准备视频教学样品申请源码下载参考程序选择芯片型号配置时钟源配置时钟树RTC时钟配置RF wakeup时钟配置查看开启STM32_WPAN条件配置HSEM配置IPCC配置RTC启动RF开启蓝牙设置工程信息工程文件设置结果演示 概述 本项目旨…

[C++]内联函数和nullptr

> &#x1f343; 本系列为初阶C的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:[小编的个人主页])小编的个人主页 > &#x1f380; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 > ✌️ &#x1f91e; &#x1…

微软OmniParser:一切皆文档,OCR驱动智能操作

前沿科技速递&#x1f680; 微软推出的OmniParser是一种创新的框架&#xff0c;旨在将手机和电脑屏幕视为文档&#xff0c;通过OCR技术与多模态大模型实现对用户界面的深度理解和操作。OmniParser能够高效识别和提取界面中的文本信息、位置和语义&#xff0c;助力自动化操作。 …

使用 Web Search 插件扩展 GitHub Copilot 问答

GitHub Copilot 是一个由 GitHub 和 OpenAI 合作开发的人工智能代码提示工具。它可以根据上下文提示代码&#xff0c;还可以回答各种技术相关的问题。但是 Copilot 本身不能回答非技术类型的问题。为了扩展 Copilot 的功能&#xff0c;微软发布了一个名为 Web Search 的插件&am…

Rust语言在系统编程中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 Rust语言在系统编程中的应用 Rust语言在系统编程中的应用 Rust语言在系统编程中的应用 引言 Rust 概述 定义与原理 发展历程 Ru…

vue+vite前端项目ci过程中遇到的问题

将项目进行ci流水线构建时&#xff0c;遇到了npm run build 构建完成后命令行不会终止的问题&#xff0c;导致了无法进行下一个步骤。如下图&#xff1a; 排查了好久找到事vite.config.js的配置出了问题&#xff0c;如图所示&#xff0c;将build下的watch改为false即可解决问…

Python 获取PDF的各种页面信息(页数、页面尺寸、旋转角度、页面方向等)

目录 安装所需库 Python获取PDF页数 Python获取PDF页面尺寸 Python获取PDF页面旋转角度 Python获取PDF页面方向 Python获取PDF页面标签 Python获取PDF页面边框信息 了解PDF页面信息对于有效处理、编辑和管理PDF文件至关重要。PDF文件通常包含多个页面&#xff0c;每个页…

企业级RAG(检索增强生成)系统构建研究

— 摘要 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;技术已经成为企业在知识管理、信息检索和智能问答等应用中的重要手段。本文将从RAG系统的现状、方法论、实践案例、成本分析、实施挑战及应对策略等方面&#xff0c;探讨企业如何…

前端学习八股资料CSS(二)

更多详情&#xff1a;爱米的前端小笔记&#xff0c;更多前端内容&#xff0c;等你来看&#xff01;这些都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们的支持才是我不断更新的动力&#xff01;找…

SAP 创建物料主数据报错:估价范围3010还没有生产式的物料帐簿

通过接口创建物料主数据&#xff08;模拟MM01&#xff09;&#xff0c;报错如图&#xff1a; 处理方案1&#xff1a;&#xff08;我的不行&#xff0c;提示已经是生产的&#xff09; 将评估范围的物料分类账设置为生产 事务码: CKMSTART - 物料分类帐的生产开始 处理方案2&a…

扫雷游戏代码分享(c基础)

hi , I am 36. 代码来之不易&#x1f44d;&#x1f44d;&#x1f44d; 创建两个.c 一个.h 1&#xff1a;test.c #include"game.h"void game() {//创建数组char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };char temp[ROWS][COLS] { 0 };//初始化数…

leetcode 148. 排序链表 中等

给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5]示例 3&#xff1a; …

Elasticsearch中什么是倒排索引?

倒排索引&#xff08;Inverted Index&#xff09;是一种索引数据结构&#xff0c;它在信息检索系统中被广泛使用&#xff0c;特别是在全文搜索引擎中。倒排索引允许系统快速检索包含给定单词的文档列表。它是文档内容&#xff08;如文本&#xff09;与其存储位置之间的映射&…

excel-VLOOKUP函数使用/XVLOOKUP使用

多个窗口同时编辑表格&#xff0c;方便对照操作 使用开始-视图-新建窗口 将战区信息表的三列数据匹配到成交数据表上 可以使用VLOOKUP函数 有4个参数&#xff08;必须要查找的值&#xff0c; 要查找的区域&#xff0c;要返回区域的第几列数据&#xff0c;一个可选参数查找匹…

netcore 静态文件目录浏览

环境&#xff1a;Net6 string dirPath "C:\\Users\\15298\\Pictures"; var fileProvider new PhysicalFileProvider(dirPath); app.UseStaticFiles(new StaticFileOptions {FileProvider fileProvider,RequestPath new PathString(("/files")) }); // …

1Panel修改PostgreSQL时区

需求 1Panel安装的PostgreSQL默认是UTC时区&#xff0c;需要将它修改为上海时间 步骤 进入PostgreSQL的安装目录 /opt/1panel/apps/postgresql/postgresql/data打开postgresql.conf文件 修改&#xff1a; log_timezone Asia/Shanghai timezone Asia/Shanghai保存后重启…

函数式接口和stream

函数式接口&#xff08;Functional Interface&#xff09;是Java 8引入的一个新特性&#xff0c;它只有一个抽象方法的接口。这意味着你可以将一个函数式接口作为参数传递给方法&#xff0c;或者将其实现为一个lambda表达式。函数式接口的主要目的是允许你以声明性方式处理操作…

Oracle 高水位线和低-高水位线(High Water Mark Low High Water Mark)

在Oracle的逻辑存储结构中&#xff08;表空间-段-区-块&#xff09;&#xff0c;数据是存在数据段中的&#xff0c;通常一个表就是一个数据段&#xff0c;而段最终又由许多数据块组成。当数据存入数据块时&#xff0c;需要对块进行格式化&#xff0c;高水位线&#xff08;High …

科技资讯|Matter 1.4 标准正式发布,低功耗蓝牙助力其发展

连接标准联盟&#xff08;CSA&#xff09;宣布推出最新的 Matter 1.4 版本&#xff0c;引入了一系列新的设备类型和功能增强&#xff0c;有望提高包括 HomeKit 在内的智能家居生态系统之间的互操作性。 设备供应商和平台能够依靠增强的多管理员功能改善多生态系统下的用户体验&…