void init_Spatial_Pooler(py::module& m) { py::class_<SpatialPooler> py_SpatialPooler(m, "SpatialPooler"); py_SpatialPooler.def( py::init<vector<UInt> , vector<UInt> , UInt , Real , bool , Real , UInt , UInt , Real , Real , Real , Real , UInt , Real , Int , UInt , bool>() , py::arg("inputDimensions") = vector<UInt>({ 32, 32 }) , py::arg("columnDimensions") = vector<UInt>({ 64, 64 }) , py::arg("potentialRadius") = 16 , py::arg("potentialPct") = 0.5 , py::arg("globalInhibition") = false , py::arg("localAreaDensity") = -1.0 , py::arg("numActiveColumnsPerInhArea") = 10 , py::arg("stimulusThreshold") = 0 , py::arg("synPermInactiveDec") = 0.01 , py::arg("synPermActiveInc") = 0.1 , py::arg("synPermConnected") = 0.1 , py::arg("minPctOverlapDutyCycle") = 0.001 , py::arg("dutyCyclePeriod") = 1000 , py::arg("boostStrength") = 0.0 , py::arg("seed") = -1 , py::arg("spVerbosity") = 0 , py::arg("wrapAround") = true ); py_SpatialPooler.def("initialize", &SpatialPooler::initialize , py::arg("inputDimensions") = vector<UInt>({ 32, 32 }) , py::arg("columnDimensions") = vector<UInt>({ 64, 64 }) , py::arg("potentialRadius") = 16 , py::arg("potentialPct") = 0.5 , py::arg("globalInhibition") = false , py::arg("localAreaDensity") = -1.0 , py::arg("numActiveColumnsPerInhArea") = 10 , py::arg("stimulusThreshold") = 0 , py::arg("synPermInactiveDec") = 0.01 , py::arg("synPermActiveInc") = 0.1 , py::arg("synPermConnected") = 0.1 , py::arg("minPctOverlapDutyCycle") = 0.001 , py::arg("dutyCyclePeriod") = 1000 , py::arg("boostStrength") = 0.0 , py::arg("seed") = -1 , py::arg("spVerbosity") = 0 , py::arg("wrapAround") = true); py_SpatialPooler.def("getColumnDimensions", &SpatialPooler::getColumnDimensions); py_SpatialPooler.def("getInputDimensions", &SpatialPooler::getInputDimensions); py_SpatialPooler.def("getNumColumns", &SpatialPooler::getNumColumns); py_SpatialPooler.def("getNumInputs", &SpatialPooler::getNumInputs); py_SpatialPooler.def("getPotentialRadius", &SpatialPooler::getPotentialRadius); py_SpatialPooler.def("setPotentialRadius", &SpatialPooler::setPotentialRadius); py_SpatialPooler.def("getPotentialPct", &SpatialPooler::getPotentialPct); py_SpatialPooler.def("setPotentialPct", &SpatialPooler::setPotentialPct); py_SpatialPooler.def("getGlobalInhibition", &SpatialPooler::getGlobalInhibition); py_SpatialPooler.def("setGlobalInhibition", &SpatialPooler::setGlobalInhibition); py_SpatialPooler.def("getNumActiveColumnsPerInhArea", &SpatialPooler::getNumActiveColumnsPerInhArea); py_SpatialPooler.def("setNumActiveColumnsPerInhArea", &SpatialPooler::setNumActiveColumnsPerInhArea); py_SpatialPooler.def("getLocalAreaDensity", &SpatialPooler::getLocalAreaDensity); py_SpatialPooler.def("setLocalAreaDensity", &SpatialPooler::setLocalAreaDensity); py_SpatialPooler.def("getStimulusThreshold", &SpatialPooler::getStimulusThreshold); py_SpatialPooler.def("setStimulusThreshold", &SpatialPooler::setStimulusThreshold); py_SpatialPooler.def("getInhibitionRadius", &SpatialPooler::getInhibitionRadius); py_SpatialPooler.def("setInhibitionRadius", &SpatialPooler::setInhibitionRadius); py_SpatialPooler.def("getDutyCyclePeriod", &SpatialPooler::getDutyCyclePeriod); py_SpatialPooler.def("setDutyCyclePeriod", &SpatialPooler::setDutyCyclePeriod); py_SpatialPooler.def("getBoostStrength", &SpatialPooler::getBoostStrength); py_SpatialPooler.def("setBoostStrength", &SpatialPooler::setBoostStrength); py_SpatialPooler.def("getIterationNum", &SpatialPooler::getIterationNum); py_SpatialPooler.def("setIterationNum", &SpatialPooler::setIterationNum); py_SpatialPooler.def("getIterationLearnNum", &SpatialPooler::getIterationLearnNum); py_SpatialPooler.def("setIterationLearnNum", &SpatialPooler::setIterationLearnNum); py_SpatialPooler.def("getSpVerbosity", &SpatialPooler::getSpVerbosity); py_SpatialPooler.def("setSpVerbosity", &SpatialPooler::setSpVerbosity); py_SpatialPooler.def("getWrapAround", &SpatialPooler::getWrapAround); py_SpatialPooler.def("setWrapAround", &SpatialPooler::setWrapAround); py_SpatialPooler.def("getUpdatePeriod", &SpatialPooler::getUpdatePeriod); py_SpatialPooler.def("setUpdatePeriod", &SpatialPooler::setUpdatePeriod); py_SpatialPooler.def("getSynPermActiveInc", &SpatialPooler::getSynPermActiveInc); py_SpatialPooler.def("setSynPermActiveInc", &SpatialPooler::setSynPermActiveInc); py_SpatialPooler.def("getSynPermInactiveDec", &SpatialPooler::getSynPermInactiveDec); py_SpatialPooler.def("setSynPermInactiveDec", &SpatialPooler::setSynPermInactiveDec); py_SpatialPooler.def("getSynPermBelowStimulusInc", &SpatialPooler::getSynPermBelowStimulusInc); py_SpatialPooler.def("setSynPermBelowStimulusInc", &SpatialPooler::setSynPermBelowStimulusInc); py_SpatialPooler.def("getSynPermConnected", &SpatialPooler::getSynPermConnected); py_SpatialPooler.def("getSynPermMax", &SpatialPooler::getSynPermMax); py_SpatialPooler.def("getMinPctOverlapDutyCycles", &SpatialPooler::getMinPctOverlapDutyCycles); py_SpatialPooler.def("setMinPctOverlapDutyCycles", &SpatialPooler::setMinPctOverlapDutyCycles); // loadFromString py_SpatialPooler.def("loadFromString", [](SpatialPooler& self, const std::string& inString) { std::istringstream inStream(inString); self.load(inStream); }); // writeToString py_SpatialPooler.def("writeToString", [](const SpatialPooler& self) { std::ostringstream os; os.flags(ios::scientific); os.precision(numeric_limits<double>::digits10 + 1); self.save(os); return os.str(); }); // compute py_SpatialPooler.def("compute", [](SpatialPooler& self, py::array& x, bool learn, py::array& y) { if (py::isinstance<py::array_t<std::uint32_t>>(x) == false) { throw runtime_error("Incompatible format. Expect uint32"); } if (py::isinstance<py::array_t<std::uint32_t>>(y) == false) { throw runtime_error("Incompatible format. Expect uint32"); } self.compute(get_it<UInt>(x), learn, get_it<UInt>(y)); }); // stripUnlearnedColumns py_SpatialPooler.def("stripUnlearnedColumns", [](SpatialPooler& self, py::array_t<UInt>& x) { self.stripUnlearnedColumns(get_it(x)); }); // setBoostFactors py_SpatialPooler.def("setBoostFactors", [](SpatialPooler& self, py::array_t<Real>& x) { self.setBoostFactors(get_it(x)); }); // getBoostFactors py_SpatialPooler.def("getBoostFactors", [](const SpatialPooler& self, py::array_t<Real>& x) { self.getBoostFactors(get_it(x)); }); // setOverlapDutyCycles py_SpatialPooler.def("setOverlapDutyCycles", [](SpatialPooler& self, py::array_t<Real>& x) { self.setOverlapDutyCycles(get_it(x)); }); // getOverlapDutyCycles py_SpatialPooler.def("getOverlapDutyCycles", [](const SpatialPooler& self, py::array_t<Real>& x) { self.getOverlapDutyCycles(get_it(x)); }); // setActiveDutyCycles py_SpatialPooler.def("setActiveDutyCycles", [](SpatialPooler& self, py::array_t<Real>& x) { self.setActiveDutyCycles(get_it(x)); }); // getActiveDutyCycles py_SpatialPooler.def("getActiveDutyCycles", [](const SpatialPooler& self, py::array_t<Real>& x) { self.getActiveDutyCycles(get_it(x)); }); // setMinOverlapDutyCycles py_SpatialPooler.def("setMinOverlapDutyCycles", [](SpatialPooler& self, py::array_t<Real>& x) { self.setMinOverlapDutyCycles(get_it(x)); }); // getMinOverlapDutyCycles py_SpatialPooler.def("getMinOverlapDutyCycles", [](const SpatialPooler& self, py::array_t<Real>& x) { self.getMinOverlapDutyCycles(get_it(x)); }); // setPotential py_SpatialPooler.def("setPotential", [](SpatialPooler& self, UInt column, py::array_t<UInt>& x) { self.setPotential(column, get_it(x)); }); // getPotential py_SpatialPooler.def("getPotential", [](const SpatialPooler& self, UInt column, py::array_t<UInt>& x) { self.getPotential(column, get_it(x)); }); // setPermanence py_SpatialPooler.def("setPermanence", [](SpatialPooler& self, UInt column, py::array_t<Real>& x) { self.setPermanence(column, get_it(x)); }); // getPermanence py_SpatialPooler.def("getPermanence", [](const SpatialPooler& self, UInt column, py::array_t<Real>& x) { self.getPermanence(column, get_it(x)); }); // getConnectedSynapses py_SpatialPooler.def("getConnectedSynapses", [](const SpatialPooler& self, UInt column, py::array_t<UInt>& x) { self.getConnectedSynapses(column, get_it(x)); }); // getConnectedCounts py_SpatialPooler.def("getConnectedCounts", [](const SpatialPooler& self, py::array_t<UInt>& x) { self.getConnectedCounts(get_it(x)); }); // getOverlaps py_SpatialPooler.def("getOverlaps", [](SpatialPooler& self) { auto overlaps = self.getOverlaps(); return py::array_t<UInt>( overlaps.size(), overlaps.data()); }); // getBoostedOverlaps py_SpatialPooler.def("getBoostedOverlaps", [](SpatialPooler& self) { auto overlaps = self.getBoostedOverlaps(); return py::array_t<Real>( overlaps.size(), overlaps.data()); }); //////////////////// // inhibitColumns auto inhibitColumns_func = [](SpatialPooler& self, py::array_t<Real>& overlaps) { std::vector<nupic::Real> overlapsVector(get_it(overlaps), get_end(overlaps)); std::vector<nupic::UInt> activeColumnsVector; self.inhibitColumns_(overlapsVector, activeColumnsVector); return py::array_t<UInt>( activeColumnsVector.size(), activeColumnsVector.data()); }; py_SpatialPooler.def("_inhibitColumns", inhibitColumns_func); py_SpatialPooler.def("inhibitColumns_", inhibitColumns_func); ////////////////////// // getIterationLearnNum py_SpatialPooler.def("getIterationLearnNum", &SpatialPooler::getIterationLearnNum); // pickle py_SpatialPooler.def(py::pickle( [](const SpatialPooler& sp) { std::stringstream ss; sp.save(ss); return ss.str(); }, [](std::string& s) { std::istringstream ss(s); SpatialPooler sp; sp.load(ss); return sp; })); }
void testSP() { Random random(10); nupic::Timer testTimer; const UInt inputSize = 500; const UInt numColumns = 500; const UInt w = 50; vector<UInt> inputDims{inputSize}; vector<UInt> colDims{numColumns}; SpatialPooler sp1; sp1.initialize(inputDims, colDims); UInt input[inputSize]; for (UInt i = 0; i < inputSize; ++i) { if (i < w) { input[i] = 1; } else { input[i] = 0; } } UInt output[numColumns]; for (UInt i = 0; i < 10000; ++i) { random.shuffle(input, input + inputSize); sp1.compute(input, true, output); } // Now we reuse the last input to test after serialization vector<UInt> activeColumnsBefore; for (UInt i = 0; i < numColumns; ++i) { if (output[i] == 1) { activeColumnsBefore.push_back(i); } } // Save initial trained model ofstream osA("outA.proto", ofstream::binary); sp1.write(osA); osA.close(); ofstream osC("outC.proto", ofstream::binary); sp1.save(osC); osC.close(); SpatialPooler sp2; long timeA = 0, timeC = 0; for (UInt i = 0; i < 100; ++i) { // Create new input random.shuffle(input, input + inputSize); // Get expected output UInt outputBaseline[numColumns]; sp1.compute(input, true, outputBaseline); UInt outputA[numColumns]; UInt outputC[numColumns]; // A - First do iostream version { SpatialPooler spTemp; testTimer.start(); // Deserialize ifstream is("outA.proto", ifstream::binary); spTemp.read(is); is.close(); // Feed new record through spTemp.compute(input, true, outputA); // Serialize ofstream os("outA.proto", ofstream::binary); spTemp.write(os); os.close(); testTimer.stop(); timeA = timeA + testTimer.getElapsed(); } // C - Next do old version { SpatialPooler spTemp; testTimer.start(); // Deserialize ifstream is("outC.proto", ifstream::binary); spTemp.load(is); is.close(); // Feed new record through spTemp.compute(input, true, outputC); // Serialize ofstream os("outC.proto", ofstream::binary); spTemp.save(os); os.close(); testTimer.stop(); timeC = timeC + testTimer.getElapsed(); } for (UInt i = 0; i < numColumns; ++i) { NTA_ASSERT(outputBaseline[i] == outputA[i]); NTA_ASSERT(outputBaseline[i] == outputC[i]); } } remove("outA.proto"); remove("outC.proto"); cout << "Time for iostream capnp: " << ((Real)timeA / 1000.0) << endl; cout << "Time for old method: " << ((Real)timeC / 1000.0) << endl; }