Skip to content

Commit 76e0abb

Browse files
committed
napi_sine now is the same as HelloSPTP
1 parent ca035fb commit 76e0abb

File tree

9 files changed

+115
-59
lines changed

9 files changed

+115
-59
lines changed

src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ install(TARGETS
417417

418418
install(TARGETS
419419
${src_executable_hotgym}
420+
${src_executable_napi_sine}
420421
${src_executable_mnistsp}
421422
RUNTIME DESTINATION bin
422423
LIBRARY DESTINATION lib

src/examples/hotgym/HelloSPTP.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ EPOCHS = 2; // make test faster in Debug
121121
input.addNoise(0.01f, rnd); //change 1% of the SDR for each iteration, this makes a random sequence, but seemingly stable
122122
tRng.stop();
123123

124-
//SP (global x local)
124+
//SP (global and local)
125125
if(useSPlocal) {
126126
tSPloc.start();
127127
spLocal.compute(input, true, outSPlocal);
@@ -154,7 +154,7 @@ EPOCHS = 2; // make test faster in Debug
154154
avgAnomOld_ = avgAnom10.getCurrentAvg(); //update
155155
}
156156
tAnLikelihood.start();
157-
anLikelihood.anomalyProbability(an); //FIXME AnLikelihood is 0.0, probably not working correctly
157+
anLikely = anLikelihood.anomalyProbability(an); //FIXME AnLikelihood is 0.0, probably not working correctly
158158
tAnLikelihood.stop();
159159

160160

@@ -173,13 +173,14 @@ EPOCHS = 2; // make test faster in Debug
173173
<< "\n";
174174

175175
// output values
176-
cout << "Epoch = " << e << endl;
176+
cout << "Epoch = " << e+1 << endl;
177177
cout << "Anomaly = " << an << endl;
178178
cout << "Anomaly (avg) = " << avgAnom10.getCurrentAvg() << endl;
179179
cout << "Anomaly (Likelihood) = " << anLikely << endl;
180-
cout << "SP (g)= " << outSP << endl;
181-
cout << "SP (l)= " << outSPlocal <<endl;
182-
cout << "TM= " << outTM << endl;
180+
cout << "input = " << input << endl;
181+
if(useSPlocal) cout << "SP (g)= " << outSP << endl;
182+
if(useSPlocal) cout << "SP (l)= " << outSPlocal <<endl;
183+
if(useTM) cout << "TM= " << outTM << endl;
183184

184185
//timers
185186
cout << "==============TIMERS============" << endl;
@@ -220,7 +221,7 @@ EPOCHS = 2; // make test faster in Debug
220221
const float goldAnAvg = 0.411894f; // ...the averaged value, on the other hand, should improve/decrease.
221222

222223
#ifdef _ARCH_DETERMINISTIC
223-
if(EPOCHS == 5000) {
224+
if(e+1 == 5000) {
224225
//these hand-written values are only valid for EPOCHS = 5000 (default), but not for debug and custom runs.
225226
NTA_CHECK(input == goldEnc) << "Deterministic output of Encoder failed!\n" << input << "should be:\n" << goldEnc;
226227
if(useSPglobal) { NTA_CHECK(outSPglobal == goldSP) << "Deterministic output of SP (g) failed!\n" << outSP << "should be:\n" << goldSP; }
@@ -230,6 +231,7 @@ EPOCHS = 2; // make test faster in Debug
230231
<< "Deterministic output of Anomaly failed! " << an << "should be: " << goldAn;
231232
NTA_CHECK(static_cast<UInt>(avgAnom10.getCurrentAvg() * 10000.0f) == static_cast<UInt>(goldAnAvg * 10000.0f))
232233
<< "Deterministic average anom score failed:" << avgAnom10.getCurrentAvg() << " should be: " << goldAnAvg;
234+
std::cout << "outputs match\n";
233235
}
234236
#endif
235237

src/examples/hotgym/HelloSPTP.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class BenchmarkHotgym {
1616
public:
1717
Real64 run(
1818
UInt EPOCHS = 5000,
19-
bool useSPlocal=true, //can toggle which (long running) components are tested, default all
19+
bool useSPlocal=false, //can toggle which (long running) components are tested, default all
2020
bool useSPglobal=true,
2121
bool useTM=true,
2222
const UInt COLS = 2048, // number of columns in SP, TP

src/examples/napi_sine/napi_sine.cpp

+51-23
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,33 @@
1919
#include <htm/utils/Random.hpp>
2020
#include <htm/utils/Log.hpp>
2121
#include <htm/ntypes/Value.hpp>
22+
#include "htm/utils/MovingAverage.hpp"
23+
#include "htm/algorithms/AnomalyLikelihood.hpp"
2224
#include <fstream>
2325

2426
using namespace htm;
2527

26-
static bool verbose = false;
28+
static bool verbose = true;
2729
#define VERBOSE if (verbose) std::cout << " "
2830

2931

3032
//this runs as an executable
3133

3234
int main(int argc, char* argv[]) {
3335
htm::UInt EPOCHS = 5000; // number of iterations (calls to encoder/SP/TP compute() )
36+
#ifndef NDEBUG
37+
EPOCHS = 2; // make test faster in Debug
38+
#endif
39+
3440
const UInt DIM_INPUT = 1000; // Width of encoder output
3541
const UInt COLS = 2048; // number of columns in SP, TP
3642
const UInt CELLS = 8; // cells per column in TP
3743
Random rnd(42); // uses fixed seed for deterministic output
3844
std::ofstream ofs;
3945

40-
std::string encoder_params = "{size: " + std::to_string(DIM_INPUT) + ", activeBits: 4, radius: 0.5, seed: 2019 }";
46+
std::string encoder_params = "{size: " + std::to_string(DIM_INPUT) + ", sparsity: 0.2, radius: 0.03, seed: 2019, noise: 0.01}";
4147
std::string sp_global_params = "{columnCount: " + std::to_string(COLS) + ", globalInhibition: true}";
42-
std::string tm_params = "{activationThreshold: 9, cellsPerColumn: " + std::to_string(CELLS) + "}";
48+
std::string tm_params = "{cellsPerColumn: " + std::to_string(CELLS) + ", orColumnOutputs: true}";
4349

4450
// Runtime arguments: napi_sine [epochs [filename]]
4551
if(argc >= 2) {
@@ -51,7 +57,7 @@ int main(int argc, char* argv[]) {
5157

5258
try {
5359

54-
std::cout << "initializing\n";
60+
std::cout << "initializing. DIM_INPUT=" << DIM_INPUT << ", COLS=" << COLS << ", CELLS=" << CELLS << "\n";
5561

5662
Network net;
5763

@@ -66,6 +72,7 @@ int main(int argc, char* argv[]) {
6672

6773
net.initialize();
6874

75+
6976
///////////////////////////////////////////////////////////////
7077
//
7178
// .----------------.
@@ -92,39 +99,60 @@ int main(int argc, char* argv[]) {
9299
// enable this to see a trace as it executes
93100
//net.setLogLevel(LogLevel::LogLevel_Verbose);
94101

95-
std::cout << "Running: \n";
102+
std::cout << "Running: " << EPOCHS << " Iterations.\n ";
103+
104+
float anLikely = 0.0f;
105+
MovingAverage avgAnomaly(1000);
106+
AnomalyLikelihood anLikelihood;
107+
96108
// RUN
97-
for (size_t i = 0; i < EPOCHS; i++) {
109+
float x = 0.00f;
110+
for (size_t e = 0; e < EPOCHS; e++) {
98111
// genarate some data to send to the encoder
99-
// -- A sin wave, one degree rotation per iteration, 1% noise added
100-
double data = std::sin(i * (3.1415 / 180)) + (double)rnd.realRange(-0.01f, +0.1f);
112+
113+
// -- A sine wave, one degree rotation per iteration (an alternate function)
114+
//double data = std::sin(i * (3.1415 / 180));
115+
116+
// -- sine wave, 0.01 radians per iteration (Note: first iteration is for x=0.01, not 0)
117+
x += 0.01f; // step size for fn(x)
118+
double data = std::sin(x);
101119
encoder->setParameterReal64("sensedValue", data); // feed data into RDSE encoder for this iteration.
102120

103121
// Execute an iteration.
104122
net.run(1);
105123

106-
// output values
107124
float an = ((float *)tm->getOutputData("anomaly").getBuffer())[0];
108-
VERBOSE << "Epoch = " << i << std::endl;
109-
VERBOSE << " Data = " << data << std::endl;
110-
VERBOSE << " Encoder out = " << encoder->getOutputData("encoded").getSDR();
111-
VERBOSE << " SP (global) = " << sp_global->getOutputData("bottomUpOut").getSDR();
112-
VERBOSE << " TM output = " << tm->getOutputData("bottomUpOut").getSDR();
113-
VERBOSE << " ActiveCells = " << tm->getOutputData("activeCells").getSDR();
114-
VERBOSE << " winners = " << tm->getOutputData("predictedActiveCells").getSDR();
115-
VERBOSE << " Anomaly = " << an << std::endl;
116-
117-
// Save the data for plotting. <iteration>, <sin data>, <anomaly>\n
118-
if (ofs.is_open())
119-
ofs << i << "," << data << "," << an << std::endl;
125+
avgAnomaly.compute(an);
126+
anLikely = anLikelihood.anomalyProbability(an);
127+
128+
129+
// Save the data for plotting. <iteration>, <sin data>, <anomaly>, <likelyhood>\n
130+
if (ofs.is_open()) {
131+
ofs << e << "," << data << "," << an << "," << anLikely << std::endl;
132+
}
133+
134+
if (e == EPOCHS - 1)
135+
{
136+
137+
// output values
138+
float final_an = ((float *)tm->getOutputData("anomaly").getBuffer())[0];
139+
VERBOSE << "Result after " << e + 1 << " iterations.\n";
140+
VERBOSE << " Anomaly(avg) = " << avgAnomaly.getCurrentAvg() << std::endl;
141+
VERBOSE << " Anomaly(Likelihood) = " << anLikely << endl;
142+
VERBOSE << " Encoder out = " << encoder->getOutputData("encoded").getSDR();
143+
VERBOSE << " SP (global) = " << sp_global->getOutputData("bottomUpOut").getSDR();
144+
VERBOSE << " TM predictive = " << tm->getOutputData("predictiveCells").getSDR();
145+
}
120146
}
121147
if (ofs.is_open())
122148
ofs.close();
149+
150+
123151
std::cout << "finished\n";
124152

125153

126-
} catch (Exception &e) {
127-
std::cerr << e.what();
154+
} catch (Exception &ex) {
155+
std::cerr << ex.what();
128156
if (ofs.is_open())
129157
ofs.close();
130158
return 1;

src/htm/algorithms/SpatialPooler.hpp

+8-7
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,18 @@ class SpatialPooler : public Serializable
6666

6767
SpatialPooler();
6868
SpatialPooler(const vector<UInt> inputDimensions, const vector<UInt> columnDimensions,
69-
UInt potentialRadius = 16u, Real potentialPct = 0.5f,
70-
bool globalInhibition = true,
69+
UInt potentialRadius = 16u,
70+
Real potentialPct = 0.5f,
71+
bool globalInhibition = false,
7172
Real localAreaDensity = 0.05f, //5%
72-
UInt stimulusThreshold = 0u,
73+
UInt stimulusThreshold = 0u,
7374
Real synPermInactiveDec = 0.008f,
74-
Real synPermActiveInc = 0.05f,
75+
Real synPermActiveInc = 0.05f,
7576
Real synPermConnected = 0.1f,
76-
Real minPctOverlapDutyCycles = 0.001f,
77-
UInt dutyCyclePeriod = 1000u,
77+
Real minPctOverlapDutyCycles = 0.001f,
78+
UInt dutyCyclePeriod = 1000u,
7879
Real boostStrength = 0.0f,
79-
Int seed = 1,
80+
Int seed = 1,
8081
UInt spVerbosity = 0u,
8182
bool wrapAround = true);
8283

src/htm/regions/RDSERegion.cpp

+16-5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <htm/engine/Region.hpp>
2929
#include <htm/engine/Spec.hpp>
3030
#include <htm/ntypes/Array.hpp>
31+
#include "htm/utils/Random.hpp"
3132
#include <htm/utils/Log.hpp>
3233

3334
#include <memory>
@@ -47,18 +48,23 @@ namespace htm {
4748
resolution: {type: Real32, default: "0.0"},
4849
category: {type: Bool, default: "false"},
4950
seed: {type: UInt32, default: "0"},
50-
sensedValue: {type: Real64, default: "0.0", access: ReadWrite }},
51+
noise: {description: "amount of noise to add to the output SDR. 0.01 is 1%",
52+
type: Real32, default: "0.0"},
53+
sensedValue: {description: "The value to encode. Overriden by input 'values'.",
54+
type: Real64, default: "0.0", access: ReadWrite }},
5155
inputs: {
52-
values: {type: Real64, count: 1, isDefaultInput: yes, isRegionLevel: yes}},
56+
values: {description: "Values to encode. Overrides sensedValue.",
57+
type: Real64, count: 1, isDefaultInput: yes, isRegionLevel: yes}},
5358
outputs: {
54-
encoded: {type: SDR, count: 0, isDefaultOutput: yes, isRegionLevel: yes }}} )");
59+
encoded: {description: "Encoded bits. Not a true Sparse Data Representation.",
60+
type: SDR, count: 0, isDefaultOutput: yes, isRegionLevel: yes }}} )");
5561

5662
return ns;
5763
}
5864

5965

6066
RDSERegion::RDSERegion(const ValueMap &par, Region *region) : RegionImpl(region) {
61-
67+
rnd_ = Random(42);
6268
spec_.reset(createSpec());
6369
ValueMap params = ValidateParameters(par, spec_.get());
6470

@@ -73,7 +79,7 @@ RDSERegion::RDSERegion(const ValueMap &par, Region *region) : RegionImpl(region)
7379

7480
encoder_ = std::make_shared<RandomDistributedScalarEncoder>(args);
7581
sensedValue_ = params.getScalarT<Real64>("sensedValue");
76-
82+
noise_ = params.getScalarT<Real32>("noise");
7783
}
7884

7985
RDSERegion::RDSERegion(ArWrapper &wrapper, Region *region)
@@ -99,6 +105,11 @@ void RDSERegion::compute() {
99105
}
100106
SDR &output = getOutput("encoded")->getData().getSDR();
101107
encoder_->encode((Real64)sensedValue_, output);
108+
109+
// Add some noise.
110+
// noise_ = 0.01 means change 1% of the SDR for each iteration, this makes a random sequence, but seemingly stable
111+
if (noise_ != 0.0f)
112+
output.addNoise(noise_, rnd_);
102113
}
103114

104115

src/htm/regions/RDSERegion.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class RDSERegion : public RegionImpl, Serializable {
6767
template<class Archive>
6868
void save_ar(Archive& ar) const {
6969
ar(CEREAL_NVP(sensedValue_));
70+
ar(CEREAL_NVP(noise_));
71+
ar(CEREAL_NVP(rnd_));
7072
ar(cereal::make_nvp("encoder", encoder_));
7173
}
7274
// FOR Cereal Deserialization
@@ -77,6 +79,8 @@ class RDSERegion : public RegionImpl, Serializable {
7779
template<class Archive>
7880
void load_ar(Archive& ar) {
7981
ar(CEREAL_NVP(sensedValue_));
82+
ar(CEREAL_NVP(noise_));
83+
ar(CEREAL_NVP(rnd_));
8084
ar(cereal::make_nvp("encoder", encoder_));
8185
setDimensions(encoder_->dimensions);
8286
}
@@ -89,6 +93,8 @@ class RDSERegion : public RegionImpl, Serializable {
8993

9094
private:
9195
Real64 sensedValue_;
96+
Real32 noise_;
97+
Random rnd_;
9298
std::shared_ptr<RandomDistributedScalarEncoder> encoder_;
9399
};
94100
} // namespace htm

src/htm/regions/SPRegion.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ SPRegion::SPRegion(const ValueMap &values, Region *region)
4343
// parameters out of the map and set aside so we can pass them to the SpatialPooler
4444
// algorithm when we create it during initialization().
4545
args_.columnCount = values.getScalarT<UInt32>("columnCount", 0);
46-
args_.potentialRadius = values.getScalarT<UInt32>("potentialRadius", 0);
46+
args_.potentialRadius = values.getScalarT<UInt32>("potentialRadius", 16u);
4747
args_.potentialPct = values.getScalarT<Real32>("potentialPct", 0.5);
4848
args_.globalInhibition = values.getScalarT<bool>("globalInhibition", false);
4949
args_.localAreaDensity = values.getScalarT<Real32>("localAreaDensity", 0.05f);
@@ -54,7 +54,7 @@ SPRegion::SPRegion(const ValueMap &values, Region *region)
5454
args_.minPctOverlapDutyCycles = values.getScalarT<Real32>("minPctOverlapDutyCycles", 0.001f);
5555
args_.dutyCyclePeriod = values.getScalarT<UInt32>("dutyCyclePeriod", 1000);
5656
args_.boostStrength = values.getScalarT<Real32>("boostStrength", 0.0f);
57-
args_.seed = values.getScalarT<Int32>("seed", -1);
57+
args_.seed = values.getScalarT<Int32>("seed", 1);
5858
args_.spVerbosity = values.getScalarT<UInt32>("spVerbosity", 0);
5959
args_.wrapAround = values.getScalarT<bool>("wrapAround", true);
6060
spatialImp_ = values.getString("spatialImp", "");
@@ -235,7 +235,7 @@ Spec *SPRegion::createSpec() {
235235
NTA_BasicType_UInt32, // type
236236
1, // elementCount
237237
"", // constraints
238-
"0", // defaultValue
238+
"16", // defaultValue
239239
ParameterSpec::ReadWriteAccess)); // access
240240

241241
ns->parameters.add(

0 commit comments

Comments
 (0)