绘制重要数据:可视化CMA策略

通过这个例子,我们展示了一种绘制进化数据的技术。作为DEAP的开发者,我们无法决定哪些数据对绘图是重要的,这部分留给了用户。尽管如此,绘图的过程都是一样的。首先,数据在进化过程中被收集,最后从数据中创建图形。这个模型是最简单的可能。也可以将所有数据写入文件,然后再次读取这些文件来绘制图形。后一种模型更具容错性,因为如果进化没有正常终止,图形仍然可以被绘制。但是,我们希望保持这个例子尽可能简单,因此我们将展示前一种模型。

进化循环

这个示例的开头与 CMA-ES 示例完全相同。函数 eaGenerateUpdate() 的通用进化循环对于我们的目的来说有些不足。我们需要在每一代收集所需的数据。因此,我们将开发它以了解记录的内容,而不是使用 eaGenerateUpdate() 函数。首先,我们将创建对象来记录我们的数据。在这里,除了 LogbookHallOfFame 对象包含的内容外,我们还希望绘制协方差矩阵的步长、轴比和主轴、迄今为止的最佳值、迄今为止的最佳坐标以及每一代所有坐标的标准偏差。

    sigma = numpy.ndarray((NGEN,1))
    axis_ratio = numpy.ndarray((NGEN,1))
    diagD = numpy.ndarray((NGEN,N))
    fbest = numpy.ndarray((NGEN,1))
    best = numpy.ndarray((NGEN,N))
    std = numpy.ndarray((NGEN,N))

一旦对象被创建,基于世代停止标准的进化循环会反复调用工具箱中注册的 generate()evaluate()update() 方法。

    for gen in range(NGEN):
        # Generate a new population
        population = toolbox.generate()
        # Evaluate the individuals
        fitnesses = toolbox.map(toolbox.evaluate, population)
        for ind, fit in zip(population, fitnesses):
            ind.fitness.values = fit

        # Update the strategy with the evaluated individuals
        toolbox.update(population)

然后,先前创建的对象开始发挥它们的作用。数据在每次生成时记录在每个对象中。

        sigma[gen] = strategy.sigma
        axis_ratio[gen] = max(strategy.diagD)**2/min(strategy.diagD)**2
        diagD[gen, :N] = strategy.diagD**2
        fbest[gen] = halloffame[0].fitness.values
        best[gen, :N] = halloffame[0]
        std[gen, :N] = numpy.std(population, axis=0)

现在数据已经记录下来,剩下的唯一事情就是绘制它。我们将使用 matplotlib 从记录的数据中生成图形。

    # The x-axis will be the number of evaluations
    x = list(range(0, strategy.lambda_ * NGEN, strategy.lambda_))
    avg, max_, min_ = logbook.select("avg", "max", "min")
    plt.figure()
    plt.subplot(2, 2, 1)
    plt.semilogy(x, avg, "--b")
    plt.semilogy(x, max_, "--b")
    plt.semilogy(x, min_, "-b")
    plt.semilogy(x, fbest, "-c")
    plt.semilogy(x, sigma, "-g")
    plt.semilogy(x, axis_ratio, "-r")
    plt.grid(True)
    plt.title("blue: f-values, green: sigma, red: axis ratio")

    plt.subplot(2, 2, 2)
    plt.plot(x, best)
    plt.grid(True)
    plt.title("Object Variables")

    plt.subplot(2, 2, 3)
    plt.semilogy(x, diagD)
    plt.grid(True)
    plt.title("Scaling (All Main Axes)")

    plt.subplot(2, 2, 4)
    plt.semilogy(x, std)
    plt.grid(True)
    plt.title("Standard Deviations in All Coordinates")

    plt.show()

这将产生以下结果。

完整的示例 : examples/es/cma_plotting