Added Neural network code
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
// Demo: Training of a Neural Network / Back-Propagation algorithm
|
||||
// Jan Oostindie, Avans Hogeschool, dd 6-12-2016
|
||||
// email: jac.oostindie@avans.nl
|
||||
|
||||
#include "NeuralNetwork.h"
|
||||
|
||||
NeuralNetwork::NeuralNetwork()
|
||||
{
|
||||
V0 = Mat();
|
||||
W0 = Mat();
|
||||
}
|
||||
|
||||
NeuralNetwork::~NeuralNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
Mat NeuralNetwork::Train(Mat& ITset, Mat& OTset)
|
||||
{
|
||||
// V0, W0 : weightfactor matrices
|
||||
// dV0, dW0 : weightfactor correction matrices
|
||||
Mat dW0, dV0;
|
||||
|
||||
// default number of hiddenNeurons. The definite number is user input
|
||||
// inputNeurons and outputNeurons are implicitly determined via
|
||||
// the trainingset, i.e.: inputNeurons = ITset.cols ; outputNeurons = OTset.cols;
|
||||
int hiddenNeurons = 8;
|
||||
|
||||
//loadTrainingSet1(ITset, OTset);
|
||||
initializeBPN(ITset.cols, hiddenNeurons, OTset.cols, V0, dV0, W0, dW0);
|
||||
//testBPN(ITset, OTset, V0, dV0, W0, dW0);
|
||||
|
||||
|
||||
// IT: current training input of the inputlayer
|
||||
// OT: desired training output of the BPN
|
||||
// OH: output of the hiddenlayer
|
||||
// OO: output of the outputlayer
|
||||
Mat IT, OT, OH, OO;
|
||||
|
||||
// outputError0: error on output for the current input and weighfactors V0, W0
|
||||
// outputError1: error on output for the current input and new calculated
|
||||
// weighfactors, i.e. V1, W1
|
||||
double outputError0, outputError1, sumSqrDiffError = MAX_OUTPUT_ERROR + 1;
|
||||
Mat V1, W1;
|
||||
|
||||
cout << endl << "Starting neural training..." << endl;
|
||||
|
||||
int runs = 0;
|
||||
while ((sumSqrDiffError > MAX_OUTPUT_ERROR) && (runs < MAXRUNS)) {
|
||||
|
||||
sumSqrDiffError = 0;
|
||||
|
||||
for (int inputSetRowNr = 0; inputSetRowNr < ITset.rows; inputSetRowNr++) {
|
||||
|
||||
IT = transpose(getRow(ITset, inputSetRowNr));
|
||||
|
||||
OT = transpose(getRow(OTset, inputSetRowNr));
|
||||
|
||||
calculateOutputHiddenLayer(IT, V0, OH);
|
||||
|
||||
calculateOutputBPN(OH, W0, OO);
|
||||
|
||||
adaptVW(OT, OO, OH, IT, W0, dW0, V0, dV0, W1, V1);
|
||||
|
||||
calculateOutputBPNError(OO, OT, outputError0);
|
||||
|
||||
calculateOutputBPNError(BPN(IT, V1, W1), OT, outputError1);
|
||||
|
||||
sumSqrDiffError += (outputError1 - outputError0) * (outputError1 - outputError0);
|
||||
|
||||
V0 = V1;
|
||||
W0 = W1;
|
||||
}
|
||||
runs++;
|
||||
|
||||
if (runs % 1000 == 0)
|
||||
cout << "Completed " << runs << " runs, still working on it.. (" << sumSqrDiffError << ")" << endl;
|
||||
}
|
||||
|
||||
cout << "Training complete in " << runs << " runs" << endl;
|
||||
|
||||
Mat inputVectorTrainingSet, outputVectorTrainingSet, outputVectorBPN;
|
||||
|
||||
// druk voor elke input vector uit de trainingset de output vector uit trainingset af
|
||||
// tezamen met de output vector die het getrainde BPN (zie V0, W0) genereerd bij de
|
||||
// betreffende input vector.
|
||||
for (int row = 0; row < ITset.rows; row++) {
|
||||
|
||||
// haal volgende inputvector op uit de training set
|
||||
inputVectorTrainingSet = transpose(getRow(ITset, row));
|
||||
|
||||
// haal bijbehorende outputvector op uit de training set
|
||||
outputVectorTrainingSet = transpose(getRow(OTset, row));
|
||||
|
||||
// bepaal de outputvector die het getrainde BPN oplevert
|
||||
// bij de inputvector uit de trainingset
|
||||
outputVectorBPN = BPN(inputVectorTrainingSet, V0, W0);
|
||||
}
|
||||
|
||||
write();
|
||||
|
||||
return outputVectorBPN;
|
||||
}
|
||||
|
||||
void NeuralNetwork::Predict(Mat& ITset, string& name)
|
||||
{
|
||||
Mat output;
|
||||
output = transpose(BPN(ITset, V0, W0));
|
||||
|
||||
mat_class(output, name);
|
||||
}
|
||||
|
||||
void NeuralNetwork::Read()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
void NeuralNetwork::write()
|
||||
{
|
||||
for (pair<int, string> p : classes)
|
||||
cout << p.first << " - " << p.second << endl;
|
||||
|
||||
FileStorage fs("factors.yml", FileStorage::WRITE);
|
||||
fs << "W0" << W0 << "V0" << V0;
|
||||
fs.release();
|
||||
|
||||
FileStorage fs2("classes.yml", FileStorage::WRITE);
|
||||
|
||||
fs2 << "classes" << "{:";
|
||||
|
||||
for (pair<int, string> p : classes)
|
||||
{
|
||||
string el = "e" + to_string(p.first);
|
||||
fs2 << el << p.second;
|
||||
}
|
||||
|
||||
fs2 << "}";
|
||||
|
||||
fs2.release();
|
||||
}
|
||||
|
||||
void NeuralNetwork::load()
|
||||
{
|
||||
FileStorage fs("factors.yml", FileStorage::READ);
|
||||
|
||||
fs["W0"] >> W0;
|
||||
fs["V0"] >> V0;
|
||||
|
||||
fs.release();
|
||||
|
||||
FileStorage fs2("classes.yml", FileStorage::READ);
|
||||
|
||||
classes.clear();
|
||||
|
||||
FileNode cls = fs2["classes"];
|
||||
FileNodeIterator it = cls.begin(), it_end = cls.end();
|
||||
int idx = 0;
|
||||
|
||||
// iterate through a sequence using FileNodeIterator
|
||||
for (; it != it_end; ++it, idx++)
|
||||
{
|
||||
cv::FileNode item = *it;
|
||||
std::string key = item.name();
|
||||
string value = (string)item;
|
||||
|
||||
classes.insert(pair<int, string>(idx, value));
|
||||
}
|
||||
|
||||
cout << endl << "Available classes: " << endl;
|
||||
|
||||
for (pair<int, string> p : classes)
|
||||
cout << p.first << " - " << p.second << endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
fs2.release();
|
||||
}
|
||||
|
||||
void NeuralNetwork::getClass(const string& name, Mat& ref)
|
||||
{
|
||||
save_class(name, ref);
|
||||
}
|
||||
|
||||
void NeuralNetwork::save_class(const string& name, Mat& ref)
|
||||
{
|
||||
for (pair<int, string> p : classes)
|
||||
{
|
||||
if (p.second == name)
|
||||
{
|
||||
class_mat(p.first, ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
classes.insert(pair<int, string>(classidx, name));
|
||||
class_mat(classidx, ref);
|
||||
classidx++;
|
||||
}
|
||||
|
||||
void NeuralNetwork::class_mat(int index, Mat& ref)
|
||||
{
|
||||
ref = cv::Mat::zeros(cv::Size(numclasses, 1), CV_32F);
|
||||
ref.at<float>(index) = 1;
|
||||
}
|
||||
|
||||
void NeuralNetwork::mat_class(Mat& ref, string& name)
|
||||
{
|
||||
double maxvalue = 0;
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < ref.cols; i++)
|
||||
{
|
||||
double temp = getEntry(ref, 0, i);
|
||||
|
||||
if (temp > maxvalue)
|
||||
{
|
||||
maxvalue = temp;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
name = classes[index] + " " + to_string(maxvalue*100) + "%";
|
||||
}
|
||||
Reference in New Issue
Block a user