Working
This commit is contained in:
parent
535c4548aa
commit
25b1839763
|
@ -1,5 +1,3 @@
|
||||||
*.exe
|
*.*
|
||||||
*.txt
|
|
||||||
*.cpp
|
|
||||||
!main.cpp
|
!main.cpp
|
||||||
!Genetic.cpp
|
!Genetic.cpp
|
||||||
|
|
287
Genetic.cpp
287
Genetic.cpp
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
#define RandomRange 1
|
#define RandomRange 1
|
||||||
#define InitialSynapseValue 0.0
|
#define InitialSynapseValue 0.0
|
||||||
#define MutationRate 0.0001
|
#define MutationRate 0.15
|
||||||
#define CrossOverRate 0.1
|
#define CrossOverRate 0.1
|
||||||
|
#define PopCrossOverRate 0.95
|
||||||
|
|
||||||
class Synapse;
|
class Synapse;
|
||||||
class Neuron;
|
class Neuron;
|
||||||
|
@ -12,6 +13,7 @@ class Layer;
|
||||||
class Input;
|
class Input;
|
||||||
class Output;
|
class Output;
|
||||||
class NeuralNetwork;
|
class NeuralNetwork;
|
||||||
|
class Generation;
|
||||||
|
|
||||||
float RandomFloat(int min, int max)
|
float RandomFloat(int min, int max)
|
||||||
{
|
{
|
||||||
|
@ -38,6 +40,9 @@ float RandomFloat(int min, int max)
|
||||||
void SetValue(float);
|
void SetValue(float);
|
||||||
void SetWeight(float);
|
void SetWeight(float);
|
||||||
void SetBias(float);
|
void SetBias(float);
|
||||||
|
float GetWeight();
|
||||||
|
float GetValue();
|
||||||
|
float GetBias();
|
||||||
float Fire();
|
float Fire();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,6 +72,21 @@ float RandomFloat(int min, int max)
|
||||||
this -> bias = bias;
|
this -> bias = bias;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Synapse::GetWeight()
|
||||||
|
{
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Synapse::GetValue()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Synapse::GetBias()
|
||||||
|
{
|
||||||
|
return bias;
|
||||||
|
}
|
||||||
|
|
||||||
float Synapse::Fire()
|
float Synapse::Fire()
|
||||||
{
|
{
|
||||||
float result = 0.0;
|
float result = 0.0;
|
||||||
|
@ -173,6 +193,7 @@ float RandomFloat(int min, int max)
|
||||||
void Mutate();
|
void Mutate();
|
||||||
void RandomizeValues();
|
void RandomizeValues();
|
||||||
void CrossOverSynapses(Layer *);
|
void CrossOverSynapses(Layer *);
|
||||||
|
friend void WriteToFile(NeuralNetwork *);
|
||||||
bool CreateNeurons(int);
|
bool CreateNeurons(int);
|
||||||
bool ConnectPrevious(Layer *);
|
bool ConnectPrevious(Layer *);
|
||||||
bool ConnectForwards(Layer *);
|
bool ConnectForwards(Layer *);
|
||||||
|
@ -403,6 +424,7 @@ float RandomFloat(int min, int max)
|
||||||
void FireNetwork();
|
void FireNetwork();
|
||||||
void RandomizeValues();
|
void RandomizeValues();
|
||||||
void MutateNetwork();
|
void MutateNetwork();
|
||||||
|
friend void WriteToFile(NeuralNetwork *);
|
||||||
void Reset();
|
void Reset();
|
||||||
void CrossOverNetwork(NeuralNetwork *);
|
void CrossOverNetwork(NeuralNetwork *);
|
||||||
bool SetInputNeurons(int);
|
bool SetInputNeurons(int);
|
||||||
|
@ -411,7 +433,8 @@ float RandomFloat(int min, int max)
|
||||||
bool ConnectLayers();
|
bool ConnectLayers();
|
||||||
bool SetLayer(int);
|
bool SetLayer(int);
|
||||||
float GetOutput(int);
|
float GetOutput(int);
|
||||||
float GetScore(float, int);
|
float GetError(int, float);
|
||||||
|
float GetScore(int);
|
||||||
int GetHiddenSize();
|
int GetHiddenSize();
|
||||||
void SetInput(float, int);
|
void SetInput(float, int);
|
||||||
};
|
};
|
||||||
|
@ -461,12 +484,9 @@ float RandomFloat(int min, int max)
|
||||||
NeuralNetwork::~NeuralNetwork()
|
NeuralNetwork::~NeuralNetwork()
|
||||||
{
|
{
|
||||||
// std::cout << "Deleted NeuralNetwork\n";
|
// std::cout << "Deleted NeuralNetwork\n";
|
||||||
if(input)
|
if(input) delete input;
|
||||||
delete input;
|
if(hidden) delete hidden;
|
||||||
if(hidden)
|
if(output) delete output;
|
||||||
delete hidden;
|
|
||||||
if(output)
|
|
||||||
delete output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeuralNetwork::Copy(const NeuralNetwork ¶meter)
|
void NeuralNetwork::Copy(const NeuralNetwork ¶meter)
|
||||||
|
@ -527,6 +547,44 @@ float RandomFloat(int min, int max)
|
||||||
output -> RandomizeValues();
|
output -> RandomizeValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteToFile(NeuralNetwork *network)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
Synapse *synapsePtr = network -> input -> synapses;
|
||||||
|
int count = network -> input -> synapseSize;
|
||||||
|
std::cout << count << "\n";
|
||||||
|
FILE *file = fopen("Data/BestSynapses.txt", "w");
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
fprintf(file, "%f, %f, ", synapsePtr -> GetWeight(), synapsePtr -> GetBias());
|
||||||
|
synapsePtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < network -> hiddenSize; j++)
|
||||||
|
{
|
||||||
|
count = (network -> hidden + j) -> synapseSize;
|
||||||
|
std::cout << count << "\n";
|
||||||
|
synapsePtr = (network -> hidden + j) -> synapses;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
fprintf(file, "%f, %f, ", synapsePtr -> GetWeight(), synapsePtr -> GetBias());
|
||||||
|
synapsePtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
synapsePtr = network -> output -> synapses;
|
||||||
|
count = network -> output -> synapseSize;
|
||||||
|
std::cout << count << "\n";
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
fprintf(file, "%f, %f, ", synapsePtr -> GetWeight(), synapsePtr -> GetBias());
|
||||||
|
synapsePtr++;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
void NeuralNetwork::Reset()
|
void NeuralNetwork::Reset()
|
||||||
{
|
{
|
||||||
input = NULL;
|
input = NULL;
|
||||||
|
@ -580,11 +638,18 @@ float RandomFloat(int min, int max)
|
||||||
return output -> GetValue(index);
|
return output -> GetValue(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
float NeuralNetwork::GetScore(float target, int index = 0)
|
float NeuralNetwork::GetError(int index = 0, float target = 0.0)
|
||||||
{
|
{
|
||||||
float result = GetOutput(index) - target;
|
float result = GetOutput(index) - target;
|
||||||
return result < 0.0 ? -result : result;
|
return result < 0.0 ? -result : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float NeuralNetwork::GetScore(int index = 0)
|
||||||
|
{
|
||||||
|
float result = GetOutput(index);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int NeuralNetwork::GetHiddenSize()
|
int NeuralNetwork::GetHiddenSize()
|
||||||
{
|
{
|
||||||
return hiddenSize;
|
return hiddenSize;
|
||||||
|
@ -612,14 +677,21 @@ float RandomFloat(int min, int max)
|
||||||
void Randomize();
|
void Randomize();
|
||||||
void Fire();
|
void Fire();
|
||||||
void SortByScore(int);
|
void SortByScore(int);
|
||||||
|
void SortByScoreArray(float *, int, int);
|
||||||
void DisplayScores(int);
|
void DisplayScores(int);
|
||||||
|
void DisplayBest(int);
|
||||||
void SetTarget(float);
|
void SetTarget(float);
|
||||||
void SetInput(float, int);
|
void SetInput(float, int);
|
||||||
|
void NextGeneration();
|
||||||
|
void WriteBestToFile();
|
||||||
bool CreateNetworks(int, int);
|
bool CreateNetworks(int, int);
|
||||||
bool ConnectNetworks();
|
bool ConnectNetworks();
|
||||||
bool SetInputNeurons(int);
|
bool SetInputNeurons(int);
|
||||||
bool SetHiddenNeurons(int, int);
|
bool SetHiddenNeurons(int, int);
|
||||||
bool SetOutputNeurons(int);
|
bool SetOutputNeurons(int);
|
||||||
|
float GetBest(int);
|
||||||
|
float GetError(int);
|
||||||
|
int GetStep();
|
||||||
};
|
};
|
||||||
|
|
||||||
Generation::Generation()
|
Generation::Generation()
|
||||||
|
@ -687,18 +759,49 @@ float RandomFloat(int min, int max)
|
||||||
int i;
|
int i;
|
||||||
std::cout << "----Scores----\n";
|
std::cout << "----Scores----\n";
|
||||||
for (i = 0; i < this -> size; i++)
|
for (i = 0; i < this -> size; i++)
|
||||||
std::cout << i << " -> " << (networks + i) -> GetScore(target, index) << "\n";
|
std::cout << i << " -> " << (networks + i) -> GetError(index) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Generation::DisplayBest(int index = 0)
|
||||||
|
{
|
||||||
|
std::cout << "Target -> " << target << "\tBest -> " << networks -> GetScore(index) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
float Generation::GetBest(int index = 0)
|
||||||
|
{
|
||||||
|
return networks -> GetScore(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Generation::GetError(int index = 0)
|
||||||
|
{
|
||||||
|
return (networks + index) -> GetError(0, target);
|
||||||
|
}
|
||||||
void Generation::SortByScore(int index = 0)
|
void Generation::SortByScore(int index = 0)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
for (i = 0; i < size - 1; i++)
|
for (i = 0; i < size - 1; i++)
|
||||||
for (j = i + 1; j < size; j++)
|
for (j = i + 1; j < size; j++)
|
||||||
if((networks + i) -> GetScore(target, index) > (networks + j) -> GetScore(target, index))
|
if((networks + i) -> GetError(index, target) > (networks + j) -> GetError(index, target))
|
||||||
_SwapNetworks((networks + i), (networks + j));
|
_SwapNetworks((networks + i), (networks + j));
|
||||||
}
|
}
|
||||||
|
void Generation::SortByScoreArray(float *array, int size, int index = 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
float temp;
|
||||||
|
|
||||||
|
for (i = 0; i < size - 1; i++)
|
||||||
|
for (j = i + 1; j < size; j++)
|
||||||
|
if(*(array + i) > *(array + j))
|
||||||
|
{
|
||||||
|
temp = *(array + i);
|
||||||
|
*(array + i) = *(array + j);
|
||||||
|
*(array + j) = temp;
|
||||||
|
_SwapNetworks((networks + i), (networks + j));
|
||||||
|
}
|
||||||
|
// if((networks + i) -> GetError(index, target) > (networks + j) -> GetError(index, target))
|
||||||
|
}
|
||||||
|
|
||||||
void Generation::SetTarget(float target)
|
void Generation::SetTarget(float target)
|
||||||
{
|
{
|
||||||
|
@ -712,6 +815,47 @@ float RandomFloat(int min, int max)
|
||||||
(networks + i) -> SetInput(value, index);
|
(networks + i) -> SetInput(value, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Generation::WriteBestToFile()
|
||||||
|
{
|
||||||
|
WriteToFile(networks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Generation::NextGeneration()
|
||||||
|
{
|
||||||
|
int i = 2;
|
||||||
|
int crossOverCount = size * PopCrossOverRate;
|
||||||
|
|
||||||
|
if(i + crossOverCount >= size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NeuralNetwork *first = NULL;
|
||||||
|
NeuralNetwork *second = NULL;
|
||||||
|
Fire();
|
||||||
|
|
||||||
|
// for (; i < size; i+=2)
|
||||||
|
for (i = 2; i < crossOverCount; i+=2)
|
||||||
|
{
|
||||||
|
first = (networks + i);
|
||||||
|
second = (networks + i + 1);
|
||||||
|
|
||||||
|
first -> Copy(*(networks + 0));
|
||||||
|
second -> Copy(*(networks + 1));
|
||||||
|
|
||||||
|
if(RandomFloat(0, 1) < 0.5)
|
||||||
|
first -> CrossOverNetwork(second);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
first -> MutateNetwork();
|
||||||
|
second -> MutateNetwork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// SortByScore();
|
||||||
|
|
||||||
|
for (; i < size; i++)
|
||||||
|
(networks + i) -> RandomizeValues();
|
||||||
|
step++;
|
||||||
|
}
|
||||||
|
|
||||||
bool Generation::CreateNetworks(int size, int hiddenSizes)
|
bool Generation::CreateNetworks(int size, int hiddenSizes)
|
||||||
{
|
{
|
||||||
if((networks = _CreateNetworks(size, hiddenSizes)))
|
if((networks = _CreateNetworks(size, hiddenSizes)))
|
||||||
|
@ -755,33 +899,120 @@ float RandomFloat(int min, int max)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
int Generation::GetStep()
|
||||||
|
{
|
||||||
|
return step;
|
||||||
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Generation generation(50, 3);
|
FILE *inputFile;
|
||||||
|
FILE *outputFile;
|
||||||
|
int decision;
|
||||||
|
float currentError;
|
||||||
|
int trainCounter;
|
||||||
|
|
||||||
std::cout << "1 - ";
|
int inputCounter;
|
||||||
std::cout << generation.SetInputNeurons(1) << "\n";
|
int floatCounter;
|
||||||
std::cout << "2 - ";
|
int i;
|
||||||
|
int j;
|
||||||
|
int generationCounter;
|
||||||
|
float trainInputs[30][5];
|
||||||
|
float scores[50];
|
||||||
|
float testInputs[120][5];
|
||||||
|
Generation generation(50, 5);
|
||||||
|
inputFile = fopen("Data/train.data", "r");
|
||||||
|
for (inputCounter = 0; inputCounter < 30; inputCounter++)
|
||||||
|
for (floatCounter = 0; floatCounter < 5; floatCounter++)
|
||||||
|
fscanf(inputFile, "%f,", &trainInputs[inputCounter][floatCounter]);
|
||||||
|
fclose(inputFile);
|
||||||
|
inputFile = fopen("Data/test.data", "r");
|
||||||
|
for (inputCounter = 0; inputCounter < 150; inputCounter++)
|
||||||
|
for (floatCounter = 0; floatCounter < 5; floatCounter++)
|
||||||
|
fscanf(inputFile, "%f,", &testInputs[inputCounter][floatCounter]);
|
||||||
|
fclose(inputFile);
|
||||||
|
|
||||||
|
std::cout << "Inputs Are Getting Set: ";
|
||||||
|
std::cout << generation.SetInputNeurons(4) << "\n";
|
||||||
|
std::cout << "Hiddens Are Getting Set: ";
|
||||||
std::cout << generation.SetHiddenNeurons(0, 2) << "\n";
|
std::cout << generation.SetHiddenNeurons(0, 2) << "\n";
|
||||||
std::cout << "3 - ";
|
std::cout << "Hiddens Are Getting Set: ";
|
||||||
std::cout << generation.SetHiddenNeurons(1, 3) << "\n";
|
std::cout << generation.SetHiddenNeurons(1, 2) << "\n";
|
||||||
std::cout << "4 - ";
|
std::cout << "Hiddens Are Getting Set: ";
|
||||||
std::cout << generation.SetHiddenNeurons(2, 2) << "\n";
|
std::cout << generation.SetHiddenNeurons(2, 2) << "\n";
|
||||||
std::cout << "5 - ";
|
std::cout << "Hiddens Are Getting Set: ";
|
||||||
|
std::cout << generation.SetHiddenNeurons(3, 2) << "\n";
|
||||||
|
std::cout << "Hiddens Are Getting Set: ";
|
||||||
|
std::cout << generation.SetHiddenNeurons(4, 2) << "\n";
|
||||||
|
std::cout << "Inputs Are Getting Set: ";
|
||||||
std::cout << generation.SetOutputNeurons(1) << "\n";
|
std::cout << generation.SetOutputNeurons(1) << "\n";
|
||||||
std::cout << "6 - ";
|
std::cout << "Networks Are Getting Connected: ";
|
||||||
std::cout << generation.ConnectNetworks() << "\n";
|
std::cout << generation.ConnectNetworks() << "\n";
|
||||||
|
|
||||||
// generation.SetTarget(12.30);
|
|
||||||
|
|
||||||
generation.Randomize();
|
generation.Randomize();
|
||||||
generation.Fire();
|
|
||||||
generation.DisplayScores();
|
do
|
||||||
std::cout << "-----------SORTING-----------\n";
|
{
|
||||||
generation.SortByScore();
|
std::cout << "-2 - Test\n-3 - Best to File\nAny Number for train count\n-1 - Exit\nDecision: ";
|
||||||
generation.DisplayScores();
|
std::cin >> decision;
|
||||||
|
|
||||||
|
switch (decision)
|
||||||
|
{
|
||||||
|
case -3:
|
||||||
|
generation.WriteBestToFile();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
trainCounter = 0;
|
||||||
|
for (int lk = 0; lk < decision; lk++)
|
||||||
|
{
|
||||||
|
std::cout << trainCounter++ << "\n";
|
||||||
|
for (inputCounter = 0; inputCounter < 10; inputCounter++)
|
||||||
|
{
|
||||||
|
// for (generationCounter = 0; generationCounter < 25; generationCounter++)
|
||||||
|
// {
|
||||||
|
for (j = 0; j < 50; j++)
|
||||||
|
scores[j] = 0.0;
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (floatCounter = 0; floatCounter < 4; floatCounter++)
|
||||||
|
generation.SetInput(trainInputs[inputCounter * 3 + i][floatCounter], floatCounter);
|
||||||
|
generation.SetTarget(trainInputs[inputCounter * 3 + i][4]);
|
||||||
|
generation.Fire();
|
||||||
|
for (j = 0; j < 50; j++)
|
||||||
|
scores[j] += generation.GetError(j);
|
||||||
|
}
|
||||||
|
generation.SortByScoreArray(scores, 50);
|
||||||
|
generation.NextGeneration();
|
||||||
|
// generation.NextGeneration();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Best -> " << scores[0] << "\n";
|
||||||
|
std::cout << "Train is Over!\n";
|
||||||
|
case -2:
|
||||||
|
outputFile = fopen("Data/results.data", "w");
|
||||||
|
trainCounter = 0;
|
||||||
|
for (inputCounter = 0; inputCounter < 120; inputCounter++)
|
||||||
|
{
|
||||||
|
for (floatCounter = 0; floatCounter < 4; floatCounter++)
|
||||||
|
generation.SetInput(testInputs[inputCounter][floatCounter], floatCounter);
|
||||||
|
generation.SetTarget(testInputs[inputCounter][4]);
|
||||||
|
|
||||||
|
generation.Fire();
|
||||||
|
// generation.DisplayBest();
|
||||||
|
currentError = testInputs[inputCounter][4] - generation.GetBest() < 0 ? generation.GetBest() - testInputs[inputCounter][4] : testInputs[inputCounter][4] - generation.GetBest();
|
||||||
|
// fprintf(outputFile, "Original = %f\t->\tTrained -> %f\t Error = %f\n", testInputs[inputCounter][4], generation.GetBest(), currentError);
|
||||||
|
fprintf(outputFile, "%f,%f,%f\n", testInputs[inputCounter][4], generation.GetBest(), currentError);
|
||||||
|
}
|
||||||
|
fclose(outputFile);
|
||||||
|
std::cout << "Test is Over!\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (decision != -1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue