int input1 = A0;
int input2 = A1;
int input3 = A2;
int input4 = A3;
float input1Val;
float input2Val;
float input3Val;
float input4Val;
float input1Weight[4];
float input2Weight[4];
float input3Weight[4];
float input4Weight[4];
float layer1_1Val;
float layer1_2Val;
float layer1_3Val;
float layer1_4Val;
float layer1_1Weight[2];
float layer1_2Weight[2];
float layer1_3Weight[2];
float layer1_4Weight[2];
float output1;
float output2;
int leftMotor = 12;
int rightMotor = 11;
float learningRate = 0.1;
int randomWeight;
int randomWeightVal;
int lastChange;
float error;
float lastError;
int TREAT;
int trainCycle;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
generateInputWeights();
generateLayer1Weights();
}
void loop()
{
/*
input1Val = anaglogRead(input1);
input2Val = anaglogRead(input2);
input3Val = anaglogRead(input3);
input4Val = anaglogRead(input4);
*/
//temp random values before LDR circuit is built.
input1Val = 276;
input2Val = 754;
input3Val = 335;
input4Val = 656;
inputMapAndConvert();
layer1Val();
output1 = layer1_1Val * layer1_1Weight[0] + layer1_2Val * layer1_2Weight[0] + layer1_3Val * layer1_3Weight[0] + layer1_4Val * layer1_4Weight[0];
output2 = layer1_1Val * layer1_1Weight[1] + layer1_2Val * layer1_2Weight[1] + layer1_3Val * layer1_3Weight[1] + layer1_4Val * layer1_4Weight[1];
output1 = 1 / (1 + exp(-1 * output1));
output2 = 1 / (1 + exp(-1 * output2));
if (input1Val + input3Val > input2Val + input4Val)
{
if (output1 < output2)
{
digitalWrite(rightMotor, HIGH);
delay(output2 - output1);
digitalWrite(rightMotor, LOW);
TREAT++;
}
else
{
training();
}
}
if (input1Val + input3Val < input2Val + input4Val)
{
if (output1 > output2)
{
digitalWrite(leftMotor, HIGH);
delay(output1 - output2);
digitalWrite(leftMotor, LOW);
TREAT++;
}
else
{
training();
}
}
Serial.print("TREAT ");
Serial.print(TREAT);
Serial.print(" ");
Serial.print("Training Cycle ");
Serial.println(trainCycle);
}
void generateInputWeights()
{
//generate input 1 weights
for (int x = 0; x <= 3; x++)
{
input1Weight[x] = random(1, 101); //101 because random number generator subtracts 1 from max.
}
//generate input 2 weights
for (int x = 0; x <= 3; x++)
{
input2Weight[x] = random(1, 101); //101 because random number generator subtracts 1 from max.
}
//generate input 3 weights
for (int x = 0; x <= 3; x++)
{
input3Weight[x] = random(1, 101); //101 because random number generator subtracts 1 from max.
}
//generate input 4 weights
for (int x = 0; x <= 3; x++)
{
input4Weight[x] = random(1, 101); //101 because random number generator subtracts 1 from max.
}
//-----convert input weights to float values---
for (int x = 0; x <= 3; x++)
{
input1Weight[x] = input1Weight[x] / 100;
}
for (int x = 0; x <= 3; x++)
{
input2Weight[x] = input2Weight[x] / 100;
}
for (int x = 0; x <= 3; x++)
{
input3Weight[x] = input3Weight[x] / 100;
}
for (int x = 0; x <= 3; x++)
{
input4Weight[x] = input4Weight[x] / 100;
}
}
void generateLayer1Weights()
{
//generate layer 1-1 weights
for (int x = 0; x <= 1; x++)
{
layer1_1Weight[x] = random(1, 101); //101 because random number generator subtracts 1 from max.
}
//generate layer 1-2 weights
for (int x = 0; x <= 1; x++)
{
layer1_2Weight[x] = random(1, 101); //101 because random number generator subtracts 1 from max.
}
//generate layer 1-3 weights
for (int x = 0; x <= 1; x++)
{
layer1_3Weight[x] = random(1, 101); //101 because random number generator subtracts 1 from max.
}
//generate layer 1-4 weights
for (int x = 0; x <= 1; x++)
{
layer1_4Weight[x] = random(1, 101); //101 because random number generator subtracts 1 from max.
}
//convert layer values to decimal
for (int x = 0; x <= 1; x++)
{
layer1_1Weight[x] = layer1_1Weight[x] / 100;
}
for (int x = 0; x <= 1; x++)
{
layer1_2Weight[x] = layer1_2Weight[x] / 100;
}
for (int x = 0; x <= 1; x++)
{
layer1_3Weight[x] = layer1_3Weight[x] / 100;
}
for (int x = 0; x <= 1; x++)
{
layer1_4Weight[x] = layer1_4Weight[x] / 100;
}
}
void training()
{
trainCycle++;
error = output1 - output2;
if (error < lastError)
{
lastError = error;
randomWeight = random(1, 9);
if (randomWeight == 1)
{
randomWeightVal = random(0, 3);
input1Weight[randomWeightVal] = input1Weight[randomWeightVal] + learningRate;
}
if (randomWeight == 2)
{
randomWeightVal = random(0, 3);
input2Weight[randomWeightVal] = input2Weight[randomWeightVal] + learningRate;
}
if (randomWeight == 3)
{
randomWeightVal = random(0, 3);
input3Weight[randomWeightVal] = input3Weight[randomWeightVal] + learningRate;
}
if (randomWeight == 4)
{
randomWeightVal = random(0, 3);
input4Weight[randomWeightVal] = input4Weight[randomWeightVal] + learningRate;
}
if (randomWeight == 5)
{
randomWeightVal = random(0, 2);
layer1_4Weight[randomWeightVal] = layer1_4Weight[randomWeightVal] + learningRate;
}
if (randomWeight == 6)
{
randomWeightVal = random(0, 2);
layer1_4Weight[randomWeightVal] = layer1_4Weight[randomWeightVal] + learningRate;
}
if (randomWeight == 7)
{
randomWeightVal = random(0, 2);
layer1_4Weight[randomWeightVal] = layer1_4Weight[randomWeightVal] + learningRate;
}
if (randomWeight == 8)
{
randomWeightVal = random(0, 2);
layer1_4Weight[randomWeightVal] = layer1_4Weight[randomWeightVal] + learningRate;
}
}
if (error > lastError)
{
if (randomWeight == 1)
{
randomWeightVal = random(0, 3);
input1Weight[randomWeightVal] = input1Weight[randomWeightVal] - (learningRate * 2);
}
if (randomWeight == 2)
{
randomWeightVal = random(0, 3);
input2Weight[randomWeightVal] = input2Weight[randomWeightVal] - (learningRate * 2);
}
if (randomWeight == 3)
{
randomWeightVal = random(0, 3);
input3Weight[randomWeightVal] = input3Weight[randomWeightVal] - (learningRate * 2);
}
if (randomWeight == 4)
{
randomWeightVal = random(0, 3);
input4Weight[randomWeightVal] = input4Weight[randomWeightVal] - (learningRate * 2);
}
if (randomWeight == 5)
{
randomWeightVal = random(0, 2);
layer1_4Weight[randomWeightVal] = layer1_4Weight[randomWeightVal] - (learningRate * 2);
}
if (randomWeight == 6)
{
randomWeightVal = random(0, 2);
layer1_4Weight[randomWeightVal] = layer1_4Weight[randomWeightVal] - (learningRate * 2);
}
if (randomWeight == 7)
{
randomWeightVal = random(0, 2);
layer1_4Weight[randomWeightVal] = layer1_4Weight[randomWeightVal] - (learningRate * 2);
}
if (randomWeight == 8)
{
randomWeightVal = random(0, 2);
layer1_4Weight[randomWeightVal] = layer1_4Weight[randomWeightVal] - (learningRate * 2);
}
}
}
void inputMapAndConvert()
{
//make LDR values between 0 and 1000 so thay can be can be converted to a value between 0 and 1.
input1Val = map(input1Val, 0, 1023, 0, 1000);
input2Val = map(input2Val, 0, 1023, 0, 1000);
input3Val = map(input3Val, 0, 1023, 0, 1000);
input4Val = map(input4Val, 0, 1023, 0, 1000);
// convert input value to a decimal between 0 and 1.
input1Val = input1Val / 1000;
input2Val = input2Val / 1000;
input3Val = input3Val / 1000;
input4Val = input4Val / 1000;
}
void layer1Val()
{
//determine layer 1 values based upon inputs and weights.
layer1_1Val = input1Val * input1Weight[0] + input2Val * input2Weight[0] + input3Val * input3Weight[0] + input4Val * input4Weight[0];
layer1_2Val = input1Val * input1Weight[1] + input2Val * input2Weight[1] + input3Val * input3Weight[1] + input4Val * input4Weight[1];
layer1_3Val = input1Val * input1Weight[2] + input2Val * input2Weight[2] + input3Val * input3Weight[2] + input4Val * input4Weight[2];
layer1_4Val = input1Val * input1Weight[3] + input2Val * input2Weight[3] + input3Val * input3Weight[3] + input4Val * input4Weight[3];
layer1_1Val = 1 / (1 + exp(-1 * layer1_1Val));
layer1_2Val = 1 / (1 + exp(-1 * layer1_2Val));
layer1_3Val = 1 / (1 + exp(-1 * layer1_3Val));
layer1_4Val = 1 / (1 + exp(-1 * layer1_4Val));
}