diff options
| author | Ben Boeckel <MathStuf@gmail.com> | 2007-10-26 20:46:09 +0000 |
|---|---|---|
| committer | Ben Boeckel <MathStuf@gmail.com> | 2007-10-26 20:46:09 +0000 |
| commit | 4385af885daf460a18e236f08509358f764b2c8c (patch) | |
| tree | 6c2838312dd7f42769280e24e8abc16b53c165cb /ai/Net.cpp | |
| parent | 1f08afc80c73087bf9bde639754670548b89fc9f (diff) | |
Reverted repo back to rev24 because committing of rev25 messed up
git-svn-id: https://pokegen.svn.sourceforge.net/svnroot/pokegen/trunk@26 6ecfd1a5-f3ed-3746-8530-beee90d26b22
Diffstat (limited to 'ai/Net.cpp')
| -rw-r--r-- | ai/Net.cpp | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/ai/Net.cpp b/ai/Net.cpp new file mode 100644 index 00000000..cd72fd6b --- /dev/null +++ b/ai/Net.cpp @@ -0,0 +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 <http://www.gnu.org/licenses/>. +///////////////////////////////////////////////////////////////////////////// + +#include "Net.h" + +PokeGen::NeuralNetwork::Net::Net(const QList<unsigned>& 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<Layer>::Iterator i = layers.begin(); i != layers.end(); ++i) + i->CalculateValues(); +} + +void PokeGen::NeuralNetwork::Net::BackPropagate() +{ + if (GetNumLayers()) + { + QMutableListIterator<Layer> 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; +} |
