私は次のような突然変異演算子を使用して、遺伝的アルゴリズムで訓練されたニューラルネットワークを実装しました。
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の場合はわかります。
@a_guestのコメントに従って、正規分布の周りの遺伝子を摂動させる突然変異演算子を使用して、最高のパフォーマンスを見つけました。私は3つのテストを行いました:
[-1.00, 1.00]
内でランダムに均一な摂動遺伝子テストに#1、#2、#3というラベルを付けました。これは、ReLUアクティベーション機能を使用して、4-3-3ネットワークでIrisデータセットを使用しています。テストごとに1回の実行は、幸運または不運の可能性があるため、重要ではありません。したがって、このプロットは、50の実行のサンプルからの30の最良の実行間の平均を使用しています。
BP-NNが比較するための適切なベースラインを示していることがわかります。
遺伝子が[-1, 1]
の外に出ることは決してないため(つまり、私がこの質問を始めた私の単純なアプローチであるため)、私のランダムな突然変異演算子は、ほぼ即座に極小値に閉じ込められます。
染色体平均の周りのガウス演算子はうまく機能し、32番目のエポックでMSE <= 0.1に達します(50番目のエポックでバックプロップを比較してください)。突然変異している遺伝子の周りのガウス演算子もうまく機能し、26番目のエポックで同じMSEしきい値に達します。
遺伝子が2回(2世代に1回)変異すると考えた場合、調査が少なくなるため、遺伝子平均を中心に変異を行うことは、変異遺伝子を中心に変異を行うことよりも少し意味が少ないと思います。変異している単一の遺伝子は、遺伝子の平均をあまり変えません、そして、遺伝子が二度目に変異されたとしたら、それほど追加された調査はありません。
遺伝子平均が0.00
であり、遺伝子が0.00
であり、極端に2.00
に変異した場合、遺伝子平均はわずかな量しか変化しなかった可能性があります(例:0.10
)。次に突然変異が発生したとき、遺伝子は2.00
である可能性がありますが、平均は0.00
からそれほど離れていません。たぶん、2番目の突然変異は、遺伝子を極端に2.05
に混乱させるでしょう。代わりに、特定の遺伝子の周りにガウス演算子を使用すると、極端に4.00
に変わる場合があります。
mu = mutating gene
およびsigma = decreasing as MSE decreases
を使用したガウス突然変異演算子が最良のアプローチだと思います。私が試したsigma = 0.7 + MSE
は、最大MSEが約0.7であるため、少なくともこのデータセットではうまく機能するようです。 MSEが0に近づくにつれ、探索的要因は減少します。つまり、早期に探索が多くなり、後で局所的に利用されるようになります。これは、検索ボリュームを定義したり、知ったりする必要さえないことも意味します。