c++ - Perceptron converging but returning odd results -
i made simple perceptron in c++ study ai , following book(pt_br) not make perceptron return expected result, tryed debug , find error didnt succeed.
my algorithm , gate results (a , b = y):
0 && 0 = 0 0 && 1 = 1 1 && 0 = 1 1 && 1 = 1
basically working or gate or random.
i tried jump peter norving , russel book, goes fast on , dont explain on depth 1 perceptron training.
i want learn every inch of content, dont want jump multilayer perceptron without making simple 1 work, can help?
the following code minimal code operation explanations:
sharp function:
int signal(float &sin){ if(sin < 0) return 0; if(sin > 1) return 1; return round(sin); }
perceptron struct (w weights):
struct perceptron{ float w[3]; };
perceptron training:
perceptron starttraining(){ //- random factory generator long int t = static_cast<long int>(time(null)); std::mt19937 gen; gen.seed(std::random_device()() + t); std::uniform_real_distribution<float> dist(0.0, 1.0); //-- //-- samples (-1 | x | y) float t0[][3] = {{-1,0,0}, {-1,0,1}, {-1,1,0}, {-1,1,1}}; //-- expected result short d [] = {0,0,0,1}; perceptron per; per.w[0] = dist(gen); per.w[1] = dist(gen); per.w[2] = dist(gen); //-- print random numbers cout <<"init "<< "w0: " << per.w[0] <<" w1: " << per.w[1] << " w2: " << per.w[2] << endl; const float n = 0.1; // lerning rate n int saida =0; // output y long int epo = 0; // simple couter bool erro = true; // loop control while(erro){ erro = false; (int amost = 0; amost < 4; ++amost) { // repeat number of samples x0=-1, x1,x2 float u=0; // variable somatory (int entrad = 0; entrad < 3; ++entrad) { // repeat every sinaptic weight w0=θ , w1, w2 u = u + (per.w[entrad] * t0[amost][entrad]);// u <- weights * inputs } // u=u-per.w[0]; // references sau take θ , subtract u, tried without success saida = signal(u); // returns 1 or 0 cout << d[amost] << " <- esperado | encontrado -> "<< saida<< endl; if(saida != d[amost]){ // if output not equal expected value (int ajust = 0; ajust < 3; ++ajust) { per.w[ajust] = per.w[ajust] + n * (d[amost] - saida) * t0[amost][ajust]; // w <- w + ɳ * ((d - y) x) erro = true; // w: weights, ɳ: learning rate } // d: desired outputs, y: outputs } // x: samples epo++; } } cout << "epocas(loops): " << epo << endl; return per; }
main testing part:
int main() { perceptron per = starttraining(); cout << "fim" << endl; cout << "w0: " << per.w[0] <<" w1: " << per.w[1] << " w2: " << per.w[2] << endl; while(true){ int x,y; cin >> x >> y; float u=0; u = (per.w[1] * x); u = u + (per.w[2] * y); //u=u-per.w[0]; cout << signal(u) << endl; } return 0; }
in main()
, re-enable line commented out. alternatively, write make more illuminating:
float u = 0.0f; u += (per.w[0] * float (-1)); u += (per.w[1] * float (x)); u += (per.w[2] * float (y));
the thing trained perceptron 3 inputs, first being hard-wired "-1" (making first weight w[0]
act constant "bias"). accordingly, in training function, u
sum of 3 of weight-input product. however, in main() posted, omit w[0] completely, producing wrong result.
Comments
Post a Comment