Working
This commit is contained in:
parent
535c4548aa
commit
25b1839763
|
@ -1,5 +1,3 @@
|
|||
*.exe
|
||||
*.txt
|
||||
*.cpp
|
||||
*.*
|
||||
!main.cpp
|
||||
!Genetic.cpp
|
||||
|
|
287
Genetic.cpp
287
Genetic.cpp
|
@ -3,8 +3,9 @@
|
|||
|
||||
#define RandomRange 1
|
||||
#define InitialSynapseValue 0.0
|
||||
#define MutationRate 0.0001
|
||||
#define MutationRate 0.15
|
||||
#define CrossOverRate 0.1
|
||||
#define PopCrossOverRate 0.95
|
||||
|
||||
class Synapse;
|
||||
class Neuron;
|
||||
|
@ -12,6 +13,7 @@ class Layer;
|
|||
class Input;
|
||||
class Output;
|
||||
class NeuralNetwork;
|
||||
class Generation;
|
||||
|
||||
float RandomFloat(int min, int max)
|
||||
{
|
||||
|
@ -38,6 +40,9 @@ float RandomFloat(int min, int max)
|
|||
void SetValue(float);
|
||||
void SetWeight(float);
|
||||
void SetBias(float);
|
||||
float GetWeight();
|
||||
float GetValue();
|
||||
float GetBias();
|
||||
float Fire();
|
||||
};
|
||||
|
||||
|
@ -67,6 +72,21 @@ float RandomFloat(int min, int max)
|
|||
this -> bias = bias;
|
||||
}
|
||||
|
||||
float Synapse::GetWeight()
|
||||
{
|
||||
return weight;
|
||||
}
|
||||
|
||||
float Synapse::GetValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
float Synapse::GetBias()
|
||||
{
|
||||
return bias;
|
||||
}
|
||||
|
||||
float Synapse::Fire()
|
||||
{
|
||||
float result = 0.0;
|
||||
|
@ -173,6 +193,7 @@ float RandomFloat(int min, int max)
|
|||
void Mutate();
|
||||
void RandomizeValues();
|
||||
void CrossOverSynapses(Layer *);
|
||||
friend void WriteToFile(NeuralNetwork *);
|
||||
bool CreateNeurons(int);
|
||||
bool ConnectPrevious(Layer *);
|
||||
bool ConnectForwards(Layer *);
|
||||
|
@ -403,6 +424,7 @@ float RandomFloat(int min, int max)
|
|||
void FireNetwork();
|
||||
void RandomizeValues();
|
||||
void MutateNetwork();
|
||||
friend void WriteToFile(NeuralNetwork *);
|
||||
void Reset();
|
||||
void CrossOverNetwork(NeuralNetwork *);
|
||||
bool SetInputNeurons(int);
|
||||
|
@ -411,7 +433,8 @@ float RandomFloat(int min, int max)
|
|||
bool ConnectLayers();
|
||||
bool SetLayer(int);
|
||||
float GetOutput(int);
|
||||
float GetScore(float, int);
|
||||
float GetError(int, float);
|
||||
float GetScore(int);
|
||||
int GetHiddenSize();
|
||||
void SetInput(float, int);
|
||||
};
|
||||
|
@ -461,12 +484,9 @@ float RandomFloat(int min, int max)
|
|||
NeuralNetwork::~NeuralNetwork()
|
||||
{
|
||||
// std::cout << "Deleted NeuralNetwork\n";
|
||||
if(input)
|
||||
delete input;
|
||||
if(hidden)
|
||||
delete hidden;
|
||||
if(output)
|
||||
delete output;
|
||||
if(input) delete input;
|
||||
if(hidden) delete hidden;
|
||||
if(output) delete output;
|
||||
}
|
||||
|
||||
void NeuralNetwork::Copy(const NeuralNetwork ¶meter)
|
||||
|
@ -527,6 +547,44 @@ float RandomFloat(int min, int max)
|
|||
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()
|
||||
{
|
||||
input = NULL;
|
||||
|
@ -580,11 +638,18 @@ float RandomFloat(int min, int max)
|
|||
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;
|
||||
return result < 0.0 ? -result : result;
|
||||
}
|
||||
|
||||
float NeuralNetwork::GetScore(int index = 0)
|
||||
{
|
||||
float result = GetOutput(index);
|
||||
return result;
|
||||
}
|
||||
|
||||
int NeuralNetwork::GetHiddenSize()
|
||||
{
|
||||
return hiddenSize;
|
||||
|
@ -612,14 +677,21 @@ float RandomFloat(int min, int max)
|
|||
void Randomize();
|
||||
void Fire();
|
||||
void SortByScore(int);
|
||||
void SortByScoreArray(float *, int, int);
|
||||
void DisplayScores(int);
|
||||
void DisplayBest(int);
|
||||
void SetTarget(float);
|
||||
void SetInput(float, int);
|
||||
void NextGeneration();
|
||||
void WriteBestToFile();
|
||||
bool CreateNetworks(int, int);
|
||||
bool ConnectNetworks();
|
||||
bool SetInputNeurons(int);
|
||||
bool SetHiddenNeurons(int, int);
|
||||
bool SetOutputNeurons(int);
|
||||
float GetBest(int);
|
||||
float GetError(int);
|
||||
int GetStep();
|
||||
};
|
||||
|
||||
Generation::Generation()
|
||||
|
@ -687,18 +759,49 @@ float RandomFloat(int min, int max)
|
|||
int i;
|
||||
std::cout << "----Scores----\n";
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
for (i = 0; i < size - 1; i++)
|
||||
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));
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
@ -712,6 +815,47 @@ float RandomFloat(int min, int max)
|
|||
(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)
|
||||
{
|
||||
if((networks = _CreateNetworks(size, hiddenSizes)))
|
||||
|
@ -755,33 +899,120 @@ float RandomFloat(int min, int max)
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int Generation::GetStep()
|
||||
{
|
||||
return step;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Generation generation(50, 3);
|
||||
FILE *inputFile;
|
||||
FILE *outputFile;
|
||||
int decision;
|
||||
float currentError;
|
||||
int trainCounter;
|
||||
|
||||
std::cout << "1 - ";
|
||||
std::cout << generation.SetInputNeurons(1) << "\n";
|
||||
std::cout << "2 - ";
|
||||
int inputCounter;
|
||||
int floatCounter;
|
||||
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 << "3 - ";
|
||||
std::cout << generation.SetHiddenNeurons(1, 3) << "\n";
|
||||
std::cout << "4 - ";
|
||||
std::cout << "Hiddens Are Getting Set: ";
|
||||
std::cout << generation.SetHiddenNeurons(1, 2) << "\n";
|
||||
std::cout << "Hiddens Are Getting Set: ";
|
||||
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 << "6 - ";
|
||||
std::cout << "Networks Are Getting Connected: ";
|
||||
std::cout << generation.ConnectNetworks() << "\n";
|
||||
|
||||
// generation.SetTarget(12.30);
|
||||
|
||||
generation.Randomize();
|
||||
generation.Fire();
|
||||
generation.DisplayScores();
|
||||
std::cout << "-----------SORTING-----------\n";
|
||||
generation.SortByScore();
|
||||
generation.DisplayScores();
|
||||
|
||||
do
|
||||
{
|
||||
std::cout << "-2 - Test\n-3 - Best to File\nAny Number for train count\n-1 - Exit\nDecision: ";
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue