BackPropagation works!

This commit is contained in:
2014-11-11 11:12:04 +01:00
parent 75ca9bc21f
commit 9ef4274396
29 changed files with 519 additions and 170 deletions

View File

@@ -22,7 +22,7 @@ Solution FeedForwardNetwork::solve(const Problem& p)
const Layer* FeedForwardNetwork::operator[](int layer) const Layer* FeedForwardNetwork::operator[](int layer)
{ {
return layers[layer]; return layers[layer];
} }
void FeedForwardNetwork::addLayer(int neurons) void FeedForwardNetwork::addLayer(int neurons)

View File

@@ -1,5 +1,5 @@
#ifndef _S_NN_FF_H_ #ifndef _S_NN_FF_H_
#define _S_NN_FFs_H_ #define _S_NN_FF_H_
#include "Problem" #include "Problem"
#include "Solution" #include "Solution"
@@ -34,7 +34,7 @@ namespace NeuronNetwork
//inline FeedForwardNetwork(std::vector<int> q); //inline FeedForwardNetwork(std::vector<int> q);
~FeedForwardNetwork(); ~FeedForwardNetwork();
virtual Solution solve(const Problem& p)override; virtual Solution solve(const Problem& p) override;
unsigned size() {return layers.size();} unsigned size() {return layers.size();}
const Layer* operator[](int layer); const Layer* operator[](int layer);
protected: protected:

View File

@@ -2,6 +2,31 @@
using namespace Shin::NeuronNetwork; using namespace Shin::NeuronNetwork;
FFLayer::~FFLayer()
{
if(neurons!=nullptr)
{
for(size_t i=0;i<layerSize;i++)
{
delete neurons[i];
}
delete[] neurons;
}
}
FFNeuron* FFLayer::operator[](int neuron)
{
if(neurons==nullptr)
{
neurons=new FFNeuron*[layerSize];
for(size_t i=0;i<layerSize;i++)
{
neurons[i]=new FFNeuron(&potentials[i],weights[i],&sums[i]);
}
}
return neurons[neuron];
}
FeedForwardNetworkQuick::~FeedForwardNetworkQuick() FeedForwardNetworkQuick::~FeedForwardNetworkQuick()
{ {
if(weights != nullptr) if(weights != nullptr)
@@ -14,54 +39,73 @@ FeedForwardNetworkQuick::~FeedForwardNetworkQuick()
} }
delete[] weights[i]; delete[] weights[i];
delete[] potentials[i]; delete[] potentials[i];
delete[] sums[i];
} }
delete[] sums[layers];
delete[] weights; delete[] weights;
delete[] potentials; delete[] potentials;
delete[] layerSizes; delete[] layerSizes;
delete[] sums;
}
if(ffLayers !=nullptr)
{
for(size_t i=0;i<layers;i++)
{
delete ffLayers[i];
}
delete[] ffLayers;
} }
} }
Solution FeedForwardNetworkQuick::solve(const Problem& p) Solution FeedForwardNetworkQuick::solve(const Problem& p)
{ {
std::vector<bool> solution=p; std::vector<bool> solution(p);
bool* sol=new bool[solution.size()]; register double* sol=sums[0];//new bool[solution.size()];
for(size_t i=0;i<solution.size();i++) for(size_t i=0;i<solution.size();i++)
{ {
sol[i]=solution[i]; sol[i+1]=solution[i];
} }
size_t prevSize=1; register size_t prevSize=layerSizes[0];
for(size_t i=0;i<layers;i++) for(register size_t i=0;i<layers;i++)
{ {
bool* newSolution= new bool[layerSizes[i]]; double* newSolution= sums[i+1];//new bool[layerSizes[i]];
for(size_t j=0;j<layerSizes[i];j++) for(register size_t j=1;j<layerSizes[i];j++)
{ {
double q; register double q=sol[0]*weights[i][j][0];
if(i==0) for(register size_t k=1;k<prevSize;k++)
{ {
q=sol[j]*weights[i][j][0]; if(i==0)
}else
{
q=0;
for(size_t k=0;k<prevSize;k++)
{ {
q+=sol[k]*weights[i][j][k]; q+=sol[k]*weights[i][j][k];
}else
{
q+=(1.0/(1.0+exp(-0.5*sol[k])))*weights[i][j][k];
} }
} }
newSolution[j]=q >= potentials[i][j]?1:0; newSolution[j]=q;
} }
prevSize=layerSizes[i]; prevSize=layerSizes[i];
delete[] sol;
sol=newSolution; sol=newSolution;
} }
std::vector<double> ret;
std::vector<bool> ret; for(size_t i=1;i<prevSize;i++)
for(size_t i=0;i<prevSize;i++)
{ {
ret.push_back(sol[i]); ret.push_back((1.0/(1.0+exp(-0.5*sol[i]))));
} }
delete[] sol;
return ret; return ret;
} }
FFLayer* FeedForwardNetworkQuick::operator[](int l)
{
if(ffLayers==nullptr)
{
ffLayers=new FFLayer*[layers];
for(size_t i=0;i<layers;i++)
{
ffLayers[i]=new FFLayer(layerSizes[i],potentials[i],weights[i],sums[i+1]);
}
}
return ffLayers[l];
}

View File

@@ -1,16 +1,17 @@
#ifndef _S_NN_FF_H_ #ifndef _S_NN_FFQ_H_
#define _S_NN_FFs_H_ #define _S_NN_FFQ_H_
#include "Problem" #include "Problem"
#include "Solution" #include "Solution"
#include "Neuron" #include "Neuron"
#include "Network" #include "FeedForward"
#include <cstdarg>
#include <vector> #include <vector>
#include <initializer_list> #include <initializer_list>
#include <iostream> #include <iostream>
#include <math.h>
namespace Shin namespace Shin
{ {
namespace NeuronNetwork namespace NeuronNetwork
@@ -21,28 +22,43 @@ namespace NeuronNetwork
FFNeuron() = delete; FFNeuron() = delete;
FFNeuron(const FFNeuron&) = delete; FFNeuron(const FFNeuron&) = delete;
FFNeuron& operator=(const FFNeuron&) = delete; FFNeuron& operator=(const FFNeuron&) = delete;
FFNeuron(double *pot, double *w):potential(pot),weights(w) { } FFNeuron(double *pot, double *w, double*s):potential(pot),weights(w),sum(s) { }
double getPotential() {return *potential;} double getPotential() {return *potential;}
void setPotential(double p) { std::cout <<"S"; *potential=p;} void setPotential(double p) { *potential=p;}
double getWeight(unsigned int i ) { return weights[i];} double getWeight(unsigned int i ) { return weights[i];}
void setWeight(unsigned int i,double p) { weights[i]=p; } void setWeight(unsigned int i,double p) { weights[i]=p; }
inline double output()
{
return 1.0/(1.0+(exp(-0.5*input())));
return input();
// register double tmp=;
// return NAN==tmp?0:tmp;
/* > *potential? 1 :0;*/ }
inline double input() { return *sum; }
inline double derivatedOutput() { return output()*(1.0-output()); };
protected: protected:
double *potential; double *potential;
double *weights; double *weights;
private: double *sum;
private:
}; };
class FFLayer//: public Layer class FFLayer//: public Layer
{ {
public: public:
FFLayer(size_t s, double *p,double **w): layerSize(s),potentials(p),weights(w) {} FFLayer(const FFLayer &) =delete;
FFNeuron* operator[](int neuron) const { return new FFNeuron(&potentials[neuron],weights[neuron]); }; FFLayer operator=(const FFLayer &) = delete;
int size() const {return layerSize;}; FFLayer(size_t s, double *p,double **w,double *su): neurons(nullptr),layerSize(s),potentials(p),weights(w),sums(su) {}
~FFLayer();
FFNeuron* operator[](int neuron);
size_t size() const {return layerSize;};
protected: protected:
FFNeuron **neurons;
size_t layerSize; size_t layerSize;
double *potentials; double *potentials;
double **weights; double **weights;
double *sums;
}; };
class FeedForwardNetworkQuick:public ACyclicNetwork class FeedForwardNetworkQuick:public ACyclicNetwork
@@ -50,42 +66,54 @@ namespace NeuronNetwork
public: public:
FeedForwardNetworkQuick(const FeedForwardNetworkQuick &f) = delete; //TODO FeedForwardNetworkQuick(const FeedForwardNetworkQuick &f) = delete; //TODO
FeedForwardNetworkQuick operator=(const FeedForwardNetworkQuick &f)=delete; FeedForwardNetworkQuick operator=(const FeedForwardNetworkQuick &f)=delete;
template<typename... Args>inline FeedForwardNetworkQuick(std::initializer_list<int> s):weights(nullptr),potentials(nullptr),layerSizes(nullptr),layers(s.size()) template<typename... Args>inline FeedForwardNetworkQuick(std::initializer_list<int> s):ffLayers(nullptr),weights(nullptr),potentials(nullptr),sums(nullptr),layerSizes(nullptr),layers(s.size())
{ {
weights= new double**[s.size()]; weights= new double**[s.size()];
potentials= new double*[s.size()]; potentials= new double*[s.size()];
layerSizes= new size_t[s.size()]; layerSizes= new size_t[s.size()];
sums= new double*[s.size()+1];
int i=0; int i=0;
int prev_size=1; int prev_size=1;
for(int layeSize:s) // TODO rename for(int layeSize:s) // TODO rename
{ {
if(i==0) layeSize+=1;
if(i==0)
{
prev_size=layeSize; prev_size=layeSize;
sums[0]= new double[layeSize];
sums[0][0]=1.0;
}
layerSizes[i]=layeSize; layerSizes[i]=layeSize;
weights[i]= new double*[layeSize]; weights[i]= new double*[layeSize];
potentials[i]= new double[layeSize]; potentials[i]= new double[layeSize];
for (int j=0;j<layeSize;j++) sums[i+1]= new double[layeSize];
potentials[i][0]=1.0;
sums[i+1][0]=1.0;
for (int j=1;j<layeSize;j++)
{ {
potentials[i][j]=1; potentials[i][j]=1.0;
weights[i][j]= new double[prev_size]; weights[i][j]= new double[prev_size];
for(int k=0;k<prev_size;k++) for(int k=0;k<prev_size;k++)
{ {
weights[i][j][k]=1; weights[i][j][k]=0.5-((double)(rand()%1000))/1000.0;
} }
} }
i++; i++;
prev_size=layeSize; prev_size=layeSize;
} }
} }
~FeedForwardNetworkQuick(); virtual ~FeedForwardNetworkQuick();
virtual Solution solve(const Problem& p) override; virtual Solution solve(const Problem& p) override;
unsigned size() { return layers;} unsigned size() { return layers;}
FFLayer* operator[](int l) { return new FFLayer(layerSizes[l],potentials[l],weights[l]); } FFLayer* operator[](int l);
protected: protected:
private: private:
FFLayer **ffLayers;
double ***weights; double ***weights;
double **potentials; double **potentials;
public:
double **sums;
size_t *layerSizes; size_t *layerSizes;
size_t layers; size_t layers;
}; };

View File

@@ -0,0 +1 @@
./BackPropagation.h

View File

@@ -0,0 +1,87 @@
#include "./BackPropagation"
Shin::NeuronNetwork::Learning::BackPropagation::BackPropagation(FeedForwardNetworkQuick &n): Supervised(n)
{
}
double Shin::NeuronNetwork::Learning::BackPropagation::calculateError(const Shin::NeuronNetwork::Solution& expectation, const Shin::NeuronNetwork::Solution& solution)
{
register double a=0;
for (size_t i=0;i<expectation.size();i++)
{
a+=pow(expectation[i]-solution[i],2)/2;
}
return a;
}
const double LAMBDA = 0.5;
void Shin::NeuronNetwork::Learning::BackPropagation::propagate(const Shin::NeuronNetwork::Solution& expectation)
{
double **deltas;
deltas=new double*[network.size()];
for(int i=(int)network.size()-1;i>=0;i--)
{
std::cerr << i << "XXXXXXXXXXXXXX\n";
deltas[i]=new double[network[i]->size()];
deltas[i][0]=0.0;
if(i==(int)network.size()-1)
{
for(size_t j=1;j<network[i]->size();j++)
{
deltas[i][j]= (expectation[j-1]-network[i]->operator[](j)->output())*network[i]->operator[](j)->derivatedOutput();
// std::cerr << "X "<< deltas[i][j] <" Z ";
}
}else
{
for(size_t j=1;j<network[i]->size();j++)
{
register double deltasWeight = 0;
for(size_t k=1;k<network[i+1]->size();k++)
{
deltasWeight+=deltas[i+1][k]*network[i+1]->operator[](k)->getWeight(j);
}
deltas[i][j]=deltasWeight*network[i]->operator[](j)->derivatedOutput();
}
}
}
for(size_t i=0;i<network.size();i++)
{
size_t max;
if(i==0)
max=network[i]->size();
else
max=network[i-1]->size();
for(size_t j=1;j<network[i]->size();j++)
{
network[i]->operator[](j)->setWeight(0,network[i]->operator[](j)->getWeight(0)+0.5*deltas[i][j]);
for(size_t k=1;k<max;k++)
{
network[i]->operator[](j)->setWeight(k,
network[i]->operator[](j)->getWeight(k)+learningCoeficient* deltas[i][j]*
(i==0? network.sums[0][k]:(double)network[i-1]->operator[](k)->output()));
}
}
}
for(size_t i=0;i<network.size();i++)
{
delete[] deltas[i];
}
delete[] deltas;
}
double Shin::NeuronNetwork::Learning::BackPropagation::teach(const Shin::NeuronNetwork::Problem& p, const Shin::NeuronNetwork::Solution& solution)
{
Shin::NeuronNetwork::Solution a=network.solve(p);
double error=calculateError(solution,a);
propagate(solution);
// std::cerr << "error: " << error << "\n";
return error;
}

View File

@@ -0,0 +1,36 @@
#ifndef _BACK_PROPAGATION_H_
#define _BACK_PROPAGATION_H_
#include <math.h>
#include <cstddef>
#include "../Solution.h"
#include "../FeedForwardQuick.h"
#include "Supervised"
/*
*
*
*
*/
namespace Shin
{
namespace NeuronNetwork
{
namespace Learning
{
class BackPropagation : public Supervised
{
public:
BackPropagation(FeedForwardNetworkQuick &n);
double calculateError(const Solution &expectation,const Solution &solution);
void propagate(const Shin::NeuronNetwork::Solution& expectation);
double teach(const Shin::NeuronNetwork::Problem &p,const Solution &solution);
protected:
double learningCoeficient=0.8;
};
}
}
}
#endif

View File

@@ -0,0 +1 @@
./Reinforcement.h

View File

@@ -0,0 +1 @@
#include "./Reinforcement"

View File

@@ -0,0 +1,36 @@
#ifndef _REINFORCEMENT_H_
#define _REINFORCEMENT_H_
#include <math.h>
#include <cstddef>
#include "../Solution.h"
#include "../FeedForwardQuick.h"
#include "Unsupervised"
/*
*
*
*
*/
namespace Shin
{
namespace NeuronNetwork
{
namespace Learning
{
class Reinforcement : public Unsupervised
{
public:
Reinforcement(FeedForwardNetworkQuick &n);
double calculateError(const Solution &expectation,const Solution &solution);
void propagate(const Shin::NeuronNetwork::Solution& expectation);
double teach(const Shin::NeuronNetwork::Problem &p,const Solution &solution);
protected:
double learningCoeficient=0.8;
};
}
}
}
#endif

View File

@@ -0,0 +1 @@
./Supervised.h

View File

@@ -0,0 +1,15 @@
#include "./Supervised"
Shin::NeuronNetwork::Learning::Supervised::Supervised(Shin::NeuronNetwork::FeedForwardNetworkQuick& n) :network(n)
{
}
void Shin::NeuronNetwork::Learning::Supervised::debugOn()
{
debug=1;
}
void Shin::NeuronNetwork::Learning::Supervised::debugOff()
{
debug=0;
}

View File

@@ -0,0 +1,33 @@
#ifndef _SUPERVISEDLEARNING_H_
#define _SUPERVIESDLERANING_H_
#include <math.h>
#include <cstddef>
#include "../Solution.h"
#include "../FeedForwardQuick.h"
namespace Shin
{
namespace NeuronNetwork
{
namespace Learning
{
class Supervised
{
public:
Supervised() =delete;
Supervised(FeedForwardNetworkQuick &n);
virtual ~Supervised() {};
virtual double calculateError(const Solution &expectation,const Solution &solution)=0;
virtual double teach(const Shin::NeuronNetwork::Problem &p,const Solution &solution)=0;
void debugOn();
void debugOff();
protected:
FeedForwardNetworkQuick &network;
bool debug=0;
};
}
}
}
#endif

View File

@@ -0,0 +1 @@
./Unsupervised.h

View File

@@ -0,0 +1,16 @@
#include "./Unsupervised"
Shin::NeuronNetwork::Learning::Unsupervised::Unsupervised(Shin::NeuronNetwork::FeedForwardNetworkQuick& n) :network(n)
{
}
void Shin::NeuronNetwork::Learning::Unsupervised::debugOn()
{
debug=1;
}
void Shin::NeuronNetwork::Learning::Unsupervised::debugOff()
{
debug=0;
}

View File

@@ -0,0 +1,33 @@
#ifndef _UNSUPERVISEDLEARNING_H_
#define _UNSUPERVIESDLERANING_H_
#include <math.h>
#include <cstddef>
#include "../Solution.h"
#include "../FeedForwardQuick.h"
namespace Shin
{
namespace NeuronNetwork
{
namespace Learning
{
class Unsupervised
{
public:
Unsupervised() =delete;
Unsupervised(FeedForwardNetworkQuick &n);
virtual ~Unsupervised() {};
virtual double calculateError(const Solution &expectation,const Solution &solution)=0;
virtual double teach(const Shin::NeuronNetwork::Problem &p,const Solution &solution)=0;
void debugOn();
void debugOff();
protected:
FeedForwardNetworkQuick &network;
bool debug=0;
};
}
}
}
#endif

View File

@@ -1,4 +1,6 @@
OBJFILES=./Solution.o ./Problem.o ./Network.o ./Neuron.o ./FeedForward.o ./FeedForwardQuick.o OBJFILES= Neuron.o ./Network.o FeedForward.o FeedForwardQuick.o \
Learning/Supervised.o Learning/Unsupervised.o Learning/Reinforcement.o Learning/BackPropagation.o \
./Solution.o ./Problem.o
LIBNAME=NeuronNetwork LIBNAME=NeuronNetwork
@@ -18,4 +20,4 @@ $(LIBNAME).a: $(OBJFILES)
nm --demangle $(LIBNAME).a > $(LIBNAME).nm nm --demangle $(LIBNAME).a > $(LIBNAME).nm
clean: clean:
@rm -f ./*.o ./*.so ./*.a ./*.nm @rm -f ./*.o ./*.so ./*.a ./*.nm ./*/*.o

View File

@@ -19,12 +19,12 @@ Layer::~Layer()
} }
Solution Layer::solve(const std::vector<bool> &input) Solution Layer::solve(const std::vector<double> &input)
{ {
std::vector <bool> ret; std::vector <double> ret;
for(Neuron *n:neurons) for(Neuron *n:neurons)
{ {
ret.push_back(n->activates(input)); ret.push_back(n->output(input));
} }
return ret; return ret;
} }

View File

@@ -42,7 +42,7 @@ namespace NeuronNetwork
} }
} }
~Layer(); ~Layer();
Solution solve(const std::vector<bool> &input); Solution solve(const std::vector<double> &input);
Neuron* operator[](int neuron) const; Neuron* operator[](int neuron) const;
int size() const {return neurons.size();}; int size() const {return neurons.size();};
protected: protected:

View File

@@ -36,15 +36,15 @@ void Neuron::setWeight(unsigned int i,double p)
weights[i]=p; weights[i]=p;
} }
bool Neuron::activates(std::vector<bool> input) double Neuron::output(std::vector<double> input)
{ {
double sum=0; register double sum=0;
for(unsigned int i=0;i<input.size();i++) for(unsigned int i=0;i<input.size();i++)
{ {
// std::cerr << "W: " << getWeight(i) <<"\n"; // std::cerr << "W: " << getWeight(i) <<"\n";
sum+=getWeight(i)*input[i]; sum+=getWeight(i)*input[i];
} }
//std::cerr << "X: " << sum <<"\n"; return 1.0/(1.0+exp(-0.5*sum));
if(sum <= getPotential()) if(sum <= getPotential())
return 0; return 0;
return 1; return 1;

View File

@@ -2,6 +2,7 @@
#define _S_NN_NEURON_H_ #define _S_NN_NEURON_H_
#include <vector> #include <vector>
#include <math.h>
namespace Shin namespace Shin
{ {
@@ -19,11 +20,14 @@ namespace NeuronNetwork
void setPotential(double p); void setPotential(double p);
double getWeight(unsigned int) const; double getWeight(unsigned int) const;
void setWeight(unsigned int i,double p); void setWeight(unsigned int i,double p);
bool activates(const std::vector<bool>); double output(const std::vector<double>);
double output() { return lastOutput;}
protected: protected:
double potential; double potential;
private: private:
std::vector<double> weights; std::vector<double> weights;
double lastOutput=0.0;
double lastInput=0.0;
}; };
class SimpleNeuron: public Neuron class SimpleNeuron: public Neuron
{ {

View File

@@ -1 +1 @@
././Problem.h ./Problem.h

View File

@@ -1,6 +1,7 @@
#ifndef _P_H_ #ifndef _P_H_
#define _P_H_ #define _P_H_
#include <cstddef>
#include <vector> #include <vector>
namespace Shin namespace Shin
@@ -19,4 +20,5 @@ namespace NeuronNetwork
}; };
} }
} }
#endif #endif

View File

@@ -1 +1 @@
././Solution.h ./Solution.h

View File

@@ -2,22 +2,31 @@
using namespace Shin::NeuronNetwork; using namespace Shin::NeuronNetwork;
Solution::Solution(std::vector<bool>sol):solution(sol) Solution::Solution(std::vector<double>sol):solution(sol)
{ {
} }
bool Solution::operator[](int pos) Solution::Solution(const Problem& p):solution()
{
std::vector<bool> q(p);
for(bool s:q)
{
solution.push_back(s);
}
}
double Solution::operator[](size_t pos) const
{ {
return solution[pos]; return solution[pos];
} }
int Solution::size() size_t Solution::size() const
{ {
return solution.size(); return solution.size();
} }
Solution::operator std::vector<bool>() Solution::operator std::vector<double>()
{ {
return solution; return solution;
} }

View File

@@ -1,6 +1,7 @@
#ifndef _SOL_H_ #ifndef _SOL_H_
#define _SOL_H_ #define _SOL_H_
#include <cstddef>
#include <vector> #include <vector>
#include "Problem" #include "Problem"
@@ -11,14 +12,16 @@ namespace NeuronNetwork
class Solution class Solution
{ {
public: public:
Solution(std::vector<bool> solution); Solution(const Problem& p);
int size(); Solution(std::vector<double> solution);
bool operator[] (int pos); size_t size() const;
operator std::vector<bool>(); double operator[] (size_t pos) const;
operator std::vector<double>();
protected: protected:
std::vector<bool> solution; std::vector<double> solution;
}; };
} }
} }
#endif #endif

View File

@@ -1,47 +1,67 @@
#include "../src/NeuronNetwork/FeedForward" #include "../src/NeuronNetwork/FeedForward"
#include "../src/NeuronNetwork/FeedForwardQuick" #include "../src/NeuronNetwork/FeedForwardQuick"
#include "../src/NeuronNetwork/Learning/BackPropagation"
#include <iostream> #include <iostream>
#include <vector>
class X: public Shin::NeuronNetwork::Problem class X: public Shin::NeuronNetwork::Problem
{ {
protected: public:
X(const X& a) :q(a.q) {}
X(const std::vector<bool> &a):q(a) {}
std::vector<bool> representation() const std::vector<bool> representation() const
{ {
return std::vector<bool>({1,1}); return q;
} }
protected:
std::vector<bool> q;
}; };
int main() int main()
{ {
Shin::NeuronNetwork::FeedForwardNetwork n({2,3,2}); srand(time(NULL));
Shin::NeuronNetwork::Solution s =n.solve(X()); std::vector<Shin::NeuronNetwork::Solution> s;
Shin::NeuronNetwork::FeedForwardNetworkQuick q({2,3,2}); std::vector<X> p;
Shin::NeuronNetwork::Solution sq =q.solve(X());
if(s.size()!=2) //
s.push_back(Shin::NeuronNetwork::Solution(std::vector<double>({1})));
p.push_back(X(std::vector<bool>({0})));
s.push_back(Shin::NeuronNetwork::Solution(std::vector<double>({0})));
p.push_back(X(std::vector<bool>({1})));
Shin::NeuronNetwork::FeedForwardNetworkQuick q({1,1});
Shin::NeuronNetwork::Learning::BackPropagation b(q);
int i=0;
std::cerr << i%4 <<". FOR: [" << p[i%2].representation()[0] << "] res: " << q.solve(p[i%2])[0] << " should be " << s[i%2][0]<<"\n";
for(int i=0;i<2000;i++)
{ {
std::cout << "1"; b.teach(p[i%2],s[i%2]);
return 1; std::cerr << i%2 <<". FOR: [" << p[i%2].representation()[0] << "] res: " << q.solve(p[i%2])[0] << " should be " << s[i%2][0]<<"\n";
}
if(s[0]!=1)
{
std::cout << "2";
return 1;
}
if(s[1]!=1)
{
std::cout << "3";
return 1;
}
if(s.size()!=sq.size())
{
std::cout << "3";
return 1;
} }
b.debugOn();
for(int i=0;i<2;i++) for(int i=0;i<2;i++)
if(s[i]!=sq[i]) {
{ b.teach(p[i%2],s[i%2]);
std::cout << "4 " << i; std::cerr << i%4 <<". FOR: [" << p[i%4].representation()[0] << "," <<p[i%4].representation()[0] << "] res: " << q.solve(p[i%4])[0] << " should be " <<
return 1; s[i%4][0]<<"\n";
} }
return 0; b.debugOff();
/*
for(int i=0;i<40;i++)
{
b.teach(p[i%4],s[i%4]);
}
b.debugOn();
std::cerr << "LEARNED\n";
for(int i=0;i<4;i++)
{
b.teach(p[i%4],s[i%4]);
std::cerr << i%4 <<". FOR: [" << p[i%4].representation()[0] << "," <<p[i%4].representation()[1] << "] res: " << q.solve(p[i%4])[0] << " should be " <<
s[i%4][0]<<"\n";
}
*/
} }

View File

@@ -43,17 +43,6 @@ int main()
return 1; return 1;
} }
if(s[0]!=0)
{
std::cout << "2";
return 1;
}
if(s[1]!=1)
{
std::cout << "3";
return 1;
}
for(int i=0;i<2;i++) for(int i=0;i<2;i++)
{ {
if(s[i]!=sq[i]) if(s[i]!=sq[i])

View File

@@ -1,74 +1,61 @@
#include "../src/NeuronNetwork/Network" #include "../src/NeuronNetwork/FeedForward"
#include "../src/NeuronNetwork/FeedForwardQuick"
#include "../src/NeuronNetwork/Learning/BackPropagation"
#include <iostream> #include <iostream>
#include <vector>
class X: public Shin::NeuronNetwork::Problem class X: public Shin::NeuronNetwork::Problem
{ {
public: X(bool x,bool y):x(x),y(y) {} public:
protected: std::vector<bool> representation() const { return std::vector<bool>({x,y}); } X(const X& a) :q(a.q) {}
private: X(const std::vector<bool> &a):q(a) {}
bool x; std::vector<bool> representation() const
bool y; {
return q;
}
protected:
std::vector<bool> q;
}; };
int main() int main()
{ {
srand(time(NULL)); std::vector<Shin::NeuronNetwork::Solution> s;
int lm=5; std::vector<X> p;
Shin::NeuronNetwork::FeedForwardNetwork net({2,lm,1});
bool x=1;
int prev_err=0;
int err=0;
int l;
int n;
int w;
int pot;
int wei;
int c=0;
std::cout << "\ntest 1 & 1 -" << net.solve(X(1,1))[0];
std::cout << "\ntest 1 & 0 -" << net.solve(X(1,0))[0];
std::cout << "\ntest 0 & 1 - " << net.solve(X(0,1))[0];
std::cout << "\ntest 0 & 0- " << net.solve(X(0,0))[0];
std::cout << "\n---------------------------------------";
do{
if(c%10000 ==1)
{
std::cout << "\nmixed";
srand(time(NULL));
}
err=0;
c++;
l=rand()%2+1;
n=rand()%lm;
w=rand()%2;
if(l==2)
n=0;
pot=net[l]->operator[](n)->getPotential();
net[l]->operator[](n)->setPotential(pot*(rand()%21+90)/100);
wei=net[l]->operator[](n)->getWeight(w);
net[l]->operator[](n)->setWeight(w,wei*(rand()%21+90)/100);
for(int i=0;i<100;i++) //
{ s.push_back(Shin::NeuronNetwork::Solution(std::vector<double>({0})));
bool x= rand()%2; p.push_back(X(std::vector<bool>({1,0})));
bool y=rand()%2; s.push_back(Shin::NeuronNetwork::Solution(std::vector<double>({0})));
Shin::NeuronNetwork::Solution s =net.solve(X(x,y)); p.push_back(X(std::vector<bool>({0,1})));
if(s[0]!= (x xor y)) s.push_back(Shin::NeuronNetwork::Solution(std::vector<double>({0})));
err++; p.push_back(X(std::vector<bool>({0,0})));
} s.push_back(Shin::NeuronNetwork::Solution(std::vector<double>({1})));
p.push_back(X(std::vector<bool>({1,1})));
Shin::NeuronNetwork::FeedForwardNetworkQuick q({2,4,1});
Shin::NeuronNetwork::Learning::BackPropagation b(q);
b.debugOn();
for(int i=0;i<4;i++)
{
b.teach(p[i%4],s[i%4]);
std::cerr << i%4 <<". FOR: [" << p[i%4].representation()[0] << "," <<p[i%4].representation()[1] << "] res: " << q.solve(p[i%4])[0] << " should be " <<
s[i%4][0]<<"\n";
}
b.debugOff();
for(int i=0;i<40;i++)
{
b.teach(p[i%4],s[i%4]);
}
b.debugOn();
std::cerr << "LEARNED\n";
for(int i=0;i<4;i++)
{
b.teach(p[i%4],s[i%4]);
std::cerr << i%4 <<". FOR: [" << p[i%4].representation()[0] << "," <<p[i%4].representation()[1] << "] res: " << q.solve(p[i%4])[0] << " should be " <<
s[i%4][0]<<"\n";
}
if(err > prev_err)
{
net[l]->operator[](n)->setPotential(pot);
net[l]->operator[](n)->setWeight(w,wei);
};
// std::cout << "C: " << c << " err: " << err << " prev: "<<prev_err << "\n";
prev_err=err;
if(err <1)
x=0;
}while(x);
std::cout << "\ntest 1 & 1 -" << net.solve(X(1,1))[0];
std::cout << "\ntest 1 & 0 -" << net.solve(X(1,0))[0];
std::cout << "\ntest 0 & 1 - " << net.solve(X(0,1))[0];
std::cout << "\ntest 0 & 0- " << net.solve(X(0,0))[0];
std::cout << "\nTotaly: " << c << "\n";
} }