From 5b55d13ead7e352ee1feaae72009e8abf5bd071a Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 21 Sep 2007 15:36:22 +0000 Subject: [FIX] Neural Network methods complete [FIX] Wrapped Node up into the layer [FIX] Wrapped NatureEffect into Nature [FIX] Getting around to fixing up the design of the PokéMod stuff [FIX] Creating new subclasses now returns pointer to new subclass [FIX] Simplified interfaces [FIX] Minor style issues [FIX] Renamed CoinItem to CoinListObject [FIX] Renamed MapTrainerTeam to MapTrainerPokemon [FIX] Renamed MapWildPokemon to MapWildListPokemon [FIX] Moved global enums to relevant classes [FIX] Removed general logging features [DEL] pokemod/Debug.{h, cpp} [DEL] pokemod/Path.{h, cpp} [FIX] Using QFile rather than custom Path class for checking for files [FIX] Set* methods now return a bool to let the caller know if anything actually changed (if it can fail, otherwise it is void) [ADD] Compliation without errors is required for pokemod from now on before commits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://pokegen.svn.sourceforge.net/svnroot/pokegen/trunk@24 6ecfd1a5-f3ed-3746-8530-beee90d26b22 --- ai/Net.cpp | 446 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 290 insertions(+), 156 deletions(-) (limited to 'ai/Net.cpp') diff --git a/ai/Net.cpp b/ai/Net.cpp index b23a09bf..cd72fd6b 100644 --- a/ai/Net.cpp +++ b/ai/Net.cpp @@ -1,156 +1,290 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: ai/Net.cpp -// Purpose: An artificial neural network class -// Author: Ben Boeckel -// Modified by: Ben Boeckel -// Created: Fri May 4 19:56:27 2007 -// Copyright: ©2007 Nerdy Productions -// Licence: -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program. If not, see . -///////////////////////////////////////////////////////////////////////////// - -#include "Net.h" - -PokeGen::NeuralNetwork::Net::Net(const QList &nodes) -{ - for (unsigned i = 0; i < nodes.size(); ++i) - AddLayer(i, nodes[i]); -} - -PokeGen::NeuralNetwork::Net::Net(const QString &fname) -{ - QFile fin(fname); - fin.open(); - -} - -void SaveData(const char *fname) const -{ - -} - -void LoadData(const char *fname) -{ - -} - -void AddLayer(const unsigned place, const unsigned numNodes) -{ - -} - -void DeleteLayer(const unsigned place) -{ - -} - -void MoveLayer(const unsigned oldPlace, const unsigned newPlace) -{ - -} - -void FeedForward() -{ - -} - -void BackPropagate() -{ - -} - -void CalculateError() -{ - -} - -unsigned GetChoice() const -{ - -} - -unsigned GetNumNodes(const unsigned layer) const -{ - -} - -void SetInput(const unsigned n, const double i) -{ - -} - -void SetDesiredOutput(const unsigned n, const double o) -{ - -} - -void SetMomentum(const unsigned layer, const unsigned n, const double m) -{ - -} - -void SetMomentumFactor(const unsigned layer, const unsigned n, const double m) -{ - -} - -void SetLearnRate(const unsigned layer, const unsigned n, const double l) -{ - -} - -void SetFunction(const unsigned layer, const unsigned n, const unsigned f) -{ - -} - -double GetOutput(const unsigned n) -{ - -} - -double GetError(const unsigned layer, const unsigned n) -{ - -} - -double GetMomentum(const unsigned layer, const unsigned n) -{ - -} - -double GetMomentumFactor(const unsigned layer, const unsigned n) -{ - -} - -double GetLearnRate(const unsigned layer, const unsigned n) -{ - -} - -unsigned GetFunction(const unsigned layer, const unsigned n) -{ - -} - -double GetWeight(const unsigned layer, const unsigned n, const unsigned i) -{ - -} - -double GetBias(const unsigned layer, const unsigned n) -{ - -} +///////////////////////////////////////////////////////////////////////////// +// Name: ai/Net.cpp +// Purpose: An artificial neural network class +// Author: Ben Boeckel +// Modified by: Ben Boeckel +// Created: Fri May 4 19:56:27 2007 +// Copyright: ©2007 Nerdy Productions +// Licence: +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see . +///////////////////////////////////////////////////////////////////////////// + +#include "Net.h" + +PokeGen::NeuralNetwork::Net::Net(const QList& nodes) +{ + for (int i = 0; i < nodes.size(); ++i) + AddLayer(i, nodes[i]); +} + +void PokeGen::NeuralNetwork::Net::SaveData(const QString& fname) const +{ + Ini nnData("NeuralNet"); + nnData.AddField("numLayers", GetNumLayers()); + for (unsigned i = 0; i < GetNumLayers(); ++i) + layers[i].SaveData(nnData, i); + nnData.Export(fname); +} + +PokeGen::NeuralNetwork::Net* PokeGen::NeuralNetwork::Net::LoadData(const QString& fname) +{ + Ini t; + + + Net* temp = new Net; + QFile fin(fname); + fin.open(QIODevice::ReadOnly | QIODevice::Text); + if (fin.isOpen()) + { + char next; + while (fin.getChar(&next)) + { + if (next == '-') + { + bool ok; + unsigned i = QString(fin.readLine()).toUInt(&ok); + if (ok) + { + temp->AddLayer(temp->GetNumLayers(), i); + for (unsigned j = 0; (j < i) && fin.getChar(&next); ++j) + { + if (next == '+') + { + if (!temp->layers[temp->GetNumLayers() - 1].AddNode(fin.readLine())) + { + delete temp; + return NULL; + } + } + else + { + delete temp; + return NULL; + } + } + } + } + else + { + delete temp; + return NULL; + } + } + } + else + { + delete temp; + return NULL; + } + return temp; +} + +void PokeGen::NeuralNetwork::Net::AddLayer(const unsigned place, const unsigned numNodes) +{ + AddLayer(place, Layer(numNodes)); +} + +void PokeGen::NeuralNetwork::Net::AddLayer(const unsigned place, const Layer& layer) +{ + if (place <= GetNumLayers()) + { + layers.insert(place, layer); + if (place) + { + layers[place - 1].SetChild(&layers[place]); + layers[place].SetParent(&layers[place - 1]); + } + if ((place + 1) < GetNumLayers()) + { + layers[place].SetChild(&layers[place + 1]); + layers[place + 1].SetParent(&layers[place]); + } + } +} + +bool PokeGen::NeuralNetwork::Net::DeleteLayer(const unsigned place) +{ + if (place < GetNumLayers()) + { + if (place) + layers[place - 1].SetChild(layers[place].child); + if ((place + 1) < GetNumLayers()) + layers[place + 1].SetParent(layers[place].parent); + layers.removeAt(place); + return true; + } + return false; +} + +void PokeGen::NeuralNetwork::Net::FeedForward() +{ + for (QList::Iterator i = layers.begin(); i != layers.end(); ++i) + i->CalculateValues(); +} + +void PokeGen::NeuralNetwork::Net::BackPropagate() +{ + if (GetNumLayers()) + { + QMutableListIterator i(layers); + for (i.toBack(); i.hasPrevious();) + i.previous().CalculateErrors(); + if (1 < GetNumLayers()) + { + for (i.toBack(), i.previous(); i.hasPrevious();) + i.previous().AdjustWeights(); + } + } +} + +double PokeGen::NeuralNetwork::Net::CalculateError() +{ + if (GetNumLayers()) + { + double error = 0; + for (unsigned i = 0; i < layers[GetNumLayers() - 1].GetNumNodes(); ++i) + error += pow(layers[GetNumLayers() - 1].GetOutput(i) - layers[GetNumLayers() - 1].GetDesired(i), 2); + return (error / layers[GetNumLayers() - 1].GetNumNodes()); + } + return 0; +} + +unsigned PokeGen::NeuralNetwork::Net::GetChoice() const +{ + if (GetNumLayers()) + { + double max = -DBL_MAX; + unsigned choice = 0; + for (unsigned i = 0; i < layers[GetNumLayers() - 1].GetNumNodes(); ++i) + { + if (max < GetOutput(i)) + { + max = GetOutput(i); + choice = i; + } + } + return choice; + } + return UINT_MAX; +} + +unsigned PokeGen::NeuralNetwork::Net::GetNumLayers() const +{ + return layers.size(); +} + +unsigned PokeGen::NeuralNetwork::Net::GetNumNodes(const unsigned layer) const +{ + if (layer < GetNumLayers()) + return layers[layer].GetNumNodes(); + return 0; +} + +bool PokeGen::NeuralNetwork::Net::SetInput(const unsigned n, const double i) +{ + if (GetNumLayers()) + return layers[0].SetInput(n, i); + return false; +} + +bool PokeGen::NeuralNetwork::Net::SetDesired(const unsigned n, const double o) +{ + if (GetNumLayers()) + return layers[GetNumLayers() - 1].SetDesired(n, o); + return false; +} + +bool PokeGen::NeuralNetwork::Net::SetMomentum(const unsigned layer, const unsigned n, const double m) +{ + if (layer < GetNumLayers()) + return layers[layer].SetMomentum(n, m); + return false; +} + +bool PokeGen::NeuralNetwork::Net::SetMomentumFactor(const unsigned layer, const unsigned n, const double m) +{ + if (layer < GetNumLayers()) + return layers[layer].SetMomentumFactor(n, m); + return false; +} + +bool PokeGen::NeuralNetwork::Net::SetLearnRate(const unsigned layer, const unsigned n, const double l) +{ + if (layer < GetNumLayers()) + return layers[layer].SetLearnRate(n, l); + return false; +} + +bool PokeGen::NeuralNetwork::Net::SetFunction(const unsigned layer, const unsigned n, const unsigned f) +{ + if (layer < GetNumLayers()) + return layers[layer].SetFunction(n, f); + return false; +} + +double PokeGen::NeuralNetwork::Net::GetOutput(const unsigned n) const +{ + if (GetNumLayers()) + return layers[GetNumLayers() - 1].GetOutput(n); + return 0; +} + +double PokeGen::NeuralNetwork::Net::GetError(const unsigned layer, const unsigned n) const +{ + if (layer < GetNumLayers()) + return layers[layer].GetError(n); + return 0; +} + +double PokeGen::NeuralNetwork::Net::GetMomentum(const unsigned layer, const unsigned n) const +{ + if (layer < GetNumLayers()) + return layers[layer].GetMomentum(n); + return 0; +} + +double PokeGen::NeuralNetwork::Net::GetMomentumFactor(const unsigned layer, const unsigned n) const +{ + if (layer < GetNumLayers()) + return layers[layer].GetMomentumFactor(n); + return 0; +} + +double PokeGen::NeuralNetwork::Net::GetLearnRate(const unsigned layer, const unsigned n) const +{ + if (layer < GetNumLayers()) + return layers[layer].GetLearnRate(n); + return 0; +} + +unsigned PokeGen::NeuralNetwork::Net::GetFunction(const unsigned layer, const unsigned n) const +{ + if (layer < GetNumLayers()) + return layers[layer].GetFunction(n); + return 0; +} + +double PokeGen::NeuralNetwork::Net::GetWeight(const unsigned layer, const unsigned n, const unsigned i) const +{ + if (layer < GetNumLayers()) + return layers[layer].GetWeight(n, i); + return 0; +} + +double PokeGen::NeuralNetwork::Net::GetBias(const unsigned layer, const unsigned n) const +{ + if (layer < GetNumLayers()) + return layers[layer].GetBias(n); + return 0; +} -- cgit