Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) TestNeuralNet

 

TestNeuralNet is a tool to test the NeuralNet class.

 

TestNeuralNet is programmed in C++ using the IDE Qt Creator. It uses the Boost, Qt, Shark and STL libraries.

 

 

 

 

Downloads

 

Technical facts

 

Application type(s)

Operating system(s) or programming environment(s)

IDE(s):

Project type:

C++ standard:

Compiler(s):

Libraries used:

 

 

 

 

 

Qt project file: ./ToolTestNeuralNet/ToolTestNeuralNet.pro

 

QT       += core gui

CONFIG(debug, debug|release) {
  message(Building debug version)

} else {
  DEFINES += NDEBUG
  message(Building release version)
}
TEMPLATE = app
LIBS += -L/usr/local/lib -lshark

SOURCES += main.cpp\
        dialogmain.cpp \
    neuralnet.cpp \
    dialogabout.cpp

HEADERS  += dialogmain.h \
    neuralnet.h \
    dialogabout.h

FORMS    += dialogmain.ui \
    dialogabout.ui

RESOURCES += \
    ToolTestNeuralNet.qrc

 

 

 

 

 

./ToolTestNeuralNet/dialogabout.h

 

//---------------------------------------------------------------------------
/*
TestNeuralNet, tool to test the NeuralNet class
Copyright (C) 2010 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolTestNeuralNet.htm
//---------------------------------------------------------------------------
#ifndef DIALOGABOUT_H
#define DIALOGABOUT_H
//---------------------------------------------------------------------------
#include <string>
//---------------------------------------------------------------------------
#include <QDialog>
//---------------------------------------------------------------------------
namespace Ui {
  class DialogAbout;
}
//---------------------------------------------------------------------------
class DialogAbout : public QDialog
{
  Q_OBJECT

public:
  explicit DialogAbout(QWidget *parent = 0);
  ~DialogAbout();

protected:
  void changeEvent(QEvent *e);

private:
  Ui::DialogAbout *ui;
};
//---------------------------------------------------------------------------
///GetBoostVersion returns the version of the current Boost library.
///From http://www.richelbilderbeek.nl/CppGetBoostVersion.htm
const std::string GetBoostVersion();
//---------------------------------------------------------------------------
#endif // DIALOGABOUT_H

 

 

 

 

 

./ToolTestNeuralNet/dialogabout.cpp

 

//---------------------------------------------------------------------------
/*
TestNeuralNet, tool to test the NeuralNet class
Copyright (C) 2010 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolTestNeuralNet.htm
//---------------------------------------------------------------------------
#include <algorithm>
#include <string>
//---------------------------------------------------------------------------
#include <boost/version.hpp>
//---------------------------------------------------------------------------
#include "dialogabout.h"
#include "dialogmain.h"
#include "ui_dialogabout.h"
#include "neuralnet.h"
//---------------------------------------------------------------------------
DialogAbout::DialogAbout(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogAbout)
{
  ui->setupUi(this);

  QObject::connect(ui->button_about_qt,SIGNAL(clicked()),
    qApp,SLOT(aboutQt()));

  ui->label_title->setText(
    QString("TestNeuralNet version ")
    + QString(DialogMain::GetVersion().c_str()));


  ui->label_boost_version->setText(
    QString("Boost version: ")
    + QString(GetBoostVersion().c_str()));

  ui->label_neuralnet_version->setText(
    QString("NeuralNet version: ")
    + QString(NeuralNet::GetVersion().c_str()));

}
//---------------------------------------------------------------------------
DialogAbout::~DialogAbout()
{
  delete ui;
}
//---------------------------------------------------------------------------
void DialogAbout::changeEvent(QEvent *e)
{
  QDialog::changeEvent(e);
  switch (e->type()) {
  case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
  default:
    break;
  }
}
//---------------------------------------------------------------------------
///GetBoostVersion returns the version of the current Boost library.
///From http://www.richelbilderbeek.nl/CppGetBoostVersion.htm
const std::string GetBoostVersion()
{
  std::string s = BOOST_LIB_VERSION;
  std::replace(s.begin(),s.end(),'_','.');
  return s;
}
//---------------------------------------------------------------------------

 

 

 

 

 

./ToolTestNeuralNet/dialogmain.h

 

//---------------------------------------------------------------------------
/*
TestNeuralNet, tool to test the NeuralNet class
Copyright (C) 2010 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolTestNeuralNet.htm
//---------------------------------------------------------------------------
#ifndef DIALOGMAIN_H
#define DIALOGMAIN_H
//---------------------------------------------------------------------------
#include <string>
//---------------------------------------------------------------------------
#include <QDialog>
//---------------------------------------------------------------------------
namespace Ui {
  class DialogMain;
}
//---------------------------------------------------------------------------
class DialogMain : public QDialog
{
  Q_OBJECT

public:
  explicit DialogMain(QWidget *parent = 0);
  ~DialogMain();
  static const std::string GetVersion() { return "0.1"; }

protected:
  void changeEvent(QEvent *e);

private:
  Ui::DialogMain *ui;

private slots:
  void onAbout();
};
//---------------------------------------------------------------------------
#endif // DIALOGMAIN_H

 

 

 

 

 

./ToolTestNeuralNet/dialogmain.cpp

 

//---------------------------------------------------------------------------
/*
TestNeuralNet, tool to test the NeuralNet class
Copyright (C) 2010 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolTestNeuralNet.htm
//---------------------------------------------------------------------------
#include "dialogabout.h"
#include "dialogmain.h"
#include "ui_dialogmain.h"
//---------------------------------------------------------------------------
DialogMain::DialogMain(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogMain)
{
  ui->setupUi(this);

  QObject::connect(ui->button_about,SIGNAL(clicked()),
    this,SLOT(onAbout()));
}
//---------------------------------------------------------------------------
DialogMain::~DialogMain()
{
  delete ui;
}
//---------------------------------------------------------------------------
void DialogMain::changeEvent(QEvent *e)
{
  QDialog::changeEvent(e);
  switch (e->type()) {
  case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
  default:
    break;
  }
}
//---------------------------------------------------------------------------
void DialogMain::onAbout()
{
  DialogAbout d;
  d.exec();
}
//---------------------------------------------------------------------------

 

 

 

 

 

./ToolTestNeuralNet/main.cpp

 

//---------------------------------------------------------------------------
/*
TestNeuralNet, tool to test the NeuralNet class
Copyright (C) 2010 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/ToolTestNeuralNet.htm
//---------------------------------------------------------------------------
#include <QApplication>
#include "dialogmain.h"
//---------------------------------------------------------------------------
int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  DialogMain w;
  w.show();
  return a.exec();
}
//---------------------------------------------------------------------------

 

 

 

 

 

./ToolTestNeuralNet/neuralnet.h

 

//---------------------------------------------------------------------------
/*
NeuralNet, a three-layered perceptron class
Copyright (C) 2010 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppNeuralNet.htm
//---------------------------------------------------------------------------
#ifndef NEURALNET_H
#define NEURALNET_H
//---------------------------------------------------------------------------
#include <Array/Array.h>
#include <ReClaM/FFNet.h>
//---------------------------------------------------------------------------
///NeuralNet is a derived class of FFNet
///to gain access to some protected member functions of FFNet
struct NeuralNet : public FFNet
{
  NeuralNet(
    const int n_inputs,
    const int n_hidden_neurons,
    const int n_outputs);

  ///Copy constructor
  NeuralNet(const NeuralNet& n);
  ///Assignment operator
  NeuralNet& operator=(const NeuralNet& n);

  ///Propagate creates the output of a neural network for certain inputs
  std::vector<double> Propagate(const std::vector<double> &inputs) const;

  std::vector<int> GetConnections() const;
  int GetNumberOfInputs() const;
  int GetNumberOfHiddenNeurons() const;
  int GetNumberOfNeurons() const;
  int GetNumberOfOutputs() const;

  ///Read the output value from any neuron
  double GetOutputValue(const int index) const;

  std::vector<double> GetWeights() const;
  void Mutate(const double m);

  static const std::string GetVersion() { return "1.0"; }

  private:
  ///Wrapper member function due to clumsy createConnectionMatrix behavior
  Array<int> CreateConnectionMatrix(
    const int n_inputs,
    const int n_hidden_neurons,
    const int n_outputs) const;
  int m_number_of_inputs;
  int m_number_of_hidden_neurons;
  int m_number_of_outputs;

  ///Activate uses default FFNet::activate member function
  ///Use Propagate instead
  void Activate(const Array<double> &inputs) const;

  ///Use Propagate instead
  std::vector<double> PropagateArray(const Array<double> &inputs) const;

  ///Read the output from the output layer from this neural network
  ///Use Propagate instead
  std::vector<double> GetOutputLayerOutputValues() const;

  void Swap(NeuralNet& rhs);

  friend bool operator==(const NeuralNet& lhs, const NeuralNet& rhs);
};
//---------------------------------------------------------------------------
bool operator==(const NeuralNet& lhs, const NeuralNet& rhs);
//---------------------------------------------------------------------------
///GetRandomUniform draws a random number in range [0,1>
///From http://www.richelbilderbeek.nl/CppGetRandomUniform.htm
double GetRandomUniform();
//---------------------------------------------------------------------------
template <class T>
std::vector<T> ConvertToVector(const Array<T> a)
{
  return std::vector<T>(a.begin(),a.end());
}
//---------------------------------------------------------------------------
template <class T>
Array<T> ConvertToArray(const std::vector<T>& v)
{
  Array<T> a;
  std::vector<T> v_copy(v); //This is terrible!
  a.append_elems(v_copy);
  return a;
}
//---------------------------------------------------------------------------
#endif // NEURALNET_H

 

 

 

 

 

./ToolTestNeuralNet/neuralnet.cpp

 

//---------------------------------------------------------------------------
/*
NeuralNet, a three-layered perceptron class
Copyright (C) 2010 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppNeuralNet.htm
//---------------------------------------------------------------------------
#include <cassert>
#include <cstdlib>
//---------------------------------------------------------------------------
#include <boost/numeric/conversion/cast.hpp>
#include <boost/foreach.hpp>
//---------------------------------------------------------------------------
#include <ReClaM/createConnectionMatrix.h>
//---------------------------------------------------------------------------
#include "neuralnet.h"
//---------------------------------------------------------------------------
NeuralNet::NeuralNet(
  const int n_inputs,
  const int n_hidden_neurons,
  const int n_outputs)
  : FFNet(
    n_inputs,
    n_outputs,
    CreateConnectionMatrix(n_inputs,n_hidden_neurons,n_outputs)),
    m_number_of_inputs(n_inputs),
    m_number_of_hidden_neurons(n_hidden_neurons),
    m_number_of_outputs(n_outputs)
{
  assert(boost::numeric_cast<int>(this->numberOfNeurons)
    == m_number_of_inputs
     + m_number_of_hidden_neurons
     + m_number_of_outputs
    && "Assume no neurons are lost in translation");
  assert(boost::numeric_cast<int>(this->numberOfNeurons)
    == this->GetNumberOfNeurons()
      && "Assume GetNumberOfNeurons() works fine");
}
//---------------------------------------------------------------------------
///Calls FFNet's copy constructor
NeuralNet::NeuralNet(const NeuralNet& n)
  : FFNet(n),
    m_number_of_inputs(n.m_number_of_inputs),
    m_number_of_hidden_neurons(n.m_number_of_hidden_neurons),
    m_number_of_outputs(n.m_number_of_outputs)
{
  //Cannot assert this internally, because it causes
  //an infinite function call stack
  //assert(n == *this);
}
//---------------------------------------------------------------------------
  ///Assignment operator
NeuralNet& NeuralNet::operator=(const NeuralNet& other)
{
  NeuralNet temp(other);
  Swap(temp);
  return *this;
}
//---------------------------------------------------------------------------
void NeuralNet::Swap(NeuralNet& other)
{
  std::swap(m_number_of_inputs,other.m_number_of_inputs);
  std::swap(m_number_of_hidden_neurons,other.m_number_of_hidden_neurons);
  std::swap(m_number_of_outputs,other.m_number_of_outputs);
  //Pray this works
  std::swap(connectionMatrix,other.connectionMatrix);
  std::swap(weightMatrix,other.weightMatrix);
}
//---------------------------------------------------------------------------
Array<int> NeuralNet::CreateConnectionMatrix(
  const int n_inputs,
  const int n_hidden,
  const int n_outputs) const
{
  Array<int> m;
  createConnectionMatrix(m,n_inputs, n_hidden, n_outputs);
  return m;
}
//---------------------------------------------------------------------------
///Activate uses default FFNet::activate member function
///FFNet::activate is not a const member function
///The code below proofs that the FFNet is not
///changed, so this member function could have been a const-member function.
///Prefer to use the const-correct Propagate member function
void NeuralNet::Activate(const Array<double> &inputs) const
{
  //I promise not to change anything
  NeuralNet * const n = const_cast<NeuralNet*>(this);

  #define CHECK_ARCHITECTURE_762347632476
  #ifdef  CHECK_ARCHITECTURE_762347632476
  const NeuralNet before(*this);
  #endif

  n->activate(inputs);

  #ifdef  CHECK_ARCHITECTURE_762347632476
  const NeuralNet after(*this);
  assert(before == after
    && "Proof that neural net does not change");
  #endif
}
//---------------------------------------------------------------------------
std::vector<int> NeuralNet::GetConnections() const
{
  #define CHECK_ARCHITECTURE_165254
  #ifdef  CHECK_ARCHITECTURE_165254
  {
    //Read the original connection matrix
    const Array<int> a_copy = this->connectionMatrix;
    //I promise not to change this NeuralNet
    NeuralNet * n = const_cast<NeuralNet*>(this);
    const Array<int> a = n->getConnections();
    assert(a == a_copy);
  }
  #endif

  const std::vector<int> v = ConvertToVector(this->connectionMatrix);
  return v;
}
//---------------------------------------------------------------------------
int NeuralNet::GetNumberOfInputs() const
{
  return m_number_of_inputs;
}
//---------------------------------------------------------------------------
int NeuralNet::GetNumberOfHiddenNeurons() const
{
  return m_number_of_hidden_neurons;
}
//---------------------------------------------------------------------------
int NeuralNet::GetNumberOfNeurons() const
{
  return boost::numeric_cast<int>(this->numberOfNeurons);
}
//---------------------------------------------------------------------------
int NeuralNet::GetNumberOfOutputs() const
{
  return m_number_of_outputs;
}
//---------------------------------------------------------------------------
std::vector<double> NeuralNet::GetWeights() const
{
  const std::vector<double> v = ConvertToVector(this->weightMatrix);
  return v;
}
//---------------------------------------------------------------------------
double NeuralNet::GetOutputValue(const int index) const
{
  assert(index >= 0 && index < this->GetNumberOfNeurons());
  //I promise not to change anything
  NeuralNet * const n = const_cast<NeuralNet*>(this);
  const double output = n->outputValue(index);
  return output;
}
//---------------------------------------------------------------------------
std::vector<double> NeuralNet::GetOutputLayerOutputValues() const
{
  std::vector<double> v;

  int i = GetNumberOfInputs() + GetNumberOfHiddenNeurons();
  assert(i == m_number_of_inputs + m_number_of_hidden_neurons);
  const int j = this->GetNumberOfNeurons();
  assert(i<=j);

  v.reserve(j-i);

  for ( ; i!=j; ++i)
  {
    const double x = this->GetOutputValue(i);
    v.push_back(x);
  }

  assert(boost::numeric_cast<int>(v.size())
    == this->GetNumberOfOutputs());

  return v;
}
//---------------------------------------------------------------------------
///Due to funny Array behavior, it is needed
///to implement Mutate a bit clumsily
void NeuralNet::Mutate(const double m)
{
  Array<double> weights = this->getWeights();
  BOOST_FOREACH(double& x,weights)
  {
    x+= (GetRandomUniform() * (2.0 * m)) - m;
  }
  this->weightMatrix = weights;
}
//---------------------------------------------------------------------------
///Propagate creates the output of a neural network for certain inputs
std::vector<double> NeuralNet::PropagateArray(const Array<double> &inputs) const
{
  //I promise not to change anything
  NeuralNet * const n = const_cast<NeuralNet*>(this);
  //Activate the neural network
  this->Activate(inputs);
  //Obtain the output layer's output
  std::vector<double> v = n->GetOutputLayerOutputValues();
  assert(boost::numeric_cast<int>(v.size())
    == this->GetNumberOfOutputs());
  return v;
}
//---------------------------------------------------------------------------
std::vector<double> NeuralNet::Propagate(const std::vector<double> &inputs) const
{
  const Array<double> a = ConvertToArray(inputs);
  return this->PropagateArray(a);
}
//---------------------------------------------------------------------------
//Cannot call member functions, because it causes
//an infinite function call stack:
bool operator==(const NeuralNet& lhs, const NeuralNet& rhs)
{
  return (
     lhs.m_number_of_inputs == rhs.m_number_of_inputs
  && lhs.m_number_of_hidden_neurons == rhs.m_number_of_hidden_neurons
  && lhs.m_number_of_outputs == rhs.m_number_of_outputs
  && lhs.connectionMatrix == rhs.connectionMatrix
  && lhs.weightMatrix == rhs.weightMatrix);
}
//---------------------------------------------------------------------------
//From http://www.richelbilderbeek.nl/CppGetRandomUniform.htm
double GetRandomUniform()
{
  return static_cast<double>(std::rand())/static_cast<double>(RAND_MAX);
}
//---------------------------------------------------------------------------

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml