void Hippocampus::Recognize(){ vector<vector<double> > lambda; Child->GetLambda(0, 0, SideCompression, lambda); unsigned r, c; //multiply all lambdas into lambdaProd vector<double> lambdaProd(MemCount, 1); for(c = 0; c < MemCount; c++) for(r = 0; r < lambda.size(); r++) lambdaProd[c] *= lambda[r][c]; BelStar.assign(MemCount, 0); double SumBelStar = 0; for(c = 0; c < MemCount; c++){ BelStar[c] = lambdaProd[c] / MemCount; SumBelStar += BelStar[c]; } // if(SumBelStar > 0) //else we get too little probabilities (not similar to anything) // for(c = 0; c < MemCount; c++) // CombinedBelief[c] += BelStar[c] / SumBelStar; //normalize (let SumBelStar = 1) // Optimisation by Greg Kochaniak if(SumBelStar > 0) //else we get too little probabilities (not similar to anything) { double RecipSumBelStar = 1.0 / SumBelStar; // Just one division here allows us to multply instead of dividing for(c = 0; c < MemCount; c++) CombinedBelief[c] += BelStar[c] * RecipSumBelStar; //normalize (let SumBelStar = 1) } vector<vector<double> > piOut; piOut.resize(lambda.size()); //lambda.size() = NumberOfChildren for(r = 0; r < piOut.size(); r++){ //piOut.size() = NumberOfChildren piOut[r].resize(MemCount); for(c = 0; c < MemCount; c++) if(lambda[r][c] == 0) piOut[r][c] = 0; else piOut[r][c] = BelStar[c] / lambda[r][c]; } Child->SetPi(0, 0, SideCompression, piOut); //distribute PiOut to each child Sub-region }
//lambda is evidence from children, measures NumberOfChildren x MemCount //for Level0: lambda[r][c] is probability that the input to the child r is //the memorized pattern c (how close is the input to the memorized pattern) //assume size(piOut) = number of children void SubRegion::recognize(vector<vector<double> > &lambda, vector<vector<double> > &piOut) { unsigned r, c; AccessKey lKey(0,0); unsigned rowCount = myRegion.getParent() -> getMemCount(); //cPiIn.size(); ? unsigned colCount = myRegion.getMemCount(); //multiply all lambdas into lambdaProd //lambdaProd[c] is combined probability from children that the input to ALL of them //(total input to this Sub-region) is the memorized pattern c //(AND operation - multiplication) vector<double> lambdaProd(colCount, 1.0); for(c = 0; c < colCount; c++) for(r = 0; r < lambda.size(); r++) //lambda.size() = NumberOfChildren lambdaProd[c] *= lambda[r][c]; // DG. I think if we try to add new learning and forget rare memories that have been referenced by higher level memories, // the program can crash due to these orphaned memories still being in cCPDMatrix. // (This version of the program does not allow addition of learning). // We could consider deleting the orphaned memories from cCPDMatrix at this point. // // Exptl - can recalculate required array size in case forgetting memories results in incorrect value // Probably not a very good strategy but code may be useful anyway. // std::map<AccessKey, double>::iterator lIter0, lIterEnd0; // lIterEnd0 = cCPDMatrix->end(); //for ( lIter0 = cCPDMatrix->begin(); lIter0 != lIterEnd0; lIter0++ ) //{ // const std::pair<unsigned,unsigned> lPosition= lIter0->first.cPosition; // r=lPosition.first; // c=lPosition.second; // if ( r > rowCount ) // rowCount = r; // if ( c > colCount ) // colCount = c; //} vector<double> v(colCount, 0); // fxu is the probability that the current input (classified as c) is // part of the higher-level pattern r // Optimisation by Greg Kochaniak - fxu does not have to be a matrix if we just have a single loop. double fxu, lOut; belStar.assign(colCount, 0); lambdaOut.assign(rowCount, 0); std::map<AccessKey, double>::iterator lIter, lIterEnd; lIterEnd = cpdMatrix.end(); for ( lIter = cpdMatrix.begin(); lIter != lIterEnd; lIter++ ) { const std::pair<unsigned,unsigned> lPosition= lIter->first.cPosition; r=lPosition.first; c=lPosition.second; double lVal = lIter->second; lOut = lambdaProd[c] * lVal; fxu = lOut * piIn[r]; if( belStar[c] < fxu ) { belStar[c] = fxu; } if( lambdaOut[r] < lOut ) { lambdaOut[r] = lOut; } } /* The following code is no longer needed //cBelStar (belStarX) is the max for each column in fxu (max over u) // colCount is the number of memorised spatial pattern coincidences cBelStar.resize(colCount, 0); cBelStar.assign(colCount, 0); for(r = 0; r < rowCount; r++) for(c = 0; c < colCount; c++) if(cBelStar[c] < fxu[r][c]) cBelStar[c] = fxu[r][c]; //cLambdaOut is the max for each row in fxu divided by cPiIn - message to our parent cLambdaOut.resize(rowCount, 0); cLambdaOut.assign(rowCount, 0); for(r = 0; r < rowCount; r++) if(cPiIn[r] == 0) cLambdaOut[r] = 0; else{ for(c = 0; c < colCount; c++) //max of each row if(cLambdaOut[r] < fxu[r][c]) cLambdaOut[r] = fxu[r][c]; cLambdaOut[r] /= cPiIn[r]; } //lambda.size() = piOut.size() = InputCount(NumberOfChildren) (or 1 for lowest level) piOut.resize(lambda.size()); for(r = 0; r < piOut.size(); r++){ piOut[r].resize(colCount); for(c = 0; c < colCount; c++) if(lambda[r][c] == 0) piOut[r][c] = 0; else piOut[r][c] = cBelStar[c] / lambda[r][c]; } */ }