先日,EvoTorchという進化計算ライブラリが公開されました(HP, Docs, GitHub, PyPI).名前ですぐに気が付くかもしれませんが,Pythonのオープンソース機械学習ライブラリPyTorchと密接に関係があります.
EvoTorchは,PyTorchと同じPythonのオープンソースライブラリで,PyTorchの上に直接構築されています.この記事は,リリース直後でほぼ英語しか情報が出てこない,EvoTorchを触ってみた雑感を書いていきます.

資料,例題が複数用意してあって良い

自分が見た限り,以下の7つの例題が公開されています.

また,Jupyter Notebookで実行可能な5つの例題が公開されています.それぞれの例題に説明があり,簡単にプログラムを動かせる点,参考文献が明記されている点,READMEやドキュメントが整備されている点が良いと感じました.

アルゴリズムは少し物足りない

このページにアルゴリズムが載っているのですが,少し物足りない感じです.現時点では,最初のリリースということで,利用可能なアルゴリズムを必要最小限に絞ったようです.SteadyStateGA,NES,CMA-ESが最初から含まれている点は素晴らしいです.今後は,DEやMOEA/Dなどのアルゴリズムが実装されていくことを期待したいです.

一通り触った感想

進化計算が良く分からなくてもプログラムを試すことができる点,強化学習と同じように進化計算が利用できる点,問題とその解決アルゴリズムがきっちり分離されている点が素晴らしいと感じました.

例題は,こちらの映像付きのプログラムが一番良かったと思います.ただ,手元ではCUIのみが動いてプログラムが終了してしまう点が残念でした.GUIが起動して,映像と同じものが手元でも描画できると,より素晴らしいものになると感じました.

問題がSphere関数Kursawe関数の時は,プログラムが高速で動いてくれるのですが,問題がMNISTなど機械学習系の時は,プログラムが低速で困りました.Googleの論文では10K世代,例題だと2000世代でプログラムを動かす設定があるのですが,遅すぎて,大きな世代で実行するのは実用的で無いと思いました.機械学習に取り組むには,最新で高性能なPCが無いと厳しいと感じました.

多目的最適化の可視化に挑戦

Multiple Objectivesの例題を利用して,解集合の分布を可視化しました.コードは以下になります.

import numpy as np
import matplotlib.pyplot as plt

#------------------------------------------------
# Multiple Objectivesの全47行のコードを貼り付け
# 1  import torch
#    ...
# 47 ga.run(100)
#------------------------------------------------

# 変数空間のプロット
def xplot(x: np.ndarray):
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')

    ax.scatter(x[:, 0], x[:, 1], x[:, 2])

    ax.set_xlabel("x1")
    ax.set_ylabel("x2")
    ax.set_zlabel("x3")

    plt.savefig("data.png")
    plt.close()

# 目的空間のプロット
def fplot(x: np.ndarray):
    plt.gca().set_aspect(2/3)
    plt.grid(True)

    plt.scatter(x[:, 0], x[:, 1], s=10, c='r')

    plt.xlim(-21, -11)
    plt.ylim(-13, 2)
    plt.xticks(np.arange(-21, -11, 2)) 
    plt.yticks(np.arange(-13, 2, 3))
    plt.xlabel("f1")
    plt.ylabel("f2")

    plt.savefig("evdata.png")
    plt.close()

# ga.run(100)後の可視化処理
xplot(ga.population._data.numpy())
fplot(ga.population._evdata.numpy())

解集合の設計変数ベクトル集合はga.population._data,解集合の目的関数値ベクトル集合はga.population._evdataで取り出すことができます.これらはtorch.Tensor型ですが,容易にnumpyのndarray型に変換する事ができます.
毎世代,解に何かしらの処理をしたい場合,StdOutLoggerに変わる新しい関数を自作するのがベストだと思います.解の値を少し確認するだけなら,情報をndarray型のデータとして取りだせれば十分だと思います.

1世代目,10世代目,100世代目の解集合の分布は,以下になります.

1世代目の変数空間
10世代目の変数空間
100世代目の変数空間
1世代目の目的空間
10世代目の目的空間
100世代目の目的空間

1世代目は,200個の解が3次元の変数空間にランダムに分布しています.目的空間の解は,f1もf2も値が大きく,良くありません.10世代目は,解が変数空間の一部に偏って分布しています.目的空間の解は,f1とf2の最小値のトレードオフ関係を粗く近似する形で分布しています.100世代目は,解が変数空間上でも,幾つかの直線に並び始めています.目的空間では,解集合が2つの目的間のトレードオフ関係を高精度に近似できています.

まとめ

オープンソースの進化計算ライブラリEvoTorchを紹介しました.
Python,機械学習分野の初心者なので,あまり難しいことに挑戦できませんでしたが,画像を出力することができて満足しています.Python,機械学習は人口が多く,発展が著しい分野です.それらを得意とする方々がEvoTorchから,(そしてこの記事から,)進化計算に少しでも興味を持って頂ければ嬉しく思います.