Perceptron implementation in C++

Recently I have been interested in Neural Networks. However, using the implementation in R often takes a long time and does not converge. After thinking about this problem I realised it would not be that hard to write my own Neural Network implementation in C++. While I doubt my implementation will be better by writing one I should improve my understanding of Neural Networks. So far I have created a perceptron class and implemented both the perceptron training rule and gradient descent. I have also laid the foundations for back propagation by adding a sigmoid method. The code is below. Also I have decided to update weights after each example instead of updating after having seen all examples.

#pragma once
#include<iostream>
#include<vector>
#include<cmath>
#include<iterator>
#include <random>
#include <algorithm>
#include<ctime>

class Perceptron
{
	std::vector<double> _weights;
	

public:
	//constructor with given weights
	Perceptron(std::vector<double> weights):_weights(weights)
	{}
	//constructor with random weights
	Perceptron(int numOfWeights,  double lowerBound=-0.5, double upperBound=0.5)
	{
		
		std::default_random_engine generator(std::time(0));
		std::uniform_real_distribution<double> distribution(lowerBound,upperBound);
		
		for(int i=0; i<numOfWeights; i++)
		{
			_weights.push_back(distribution(generator));
		}
	
	}


	//inner product between a vector and the weights. Assume x0=1 and is not given. 
	double innerProd(std::vector<double> vect)
	{
		double prod=_weights[0];
		for(int i=1; i<_weights.size(); i++)
		{
			prod+=_weights[i]*vect[i-1];
		}
		return(prod);
	}

	//step function for perceptron training rule
	double outputSgn(std::vector<double> vect)
	{
		if(innerProd(vect)>0)
			return 1;
		else
			return -1;
	}
	
	//sigmoid function for backprop 
	double outputSig(std::vector<double> vect)
	{
		return 1.0/(1+ std::exp(-innerProd(vect)));
	}

	//implement the perceptron training rule for one example
	void perceptronTrainingRule(std::vector<double> vect, double target, double learningRate, bool verbose=false)
	{
		double factor=learningRate*(target-outputSgn(vect));



		_weights[0]+=factor;
		for(int i=1; i<_weights.size(); i++)
		{
			_weights[i]+=factor*vect[i-1];
		}

		if(verbose)
			dispWeights();


	}

	//implement the perceptron training rule for a training set assuming the last component of each vector
	//is the target value
	void perceptronTrainingRule(std::vector<std::vector<double>> trainSet, double learningRate, int epochs=1, bool verbose=false)
	{

		for(int i=0; i<epochs; i++)
		{
			for(auto it=trainSet.begin(); it!=trainSet.end(); it++)
			{
				auto vect=*it;

				perceptronTrainingRule(vect,*(vect.end()-1) , learningRate, verbose);


			}
		}
	}

	//gradient descent for one example
	void gradientDescent(std::vector<double> vect, double target, double learningRate, bool verbose=false)
	{
		double factor=learningRate*(target-innerProd(vect));



		_weights[0]+=factor;
		for(int i=1; i<_weights.size(); i++)
		{
			_weights[i]+=factor*vect[i-1];
		}

		if(verbose)
			dispWeights();
	}
	

	//implement the gradient descent for a training set assuming the last component of each vector
	//is the target value
	void gradientDescent(std::vector<std::vector<double>> trainSet, double learningRate, int epochs=1, bool verbose=false)
	{

		for(int i=0; i<epochs; i++)
		{
			for(auto it=trainSet.begin(); it!=trainSet.end(); it++)
			{
				auto vect=*it;

				gradientDescent(vect,*(vect.end()-1) , learningRate, verbose);


			}
		}
	}
	
	
	//function to retreive weights
	std::vector<double> getWeights()
	{
		return _weights;
	}

	//function to display weights
	void dispWeights()
	{
		for(auto it=_weights.begin(); it!=_weights.end(); it++)
		{

			std::cout<<*it<<std::endl;
		}
		std::cout<<std::endl;

	}

	//function to set weights
	void setWeights(std::vector<double> v)
	{
		std::copy(v.begin(), v.end(), _weights.begin());
	}
};


Below is some code to test the features. It compares the perceptron training rule and gradient descent. The IDE I used is visual studio.

#include&amp;lt;iostream&amp;gt;
#include&amp;quot;Perceptron.h&amp;quot;

int main()
{
	
	std::vector&amp;lt;std::vector&amp;lt;double&amp;gt;&amp;gt; train;
	
	
	
	for(int i=0; i&amp;lt;100000; i++)
	{
		std::vector&amp;lt;double&amp;gt; vect;
		std::srand(i);
		double x=std::rand()%10;
		std::srand(i+1);
		double y=std::rand()%10;
		vect.push_back(x);
		vect.push_back(y);
		if(x&amp;lt;y)
		{
			vect.push_back(1);
		}
		else
		{
			vect.push_back(-1);
		}
		train.push_back(vect);
	}
	
	std::vector&amp;lt;double&amp;gt; initWeights;
	std::srand(1);
	initWeights.push_back((double)(std::rand()%10-5)/5);
	//std::srand(2);
	initWeights.push_back((double)(std::rand()%10-5)/5);
	//std::srand(3);
	initWeights.push_back((double)(std::rand()%10-5)/5);

	Perceptron perceptron(initWeights);
	
	std::cout&amp;lt;&amp;lt;&amp;quot;Perceptron training rule \n&amp;quot;;
	perceptron.dispWeights();

	perceptron.perceptronTrainingRule(train, 0.01, 2);

	perceptron.dispWeights();
	

	std::cout&amp;lt;&amp;lt;&amp;quot;Gradient descent \n&amp;quot;;
	Perceptron perceptron2(initWeights);
	perceptron2.dispWeights();
	perceptron2.gradientDescent(train, 0.01, 2);
	perceptron2.dispWeights();
	
	
	
	
	system(&amp;quot;pause&amp;quot;);
	return 1;
}

Advertisements

One thought on “Perceptron implementation in C++

  1. Pingback: Simple Neural Network Implementation in C++ – Learning Data Analysis

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s