#include "jwindow.h" #include "jgraphics.h" #include #include #include #include #include #include #define NOISE 1.0 class Signal { private: double *_signals; int _nsignals; public: Signal(int nsignals) { _signals = new double[nsignals]; _nsignals = nsignals; } virtual ~Signal() { delete _signals; } int GetSize() { return _nsignals; } void SetSignal(int index, double signal) { _signals[index] = signal; } double GetSignal(int index) { return _signals[index]; } }; class Neuron { private: Signal *_inputs; double *_weights; int _weights_size; public: Neuron(int ninputs) { _inputs = new Signal(ninputs+1); _weights = new double[ninputs+1]; _weights_size = ninputs+1; for (int i=0; iSetSignal(i, 1.0); } for (int i=0; iGetSize(); i++) { _inputs->SetSignal(i, signal->GetSignal(i)); } } Signal * GetInput() { return _inputs; } int GetInputSize() { return _inputs->GetSize(); } double GetResult() { double sum = 0.0; for (int i=0; i<_inputs->GetSize(); i++) { sum = sum + _inputs->GetSignal(i)*_weights[i]; } return sum; } }; class NeuralNet { private: Neuron **_neurons; int _neurons_size; double _step; public: NeuralNet(int ninputs, int neurons) { _step = 0.001; _neurons = new Neuron*[neurons]; for (int i=0; i tinput, std::vector toutput) { for (int t=0; t<1000; t++) { // shuffle for (int i=0; i<(int)tinput.size(); i++) { int r = random()%tinput.size(); Signal *i1 = tinput[i], *i2 = tinput[r]; Signal *o1 = toutput[i], *o2 = toutput[r]; tinput[i] = i2; tinput[r] = i1; toutput[i] = o2; toutput[r] = o1; } for (int i=0; i<(int)tinput.size(); i++) { Signal *input = tinput[i], *output = toutput[i]; for (int j=0; j<_neurons_size; j++) { Neuron *neuron = _neurons[j]; Signal signal(input->GetSize()+1); signal.SetSignal(0, 1.0); for (int k=0; kGetSize(); k++) { signal.SetSignal(k+1, input->GetSignal(k)); } neuron->SetInput(&signal); } for (int j=0; j<_neurons_size; j++) { Neuron *neuron = _neurons[j]; double y = Function(neuron->GetResult()), dy = DFunction(neuron->GetResult()), e = output->GetSignal(j)-y; for (int k=0; kGetInputSize(); k++) { if (k != 0) { neuron->SetWeight(k, neuron->GetWeight(k)+_step*input->GetSignal(k-1)*e*dy); } else { neuron->SetWeight(k, neuron->GetWeight(k)+_step*1*e*dy); } } } } } } double Process(Signal *input) { /* printf("\ninput:: [ "); for (int k=0; kGetSize(); k++) { printf("%f ", input->GetSignal(k)); } printf("]\n"); */ for (int j=0; j<_neurons_size; j++) { Neuron *neuron = _neurons[j]; Signal signal(input->GetSize()+1); signal.SetSignal(0, 1.0); for (int k=0; kGetSize(); k++) { signal.SetSignal(k+1, input->GetSignal(k)); } neuron->SetInput(&signal); } for (int j=0; j<_neurons_size; j++) { Neuron *neuron = _neurons[j]; double v = neuron->GetResult(), y = Function(v); /* { // if (v > 0) { printf("v:: [%.2f], y:: [%.4f], classe:: [%d]\n", v, y, j); for (int k=0; kGetInputSize(); k++) { printf("indice::[%d], weight::[%f]\n", k, neuron->GetWeight(k+1)); } } */ return y; } return 0.0; } }; double s(int n) { return sin(0.075*n); } double noise[100000]; double v(int n) { if (n <= 0) { return 0; } // return cos(15*n);// + (0.1*((double)rand()/((double)(RAND_MAX)))); // return (NOISE*((double)rand()/((double)(RAND_MAX))))-NOISE/2.0; return noise[n]; } double v1(int n) { if (n <= 0) { return 0; } return -0.5*v1(n-1)+v(n); } double v2(int n) { if (n <= 0) { return 0; } return 0.8*v2(n-1)+v(n); } double x(int n) { return s(n)+v1(n); } int main() { srand(time(NULL)); for (int i=0; i<10000; i++) { noise[i] = (NOISE*((double)rand()/((double)(RAND_MAX))))-NOISE/2.0; } NeuralNet net(6, 1); std::vector tinput, toutput; int training_set = 5000; Signal *sinput[training_set], *soutput[training_set]; for (int i=0; iSetSignal(i, v2(-i+t)); } soutput[l]->SetSignal(0, x(t)); l++; } printf("Training Set\n"); for (int t=0; tGetSignal(i)); } printf("] output:: [ "); for (int i=0; i<1; i++) { printf("%.2f ", soutput[t]->GetSignal(i)); } puts("]"); } net.Training(tinput, toutput); Signal in01(6); int t = 10; in01.SetSignal(0, v2(t-0)); in01.SetSignal(1, v2(t-1)); in01.SetSignal(2, v2(t-2)); in01.SetSignal(3, v2(t-3)); in01.SetSignal(4, v2(t-4)); in01.SetSignal(5, v2(t-5)); printf("v1(%d) = %.6f => %.6f, e::[%.6f]\n", t, v1(t), net.Process(&in01), v1(t)-net.Process(&in01)); double scalex = 10.0, scaley = 100.0, x0 = 0, y0 = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0, x5 = 0, y5 = 0; int dx = 100, dy = 500; jgui::Window window(0, 0, 1920, 1080); window.Show(); jgui::Graphics *g = window.GetGraphics(); g->SetColor(0xff, 0x00, 0x00, 0xff); g->FillRectangle(dx, dy-400, 20, 20); g->DrawString("Sinal Original", dx+40, dy-400); g->SetColor(0xff, 0xff, 0x00, 0xff); g->SetColor(0xff, 0xff, 0x00, 0xff); g->FillRectangle(dx, dy-350, 20, 20); g->DrawString("Sinal Ruidoso", dx+40, dy-350); g->SetColor(0x00, 0xff, 0x00, 0xff); g->FillRectangle(dx, dy-300, 20, 20); g->DrawString("Sinal Filtrado", dx+40, dy-300); for (double i=0.0; i<100.0; i+=1.0) { Signal in(6); in.SetSignal(0, v2(i-0)); in.SetSignal(1, v2(i-1)); in.SetSignal(2, v2(i-2)); in.SetSignal(3, v2(i-3)); in.SetSignal(4, v2(i-4)); in.SetSignal(5, v2(i-5)); x1 = i; y1 = x(i); x3 = i; y3 = x(i)-net.Process(&in); x5 = i; y5 = s(i); g->SetColor(0xff, 0xff, 0x00, 0xff); g->DrawLine(x0*scalex+dx, y0*scaley+dy, x1*scalex+dx, y1*scaley+dy); g->SetColor(0x00, 0xff, 0x00, 0xff); g->DrawLine(x2*scalex+dx, y2*scaley+dy, x3*scalex+dx, y3*scaley+dy); g->SetColor(0xff, 0x00, 0x00, 0xff); g->DrawLine(x4*scalex+dx, y4*scaley+dy, x5*scalex+dx, y5*scaley+dy); g->SetColor(0xff, 0xff, 0x00, 0xff); // g->DrawLine(x4*scalex+dx, y4*scaley+dy+offset, x5*scalex+dx, y5*scaley+dy+offset); x0 = x1; y0 = y1; x2 = x3; y2 = y3; x4 = x5; y4 = y5; int a = (i*100); if ((a%100) == 0) { char tmp[16]; sprintf(tmp, "%d", a/100); g->SetColor(0x00, 0xff, 0xff, 0xff); // g->DrawString(tmp, i*scalex+dx, dy); } } g->Flip(); sleep(10000); return 0; }