如何实现具有可配置数量和输入输出动态行为的前馈神经网络?
我正在尝试将神经网络添加到我正在开发的游戏中的实体中。然而,对于我添加的每个实体类型,我必须创建一个具有不同数量的输入和输出的新神经网络,然后硬编码如何设置输入以及如何使用输出来指导行为。
我希望找到一种动态设置所有这些的方法,这样我就不必为每个实体类型重写新的神经网络。
因为我使用的是C++,所以我目前有一个双精度向量作为输入和输出容器。目前,我的神经网络算法遍历一层中的每个元素(包括输入的“层”),并将信息传递到下一层,我相信现在这将很好地工作(尽管我对建议持开放态度)。然而,我真正的问题是如何在不限制输入/输出数量或允许实体拥有的感觉/行为类型的情况下,为每种类型的实体提供不同的行为。
举个例子,假设我想要在游戏中添加一个生物,它可以看到其他生物,闻到食物,咬人作为攻击,并沿着地面移动。每只眼睛都是输入,还有嗅觉;咬人是输出,还有x和y的运动。我需要一种方法来计算输入值,并从神经网络的输出值中提取含义。
现在,如果我还想添加一个可以闻到其他生物的气味,从它自己定位它们的方向,拍摄脊椎,并在空中漂浮的生物,我将需要不同数量的输入和输出计算(输入:嗅觉,位置;输出:拍摄,x,y,z移动)。
我希望每种实体类型都有自己的神经网络结构,但在处理和迭代每个单独的网络时,又有一个供AI系统使用的整体标准接口。更具体地说,当处理游戏感官到输入的转换,以及输出到游戏行为的转换时。
我想要我添加的生物的紧急行为,所以我不知道什么是“正确”的输出。正因为如此,我使用一个简单的遗传算法来控制权重的进化。
由于我还没有找到关于我的问题的太多信息,到目前为止,我想出的唯一想法是将每个实体的感觉和行为实现为函数指针的向量,每个函数对应于特定的输入或输出。虽然这允许我定制每个实体的工作方式,并为AI保留单个系统,但我不确定这是否是实现我想要的最有效的方式。
process函数执行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]);
}
}
}
我很好奇实现这一想法的其他方式,以及是否有任何资源来解决这类问题。任何帮助都将不胜感激。
发布于 2012-06-08 21:42:35
我很久以前就写过这样的东西,不幸的是我没有源代码,但我记得我将网络的结构定义为一个数组,该数组被传递给一个将创建网络的函数。数组的每个元素都是一个整数,它描述了网络层中神经元的数量,因此2,3,2将创建一个具有2个输入神经元,3个在隐藏层和2个输出神经元的神经网络。突触是通过连接相邻层中的每个神经元而自动创建的。它非常简单,所以从输入/输出层设置/获取值是通过如下所示的函数调用完成的
double getValue(int layer, int neuron);
对不起,这有点含糊,但这是我能记住的全部。
https://stackoverflow.com/questions/10927171
复制相似问题