Go Down

Topic: Deep Think Project - Artificial Intelligence Research Project (Read 22745 times) previous topic - next topic

AWOL

Quote
, but I get no output.
Because you've got no input?

goodinventor

#211
May 09, 2016, 02:41 pm Last Edit: May 09, 2016, 02:43 pm by goodinventor
I couldn't test it because "fatal error: vector: No such file or directory" but I'd just start commenting things out until it starts working and then add things back in until you find out what is causing the problem.
It is one of the C++ standard libraries. I suppose then that the Arduino environment really doesn't support some of the standard libraries.

Because you've got no input?
I just set up some Serial output so that I can make sure the cost function is working. I still have a whole other process to get working (the gradient descent part). I decided to check each function as I program it so that I can troubleshoot more effectively.

pert

Yes, I found some instructions for how to install it but wasn't that motivated.

goodinventor

Yes, I found some instructions for how to install it but wasn't that motivated.
I understand that. You probably see little point in going through that much trouble to troubleshoot someone else's problem.

ChrisTenone

I understand that. You probably see little point in going through that much trouble to troubleshoot someone else's problem.
When posted code doesn't compile, it's easy to understand why folks wouldn't want to alpha-test it, right? I mean, then say someone found something else that didn't work as expected. Would your reply be another admonition to the tester?
What, I need to say something else too?

goodinventor

When posted code doesn't compile, it's easy to understand why folks wouldn't want to alpha-test it, right? I mean, then say someone found something else that didn't work as expected. Would your reply be another admonition to the tester?
Exactly. My code probably still has lots of bugs since I'm not getting any feedback from the terminal. This means that either something was wrong with the connection to the terminal (I doubt it though since I tested it several times) or my output code never executed properly (somewhere my execution is cut off). I think the second problem is much more likely.

goodinventor

I have a full implementation now. I get the following output.

Code: [Select]

Starting...
Computing gradient descent...


My problem is that it doesn't return the values of MyNode->theta_0 and MyNode->theta_1. Any ideas on what I am doing wrong? The code is below.

Code: [Select]

//
// Deep Think 0.0.0.5
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Implement a basic deep learning algorithm (created by the
//    programmer) to choose what course of action to take (a
//    limited number of options).
// 2. Implement a basic system for conversation via the Serial port
//    (this means the robot generates output in response to the
//    user's input).
//
// This version of the program starts dealing with a different
// problem than the previous versions. It handles the
// intelligence aspect of the robot rather than the motors and
// sensors. Later versions will incorporate both once the
// intelligence capabilities have matured. I expect this will be a
// valuable learning process that will help the project succeed in
// the future.
//

//
// Preprocessor Section
//

//
// Let the file be included only once in compilation.
//
#pragma once

//
// Makes sure the appropriate compiler is being used.
//
#ifndef __cplusplus
  #error "A C++ compiler is required."
#endif

//
// Makes sure the appropriate Arduino header is included.
//
#if (ARDUINO >= 100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

//
// The other necessary headers are included here.
//

//
// Namespaces
//
using namespace std;

//
// Classes
//

class Node
{
  public:
    //
    // This is to keep track of xi and yi during the summation.
    //
    int col = 0;
   
    //
    // Here is the training set size, which will be used in the calculations.
    //
    int TrainingSetSize = 3;
   
    //
    // Here is the learning rate, which will be adjusted by
    // experimentation until the desired results are achieved.
    //
    float LearningRate = 0;
   
    //
    // Here is the training set to test the algorithm.
    //
    float TrainingSet[2][3] =
    {
      {1.0, 2.0, 3.0}, // row 0 = 1.0, 2.0, 3.0
      {1.0, 2.0, 3.0}  // row 1 = 1.0, 2.0, 3.0
    };
   
    //
    // These variables denote the ith element of x and y
    // respectively in the training set, where x corresponds
    // to row 0 in the training set and y corresponds to row
    // 1 in the training set.
    //
    float xi = TrainingSet[0][col];
    float yi = TrainingSet[1][col];
   
    //
    // These variables are used in the hypothesis function. For this
    // machine learning example h_theta(x) = theta_0 + theta_1 * x.
    //
    float theta_0 = 0;
    float theta_1 = 0;
   
    //
    // Compute the hypothesis function.
    //
    float h_theta(float xi)
    {
      return (theta_0 + theta_1 * xi);
    }
   
    //
    // Computes the summation of (h_theta(xi) - yi)^2, where
    // h_theta(xi) is the hypothesis function of the ith element
    // of x in the training set (xi) and yi is the ith element of
    // y in the training set. This function will be used to
    // compute the cost function.
    //
    float ComputeSummationOfSquareOfDifferenceBetweenH_ThetaAndYI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += pow(h_theta(xi) - yi, 2);
       
        //
        // Update the column for xi and yi.
        //
        col++;
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      return sum;
    }
   
    //
    // Computes the summation of (h_theta(xi) - yi).
    //
    float ComputeSummationOfDifferenceBetweenH_ThetaAndYI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += (h_theta(xi) - yi);
       
        //
        // Update the column for xi and yi.
        //
        col++;
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      return sum;
    }
   
    //
    // Computes the summation of xi * (h_theta(xi) - yi).
    //
    float ComputeSummationOfDifferenceBetweenH_ThetaAndYIMultipliedByXI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += xi * (h_theta(xi) - yi);
       
        //
        // Update the column for xi and yi.
        //
        col++;
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      return sum;
    }
   
    //
    // Computes the cost function.
    //
    float ComputeCostFunction()
    {
      float cost = (1 / (2 * TrainingSetSize)) * ComputeSummationOfSquareOfDifferenceBetweenH_ThetaAndYI(TrainingSetSize);
      return cost;
    }
   
    //
    // Updates theta_0 and theta_1 using gradient descent.
    //
    void UpdateGradientDescent()
    {
      //
      // We can't assign the values directly to theta_0 and theta_1 because they are dependent
      // on each other, therefore the assignment must be simultaneous.
      //
      float new_theta_0 = (LearningRate / TrainingSetSize) * ComputeSummationOfDifferenceBetweenH_ThetaAndYI(TrainingSetSize);
      float new_theta_1 = (LearningRate / TrainingSetSize) * ComputeSummationOfDifferenceBetweenH_ThetaAndYIMultipliedByXI(TrainingSetSize);
     
      theta_0 = new_theta_0;
      theta_1 = new_theta_1;
    }
};

//
// Class Objects
//

//
// Create a Node class object here.
//
Node *MyNode;

void setup()
{
  Serial.begin(9600);
 
  while (!Serial)
  {
    ; // wait for Serial port to connect
  }
 
  //
  // Test to make sure Serial is working.
  //
  Serial.println("Starting...");
}

void loop()
{
  Serial.println("Computing gradient descent...");
 
  //
  // Update theta0 and theta1 using gradient descent.
  // ComputeCostFunction is not used here, since the gradient
  // descent algorithm incorporates it (partial derivative
  // of the cost function for j = 0 and j = 1 for theta_j),
  // although it is included since it will likely be used later.
  //
  MyNode->UpdateGradientDescent();
 
  //
  // Print results for observation and analysis.
  //
  Serial.print("theta_0");
  delay(1000);
  Serial.println(MyNode->theta_0, DEC);
  delay(1000);
  Serial.print("theta_1");
  delay(1000);
  Serial.println(MyNode->theta_1, DEC);
  delay(2000);
}

el_supremo

It prints this for me on a Nano:
Code: [Select]
Starting...
Computing gradient descent...
theta_00.0000000000
theta_10.0000000000
Computing gradient descent...
theta_00.0000000000
theta_10.0000000000
Computing gradient descent...
theta_00.0001193267
theta_10.0000000000
Computing gradient descent...
theta_020485726.0000000000
theta_10.0000000000
Computing gradient descent...
theta_0ovf
theta_10.0000000000

etc...
Don't send me technical questions via Private Message.

goodinventor

OK, thanks. I need to include a space in between the theta_0/theta_1 and the numbers. Based on this my learning rate is likely wrong (it needs to not be 0). But it's good that the function works.

goodinventor

I've cleaned up my code a little so that the summations work properly. My output looks like below.

Code: [Select]

Starting...
Computing gradient descent...
theta_0 ovf
theta_1 0.0000000000
Computing gradient descent...
theta_0 nan
theta_1 0.0000000000
Computing gradient descent...
theta_0 nan
theta_1 0.0000000000
...etc


Below is my code.

Code: [Select]

//
// Deep Think 0.0.0.5
//
// programmed by George Andrews
//
// NOTE: This program is designed for the Meccanoid G15 (combined
// with the 86Duino One). It is a part of the Deep Think Project
// (first version of the software for the project). The Deep Think
// Project is designed to advance the intelligence (as well as
// motion and structural capabilities) of humanoid robots. This
// version of the program is designed to do the following.
//
// 1. Implement a basic deep learning algorithm (created by the
//    programmer) to choose what course of action to take (a
//    limited number of options).
// 2. Implement a basic system for conversation via the Serial port
//    (this means the robot generates output in response to the
//    user's input).
//
// This version of the program starts dealing with a different
// problem than the previous versions. It handles the
// intelligence aspect of the robot rather than the motors and
// sensors. Later versions will incorporate both once the
// intelligence capabilities have matured. I expect this will be a
// valuable learning process that will help the project succeed in
// the future.
//

//
// Preprocessor Section
//

//
// Let the file be included only once in compilation.
//
#pragma once

//
// Makes sure the appropriate compiler is being used.
//
#ifndef __cplusplus
  #error "A C++ compiler is required."
#endif

//
// Makes sure the appropriate Arduino header is included.
//
#if (ARDUINO >= 100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

//
// The other necessary headers are included here.
//

//
// Namespaces
//
using namespace std;

//
// Classes
//

class Node
{
  public:
    //
    // This is to keep track of xi and yi during the summation.
    //
    int col = 0;
   
    //
    // Here is the training set size, which will be used in the calculations.
    //
    int TrainingSetSize = 3;
   
    //
    // Here is the learning rate, which will be adjusted by
    // experimentation until the desired results are achieved.
    //
    float LearningRate = 1;
   
    //
    // Here is the training set to test the algorithm.
    //
    float TrainingSet[2][3] =
    {
      {1.0, 2.0, 3.0}, // row 0 = 1.0, 2.0, 3.0
      {1.0, 2.0, 3.0}  // row 1 = 1.0, 2.0, 3.0
    };
   
    //
    // These variables denote the ith element of x and y
    // respectively in the training set, where x corresponds
    // to row 0 in the training set and y corresponds to row
    // 1 in the training set.
    //
    float xi = TrainingSet[0][col];
    float yi = TrainingSet[1][col];
   
    //
    // These variables are used in the hypothesis function. For this
    // machine learning example h_theta(x) = theta_0 + theta_1 * x.
    //
    float theta_0 = 0;
    float theta_1 = 0;
   
    //
    // Compute the hypothesis function.
    //
    float h_theta(float xi)
    {
      return (theta_0 + theta_1 * xi);
    }
   
    //
    // Computes the summation of (h_theta(xi) - yi)^2, where
    // h_theta(xi) is the hypothesis function of the ith element
    // of x in the training set (xi) and yi is the ith element of
    // y in the training set. This function will be used to
    // compute the cost function.
    //
    float ComputeSummationOfSquareOfDifferenceBetweenH_ThetaAndYI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += pow(h_theta(xi) - yi, 2);
       
        //
        // Update the column for xi and yi.
        //
        xi = TrainingSet[0][col++];
        yi = TrainingSet[1][col++];
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      xi = TrainingSet[0][col];
      yi = TrainingSet[1][col];
     
      return sum;
    }
   
    //
    // Computes the summation of (h_theta(xi) - yi).
    //
    float ComputeSummationOfDifferenceBetweenH_ThetaAndYI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += (h_theta(xi) - yi);
       
        //
        // Update the column for xi and yi.
        //
        col++;
       
        xi = TrainingSet[0][col];
        yi = TrainingSet[1][col];
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      xi = TrainingSet[0][col];
      yi = TrainingSet[1][col];
     
      return sum;
    }
   
    //
    // Computes the summation of xi * (h_theta(xi) - yi).
    //
    float ComputeSummationOfDifferenceBetweenH_ThetaAndYIMultipliedByXI(int maxval)
    {
      float sum = 0;
     
      for (int i = 1; i <= maxval; ++i)
      {
        //
        // Update the sum.
        //
        sum += xi * (h_theta(xi) - yi);
       
        //
        // Update the column for xi and yi.
        //
        col++;
       
        xi = TrainingSet[0][col];
        yi = TrainingSet[1][col];
      }
     
      //
      // Reset col.
      //
      col = 0;
     
      xi = TrainingSet[0][col];
      yi = TrainingSet[1][col];
     
      return sum;
    }
   
    //
    // Computes the cost function.
    //
    float ComputeCostFunction()
    {
      float cost = (1 / (2 * TrainingSetSize)) * ComputeSummationOfSquareOfDifferenceBetweenH_ThetaAndYI(TrainingSetSize);
      return cost;
    }
   
    //
    // Updates theta_0 and theta_1 using gradient descent.
    //
    void UpdateGradientDescent()
    {
      //
      // We can't assign the values directly to theta_0 and theta_1 because they are dependent
      // on each other, therefore the assignment must be simultaneous.
      //
      float new_theta_0 = (LearningRate / TrainingSetSize) * ComputeSummationOfDifferenceBetweenH_ThetaAndYI(TrainingSetSize);
      float new_theta_1 = (LearningRate / TrainingSetSize) * ComputeSummationOfDifferenceBetweenH_ThetaAndYIMultipliedByXI(TrainingSetSize);
     
      theta_0 = new_theta_0;
      theta_1 = new_theta_1;
    }
};

//
// Class Objects
//

//
// Create a Node class object here.
//
Node *MyNode;

void setup()
{
  Serial.begin(9600);
 
  while (!Serial)
  {
    ; // wait for Serial port to connect
  }
 
  //
  // Test to make sure Serial is working.
  //
  Serial.println("Starting...");
}

void loop()
{
  Serial.println("Computing gradient descent...");
 
  //
  // Update theta0 and theta1 using gradient descent.
  // ComputeCostFunction is not used here, since the gradient
  // descent algorithm incorporates it (partial derivative
  // of the cost function for j = 0 and j = 1 for theta_j),
  // although it is included since it will likely be used later.
  //
  MyNode->UpdateGradientDescent();
 
  //
  // Print results for observation and analysis.
  //
  Serial.print("theta_0 ");
  delay(1000);
  Serial.println(MyNode->theta_0, DEC);
  delay(1000);
  Serial.print("theta_1 ");
  delay(1000);
  Serial.println(MyNode->theta_1, DEC);
  delay(2000);
}


The interesting thing about the code is that theta_0 outputs characters and theta_1 remains 0 (for this run). Also, when I run the same code more than once it will oftentimes come to different results. What is going on here?? I calculated the math on my calculator, and according to it my implementation is correct. So is there a problem with the Serial?

goodinventor

Just to make sure my algorithm works I'll test it on Octave instead of the Arduino, so I can verify that my implementation is correct. Then I'll post my results here.

goodinventor

I'm now beginning to research sensors for use in a basic obstacle detection system, now that I have the servos working and the machine learning research is coming along nicely. I'm thinking of mounting the mechanism in the head (it can be the eyes of the robot). Right now at this moment my biggest problem is keeping the sensitive electronics save. Is there any kind of good quality enclosure that can be mounted vertically that you would recommend? Also, at some point (maybe in a year or so, or less, depending on how progress goes), I am looking into a basic camera system for use with the Arduino.

I was thinking of something like this:

http://www.robotshop.com/en/pixy-cmucam5-image-sensor.html

Of course, there are likely plenty of better options, as I haven't done very much research yet (I have learned over time that it is better to spend a lot of time planning rather than diving right into things so that I can get better results). Any advice for working with sensors (particularly vision/obstacle detection related ones) would be greatly appreciated.

Thanks for reading,
goodinventor

Go Up