@@ -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