Hi guys,

I'd like some advice on designing and implementing my neural network class. It has three input neurons, four hidden neurons (one of which is a bias neuron, having the connections from the input layer of weight 1.0), and one output neuron.

It's goal is to determine where (x, y, z) lies in relation to a given 3D function.

Here's the code I have so far:

Typedefs.hpp
Code:
#ifndef TYPEDEF_HPP
#define TYPEDEF_HPP
#include <vector>
#include <random>

typedef std::vector <float>FloatV;
typedef std::random_device RNG;
typedef std::uniform_int_distribution <> UID;

#endif
BadInput.hpp
Code:
#ifndef BADINPUT_HPP
#define BADINPUT_HPP

class BadInput
{
  public:
	BadInput(int val):difference(val)
	{
	}
	int difference;
};

#endif
Functor.hpp
Code:
#ifndef FUNCTOR_HPP
#define FUNCTOR_HPP
#include "Typedefs.hpp"

class Functor
{
  public:
	Functor();
	Functor(const Functor & rhs) = default;
   virtual ~Functor() =default; 
	virtual float operator() (const FloatV  & input) const =0;
	virtual int GetArgNum() const =0;
};

class Plane: public Functor
{
  public:
	Plane() = delete;
	Plane(const FloatV& values);
	Plane(const Plane & rhs) = default;
	 virtual ~Plane() = default; 
	virtual float operator() (const FloatV & input) const;
	virtual int GetArgNum() const;
  private:
     const int argnum;
     const FloatV cf;
};

#endif
Functor.cpp
Code:
#include "BadInput.hpp"
#include "Functor.hpp"
#include <iostream>

Functor::Functor()
{
}

Functor::~Functor()
{
}

Plane::Plane(const FloatV& val):cf(val), argnum(2)
{
}

float Plane::operator() (const FloatV & input) const
	{ 
		if (input.size() != argnum)
		{
			int val = input.size() - argnum;
			BadInput error(val);
			std::cerr << "Number of arguments is " << val << " more than the maximum arguments of two for this function." << std::endl;
			throw error;
		}
		
		 vector < future < float >>results(input.size());
		 auto sum =[this, input] (int i)->float { return input[i] * cf[i];
		 }
		 for (int i = 0; i < input.size(); i++)
			 results.push_back(async(sum, i));
		 float sumofprod =0;
	   for (auto & result:results)
			 sumofprod += result.get();
		 return sumofprod += cf.back();	
}
	
	int Plane::GetArgNum() const
	{
		return argnum;
	}
Trainer.hpp
Code:
#ifndef TRAINER_HPP
#define TRAINER_HPP
#include "Typedefs.hpp"
#include "Functor.hpp"

class Trainer
{
  public:
	Trainer() = delete;
	Trainer(const Functor& function);
	void GenerateData();
	  FloatV& GetData();
	int GetAnswer() const;
  private:
	const Functor& f;
	mutable FloatV TrainingData;
	mutable int answer;
};

#endif
Trainer.cpp
Code:
#include "BadInput.hpp"
#include "Trainer.hpp"
#include <future>
using std::async; 

namespace
{
	RNG rand;
}

Trainer::Trainer(const Functor& function):f(function),
TrainingData(f.GetArgNum())
{
}

void Trainer::GenerateData()
{
	auto randomize = [this](int i) {TrainingData[i]=rand();}
	
    for (int i =0; i < TrainingData.size(); i++)
    async(randomize, TrainingData[i]);	
	
	float z;
	try
	{
		z = f(TrainingData);
	}
	catch(BadInput&)
	{
		throw;
	}
	TrainingData.push_back(rand());
	if (TrainingData.back() < z)
		answer = -1;
	else
		answer = 1;
}

FloatV& Trainer::GetData()
{
	return TrainingData;
}

int Trainer::GetAnswer() const
{
	return answer;
}
Perceptron.hpp
Code:
#ifndef PERCEPTRON_HPP
#define PERCEPTRON_HPP
#include "Typedefs.hpp"
#include "Trainer.hpp"

class Perceptron
{
  public:
    Perceptron() = delete;
	Perceptron(int val);
	~Perceptron();
	float feedforward(FloatV& input);
  private:
	FloatV weights;
	static const float bias;
	static const float correction;
};
#endif
Perceptron.cpp
Code:
#include "BadInput.hpp"
#include "Perceptron.hpp"
#include <iostream>
#include <cmath>
#include <future>
using std::async;
using std::future;
using std::exp;

const float Perceptron::bias = 1.0;
const float Perceptron::correction = 0.01;

namespace
{
	UID rand(-1, 1);
    RNG rng;
}

Perceptron::Perceptron(int val):weights(rand(rng))
{
}

Perceptron::~Perceptron()
{
}

int Perceptron::feedforward(FloatV& input)
{
	float sum = 0;
	input.push_back(bias);
	if (input.size() != weights.size())
	{
		BadInput error(input.size() - weights.size());
		std::cerr << "Biased input is " << error.difference <<
			" value different from the number of weights in the perceptron." <<
			std::endl;
		throw error;
	}
	
	vector <future<float>> results;
	 auto WeightedInput = [this](float x) -> float {return x*weights[i];}
	for (int i=0; i < input.size(); i++)		   results.push_back(async(WeightedInput, input[i]));
	
	float sum=0;
	for(auto& result: results)
	sum += result.get();
	
	return 1.0/(1.0 + exp(-sum));	
}
NeuralNetwork.hpp
Code:
#ifndef NEURAL_NETWORK_HPP
#define NEURAL_NETWORK_HPP
#include "Trainer.hpp"
#include "Perceptron.hpp"
#include "Typedefs.hpp"

class NeuralNetwork
{
	public:
	NeuralNetwork() = delete; 
	NeuralNetwork(Trainer& trainer);
	float operator()(FloatV& input);
	private:
	void Train(Trainer& trainer);
	void Classify(FloatV& input);
	vector<Perceptron> InputLayer;
	vector<Perceptron> HiddenLayer;
	Perceptron Output;
	FloatV InputWeight;
	FloatV OutputWeight;
};

#endif
I'm having code block right now. Also, I want the vector operations to run in it's own thread, as speed is critical.

Thanks,
Lexi