/*****************************************************************/ /** **/ /** Art.C **/ /** functions for learning of Art1 models **/ /** **/ /** Takehisa Tanaka **/ /** M.R.I.T. **/ /** revised 2/2000 **/ /*****************************************************************/ #include "nsl_include.h" #include "art.h" ArtModel::ArtModel() : NslModel("ArtModel"), art("art",this,25,30,5,5) { } Art::Art(char* str, NslModule* parent,int sizeF1,int sizeF2,int sizeX,int sizeY) : NslModule(str,parent), f1("f1",this,sizeF1,sizeF2), f2("f2",this,sizeF1,sizeF2), in("in",this,sizeF1), x("x",this,sizeF1), matI("matI",this,sizeX,sizeY), matX("matX",this,sizeX,sizeY) { makeConn(); } void Art::makeConn() { nslConnect(f1.x,f2.s); nslConnect(f2.x,f1.s); nslConnect(in,f1.in); nslConnect(in,f2.in); nslConnect(f1.x,x); } void Art::initTrain() { matrix_vector(matI,in); } void Art::endTrain() { vector_matrix(x,matX); } Comparison::Comparison(char* str, NslModule* parent,int sizeF1,int sizeF2) : NslModule(str,parent), in("in",this,sizeF1), // input pattern x("x",this,sizeF1), // activity and output pattern from F1 s("s",this,sizeF2), // input pattern to F1 v("v",this,sizeF1), // top-down template, or learned expectation w("w",this,sizeF1,sizeF2), // LTM weights from F2 to F1 rho("rho",this) // vigilance parameter { initSys(); } void Comparison::initSys() { // initialization of all patterns x = 0; s = 0; v = 0.0; // initialization of all LTM weights w = 1.0; } void Comparison::initTrain() { resetActive = 1; active = -1; } void Comparison::simTrain() { // activation of X from I or from V & I // I don't use STM equation. I directly calculate activation of X // if (in.sum() <= 0) // < 1 if (resetActive == 1) { resetActive = 0; active = -1; x = in; } else { if (s.max() > 0) s.max(active); v = NSLprod(w,s); for (int i = 0;i < in.get_size();i++) { if (in[i] + v[i] >= 1.99) x[i] = 1; else x[i] = 0; } } } void Comparison::endTrain() { // learning of bottom-up and top_down LTM traces s.max(active); for (int i = 0;i < w.get_imax();i++) { if (x[i] == 1) w[i][active] = 1.0; else w[i][active] = 0.0; } } // F2: Recognition Recognition::Recognition(char* str, NslModule* parent,int sizeF1,int sizeF2) : NslModule(str,parent), in("in",this,sizeF1), // input pattern s("s",this,sizeF1), // input pattern to F2 x("x",this,sizeF2), // activity and topdown output pattern from F2 v("v",this,sizeF2), // top-down template, or learned expectation w("w",this,sizeF2,sizeF1), // LTM weights from F1 to F2 resetY("resetY",this,sizeF2), // list of reset units in F2 rho("rho",this), // vigilance parameter l("l",this) // constant on initializing bottom-up LTM traces { initSys(); } void Recognition::initSys() { // initialization of all patterns x = 0; s = 0; v = 0.0; // temp l = 2.0; // initialization of all LTM weights float max_value = l.elem() / (l.elem() - 1.0 + in.get_size()); for (int xi = 0; xi < w.get_imax(); xi++) for (int yi = 0; yi < w.get_jmax(); yi++) w[xi][yi] = uniform_random(float(0.0),max_value); } void Recognition::initTrain() { resetY = 0.0; active = -1; } void Recognition::simTrain() { float sin = (float) s.sum() / (float) in.sum(); if (sin < rho.get_data() && active >= 0) { resetY[active] = -1; active = -1; } if (active >= 0) { cmd_out("Matching is passed"); nslBreakSim(); return; // -1; } v = NSLprod(w,s); num_type maxvalue; int i; active = -1; x = 0; const float BIG_MINUS = -1; /* the smallest value in this program */ // To exclude units which have been already reset for (i = 0;i < resetY.get_size();i++) if (resetY[i] == -1) v[i] = BIG_MINUS; // search for the unit which receives maximum input maxvalue = v.max(); // In the case that there is no available unit if (maxvalue == BIG_MINUS) { active = -1; cmd_out("An error has occured"); nslBreakSim(); return; // 0; } // To find the maximum input for (i = 0;i < v.get_size();i++) { if (v[i] == maxvalue) { x[i] = 1; active = i; break; } } // For the error if (i >= v.get_size()) { cmd_out("An error has occured"); nslBreakSim(); return; // 0; } if (active < 0) { cmd_out("There are no available units"); nslBreakSim(); return; // 0; } } void Recognition::endTrain() { cmd_out("Top-Down Template Unit: ",active); if (active < 0) { cmd_out("There are no units for this input"); nslBreakSim(); return; // 0; } float val = l.get_data() / (l.get_data() - 1.0 + s.sum()); for (int i = 0; i < w.get_jmax(); i++) { if (s[i] == 1) { w[active][i] = val; } else { w[active][i] = 0.0; } } } AslSchemaModel _ArtModel("ArtModel");