Neural Networks Source Codes - The Hopfield Model -------------------------------------------------------------------------------- The Hopfield Model -------------------------------------------------------------------------------- This program is copyright (c) 1996 by the author. It is made available as is, and no warranty - about the program, its performance, or its conformity to any specification - is given or implied. It may be used, modified, and distributed freely for private and commercial purposes, as long as the original author is credited as part of the final work. Hopfield Model Simulator /****************************************************************************** ============== Network: Hopfield Model ============== Application: Autoassociative Memory Associative Recall of Images Author: Karsten Kutza Date: 30.1.96 Reference: J.J. Hopfield Neural Networks and Physical Systems with Emergent Collective Computational Abilities Proceedings of the National Academy of Sciences, 79, pp. 2554-2558, 1982 ******************************************************************************/ /****************************************************************************** D E C L A R A T I O N S ******************************************************************************/ #include #include typedef int BOOL; typedef char CHAR; typedef int INT; #define FALSE 0 #define TRUE 1 #define NOT ! #define AND && #define OR || #define LO -1 #define HI +1 #define BINARY(x) ((x)==LO ? FALSE : TRUE) #define BIPOLAR(x) ((x)==FALSE ? LO : HI) typedef struct { /* A NET: */ INT Units; /* - number of units in this net */ INT* Output; /* - output of ith unit */ INT* Threshold; /* - threshold of ith unit */ INT** Weight; /* - connection weights to ith unit */ } NET; /****************************************************************************** R A N D O M S D R A W N F R O M D I S T R I B U T I O N S ******************************************************************************/ void InitializeRandoms() { srand(4711); } INT RandomEqualINT(INT Low, INT High) { return rand() % (High-Low+1) + Low; } /****************************************************************************** A P P L I C A T I O N - S P E C I F I C C O D E ******************************************************************************/ #define NUM_DATA 5 #define X 10 #define Y 10 #define N (X * Y) CHAR Pattern[NUM_DATA][Y][X] = { { "O O O O O ", " O O O O O", "O O O O O ", " O O O O O", "O O O O O ", " O O O O O", "O O O O O ", " O O O O O", "O O O O O ", " O O O O O" }, { "OO OO OO", "OO OO OO", " OO OO ", " OO OO ", "OO OO OO", "OO OO OO", " OO OO ", " OO OO ", "OO OO OO", "OO OO OO" }, { "OOOOO ", "OOOOO ", "OOOOO ", "OOOOO ", "OOOOO ", " OOOOO", " OOOOO", " OOOOO", " OOOOO", " OOOOO" }, { "O O O O", " O O O ", " O O O ", "O O O O", " O O O ", " O O O ", "O O O O", " O O O ", " O O O ", "O O O O" }, { "OOOOOOOOOO", "O O", "O OOOOOO O", "O O O O", "O O OO O O", "O O OO O O", "O O O O", "O OOOOOO O", "O O", "OOOOOOOOOO" } }; CHAR Pattern_[NUM_DATA][Y][X] = { { " ", " ", " ", " ", " ", " O O O O O", "O O O O O ", " O O O O O", "O O O O O ", " O O O O O" }, { "OOO O O", " O OOO OO", " O O OO O", " OOO O ", "OO O OOO", " O OOO O", "O OO O O", " O OOO ", "OO OOO O ", " O O OOO" }, { "OOOOO ", "O O OOO ", "O O OOO ", "O O OOO ", "OOOOO ", " OOOOO", " OOO O O", " OOO O O", " OOO O O", " OOOOO" }, { "O OOOO O", "OO OOOO ", "OOO OOOO ", "OOOO OOOO", " OOOO OOO", " OOOO OO", "O OOOO O", "OO OOOO ", "OOO OOOO ", "OOOO OOOO" }, { "OOOOOOOOOO", "O O", "O O", "O O", "O OO O", "O OO O", "O O", "O O", "O O", "OOOOOOOOOO" } }; INT Input [NUM_DATA][N]; INT Input_[NUM_DATA][N]; FILE* f; void InitializeApplication(NET* Net) { INT n,i,j; for (n=0; nOutput[i*X+j]) ? 'O' : ' '); } fprintf(f, "\n"); } fprintf(f, "\n"); } void FinalizeApplication(NET* Net) { fclose(f); } /****************************************************************************** I N I T I A L I Z A T I O N ******************************************************************************/ void GenerateNetwork(NET* Net) { INT i; Net->Units = N; Net->Output = (INT*) calloc(N, sizeof(INT)); Net->Threshold = (INT*) calloc(N, sizeof(INT)); Net->Weight = (INT**) calloc(N, sizeof(INT*)); for (i=0; iThreshold[i] = 0; Net->Weight[i] = (INT*) calloc(N, sizeof(INT)); } } void CalculateWeights(NET* Net) { INT i,j,n; INT Weight; for (i=0; iUnits; i++) { for (j=0; jUnits; j++) { Weight = 0; if (i!=j) { for (n=0; nWeight[i][j] = Weight; } } } void SetInput(NET* Net, INT* Input) { INT i; for (i=0; iUnits; i++) { Net->Output[i] = Input[i]; } WriteNet(Net); } void GetOutput(NET* Net, INT* Output) { INT i; for (i=0; iUnits; i++) { Output[i] = Net->Output[i]; } WriteNet(Net); } /****************************************************************************** P R O P A G A T I N G S I G N A L S ******************************************************************************/ BOOL PropagateUnit(NET* Net, INT i) { INT j; INT Sum, Out; BOOL Changed; Changed = FALSE; Sum = 0; for (j=0; jUnits; j++) { Sum += Net->Weight[i][j] * Net->Output[j]; } if (Sum != Net->Threshold[i]) { if (Sum < Net->Threshold[i]) Out = LO; if (Sum > Net->Threshold[i]) Out = HI; if (Out != Net->Output[i]) { Changed = TRUE; Net->Output[i] = Out; } } return Changed; } void PropagateNet(NET* Net) { INT Iteration, IterationOfLastChange; Iteration = 0; IterationOfLastChange = 0; do { Iteration++; if (PropagateUnit(Net, RandomEqualINT(0, Net->Units-1))) IterationOfLastChange = Iteration; } while (Iteration-IterationOfLastChange < 10*Net->Units); } /****************************************************************************** S I M U L A T I N G T H E N E T ******************************************************************************/ void SimulateNet(NET* Net, INT* Input) { INT Output[N]; SetInput(Net, Input); PropagateNet(Net); GetOutput(Net, Output); } /****************************************************************************** M A I N ******************************************************************************/ void main() { NET Net; INT n; InitializeRandoms(); GenerateNetwork(&Net); InitializeApplication(&Net); CalculateWeights(&Net); for (n=0; n O O O O O OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO -> OO OO OO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO OOOOO -> OOOOO O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O -> O O O O OOOOOOOOOO OOOOOOOOOO O O O O O OOOOOO O O OOOOOO O O O O O O O O O O O OO O O O O OO O O O O OO O O O O OO O O O O O O O O O O O OOOOOO O O OOOOOO O O O O O OOOOOOOOOO -> OOOOOOOOOO O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O -> O O O O O OOO O O OO OO OO O OOO OO OO OO OO O O OO O OO OO OOO O OO OO OO O OOO OO OO OO O OOO O OO OO OO O OO O O OO OO O OOO OO OO OO OOO O OO OO OO O O OOO -> OO OO OO OOOOO OOOOO O O OOO OOOOO O O OOO OOOOO O O OOO OOOOO OOOOO OOOOO OOOOO OOOOO OOO O O OOOOO OOO O O OOOOO OOO O O OOOOO OOOOO -> OOOOO O OOOO O O O O O OO OOOO O O O OOO OOOO O O O OOOO OOOO O O O O OOOO OOO O O O OOOO OO O O O O OOOO O O O O O OO OOOO O O O OOO OOOO O O O OOOO OOOO -> O O O O OOOOOOOOOO OOOOOOOOOO O O O O O O O OOOOOO O O O O O O O O OO O O O OO O O O OO O O O OO O O O O O O O O O O O OOOOOO O O O O O OOOOOOOOOO -> OOOOOOOOOO