当前位置: 首页 > news >正文

遗传算法与深度学习实战(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.mrgr.cn/news/72318.html

相关文章:

  • AI生活之我用AI处理Excel表格
  • 世界坐标系、相机坐标系、图像物理坐标系、像素平面坐标系
  • Linux 常用操作指令大揭秘(下)
  • 简析大模型参数高效微调方法
  • JAVA学习日记(十五) 数据结构
  • PET-文件包含-FINISHED
  • Mysql详细知识点(建议收藏)
  • JUC-locks锁
  • Java基础-组件及事件处理(上)
  • AIDL HAL简介
  • Ajax 与 Vue 框架应用点——随笔谈
  • UI自动化测试|XPath元素定位实践
  • 开闭原则(OCP)在SpringBoot系统中的应用
  • 【求阶乘——二分+阶乘的质因数分解】
  • 大数据分析案例-基于XGBoost算法构建电子商务交易欺诈预测模型
  • Servlet的使用
  • 创建逻辑卷报错:Device /dev/sdb excluded by a filter
  • 高考、考研、考公,究竟哪个更容易?网友众说纷纭,真相在这里
  • 通过生成式人工智能绕过面部识别认证
  • 深入理解接口测试:实用指南与最佳实践5.0(二)
  • Java基础-组件及事件处理(中)
  • flutter下拉刷新上拉加载的简单实现方式三
  • 【SSL-RL】自监督强化学习:自预测表征 (SPR)算法
  • 猎板 PCB 之罗杰斯板材:高性能驱动多领域发展
  • Spring Boot 接口防重复提交解决方案
  • 办公必备:非常好用的截图软件-snipaste