NEAT (増強トポロジーの神経進化) を実装しようとしています。
「遺伝子」と呼ばれるネットワーク接続のリストがあります。ニューロン 1 とニューロン 2 の間の接続は、gene.from = ニューロン 1、gene.to = ニューロン 2 になります。
私の仕事は、これらの遺伝子からニューラル ネットワークを生成することです (ニューラル ネットワークは単にインデックスからニューロンへのマップであり、gene.from とgene.to はマップ内のニューロンへのキーです)。
入力ノードがnumPossibleInputs
あるので、最初にそれらを追加します (0-numPossibleInputs-1 は入力ニューロンです)。
出力ノードがnumOutputs
あるので、それらも追加します。
次に、「to」接続インデックスに基づいて遺伝子を並べ替えます。
最後に、遺伝子に基づいて隠れ層ニューロンを作成します... ニューラル ネットワークはマップであるため、接続の to または from が既にニューロンであるかどうかを確認し、そうでない場合は新しいニューロンを作成します。このアルゴリズムはネットワークを問題なく作成します。
public void generateNetwork()
{
neuralNetwork.clear();
for(int i = 0; i < numPossibleInputs; i++)
{
neuralNetwork.put(i, new Neuron());
}
for(int i = 0; i < numOutputs; i++)
{
neuralNetwork.put(i+numPossibleInputs+numPossibleHidden, new Neuron());
}
genes.sort((ConnectionGene g1, ConnectionGene g2)-> Integer.compare(g1.toNeuronIndex, g2.toNeuronIndex));
for(ConnectionGene gene : getCleanGenes(genes))
{
if(gene.enabled)
{
if(!neuralNetwork.containsKey(gene.toNeuronIndex))
{
neuralNetwork.put(gene.toNeuronIndex, new Neuron());
}
neuralNetwork.get(gene.toNeuronIndex).incomingConnections.add(gene); // Add this gene to the incoming of the above neuron
if(!neuralNetwork.containsKey(gene.fromNeuronIndex))
{
neuralNetwork.put(gene.fromNeuronIndex, new Neuron());
}
}
}
}
問題は、進化アルゴリズムが一部の遺伝子を「オフ」にしたときに発生します ( に注意してくださいgene.enabled
)。たとえば、次の遺伝子を考えてみましょう (他にもありますが、無効になっています)。
2->4
4->4
13->4
0->13
1->13
5->13
また、2->5 および 4->13 の無効化された遺伝子もあります。これらは表現されていないため、ネットワークでは使用できません。(これが、世代ごとに新しいネットワークを生成する必要がある理由です。遺伝子を追加、有効化、無効化することができます)。
これは 用numPossibleInputs ==3
なので、0 1 と 2 は入力です (2 はバイアス)。5 > 3 であるため、5 は非表示層ノードですが、10 + 3 = 13 未満です。13 は出力ノードですnumPossibleHidden == 10
。10 + 3 = 13 でした。次のようにイメージできます: [input input input hidden*10 output*1] 3 つの入力、10 の非表示、および 1 つの出力の場合
これは単純に生成されたネットワークの写真です: Simple Network
ご覧のように、削減されたネットワークには 4 または 5 はまったくないはずです。これらはどの出力にも影響を与えないためです (この場合は 1 つの出力、13 のみ)。削減されたニューラル ネットワークは、0->13 および 1->13 になります。
私はこれを解決する方法についていくつかの最初の考えを持っていました:
A. 1. 各接続をループし、gene.from ID をハッシュします。これらは、何か他のものへの入力であるニューロン ID です。ハッシュ)。3. 何も削除されなくなるまで繰り返します
B. 単純なネットワークを生成します...次に、各出力からネットワーク内を逆方向にクロールし、それ以上進むことができなくなります (繰り返しのサイクルに注意してください)。見つけた各ノードをハッシュします。グラフ検索が完了したら、見つかったノードのハッシュを、遺伝子リストで表されたノードの合計と比較します。見つかったノードのハッシュでニューロンを持つ遺伝子のみを使用し、ネットワークを作り直します。
ネットワーク表現に基づいて、これを行うための最良のアルゴリズムについてフィードバックを得たいと思っていました-BはAよりも優れていると思いますが、私が関与しないよりエレガントなソリューションがあることを望んでいましたグラフ トポロジを解析しています。おそらく、接続をソートすることで何か賢いことができるでしょうか(by to、from)?
ありがとう!