Skip to content

Commit faf0ab1

Browse files
committed
add anomaly detection test example
add unit test for ANSI C to demo a very basic anomaly detection strategy for a simple HTM region
1 parent 09087ac commit faf0ab1

File tree

1 file changed

+68
-1
lines changed

1 file changed

+68
-1
lines changed

src/HTM/c_ansi/UnitTests.c

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ void testRegion2() {
339339
}
340340

341341
/**
342-
* This test creates a Region of size 32x32 columsn that accepts a larger
342+
* This test creates a Region of size 32x32 columns that accepts a larger
343343
* input of size 128x128. Each input has a 128x128 sparse bit representation with about
344344
* 5% of the bits active. This example is much closer to a Region that works on
345345
* real world sized data. It tests the ability of the spatial pooler to produce a
@@ -414,6 +414,8 @@ void testRegion3() {
414414
if(DEBUG)
415415
printf("total iters = %i\n", iters);
416416

417+
418+
417419
deleteRegion(region);
418420
free(region);
419421
free(data);
@@ -422,6 +424,70 @@ void testRegion3() {
422424
printf("OK\n");
423425
}
424426

427+
/**
428+
* This test creates a hardcoded Region of size 250x1 and feeds in data that
429+
* has 10% (25) elements active. We then repeat the same sequence 10 times to
430+
* try to teach the region to learn the full sequence. From there we wish to
431+
* introduce an "anomaly", that is an input that is not expected. We detect this
432+
* by examining the prediction accuracy value. Smaller accuracy indicates a larger
433+
* anomaly. For this test we consider accuracy values <30% to be large anomalies, while
434+
* values 30%-70% are 'possible' anomalies.
435+
*/
436+
void testRegionAnomalyDetection() {
437+
printf("testRegionAnomalyDetection()...\n");
438+
439+
float acc[2];
440+
char* data = malloc(250 * sizeof(char));
441+
Region* region = newRegionHardcoded(250,1, 0, 1, 3, 4, data);
442+
srand(42);
443+
444+
/*create a sequence of length 10. repeat it 10 times and check region accuracy. */
445+
int i,j,k;
446+
for(k=0; k<11; ++k) {
447+
/*on final iteration, disable learning and detect anomalies in inference*/
448+
if(k==10) region->temporalLearning = false;
449+
450+
for(i=0; i<10; ++i) {
451+
for(j=0; j<250; ++j) /*reset all data to 0*/
452+
data[j] = 0;
453+
for(j=0; j<25; ++j) /*assign next set of 25 to 1's*/
454+
data[(i*25)+j] = 1;
455+
456+
/* introduce unexpected/anomalous inputs randomly on last iteration */
457+
if(k >= 10 && rand() % 4 == 0) {
458+
for(j=0; j<250; ++j) /*reset all data to 0*/
459+
data[j] = 0;
460+
for(j=0; j<25; ++j) { /*randomly assign set of 25 to 1's*/
461+
int ri = rand() % 10;
462+
data[(ri*25)+j] = 1;
463+
}
464+
}
465+
466+
runOnce(region);
467+
468+
getLastAccuracy(region, acc);
469+
470+
if(k>1 || (k==1 && i>=1)) {
471+
/*check for prediction accuracy <30% to be consider 'anomaly'*/
472+
if(acc[0]<0.3f && acc[1]<0.3f) {
473+
printf("Anomaly Detected (<0.3 accuracy)! Input (%i %i) produced: %f, %f\n",
474+
k, i, acc[0],acc[1]);
475+
}/*printf("k%i i%i: aAcc=%f pAcc=%f\n", k, i, acc[0], acc[1]);*/
476+
else if(acc[0]<0.7f && acc[1]<0.7f) {
477+
printf("Possible Anomaly Detected (<0.7 accuracy). Input (%i %i) produced: %f, %f\n",
478+
k, i, acc[0],acc[1]);
479+
}
480+
}
481+
}
482+
}
483+
484+
deleteRegion(region);
485+
free(region);
486+
free(data);
487+
488+
printf("OK\n");
489+
}
490+
425491
/**
426492
* This test creates a small Region of size 5x5 that is connected to an
427493
* input of size 10x10. The input has 10% (10) elements active per time
@@ -716,6 +782,7 @@ int main(void) {
716782
/*testRegionPerformance(0);*/
717783
/*testRegionPerformanceDickens();*/
718784
testRegion3();
785+
testRegionAnomalyDetection();
719786

720787
return EXIT_SUCCESS;
721788
}

0 commit comments

Comments
 (0)