780 lines
24 KiB
Plaintext
780 lines
24 KiB
Plaintext
|
/***********************************************************
|
|||
|
OUTSTAR Simulator
|
|||
|
|
|||
|
)Maureen Caudill
|
|||
|
Adaptics
|
|||
|
16776 Bernardo Center Drive
|
|||
|
Suite 110 B
|
|||
|
San Diego, CA 92128
|
|||
|
(617) 451-3752
|
|||
|
July, 1988
|
|||
|
Written in Lightspeed C (v. 2.15) on Macintosh
|
|||
|
Version 1.0
|
|||
|
|
|||
|
This outstar learns to reproduce a specified pattern
|
|||
|
on a grid of border neurodes. The pattern to be learned
|
|||
|
is read from an external text file called "pattern"
|
|||
|
|
|||
|
--------------------------------------------------------------------------------
|
|||
|
OPERATION OF THIS SIMULATOR
|
|||
|
|
|||
|
Read AI Expert Article, November, 1988 for discussion of Grossberg
|
|||
|
Learning, Activation Equations and Instar/Outstar.
|
|||
|
|
|||
|
This simulator models a biological system. The outstar neurode stimulates
|
|||
|
each of a 7x10 grid of neurodes at the same time as an external pattern
|
|||
|
stimulates the grid. The initial weight connections between the outstar
|
|||
|
and the grid neurodes are randomly set between -0.5 and +0.5. The initial
|
|||
|
activity in the grid is also randomly set to activity between 0.0 and 0.5.
|
|||
|
|
|||
|
To run the simulator, you need to have a pattern file which contains the
|
|||
|
pattern you want the grid to learn to reproduce when stimulated by the outstar.
|
|||
|
The program begins by initializing the weights, activations, reading the data
|
|||
|
file and so on. Then the values of the Grossberg learning/activation constants
|
|||
|
are checked, with default values assumed initially. I suggest that you leave
|
|||
|
these values as they are until you are sure you understand the learning laws.
|
|||
|
|
|||
|
The menu gives you four choices.
|
|||
|
1. Train the network for some specified number of time units.
|
|||
|
2. Allow the activation in the grid to decay for some number of time units
|
|||
|
3. Test the network by having the outstar stimulate the grid for some number
|
|||
|
of time units.
|
|||
|
-1. Reset the network (and possibly change the network constants) to either
|
|||
|
quit or start over.
|
|||
|
When asked to enter the number of time units (for 1 or 2 or 3), remember that
|
|||
|
a negative number will only display the grid activation after that number of time
|
|||
|
units has passed, while a positive number displays the grid activation after each
|
|||
|
time unit.
|
|||
|
|
|||
|
The proper operation of the simulator is as follows:
|
|||
|
train the network for some number of time periods. Remember that the
|
|||
|
transmission constant t0 determines how many time units must pass before
|
|||
|
the grid even sees the outstar's stimulus (the external pattern is applied
|
|||
|
immediately). Thus, if the t0 constant is 3, you should do NOTHING in less
|
|||
|
than 4 time units (3 to travel, and 1 to have an effect on the grid).
|
|||
|
allow the grid activation levels to decay to zero. No weight changes occur
|
|||
|
during this time (why?), so you are effectively just "clearing the slate".
|
|||
|
test the network (again for t0+1 time units). If the performance is inadequate,
|
|||
|
train again for additional time periods, then allow decay, then test.
|
|||
|
Have fun!
|
|||
|
-----------------------------------------------------------------------------------------
|
|||
|
|
|||
|
--------------------------------------------------------------------------------
|
|||
|
STRUCTURE OF THIS FILE
|
|||
|
|
|||
|
include files
|
|||
|
constant definitions
|
|||
|
general global storage
|
|||
|
Grossberg activation/learning constant storage (global)
|
|||
|
|
|||
|
QQ Major functions QQ
|
|||
|
initialize();; initialize network operations
|
|||
|
train();; train the grid for a specified time
|
|||
|
decay();; allow grid activation to decay a specified time
|
|||
|
test();; test the grid for a specified time
|
|||
|
QQ Utility functions QQ
|
|||
|
compute_activation();; compute current activation for a grid neurode
|
|||
|
change_weight();; modify weight of a grid neurode
|
|||
|
read_pattern() ;; read pattern from data file
|
|||
|
parseline() ;; parse one line of data from file
|
|||
|
randomize_wts();; randomize weights on grid neurodes
|
|||
|
randomize_activity();; randomize activity of grid neurodes
|
|||
|
set_constants();; set Grossberg equation constants
|
|||
|
show_constants();; show current values of learning/activity constants
|
|||
|
show_wts();; print current weights on grid neurodes
|
|||
|
displaygrid();; print the current grid activation
|
|||
|
print_menu();; print menu of operator choices (train, test, decay, quit)
|
|||
|
QQ Main control function QQ
|
|||
|
main();; main control function
|
|||
|
-----------------------------------------------------------------------------------
|
|||
|
****************************************************************************************/
|
|||
|
|
|||
|
include <math.h>
|
|||
|
include <stdio.h>
|
|||
|
#defineROWSIZE7
|
|||
|
defineCOLSIZE10
|
|||
|
defineSTRINGSIZE80
|
|||
|
defineQUIT-1
|
|||
|
defineSTIMMASK1
|
|||
|
defineACTIVATION 1
|
|||
|
defineLEARNING2
|
|||
|
defineDISPLAYON1
|
|||
|
defineDISPLAYOFF2
|
|||
|
defineSTIM1
|
|||
|
defineNOSTIM0
|
|||
|
/************* General Global Storage ***************************************************/
|
|||
|
oublegridwts[ROWSIZE][COLSIZE]; /* this stores only the weights from the
|
|||
|
single outstar neurode to the grid of rim
|
|||
|
neurodes. */
|
|||
|
ntpattern[ROWSIZE][COLSIZE]; /*this contains the pattern to be impressed
|
|||
|
on the grid of rim neurodes */
|
|||
|
oubleactivity[ROWSIZE][COLSIZE]; /*this contains the current activation levels
|
|||
|
of each grid neurode */
|
|||
|
ntcurtime;/* current time (in integral units) */
|
|||
|
oubleoutstar;/* activation level of outstar */
|
|||
|
har*inpath = "pattern";/* file containing pattern to be learned */
|
|||
|
nsigned intoutstar_save;/*saves history of outstar's output */
|
|||
|
/*****************************************************************************************/
|
|||
|
/************* Grossberg Activation Constants (set by user or default values) ************/
|
|||
|
oubleA = 0.9;/* activation decay constant */
|
|||
|
oubleT = 0.0;/* threshold */
|
|||
|
ntt0 = 1;/* transmission time between neurodes */
|
|||
|
oubleF = 0.01;/* forgetting constant for long term memory */
|
|||
|
oubleG = 0.2;/* learning constant for Hebbian learning term */
|
|||
|
/*************************************************************
|
|||
|
initialize()
|
|||
|
initializes the system by:
|
|||
|
1. reading in the pattern file
|
|||
|
2.randomizing the weights
|
|||
|
3.setting the current time to 0
|
|||
|
4.establishing the activation/learning constants
|
|||
|
*************************************************************/
|
|||
|
nitialize()
|
|||
|
|
|||
|
read_pattern();/* read in training pattern from file */
|
|||
|
randomize_wts();/* randomize weights to grid neurodes from outstar */
|
|||
|
randomize_activity();/* randomize activity of grid neurodes */
|
|||
|
show_wts();/* display resulting grid neurode weights */
|
|||
|
curtime = 0;/* reset current time to 0 */
|
|||
|
displaygrid(curtime);/* display the initial activity of the grid */
|
|||
|
set_constants();/* set the constants to user specified values */
|
|||
|
return;
|
|||
|
|
|||
|
*************************************************************
|
|||
|
train(duration)
|
|||
|
trains the outstar and grid for "duration" timeunits.
|
|||
|
weights are modified during this training period
|
|||
|
After each synchronous update of the grid, the
|
|||
|
activations are displayed.
|
|||
|
|
|||
|
If training time is negative, only the grid status after
|
|||
|
all "duration" time units will be displayed.
|
|||
|
|
|||
|
*************************************************************/
|
|||
|
rain()
|
|||
|
|
|||
|
intduration, displayflag;
|
|||
|
intstoptime;
|
|||
|
inti,j;
|
|||
|
intstim_grid, stim_outstar;
|
|||
|
/* ask how many time units to train */
|
|||
|
printf("\n How many time units do you want the network to train? ");
|
|||
|
printf("\n (Integer value < 32767, negative suppresses all but final display) ");
|
|||
|
scanf("%d", &duration);
|
|||
|
displayflag = DISPLAYON;
|
|||
|
if (duration<0)
|
|||
|
{
|
|||
|
duration = -duration;
|
|||
|
displayflag = DISPLAYOFF;
|
|||
|
}
|
|||
|
stoptime = curtime+duration;
|
|||
|
for ( ; curtime<stoptime; curtime++)
|
|||
|
{
|
|||
|
stim_grid = STIM;
|
|||
|
stim_outstar = STIM;
|
|||
|
printf("\n Current time = %d",curtime);
|
|||
|
save_outstim(stim_outstar);
|
|||
|
for (i=0; i<ROWSIZE; i++)
|
|||
|
{
|
|||
|
for (j=0; j<COLSIZE; j++)
|
|||
|
{
|
|||
|
compute_activation(i,j,stim_grid, stim_outstar);
|
|||
|
change_weight(i,j,stim_outstar);
|
|||
|
}
|
|||
|
}
|
|||
|
if(displayflag == DISPLAYON)
|
|||
|
displaygrid();
|
|||
|
}
|
|||
|
curtime--; /* decrement to avoid using an extra time unit */
|
|||
|
/* when complete, if have not been updating display, do a final display of status */
|
|||
|
if (displayflag == DISPLAYOFF)
|
|||
|
displaygrid();
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
/*************************************************************
|
|||
|
decay(duration)
|
|||
|
allows grid activation to decay for "duration" timeunits.
|
|||
|
no weights are modified during this period, since
|
|||
|
stimulations from the outstar are 0.0
|
|||
|
After each synchronous update of the grid, the
|
|||
|
activations are displayed.
|
|||
|
|
|||
|
If decay time is negative, only the grid status after
|
|||
|
all "duration" time units will be displayed.
|
|||
|
|
|||
|
*************************************************************/
|
|||
|
ecay()
|
|||
|
|
|||
|
intduration;
|
|||
|
intdisplayflag;
|
|||
|
intstoptime;
|
|||
|
inti,j;
|
|||
|
intstim_grid, stim_outstar;
|
|||
|
/* ask how many time units to decay */
|
|||
|
printf("\n How many time units do you want the network to decay? ");
|
|||
|
printf("\n (Integer value < 32767, negative suppresses all but final display) ");
|
|||
|
scanf("%d", &duration);
|
|||
|
|
|||
|
displayflag = DISPLAYON;
|
|||
|
if (duration<0)
|
|||
|
{
|
|||
|
duration = -duration;
|
|||
|
displayflag = DISPLAYOFF;
|
|||
|
}
|
|||
|
stim_grid = NOSTIM;/* during decay, no external stimulation of grid */
|
|||
|
stim_outstar = NOSTIM;/* during decay, the outstar does not stimulate grid */
|
|||
|
stoptime = curtime+duration;
|
|||
|
for ( ; curtime<stoptime; curtime++)
|
|||
|
{
|
|||
|
printf("\n Current time = %d",curtime);
|
|||
|
save_outstim(stim_outstar);
|
|||
|
for (i=0; i<ROWSIZE; i++)
|
|||
|
{
|
|||
|
for (j=0; j<COLSIZE; j++)
|
|||
|
{
|
|||
|
compute_activation(i,j,stim_grid, stim_outstar);
|
|||
|
}
|
|||
|
}
|
|||
|
if(displayflag == DISPLAYON)
|
|||
|
displaygrid();
|
|||
|
}
|
|||
|
curtime--;
|
|||
|
/* when complete, if have not been updating display, do a final display of status */
|
|||
|
if (displayflag == DISPLAYOFF)
|
|||
|
displaygrid();
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
/*************************************************************
|
|||
|
test(duration)
|
|||
|
tests the outstar and grid for "duration" timeunits.
|
|||
|
weights are not modified during this training period
|
|||
|
After each synchronous update of the grid, the
|
|||
|
activations are displayed.
|
|||
|
|
|||
|
If testing time is negative, only the grid status after
|
|||
|
all "duration" time units will be displayed.
|
|||
|
|
|||
|
*************************************************************/
|
|||
|
est()
|
|||
|
|
|||
|
intduration, displayflag;
|
|||
|
intstoptime;
|
|||
|
inti,j;
|
|||
|
intstim_grid, stim_outstar;
|
|||
|
|
|||
|
/* ask how many time units to test */
|
|||
|
printf("\n How many time units do you want the network to test? ");
|
|||
|
printf("\n (Integer value < 32767, negative suppresses all but final display) ");
|
|||
|
scanf("%d", &duration);
|
|||
|
displayflag = DISPLAYON;
|
|||
|
if (duration<0)
|
|||
|
{
|
|||
|
duration = -duration;
|
|||
|
displayflag = DISPLAYOFF;
|
|||
|
}
|
|||
|
|
|||
|
stim_grid = NOSTIM;/* no external stimulation of grid during testing */
|
|||
|
stim_outstar = STIM;/* outstar does stimulate grid during testing */
|
|||
|
stoptime = curtime+duration;
|
|||
|
for ( ; curtime<stoptime; curtime++)
|
|||
|
{
|
|||
|
printf("\n Current time = %d",curtime);
|
|||
|
save_outstim(stim_outstar);
|
|||
|
for (i=0; i<ROWSIZE; i++)
|
|||
|
{
|
|||
|
for (j=0; j<COLSIZE; j++)
|
|||
|
{
|
|||
|
compute_activation(i,j,stim_grid, stim_outstar);
|
|||
|
}
|
|||
|
}
|
|||
|
if(displayflag == DISPLAYON)
|
|||
|
displaygrid();
|
|||
|
}
|
|||
|
curtime-- ; /* decrement to avoid using an extra time unit */
|
|||
|
/* when complete, if have not been updating display, do a final display of status */
|
|||
|
if (displayflag == DISPLAYOFF)
|
|||
|
displaygrid();
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
****************************************************************************
|
|||
|
save_outstim(stimout)
|
|||
|
Parameter stimout either has the value STIM (1) or NOSTIM (0).
|
|||
|
save_outstim keeps a 16-time-unit historical record of
|
|||
|
the outputs of the outstar by modifying the global unsigned
|
|||
|
integer "outstar_save".
|
|||
|
Each time unit the outstar is stimulating the grid is represented
|
|||
|
by a "1" in outstar_save; if there is no stimulus, outstar_save has
|
|||
|
a "0". The 0th bit has the most recent record, the 15th bit has
|
|||
|
the oldest record.
|
|||
|
****************************************************************************/
|
|||
|
ave_outstim(stimout)
|
|||
|
ntstimout;
|
|||
|
|
|||
|
outstar_save = outstar_save << 1;/* left shift one bit. A zero fills
|
|||
|
the lowest order bit, and the oldest
|
|||
|
(highest order bit) is lost */
|
|||
|
outstar_save += stimout;/* add current stimulus value
|
|||
|
(0 if no stim, 1 if stim) */
|
|||
|
return;
|
|||
|
|
|||
|
|
|||
|
**************************************************************
|
|||
|
compute_activation(row,col,grid_on,out_on)
|
|||
|
compute the current activation for the specified
|
|||
|
grid neurode
|
|||
|
Parameter "grid_on" is a flag to tell whether or not
|
|||
|
the external stimulus is impressing the pattern on
|
|||
|
the grid.
|
|||
|
Parameter "out_on" is a flag indicating whether the
|
|||
|
outstar is currently stimulating the grid.
|
|||
|
|
|||
|
Note that differential equation is calculated as an
|
|||
|
incremental difference equation.
|
|||
|
**************************************************************/
|
|||
|
ompute_activation(row,col,grid_on,out_on)
|
|||
|
ntrow,col,grid_on,out_on;
|
|||
|
|
|||
|
doublechange;
|
|||
|
unsigned intstatus;
|
|||
|
intoutstim;/* effective outstar stimulation at current time */
|
|||
|
|
|||
|
change = -A*activity[row][col] ; /* no matter what, activity will tend to try to decay */
|
|||
|
if (grid_on == STIM) /* if there is external stimulus, it will counter decay */
|
|||
|
change += pattern[row][col];
|
|||
|
if (out_on == STIM) /* if there is outstar stimulus... */
|
|||
|
{
|
|||
|
status = outstar_save;/* Be sure not to change the global version */
|
|||
|
status = status >> t0;/* right shift by t0 time units to allow for
|
|||
|
transmission time from outstar */
|
|||
|
outstim = status & STIMMASK;
|
|||
|
change += gridwts[row][col]*outstim - T;
|
|||
|
}
|
|||
|
activity[row][col] += change;/* new activity = old plus incremental change */
|
|||
|
return;
|
|||
|
|
|||
|
/**************************************************************************************
|
|||
|
change_weight(row,col,out_on)
|
|||
|
modify the weight of the specified grid neurode synapse
|
|||
|
Parameter "out_on" is a flag indicating whether or not
|
|||
|
the outstar is currently stimulating the grid.
|
|||
|
Note that differential equation is calculated as an
|
|||
|
incremental difference equation.
|
|||
|
***************************************************************************************/
|
|||
|
hange_weight(row,col,out_on)
|
|||
|
ntrow,col, out_on;
|
|||
|
|
|||
|
doublechange;/* the incremental change to this weight */
|
|||
|
unsigned intstatus;/* local copy of global outstar output history */
|
|||
|
intoutstim;/* effective stimulus from outstar at this time */
|
|||
|
|
|||
|
change = -F * activity[row][col];
|
|||
|
if (out_on == STIM)
|
|||
|
{
|
|||
|
status = outstar_save;/* Be sure not to change the global version */
|
|||
|
status = status >> t0;/* right shift by t0 time units to allow for
|
|||
|
transmission time from outstar */
|
|||
|
outstim = status & STIMMASK;
|
|||
|
change += G * activity[row][col] * (outstim - T);
|
|||
|
}
|
|||
|
gridwts[row][col] += change;
|
|||
|
return;
|
|||
|
|
|||
|
/*******************************************************************
|
|||
|
read_pattern()
|
|||
|
Read in the input data file and store the patterns in
|
|||
|
in_pats and out_pats.
|
|||
|
|
|||
|
The format for the data file is as follows:
|
|||
|
line# data expected
|
|||
|
----- -----------------------------
|
|||
|
1In-X-size,in-y-size
|
|||
|
21st X row of 1st pattern
|
|||
|
3..following rows of 1st pattern
|
|||
|
etc.
|
|||
|
|
|||
|
Each row of data is separated by commas or spaces.
|
|||
|
The data is expected to be ascii text corresponding to
|
|||
|
either a +1 or a 0.
|
|||
|
|
|||
|
Sample input for a pattern file (The comments to the
|
|||
|
right may NOT be in the file unless more sophisticated
|
|||
|
parsing of the input is done.):
|
|||
|
|
|||
|
5,7 input is 5x7 grid
|
|||
|
0,1,1,1,0 beginning of pattern for "O"
|
|||
|
1,0,0,0,1
|
|||
|
1,0,0,0,1
|
|||
|
1,0,0,0,1
|
|||
|
1,0,0,0,1
|
|||
|
1,0,0,0,0
|
|||
|
0,1,1,1,0
|
|||
|
|
|||
|
Clearly, this simple scheme can be expanded or enhanced
|
|||
|
any way you like.
|
|||
|
|
|||
|
Returns -1 if any file error occurred, otherwise 0.
|
|||
|
*******************************************************************/
|
|||
|
ead_pattern()
|
|||
|
|
|||
|
FILE*infile;
|
|||
|
|
|||
|
intxinsize,yinsize;
|
|||
|
intrownum, numcols,x;
|
|||
|
intvalue, vals_read, status;
|
|||
|
charinstring[STRINGSIZE];
|
|||
|
|
|||
|
printf("\n Opening and retrieving data from file.");
|
|||
|
|
|||
|
infile = fopen(inpath, "r");
|
|||
|
if (infile == NULL)
|
|||
|
{
|
|||
|
printf("\n error in opening file!");
|
|||
|
return -1 ;
|
|||
|
}
|
|||
|
vals_read =fscanf(infile,"%d,%d",&xinsize,&yinsize);
|
|||
|
if (vals_read != 2)
|
|||
|
{
|
|||
|
printf("\n Should read 2 items in line one; did read %d",vals_read);
|
|||
|
return -1;
|
|||
|
}
|
|||
|
if ((xinsize != ROWSIZE) || (yinsize != COLSIZE))
|
|||
|
{
|
|||
|
printf("\n\n ERROR: Pattern file is invalid!");
|
|||
|
printf("\n Pattern is a %d by %d grid instead of %d by %d",
|
|||
|
xinsize, yinsize, ROWSIZE, COLSIZE);
|
|||
|
return -1;
|
|||
|
}
|
|||
|
numcols = ROWSIZE;
|
|||
|
for (rownum = 0; rownum<COLSIZE; rownum++)
|
|||
|
{
|
|||
|
status = fscanf(infile,"%s",&instring);
|
|||
|
if (status == -1)
|
|||
|
{
|
|||
|
printf("\n ERROR: Insufficient data in file!");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
value = parseline(instring,numcols,rownum);
|
|||
|
if (value == -1)
|
|||
|
return -1;
|
|||
|
}
|
|||
|
printf("\n Closing the input file now. ");
|
|||
|
fclose(infile);
|
|||
|
return 0;
|
|||
|
|
|||
|
/*******************************************************************
|
|||
|
parseline(string,numele,row)
|
|||
|
parse line of text to derive elements from pattern string.
|
|||
|
Parameters
|
|||
|
"string" is a pointer to string to be parsed.
|
|||
|
"numele" specifies number of elements contained in "string"
|
|||
|
"row" is pointer to correct row of "pattern" for elements.
|
|||
|
Elements in the string must be either "0", "1", <space>, ","
|
|||
|
0,1 puts appropriate values in pattern array
|
|||
|
"<space>", or "," is ignored
|
|||
|
|
|||
|
Notice that this is an extremely primitive parsing routine.
|
|||
|
This can (and should) be improved or modified as desired.
|
|||
|
|
|||
|
Return:
|
|||
|
-1 if error, 0 else.
|
|||
|
*******************************************************************/
|
|||
|
arseline(string,numele,ygrid)
|
|||
|
harstring[];
|
|||
|
ntnumele,ygrid;
|
|||
|
|
|||
|
intvalue;
|
|||
|
intcharnum, ele;
|
|||
|
charch;
|
|||
|
|
|||
|
charnum = 0;
|
|||
|
value = 0;
|
|||
|
ele = 0;
|
|||
|
while ((ele < numele) && (value == 0))
|
|||
|
{
|
|||
|
if (charnum == STRINGSIZE) /* made it to the end without filling all element entries */
|
|||
|
value = -1;
|
|||
|
else
|
|||
|
{/*This routine does not care if digits are separated or not.
|
|||
|
each instance of a 0 or 1 will be taken as an element entry in
|
|||
|
the pattern. */
|
|||
|
|
|||
|
ch = string[charnum];
|
|||
|
switch (ch)
|
|||
|
{
|
|||
|
case '0' : /* each "0" will be treated as a grid entry */
|
|||
|
pattern[ele][ygrid] = 0;
|
|||
|
ele++;
|
|||
|
break;
|
|||
|
case '1' : /* each "1" will be treated as a grid entry */
|
|||
|
pattern[ele][ygrid] = 1;
|
|||
|
ele++;
|
|||
|
break;
|
|||
|
default : /* all other characters are ignored. */
|
|||
|
break;
|
|||
|
}
|
|||
|
charnum++;
|
|||
|
}
|
|||
|
}
|
|||
|
return value;
|
|||
|
|
|||
|
/*******************************************************************
|
|||
|
randomize_wts()
|
|||
|
Intialize the weights in the grid neurodes to
|
|||
|
random values between -0.25..+0.25
|
|||
|
*******************************************************************/
|
|||
|
andomize_wts()
|
|||
|
|
|||
|
inti,j;
|
|||
|
doublevalue;
|
|||
|
|
|||
|
printf("\n Please enter a random number seed (1..32767): ");
|
|||
|
scanf("%d", &i);
|
|||
|
srand(i);
|
|||
|
for(i=0; i<ROWSIZE; i++)
|
|||
|
{
|
|||
|
for (j = 0; j<COLSIZE; j++)
|
|||
|
{
|
|||
|
value = (rand() / 32767.0 ) - 0.5;
|
|||
|
gridwts[i][j] = value/2;
|
|||
|
}
|
|||
|
}
|
|||
|
return;
|
|||
|
|
|||
|
*******************************************************************
|
|||
|
randomize_activity()
|
|||
|
Intialize the activity in the grid neurodes to
|
|||
|
random values between 0.0..0.5
|
|||
|
*******************************************************************/
|
|||
|
andomize_activity()
|
|||
|
|
|||
|
inti,j;
|
|||
|
doublevalue;
|
|||
|
|
|||
|
for(i=0; i<ROWSIZE; i++)
|
|||
|
{
|
|||
|
for (j = 0; j<COLSIZE; j++)
|
|||
|
{
|
|||
|
value = ( rand() / 32767.0 );
|
|||
|
activity[i][j] = value/2.0;
|
|||
|
}
|
|||
|
}
|
|||
|
return;
|
|||
|
|
|||
|
/*******************************************************************
|
|||
|
set_constants()
|
|||
|
displays current (default) values for learning/activation
|
|||
|
constants and requests user changes.
|
|||
|
*******************************************************************/
|
|||
|
et_constants()
|
|||
|
|
|||
|
intans;
|
|||
|
floatvalue;
|
|||
|
|
|||
|
show_constants(ACTIVATION);
|
|||
|
scanf("%d",&ans);
|
|||
|
while (ans != 0)
|
|||
|
{
|
|||
|
printf("\n New value for A? ");
|
|||
|
scanf("%f",&value);
|
|||
|
A = (double) value;
|
|||
|
printf("\n New value for T? ");
|
|||
|
scanf("%f",&value);
|
|||
|
T = (double) value;
|
|||
|
printf("\n New value for t0? ");
|
|||
|
scanf("%d",&t0);
|
|||
|
show_constants(ACTIVATION);
|
|||
|
scanf("%d",&ans);
|
|||
|
}
|
|||
|
show_constants(LEARNING);
|
|||
|
scanf("%d",&ans);
|
|||
|
while (ans != 0)
|
|||
|
{
|
|||
|
printf("\n New value for F? ");
|
|||
|
scanf("%f",&value);
|
|||
|
F = (double) value;
|
|||
|
printf("\n New value for G? ");
|
|||
|
scanf("%f",&value);
|
|||
|
G = (double) value;
|
|||
|
show_constants(LEARNING);
|
|||
|
scanf("%d",&ans);
|
|||
|
}
|
|||
|
return;
|
|||
|
|
|||
|
*********************************************************************
|
|||
|
show_constants (which)
|
|||
|
displays either activation or learning constants for
|
|||
|
user approval or modification
|
|||
|
Paramter "which" determines which set will be displayed
|
|||
|
*********************************************************************/
|
|||
|
how_constants(which)
|
|||
|
ntwhich;
|
|||
|
|
|||
|
if (which == ACTIVATION)
|
|||
|
{
|
|||
|
printf("\n The current values for the Grossberg activation constants are:");
|
|||
|
printf("\n Activation Decay Time constant (A): %6.3f",A);
|
|||
|
printf("\n Activity Threshold (T): %6.3f",T);
|
|||
|
printf("\n Transmission time to grid (t0): %d",t0);
|
|||
|
}
|
|||
|
if (which == LEARNING)
|
|||
|
{
|
|||
|
printf("\n The current values for the Grossberg learning constants are:");
|
|||
|
printf("\n Learning Decay 'Forgetting' constant (F): %6.3f",F);
|
|||
|
printf("\n Learning Gain constant (G): %6.3f",G);
|
|||
|
}
|
|||
|
printf("\n\n Do you wish to change any of these constants? (0 = no) ");
|
|||
|
return;
|
|||
|
|
|||
|
/*******************************************************************
|
|||
|
show_wts()
|
|||
|
print out the weights for the grid neurodes on the screen
|
|||
|
*******************************************************************/
|
|||
|
how_wts()
|
|||
|
|
|||
|
introw,col;
|
|||
|
|
|||
|
printf("\n The current weights for the grid neurodes are:\n");
|
|||
|
for (col = 0; col < COLSIZE; col++)
|
|||
|
{
|
|||
|
printf ("\n");
|
|||
|
for (row = 0; row < ROWSIZE; row++)
|
|||
|
{
|
|||
|
printf(" %6.3f ",gridwts[row][col]);
|
|||
|
}
|
|||
|
}
|
|||
|
printf("\n\n");
|
|||
|
return;
|
|||
|
|
|||
|
/**************************************************************
|
|||
|
displaygrid()
|
|||
|
prints (text-only for portability) the current activity
|
|||
|
of the grid neurodes. Also displays the current time,
|
|||
|
and the desired pattern.
|
|||
|
**************************************************************/
|
|||
|
isplaygrid()
|
|||
|
|
|||
|
inti,j;
|
|||
|
doublevalue;
|
|||
|
|
|||
|
printf("\n Current pattern and activity at time %d:",curtime);
|
|||
|
printf("\n Scale (0.0 to 1.0): ' . _ o O %' \n");
|
|||
|
printf("\n Grid activity is:");
|
|||
|
printf(" ");
|
|||
|
printf(" Desired pattern is:");
|
|||
|
for (j=0; j<COLSIZE; j++)
|
|||
|
{
|
|||
|
printf("\n ");
|
|||
|
for (i=0; i<ROWSIZE; i++)
|
|||
|
{
|
|||
|
value = activity[i][j];
|
|||
|
if (value < 0.17)
|
|||
|
printf(" ");
|
|||
|
if ((value >= 0.17) && (value < 0.35))
|
|||
|
printf(" . ");
|
|||
|
if ((value >= 0.35) && (value < 0.50))
|
|||
|
printf(" _ ");
|
|||
|
if ((value >= 0.50) && (value < 0.67))
|
|||
|
printf(" o ");
|
|||
|
if ((value >= 0.67) && (value < 0.83))
|
|||
|
printf(" O ");
|
|||
|
if (value >= 0.83)
|
|||
|
printf(" % ");
|
|||
|
}
|
|||
|
printf(" ");
|
|||
|
for (i=0; i<ROWSIZE; i++)
|
|||
|
{
|
|||
|
switch(pattern[i][j])
|
|||
|
{
|
|||
|
case 0:printf(" ");
|
|||
|
break;
|
|||
|
case 1:printf(" % ");
|
|||
|
break;
|
|||
|
default:break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
printf("\n");
|
|||
|
return;
|
|||
|
|
|||
|
/***************************************************************
|
|||
|
print_menu()
|
|||
|
prints out menu of operations for user choice
|
|||
|
***************************************************************/
|
|||
|
rint_menu()
|
|||
|
|
|||
|
printf("\n\n\n Please select an operation:");
|
|||
|
printf("\n\n 1. Train the network for a period of time.");
|
|||
|
printf("\n (Both external and outstar stimulate grid)");
|
|||
|
printf("\n\n 2. Allow the network to decay for a period of time.");
|
|||
|
printf("\n (Neither external or outstar stimulates grid)");
|
|||
|
printf("\n\n 3. Test the network for a period of time.");
|
|||
|
printf("\n (Only outstar stimulates grid)");
|
|||
|
printf("\n\n -1. Train the network for a period of time.");
|
|||
|
return;
|
|||
|
|
|||
|
/***************************************************************
|
|||
|
main()
|
|||
|
main program
|
|||
|
***************************************************************/
|
|||
|
ain()
|
|||
|
|
|||
|
intyesno;
|
|||
|
intdone, donetraining;
|
|||
|
inttraintime;
|
|||
|
intchoice;
|
|||
|
|
|||
|
done = 0; donetraining = 0;
|
|||
|
while (done == 0)
|
|||
|
{
|
|||
|
initialize();
|
|||
|
choice = 0;
|
|||
|
/* display the desired grid pattern on the screen */
|
|||
|
print_menu();
|
|||
|
printf("\n\n Please enter your choice: ");
|
|||
|
scanf("%d",&choice);
|
|||
|
printf("\n Your selection was %d",choice);
|
|||
|
while (choice != QUIT)
|
|||
|
{
|
|||
|
switch (choice)
|
|||
|
{
|
|||
|
case 1:
|
|||
|
train();
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
decay();
|
|||
|
break;
|
|||
|
case 3:
|
|||
|
test();
|
|||
|
break;
|
|||
|
default:
|
|||
|
{
|
|||
|
choice = QUIT;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
print_menu();
|
|||
|
printf("\n\n Please enter your choice: ");
|
|||
|
scanf("%d",&choice);
|
|||
|
printf("\n Your selection was %d",choice);
|
|||
|
}
|
|||
|
printf("\n\n Training session terminated at user request...");
|
|||
|
|
|||
|
/* want to start over (allows modification of constants)? */
|
|||
|
printf("\n\n Would you like to reset the network and begin again (no = 0)? ");
|
|||
|
scanf("%d",&yesno);
|
|||
|
if (yesno < 1)
|
|||
|
done = 2;
|
|||
|
}
|
|||
|
printf("\n\n Program complete.");
|
|||
|
/* stop */
|
|||
|
return;
|
|||
|
ain (no = 0)? ");
|
|||
|
scanf("%d",&yesno);
|
|||
|
if (yesno < 1)
|
|||
|
done = 2;
|
|||
|
}
|
|||
|
printf("\n\n Program complete.");
|
|||
|
/* stop
|