【问题标题】:How can a genetic algorithm optimize a neural network's weights without knowing the search volume?遗传算法如何在不知道搜索量的情况下优化神经网络的权重?
【发布时间】:2020-07-27 14:59:34
【问题描述】:

我已经实现了一个带有变异算子的遗传算法训练的神经网络,如下所示:

def mutation(chromosome, mutation_rate):
  for gene in chromosome:
    if random.uniform(0.00, 1.00) <= mutation_rate:
      gene = random.uniform(-1.00, 1.00)

并且染色体最初是随机初始化的:

def make_chromosome(chromosome_length):
  chromosome = []
  for _ in range(chromosome_length):
    chromosome.append(random.uniform(-1.00, 1.00))
  return chromosome

在执行交叉时,后代染色体只能在区间[-1, 1] 内具有基因,因为父染色体也只能在该区间内具有基因。当一个后代发生突变时,它同样会将其基因保持在该区间内。

这似乎适用于某些问题,但不适用于其他问题。如果一个神经元的最优权重在[-1, 1]之内,那么遗传算法就可以工作,但是如果一个神经元的最优权重在不同的区间内呢?

例如,如果我使用反向传播训练了一个网络,其终止条件的分类误差低于 5%,我可以查看网络权重并查看 -1.49、1.98、2.01 等值。我的基因算法永远无法产生这些基因,因为基因在[-1, 1] 内初始化,交叉和突变也不能产生超出该范围的基因。

看来我需要更好地定义搜索空间,像这样:

# search space boundaries
S_MIN = -1.00
S_MAX = 1.00

# in mutation()
gene = random.uniform(S_MIN, S_MAX)

# in make_chromosome()
chromosome.append(random.uniform(S_MIN, S_MAX))

然后我可以根据问题设置搜索空间边界。但是如何确定搜索空间?此信息不是先验已知的,而是通过训练网络找到的。但是如果训练需要知道搜索空间,那我就停滞不前了。

我可以将搜索空间设置为任意大(例如,肯定比必要的大),但是算法收敛速度很慢。我至少需要知道搜索空间的大致数字才能使遗传算法有效。

通过反向传播,搜索空间是先验未知的,这并不重要,但对于 GA 来说是这样。

【问题讨论】:

  • 也许你应该考虑一个不同的变异算子?一个不使用任何边界的?例如。 gene = random.gauss(mu=gene, sigma=scale)(+ 可能随着时间的推移而衰减 scale)。无论如何,如果您对数据进行规范化,您可以期望权重处于同一数量级,即(-10, 10) 应该足以作为界限。
  • @a_guest 你能详细说明数据规范化吗?最优网络权重与数据属性大小之间是否存在关系?
  • 例如归一化为零均值和单位方差。根据您的网络架构,预计权重不会有太大差异,但也不能保证。您可以从一些边界值开始,如果您没有达到所需的精度,您仍然可以扩大边界。无论如何,神经网络通常使用基于梯度的优化器进行拟合是有原因的。
  • @a_guest 您的信息可以很好地作为答案,而不仅仅是评论。我发现在染色体平均值周围使用正态分布的突变似乎效果很好,在对数据进行归一化后更是如此。对于我尝试过的集合,网络权重几乎总是在[-3, 3] 左右结束,但对于更深的网络而言并非如此。我已经为更权威的答案添加了赏金,但我想为你的答案投票,因为它确实有帮助。
  • gator 当您开始通过损失更新采样分布的mu 和sigma 时,您也正在接近bayesian neural networks的想法

标签: python machine-learning neural-network genetic-algorithm mutation


【解决方案1】:

这似乎是对神经网络强化学习的核心挑战的重述。您有一个损失函数,可以数值量化解决方案空间的当前局部中可能的操作有多好,这样当采取操作时,您会更接近/远离全局最优值(答案)。 {IE。梯度w.r.t.损失函数}

在开始之前,您无法知道答案的确切位置,因此您有一个探索策略,您将其定义为算法的一部分。这推动了对可能的解决方案空间的探索,其指导是某些动作在接近损失函数定义的答案方面有多大改进。

一开始探索非常激进,并且采取大胆的行动,以便快速探索解决方案空间。然后,随着解决方案空间的区域越来越有希望,探索变得不那么大胆,试图收敛到解决方案上。

在您的情况下,探索策略会改变染色体的突变大小、突变率和交叉。突变大小和速率将代表局部内的移动大小,交叉将代表解空间中的维度转置。

因此,您将在解决方案空间中拥有一个起始位置,并假设统一缩放和归一化的解决方案空间特征,而不是具有最大值/最小值,最佳猜测将是单位空间中的任何随机点。

然后,探索策略将选择突变大小、速率和交叉,以便最初积极地进行广泛探索。后代的选择会更喜欢那些更接近答案且探索策略不那么激进的人。因此,后几代人往往会更接近“答案”,而且探索策略也不那么激进,因此会趋于收敛。

本文对这些概念进行了更正式的回顾。

https://towardsdatascience.com/reinforcement-learning-demystified-exploration-vs-exploitation-in-multi-armed-bandit-setting-be950d2ee9f6

【讨论】:

    【解决方案2】:

    这是一个故事。曾经有一个演示文稿,可能是this 论文,介绍了用于配置室内飞行的输入、输出和架构的遗传算法。也就是说,它将愚蠢的传感器连接到那些漂浮的室内飞艇上,让它们探索房间,同时优化直线和水平飞行。

    这种情况下的“基因”是:

    • 从对标准成像处理过滤器(垂直边缘检测、低对比度、线条检测等)的响应列表中选择两个或三个输入值
    • 从每个引擎的标准电压配置文件列表中选择两个输出连接(硬斜坡/慢斜坡/立即到 0%、50%、100%、-50%、-100% 等)
    • 在两级神经网络中选择节点之间的连接,每层只有五个节点。例如,“输入 2 连接到第 1 层中的节点 3”。只允许一小部分(30%?)的连接。

    因此,一个 DNA 由两个输入节点、五十个连接和两个输出节点组成。一个种群从一百个随机 DNA 选择开始,运行训练所选神经网络的飞艇,计算水平飞行时间并进行繁殖。通过品种,我的意思是它杀死了得分最低的一半并创造了获胜者的变异副本。成功了。

    现在,关于你的问题。

    您需要非常清楚什么是您的基因。一些不错的选择可能是:

    • 网络架构,如上图所示
    • 用于淘汰赛、学习率、重启、损失函数等的超参数。
    • 初始权重分布,实际上更多参数,包括一些用于添加偶尔野生权重的参数。
    • Wild 踢到一个或另一个参数,这意味着选择一个或两个轴以使用 Wild 值或细粒度精度进行搜索。

    还要记住,突变和杂交是不同的。有时你应该允许野生突变。繁殖约 70%(复制,交换一些基因)和突变约 30%(复制幸存者并进行随机更改)的常见策略。

    正如通常的快速建议一样,我猜你的描述中没有说什么。如果我完全不理解你在做什么,那就假装它在基础上;你是 可能是解决您问题的人。

    【讨论】:

    • 这似乎更多是关于优化拓扑和超参数选择,而不是使用 GA 来训练网络。您链接的论文确实提供了一些关于平衡探索和利用的想法,这完全是我所追求的,但是,因为我发现定义探索和利用策略是使用 GA 优化网络权重以进行训练的最大障碍。
    【解决方案3】:

    根据@a_guest 的评论,我发现使用突变算子的性能最佳,该算子会扰乱正态分布周围的基因。我做了三个测试:

    • 扰动基因在[-1.00, 1.00] 内随机均匀
    • 在染色体中所有基因的平均值附近的正态分布内扰动基因
    • 在被突变基因周围的正态分布内扰乱基因

    我已将测试标记为 #1、#2、#3。这是在使用 ReLU 激活函数的 4-3-3 网络中使用 Iris 数据集。每次测试运行一次并不重要,因为它可能是幸运的,也可能是不幸的,因此该图使用了 50 次运行样本中 30 次最佳运行之间的平均值。

    您可以看到 BP-NN 提供了一个很好的基准来进行比较。

    我的统一随机变异算子几乎立即陷入局部最小值,因为没有探索搜索空间(因为基因永远不能在[-1, 1] 之外,即我开始这个问题的天真方法)。

    染色体平均值周围的高斯算子运行良好,在第 32 个时期达到了 MSE

    我认为围绕基因平均值进行突变比围绕突变基因进行突变更有意义,因为如果您考虑一个基因要突变两次(两代一次),那么探索就更少了。单个基因发生突变不会对基因平均值产生太大影响,如果一个基因发生第二次突变,则没有太多额外的探索。

    如果你有一个基因平均值0.00,一个基因是0.00,在极端情况下突变为2.00,那么基因平均值可能只有很小的变化(例如0.10)。下次发生突变时,该基因可能是2.00,但平均值与0.00 相差不远。也许第二个突变会将基因扰乱到最末端的2.05。在特定基因周围使用高斯算子可能会看到它在最末端变为4.00。

    我认为带有mu = mutating gene 和sigma = decreasing as MSE decreases 的高斯变异算子是最好的方法。我试过sigma = 0.7 + MSE 似乎工作得很好,至少对于这个数据集,因为最大 MSE 大约是 0.7。当 MSE 接近 0 时,探索性因素会缩小,这意味着早期的探索更多,之后的局部开发更多。这也意味着我不需要定义甚至知道搜索量。

    【讨论】:

      猜你喜欢
      • 2018-05-11
      • 2020-08-19
      • 2010-10-24
      • 2011-01-06
      • 2015-12-14
      • 2019-04-15
      • 2011-07-04
      • 2011-06-30
      • 2019-04-02
      相关资源
      最近更新 更多