入力と出力の構成可能な数と動的な動作を備えたフィードフォワードニューラルネットワークをどのように実装しますか?
作業中のゲームのエンティティにニューラルネットワークを追加しようとしています。ただし、追加するエンティティタイプごとに、入力と出力の数が異なる新しいニューラルネットワークを作成し、入力の設定方法と出力を使用して動作を指示する方法をハードコーディングする必要があります。
これらすべてを動的に設定する方法を見つけたいので、エンティティタイプごとに新しいニューラルネットを書き直す必要はありません。
私はC++を使用しているので、現在、入力コンテナーと出力コンテナーとしてdoubleのベクトルがあります。現在、私のNNアルゴリズムは、レイヤー内のすべての要素(入力「レイヤー」を含む)を反復処理し、情報を次のレイヤーに渡します。これは今のところうまくいくと思います(ただし、提案は受け付けています)。しかし、私の本当の問題は、入力/出力の数、またはエンティティが持つことができる感覚/動作のタイプを制限することなく、エンティティのタイプごとに異なる動作をどのように行うかです。
例として、他のクリーチャーを見て、食べ物の匂いを嗅ぎ、攻撃として噛み、地面に沿って移動できるクリーチャーをゲームに追加したいとします。それぞれの目は、匂いの感覚とともに入力になります。噛むことは、xとyの動きとともに出力になります。入力値を計算し、ニューラルネットの出力値から意味を抽出する方法が必要です。
ここで、他の生き物の匂いを嗅ぎ、それ自体からの方向を特定し、棘を撃ち、空中に浮かぶことができる生き物も追加したい場合は、異なる数の入力と出力の計算が必要になります(入力:匂い、場所、出力:シュート、x、y、zの動き)。
各エンティティタイプに独自のニューラルネット構造を持たせながら、AIシステムが個々のネットワークを処理および反復するときに機能する全体的な標準インターフェイスを持たせたいと思います。より具体的には、ゲーム感覚から入力への変換、および出力からゲーム動作への変換を処理する場合。
追加したクリーチャーからの創発的な振る舞いが欲しいので、「正しい」出力がどうなるかわかりません。このため、私は単純な遺伝的アルゴリズムを使用して体重の進化を制御しています。
私は自分の問題に関する多くの情報を見つけることができなかったので、これまでに思いついた唯一のアイデアは、各エンティティの感覚と動作を関数ポインターのベクトルとして実装することです。各関数は特定の入力に対応します。出力。これにより、各エンティティの動作をカスタマイズし、AI用の単一のシステムを維持できますが、これが私が望むことを達成するための最も効率的な方法であるかどうかはわかりません。
プロセス関数は、LearningSystemクラスのすべての作業を実行します。
void LearningSystem::process(int const last_frame_time) {
std::set<unsigned int> const& learning_list = eManager->getAllEntitiesPossessingComponent(ComponentType::intelligence);
vector<double> outputs, inputs;
for (auto entity : learning_list) {
Intelligence& intel = eManager->getComponent<Intelligence>(entity, ComponentType::intelligence);
Sensors& sensor = eManager->getComponent<Sensors>(entity, ComponentType::sensors);
Behavior& behavior = eManager->getComponent<Behavior>(entity, ComponentType::behavior);
// calculate each input value
for (unsigned int i = 0; i < sensor.sensor_list.size(); ++i) {
sensor.triggers[i](sensor.sensor_list[i]);
}
// retrieve the inputs from the sensors...
inputs = sensor.sensor_list;
// ...and add the bias
inputs.push_back(bias);
// for each layer
for (auto i : intel.vecLayers) {
// clear the internal outputs
outputs.clear();
// for each neuron
for (auto j : i.vecNeurons) {
// reset the neuron value
double neuronValue = 0.0;
// for each weight/input pair, sum the weights * inputs
for (auto k = j.vecWeights.begin(), in = inputs.begin(); k != j.vecWeights.end(); ++k, ++in) {
neuronValue += (*k) * (*in);
}
// store the internal outputs for use by the next layer
outputs.push_back(sigmoid(neuronValue));
}
// assign the inputs for the next layer...
inputs = outputs;
// ...and add the bias
inputs.push_back(bias);
}
behavior.values = outputs;
// calculate actions based on output values
for (unsigned int i = 0; i < behavior.values.size(); ++i) {
behavior.actions[i](behavior.values[i]);
}
}
}
このアイデアを実装する他の方法について、そしてこの種の問題に対処するリソースがあるかどうかについて興味があります。どんな助けでも大歓迎です。