-
Notifications
You must be signed in to change notification settings - Fork 276
Fix SP unstable output, synapse decay #1382
Changes from all commits
eba72d0
30f9227
c01a95b
b34d1cf
9d4c4a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -488,6 +488,16 @@ const vector<Real>& SpatialPooler::getBoostedOverlaps() const | |
return boostedOverlaps_; | ||
} | ||
|
||
/** helper method that checks SP output is stable for given configuration */ | ||
bool checkUnstableParams_(SpatialPooler &sp) { | ||
vector<UInt> input(sp.getNumInputs(), 1); //auto size of input | ||
vector<UInt> out1(sp.getNumColumns(), 0); | ||
vector<UInt> out2(sp.getNumColumns(), 0); | ||
sp.compute(input.data(), false, out1.data()); | ||
sp.compute(input.data(), false, out2.data()); | ||
return std::equal(std::begin(out1), std::end(out1), std::begin(out2)); //compare all, element wise | ||
} | ||
|
||
void SpatialPooler::initialize(vector<UInt> inputDimensions, | ||
vector<UInt> columnDimensions, | ||
UInt potentialRadius, | ||
|
@@ -593,6 +603,9 @@ void SpatialPooler::initialize(vector<UInt> inputDimensions, | |
printParameters(); | ||
std::cout << "CPP SP seed = " << seed << std::endl; | ||
} | ||
|
||
//check for reasonable params | ||
NTA_CHECK(checkUnstableParams_(*this)); //TODO the assert runs only at debug builds, make mandatory? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: make this mandatory even for Release builds? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently the check crashes? on some instances, while already identifies some problematic instances in our unit-tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. .. crash fixed in #1391 |
||
} | ||
|
||
void SpatialPooler::compute(UInt inputArray[], bool learn, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,8 @@ | |
* Implementation of unit tests for SpatialPooler | ||
*/ | ||
|
||
#include <algorithm> //generate | ||
#include <cstdlib> //rand | ||
#include <cstring> | ||
#include <fstream> | ||
#include <stdio.h> | ||
|
@@ -2222,6 +2224,54 @@ namespace { | |
EXPECT_EQ(0, countNonzero(activeColumns)); | ||
} | ||
|
||
|
||
// function generator: | ||
int RandomNumber01 () { return (rand()%2); } // returns random (binary) numbers from {0,1} | ||
|
||
TEST(SpatialPoolerTest, testConstructorInitParamsUnstable) | ||
{ | ||
/** this test exposes bug where c++ SP (wrongly) produces | ||
different output for the same input. | ||
XXX sensitive - marks (empirically!) discovered set of parameter | ||
that produce the err behavior; changing any of the XXX params | ||
may cause the SP to behave "normally" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test-case for unstable combination of init params |
||
*/ | ||
SpatialPooler sp{std::vector<UInt>{1000} /* input*/, std::vector<UInt>{20}/* SP output cols XXX sensitive*/, | ||
/*pot radius*/ 20, //each col sees | ||
/*pot pct*/ 0.5, //XXX sensitive | ||
/*global inhibition*/ false, //XXX sensitive | ||
/*Real localAreaDensity=*/0.02, //2% active cols | ||
/*UInt numActiveColumnsPerInhArea=*/0, //mutex with above ^^ //XXX sensitive | ||
}; | ||
sp.setBoostStrength(0.0); | ||
|
||
vector<UInt> input(sp.getNumInputs(), 1); | ||
vector<UInt> out1(sp.getNumColumns(), 0); | ||
vector<UInt> out2(sp.getNumColumns(), 0); | ||
|
||
for(UInt i=0; i< 1800; i++) { //epochs | ||
//burn in | ||
for (UInt burnIn=1; burnIn < 90; burnIn++) { | ||
generate(input.begin(), input.end(), RandomNumber01); //random input | ||
sp.compute(input.data(), true, out1.data()); //burn in | ||
cout<<"."; | ||
cout.flush(); | ||
} | ||
|
||
//compare | ||
for (UInt noLearn=1; noLearn < 90; noLearn++) { | ||
generate(input.begin(), input.end(), RandomNumber01); //random input | ||
sp.compute(input.data(), false, out1.data()); | ||
sp.compute(input.data(), false, out2.data()); | ||
EXPECT_EQ(out1, out2); //not necessary with the check in SP initialize(), but keep here as example | ||
cout<<"="; | ||
cout.flush(); | ||
} | ||
cout<<endl; | ||
} | ||
} | ||
|
||
|
||
TEST(SpatialPoolerTest, testSaveLoad) | ||
{ | ||
const char* filename = "SpatialPoolerSerialization.tmp"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the "stability check" that I suggest to run on each SP initialization. So far it has already identified many misconfigurations in our unit-tests.