Skip to content

Commit

Permalink
Work
Browse files Browse the repository at this point in the history
  • Loading branch information
mr-andreas committed Jun 23, 2013
1 parent 540d469 commit 83eabe8
Show file tree
Hide file tree
Showing 7 changed files with 478 additions and 4 deletions.
244 changes: 244 additions & 0 deletions CNeuralNet.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
#include "CNeuralNet.h"

const double D_BIAS = -1.0;
const double D_ACTIVE_RESPONSE = 1.0;

//*************************** methods for Neuron **********************
//
//---------------------------------------------------------------------
SNeuron::SNeuron(int NumInputs): m_NumInputs(NumInputs+1)

{
//we need an additional weight for the bias hence the +1
for (int i=0; i<NumInputs+1; ++i)
{
//set up the weights with an initial random value
m_vecWeight.push_back(RandomClamped());
}
}




//************************ methods for NeuronLayer **********************

//-----------------------------------------------------------------------
// ctor creates a layer of neurons of the required size by calling the
// SNeuron ctor the rqd number of times
//-----------------------------------------------------------------------
SNeuronLayer::SNeuronLayer(int NumNeurons,
int NumInputsPerNeuron): m_NumNeurons(NumNeurons)
{
for (int i=0; i<NumNeurons; ++i)

m_vecNeurons.push_back(SNeuron(NumInputsPerNeuron));
}




//************************ methods forCNeuralNet ************************

//------------------------------default ctor ----------------------------
//
// creates a ANN based on the default values in params.ini
//-----------------------------------------------------------------------
CNeuralNet::CNeuralNet()
{
m_NumInputs = 4;
m_NumOutputs = 2;
m_NumHiddenLayers = 1;
m_NeuronsPerHiddenLyr = 6;

CreateNet();

}

//------------------------------createNet()------------------------------
//
// this method builds the ANN. The weights are all initially set to
// random values -1 < w < 1
//------------------------------------------------------------------------
void CNeuralNet::CreateNet()
{
//create the layers of the network
if (m_NumHiddenLayers > 0)
{
//create first hidden layer
m_vecLayers.push_back(SNeuronLayer(m_NeuronsPerHiddenLyr, m_NumInputs));

for (int i=0; i<m_NumHiddenLayers-1; ++i)
{

m_vecLayers.push_back(SNeuronLayer(m_NeuronsPerHiddenLyr,
m_NeuronsPerHiddenLyr));
}

//create output layer
m_vecLayers.push_back(SNeuronLayer(m_NumOutputs, m_NeuronsPerHiddenLyr));
}

else
{
//create output layer
m_vecLayers.push_back(SNeuronLayer(m_NumOutputs, m_NumInputs));
}
}

//---------------------------------GetWeights-----------------------------
//
// returns a vector containing the weights
//
//------------------------------------------------------------------------
vector<double> CNeuralNet::GetWeights() const
{
//this will hold the weights
vector<double> weights;

//for each layer
for (int i=0; i<m_NumHiddenLayers + 1; ++i)
{

//for each neuron
for (int j=0; j<m_vecLayers[i].m_NumNeurons; ++j)
{
//for each weight
for (int k=0; k<m_vecLayers[i].m_vecNeurons[j].m_NumInputs; ++k)
{
weights.push_back(m_vecLayers[i].m_vecNeurons[j].m_vecWeight[k]);
}
}
}

return weights;
}

//-----------------------------------PutWeights---------------------------
//
// given a vector of doubles this function replaces the weights in the NN
// with the new values
//
//------------------------------------------------------------------------
void CNeuralNet::PutWeights(vector<double> &weights)
{
int cWeight = 0;

//for each layer
for (int i=0; i<m_NumHiddenLayers + 1; ++i)
{

//for each neuron
for (int j=0; j<m_vecLayers[i].m_NumNeurons; ++j)
{
//for each weight
for (int k=0; k<m_vecLayers[i].m_vecNeurons[j].m_NumInputs; ++k)
{
m_vecLayers[i].m_vecNeurons[j].m_vecWeight[k] = weights[cWeight++];
}
}
}

return;
}

//---------------------------------GetNumberOfWeights---------------------
//
// returns the total number of weights needed for the net
//
//------------------------------------------------------------------------
int CNeuralNet::GetNumberOfWeights() const
{

int weights = 0;

//for each layer
for (int i=0; i<m_NumHiddenLayers + 1; ++i)
{

//for each neuron
for (int j=0; j<m_vecLayers[i].m_NumNeurons; ++j)
{
//for each weight
for (int k=0; k<m_vecLayers[i].m_vecNeurons[j].m_NumInputs; ++k)

weights++;

}
}

return weights;
}

//-------------------------------Update-----------------------------------
//
// given an input vector this function calculates the output vector
//
//------------------------------------------------------------------------
vector<double> CNeuralNet::Update(vector<double> &inputs)
{
//stores the resultant outputs from each layer
vector<double> outputs;

int cWeight = 0;

//first check that we have the correct amount of inputs
if (inputs.size() != m_NumInputs)
{
//just return an empty vector if incorrect.
return outputs;
}

//For each layer....
for (int i=0; i<m_NumHiddenLayers + 1; ++i)
{
if ( i > 0 )
{
inputs = outputs;
}

outputs.clear();

cWeight = 0;

//for each neuron sum the (inputs * corresponding weights).Throw
//the total at our sigmoid function to get the output.
for (int j=0; j<m_vecLayers[i].m_NumNeurons; ++j)
{
double netinput = 0;

int NumInputs = m_vecLayers[i].m_vecNeurons[j].m_NumInputs;

//for each weight
for (int k=0; k<NumInputs - 1; ++k)
{
//sum the weights x inputs
netinput += m_vecLayers[i].m_vecNeurons[j].m_vecWeight[k] *
inputs[cWeight++];
}

//add in the bias
netinput += m_vecLayers[i].m_vecNeurons[j].m_vecWeight[NumInputs-1] *
D_BIAS;

//we can store the outputs from each layer as we generate them.
//The combined activation is first filtered through the sigmoid
//function
outputs.push_back(Sigmoid(netinput,
D_ACTIVE_RESPONSE));

cWeight = 0;
}
}

return outputs;
}

//-------------------------------Sigmoid function-------------------------
//
//------------------------------------------------------------------------
double CNeuralNet::Sigmoid(double netinput, double response)
{
return ( 1 / ( 1 + exp(-netinput / response)));
}


101 changes: 101 additions & 0 deletions CNeuralNet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#ifndef CNEURALNET_H
#define CNEURALNET_H
//------------------------------------------------------------------------
//
// Name: CNeuralNet.h
//
// Author: Mat Buckland 2002
//
// Desc: Class for creating a feedforward neural net.
//-------------------------------------------------------------------------
#include <vector>
#include <fstream>
#include <math.h>

#include "utils.h"

using namespace std;



//-------------------------------------------------------------------
// define neuron struct
//-------------------------------------------------------------------
struct SNeuron
{
//the number of inputs into the neuron
int m_NumInputs;

//the weights for each input
vector<double> m_vecWeight;


//ctor
SNeuron(int NumInputs);
};


//---------------------------------------------------------------------
// struct to hold a layer of neurons.
//---------------------------------------------------------------------

struct SNeuronLayer
{
//the number of neurons in this layer
int m_NumNeurons;

//the layer of neurons
vector<SNeuron> m_vecNeurons;

SNeuronLayer(int NumNeurons,
int NumInputsPerNeuron);
};


//----------------------------------------------------------------------
// neural net class
//----------------------------------------------------------------------

class CNeuralNet
{

private:

int m_NumInputs;

int m_NumOutputs;

int m_NumHiddenLayers;

int m_NeuronsPerHiddenLyr;

//storage for each layer of neurons including the output layer
vector<SNeuronLayer> m_vecLayers;

public:

CNeuralNet();

void CreateNet();

//gets the weights from the NN
vector<double> GetWeights()const;

//returns total number of weights in net
int GetNumberOfWeights()const;

//replaces the weights with new ones
void PutWeights(vector<double> &weights);

//calculates the outputs from a set of inputs
vector<double> Update(vector<double> &inputs);

//sigmoid response curve
inline double Sigmoid(double activation, double response);

};




#endif
15 changes: 11 additions & 4 deletions gamestate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@ Gamestate::Gamestate(int boardWidth, int boardHeight) {
}

void moveSweeper(Gamestate *gs, Sweeper &sweeper) {
vector<double> vals(4);
vals[0] = 0.0;
vals[1] = 0.0;
vals[3] = 0.0;
vals[4] = 0.0;
vector<double> output = sweeper.brain.Update(vals);

double lTrack, rTrack;
lTrack = rand() / ((double)RAND_MAX/2) - 1.0;
rTrack = rand() / ((double)RAND_MAX/2) - 1.0;
// lTrack = rand() / ((double)RAND_MAX/2) - 1.0;
// rTrack = rand() / ((double)RAND_MAX/2) - 1.0;

lTrack = 1.0;
rTrack = 0.95;
lTrack = output[0];
rTrack = output[1];

double rotForce = lTrack - rTrack;
if(rotForce < -0.3) rotForce = -0.3;
Expand Down
3 changes: 3 additions & 0 deletions gamestate.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _GAMESTATE_H

#include <vector>
#include "CNeuralNet.h"

class Sweeper {
public:
Expand All @@ -11,6 +12,8 @@ class Sweeper {

// Rotation, value between 0 and 1
double rotation;

CNeuralNet brain;
};

class Gamestate {
Expand Down
Loading

0 comments on commit 83eabe8

Please sign in to comment.