【问题标题】:In Python's DEAP, how can I have an individual with multiple genes, eg a "Genotype"?在 Python 的 DEAP 中,我怎样才能拥有一个具有多个基因的个体,例如“基因型”?
【发布时间】:2018-08-17 09:59:07
【问题描述】:

TLDR:

我如何使用DEAP 来进化基因型 而不仅仅是基因,例如(Gene1, Gene2, ...){'gene1':..., 'gene2':...}

一个最小的示例是创建 DEAP 的 OneMax 示例的演变,使用 (np.ndarray(10), np.ndarray(42)) 的基因型,其中 Genotype[0] 仅与 Genotype[0]...[1]...[1] 配对,以及整个基因型可用于评估适应度。


在 Python 的 DEAP 中,常见的用例是拥有一个“基因”,例如一个可以配对、变异和评估适合度的“基因”。

我的一般问题是,我想使用基因的异构列表/元组/字典,每个都有自己的类型,并且交配等功能仅按类型定义。

具体来说,我有一个“神经网络”,我想用

来表示
  1. 神经元参数的一个基因

  2. 和一个用于网络结构+参数的基因。

类型(借用类型语言的语法)可能是

NeuronGene  :: np.ndarray(n)
NetworkGene :: np.ndarray((n, n))

这些数组是structured numpy arrays,带有各种键,例如:np.dtype([('a', int), ('b', float), ...]),所以在NeuronGene 中的每个索引处,我都有一个带有键{'a':..., 'b':..., ...} 的类字典参数。如果这使问题过于复杂,我仍然很想看看如何拥有通用np.ndarrays 的基因型。

“基因型”可能类似于Individual :: (NeuronGene, NetworkGene),并且

适当的mate 函数可能定义如下:

mate :: NeuronGene  -> NeuronGene  -> NeuronGene
mate :: NetworkGene -> NetworkGene -> NetworkGene

作为一个最小的例子,我尝试复制 DEAP 的 OneMax 问题,但使用 2 个基因的基因型。所以 2 个不同大小的np.ndarrays,每个都试图单独最大化它们的总和。即使阅读 DEAP's docscodebase,我的代码也不值得发布。

对于像这个最小示例这样的简单问题,当然可以使用长度为 n + m 的一个基因,但在我的实际情况中,我有一个基因是 (1D array, 2D array),并且突变/交配对每个单独的基因意味着不同的东西在那个基因型中。

我应该提到我的eval 函数只是解析为一个单一的适应度函数,尽管我认为一个适当的一般答案可以优化多个。

eval :: Genotype -> Float
# or
eval :: Genotype -> (Float, Float, ...)

【问题讨论】:

    标签: python numpy genetic-algorithm evolutionary-algorithm deap


    【解决方案1】:

    我不确定我是否完全理解您的需求,但这可能会有所帮助:

    1) 使用 dict 作为单独的容器,自定义 initDict 函数

    2) 编写您的自定义 dict 版本的交配和个体评估函数,对个体的不同键执行不同的操作

    下面是一个创建类似dict的随机数组个体并评估它们的示例。然后,您可以修改用于交配、突变等的 DEAP 基本算法,以便它们可以按照您想要的方式使用 dicts。

    from deap import base
    from deap import creator
    from deap import tools
    import numpy as np
    
    def initDict(container, func, dim):
        return container(zip(dim.keys(), map(lambda val: func(val), dim.values())))
    
    def evalIndividual(individual):
        return [individual[key].sum() for key in individual.keys()]
    
    toolbox = base.Toolbox()
    creator.create("FitnessMax", base.Fitness, weights=(1.0,1.0))  # fitness
    creator.create("Individual", dict, fitness=creator.FitnessMax)
    
    #function for generation arrays of random values and random size in each dimension (min 2, max 10) but fixed number of dimensions by the dim argument
    toolbox.register("attr_random", lambda dim: np.random.rand(*np.random.randint(2,10,dim)))
    toolbox.register("individual", initDict, creator.Individual, toolbox.attr_random, dim = dict(neuron = 2, network = 3))
    ind = toolbox.individual()
    ind.fitness.values = evalIndividual(ind)
    print(ind.fitness)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多