This commit is contained in:
Asrın Doğan 2019-12-24 16:49:49 +03:00
parent 535c4548aa
commit 25b1839763
2 changed files with 260 additions and 31 deletions

4
.gitignore vendored
View File

@ -1,5 +1,3 @@
*.exe *.*
*.txt
*.cpp
!main.cpp !main.cpp
!Genetic.cpp !Genetic.cpp

View File

@ -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 &parameter) void NeuralNetwork::Copy(const NeuralNetwork &parameter)
@ -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;
} }