home *** CD-ROM | disk | FTP | other *** search
- _USING NEURAL NETWORKS FOR PATTERN RECOGNITION_
-
- by Todd King
-
-
- [LISTING ONE]
-
- #include <stdio.h>
- #define EXTERN extern
- #include "neural.h"
-
- /*-- MAKE_MIND ---------------------------------------
- Constructs a mental unit with the given number
- of input, hidden and output neurons.
- ------------------------------------------------------*/
- make_mind(in, hid, out)
- int in;
- int hid;
- int out;
- {
- if ( in > MAX_NEURONS ||
- hid > MAX_NEURONS ||
- out > MAX_NEURONS ) return(0);
- if (in < 1 || hid < 1 || out < 1 ) return(0);
- Mind.n_input = in;
- Mind.n_hidden = hid;
- Mind.n_output = out;
- set_cluster_fun(NULL, NULL);
- set_all_weights(1.0);
- set_act_fun(pass);
- set_user_in_fun(prompted);
- set_result_fun(print_binary_state);
- strcpy(Prompt.string, "Input a value for neuron %d: ");
- Prompt.count = 1;
- return(1);
- }
-
- /*-- ACTIVATE_MIND -----------------------------------------
- Sets a mind in motion. Sequentially activating each neuron
- -----------------------------------------------------------*/
- activate_mind()
- {
- int i;
- float net_input;
-
- /* Activate input layer */
- Prompt.count = 1;
- for (i = 0; i < Mind.n_input; i++)
- {
- Mind.i_layer[i].value = Mind.user_in_fun();
- }
-
- /* Activate hidden layer */
- for (i= 0; i < Mind.n_hidden; i++)
- {
- net_input = weighted_sum(i, HIDDEN);
- Mind.h_layer[i].value = Mind.act_fun(net_input);
- }
-
- /* Activate feedback/certainty function (if one is set) */
- if ( Mind.certainty != NULL) Mind.cluster_fun(Mind.certainty);
-
- /* Activate output layer */
- for (i=0; i < Mind.n_output; i++)
- {
- net_input = weighted_sum(i, OUTPUT);
- Mind.o_layer[i].value = Mind.act_fun(net_input);
- Mind.result_fun(Mind.o_layer[i].value);
- }
- }
-
- /*-- SET_ALL_WEIGHTS --------------------------------------
- Sets the weight of all connections between all neurons
- in all layers to the given value
- ----------------------------------------------------------*/
- set_all_weights(value)
- float value;
- {
- int i, j;
-
- /* Weights between input and hidden */
-
- for(i = 0; i < Mind.n_input; i++)
- {
- for(j = 0; j < Mind.n_hidden; j++)
- {
- Input_to_hidden[i][j].weight = value;
- }
- }
-
- /* Weights between hidden and output */
-
- for(i=0; i< Mind.n_hidden; i++)
- {
- for(j = 0; j < Mind.n_output; j++)
- {
- Hidden_to_output[i][j].weight = value;
- }
- }
- }
-
- /*-- SET_WEIGHT -------------------------------------
- Sets the weight between two neurons to a given value.
- ------------------------------------------------------*/
- set_weight(from, to, layer, value)
- int from;
- int to;
- int layer;
- float value;
- {
- switch (layer)
- {
- case HIDDEN:
- if (from > Mind.n_input) return;
- if (to > Mind.n_hidden) return;
- Input_to_hidden[from][to].weight = value;
- break;
- case OUTPUT:
- if (from > Mind.n_hidden) return;
- if (to > Mind.n_output) return;
- Hidden_to_output[from][to].weight = value;
- break;
- default:
- break;
- }
- return;
- }
-
- /*-- WEIGHT_SUM --------------------------------------------
- Calculates the weighted sum for a given neuron in a given
- layer
- ----------------------------------------------------------*/
- float weighted_sum(this_neuron, this_layer)
- int this_neuron;
- int this_layer;
- {
- int i;
- float sum = 0.0;
-
- switch (this_layer)
- {
- case HIDDEN:
- for (i = 0; i < Mind.n_input; i++)
- {
- sum += (Mind.i_layer[i].value * Input_to_hidden[i][this_neuron].weight);
- }
- break;
- case OUTPUT:
- for (i = 0; i < Mind.n_hidden; i++)
- {
- sum += (Mind.h_layer[i].value * Hidden_to_output[i][this_neuron].weight);
- }
- break;
- default:
- break;
- }
-
- return (sum);
- }
-
- /*-- PASS ----------------------------------------------
- Returns the input value. A dummy activation function.
- --------------------------------------------------------*/
- float pass(value)
- float value;
- {
- return (value);
- }
-
- /*-- PROMPTED ---------------------------------------
- Prompts the user for an input value and returns the
- value. A user input function.
- -----------------------------------------------------*/
- float prompted()
- {
- float value;
-
- printf(Prompt.string, Prompt.count++);
- scanf("%f", &value);
- return(value);
- }
-
- /*-- PRINT_BINARY_STATE -------------------------------
- Prints the output state of a neuron. If greater than
- 0.0 the value printed is "on", otherwise "off".
- ------------------------------------------------------*/
- float print_binary_state(value)
- float value;
- {
- printf("The output gate is: ");
-
- if (value > 0.0) printf("ON.");
- else printf("OFF.");
-
- printf("\n");
- }
-
-
-
- [LISTING TWO]
-
- /* Linear network */
-
- #define EXTERN
- #include "neural.h"
-
- #define MEMBERS 5
-
- float print_vote_state();
- #define plural(x) (x == 1 ? "" : "s")
-
- main()
- {
- int i;
-
- make_mind(5,1,1);
- set_result_fun(print_vote_state);
- strcpy(Prompt.string, "Ballot for member %d: ");
- for(i=0; i<MEMBERS; i++)
- {
- set_weight(i, 0, HIDDEN, (float)(i+1) );
- }
- printf("Ballot values: 1 = for, 0 = obstain, -1 = against\n\n");
- activate_mind();
- }
-
- float print_vote_state(value)
- float value;
- {
- int votes;
- printf("The vote is: ");
-
- votes = (int)value;
- if (votes > 0)
- printf("FOR, by %d vote%s", votes, plural(votes) );
- else if (votes < 0)
- printf("AGAINST, by %d vote%s", -votes, plural(-votes) );
- else
- printf("A TIE");
-
- printf(".\n");
- }
-
-
- [LISTING THREE]
-
- /* Simple linear threshold network.
- Demonstates logic gates */
-
- #define EXTERN
- #include "neural.h"
-
- float linear_threshold();
-
- main()
- {
- int i;
-
- /* OR gates work using the default weights (1.0) */
-
- strcpy(Prompt.string, "Logic state of gate %d: ");
- printf("Logic values: 1, on; 0, off\n\n");
-
- printf("OR logic gate.\n");
- printf("--------------\n\n");
- make_mind(2, 1, 1);
- activate_mind();
-
- /* AND gates must have weights < 1.0 ( and > 0.0) */
-
- printf("\n");
- printf("AND logic gate.\n");
- printf("--------------\n\n");
-
- for(i = 0; i < 2; i++)
- {
- set_weight(i, 0, HIDDEN, 0.5);
- }
- activate_mind();
-
- /* XOR gates are the most complicated */
-
- printf("\n");
- printf("XOR logic gate.\n");
- printf("--------------\n\n");
- make_mind(2, 2, 1);
- set_weight(0, 0, HIDDEN, 1.0);
- set_weight(1, 0, HIDDEN, -1.0);
- set_weight(0, 1, HIDDEN, -1.0);
- set_weight(1, 1, HIDDEN, 1.0);
- set_weight(0, 0, OUTPUT, 1.0);
- set_weight(1, 0, OUTPUT, 1.0);
- set_act_fun(linear_threshold);
- activate_mind();
- }
-
- /*-- LINEAR_THRESHOLD -------------------------------------
- If the input value is greater than zero then it returns
- 1.0, otherwise it returns 0.0. A linear threshold
- activation function.
- ----------------------------------------------------------*/
- float linear_threshold(value)
- float value;
- {
- if (value > 0.0) return(1.0);
- else return(0.0);
- }
-
-
-
-
- [LISTING FOUR]
-
- /*
- Optical Character Recognition (OCR) neural network
- This is a hybrid between a linear threshold, fully
- interconnected network and a linear network. The
- transition being at the hidden layer. A Feedback neuron
- gaurantees a pattern match in the threshold layer.
- */
- #include <stdio.h>
- #define EXTERN
- #include "neural.h"
-
- float percep();
- float print_ocr();
- float certainty_cluster();
-
- float Certainty;
- FILE *Ocr_fptr;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i;
-
- if(argc < 2)
- {
- printf("proper usage: ocr [<train_file> ...] [-test <test_file> ...]\n");
- exit(-1);
- }
-
- make_mind(35, 3, 1);
- set_user_in_fun(percep);
- set_result_fun(print_ocr);
- set_cluster_fun(certainty_cluster, &Certainty);
- set_all_weights(0.0);
-
- /* Teach the network about the patterns */
- i = 1;
- while(strcmp(argv[i], "-test") != 0)
- {
- printf("Learning: %s\n", argv[i]);
- if( i > Mind.n_hidden)
- {
- printf("Too many pattern groups for the given topology, aborting.\n");
- exit(-1);
- }
- ocr_learn(argv[i], i - 1);
- i++;
- if(i >= argc)
- {
- printf("Nothing to test - exiting\n");
- exit(-1);
- }
- }
-
- /* Classify each pattern based on what the network knows */
- i++; /* Skip over "-test" deliniator */
- while(i < argc)
- {
- printf("Testing %s\n", argv[i]);
- if ((Ocr_fptr = fopen(argv[i], "r")) == NULL)
- {
- perror(argv[i]);
- printf("Unable to open file, skipping pattern.\n");
- i++;
- continue;
- }
- activate_mind();
- fclose(Ocr_fptr);
- i++;
- }
- }
-
- /*-- PERCEP ------------------------------------------------
- Returns the value of the next pixel every time its called.
- The pixel state is determined from the contents of the
- pre-opened file pointed to by 'Ocr_fptr'.
- ----------------------------------------------------------*/
- float percep()
- {
- extern FILE *Ocr_fptr;
- int pixel_value;
-
- fscanf(Ocr_fptr, "%1d", &pixel_value);
- return( (float)pixel_value);
- }
-
- /*-- PRINT_OCR -------------------------------------
- Prints the character which the network determines
- it to be. Also prints the certainty of the match.
- ------------------------------------------------------*/
- float print_ocr(value)
- float value;
- {
- extern float Certainty;
-
- printf("The character is '%c' (%d).\n", (int)value, (int)value);
- printf("with a certainty of %3.2f%.\n", Certainty);
- }
-
- /*-- OCR_LEARN -----------------------------
- Teach the network how to classify
- a pattern.
- --------------------------------------------*/
- ocr_learn(filename, group_id)
- char filename[];
- int group_id;
- {
- int i;
- FILE *fptr;
- int pixel_cnt = 0;
- int pixel_value;
- float dist_weight;
- float output_value;
-
- if ((fptr = fopen(filename, "r")) == NULL)
- {
- perror(filename);
- printf("Skipping pattern.\n");
- return(0);
- }
-
- /* Determine the number of "on" pixels, hence fractional weight */
- for(i=0; i < Mind.n_input; i++)
- {
- fscanf(fptr, "%1d", &pixel_value);
- if(pixel_value == 1) pixel_cnt++;
- }
- dist_weight = 1.0/pixel_cnt;
- rewind(fptr);
-
- /* Set fractional weight for each "on" connection */
- for(i=0; i < Mind.n_input; i++)
- {
- fscanf(fptr, "%1d", &pixel_value);
- if(pixel_value == 1) set_weight(i, group_id, HIDDEN, dist_weight);
- }
-
- /* Now set weight for output value for this character */
- fscanf(fptr, "%f", &output_value);
- set_weight(group_id, 0, OUTPUT, output_value);
-
- fclose(fptr);
- return(1);
- }
-
- /*-- CERTAINTY_CLUSTER ------------------------------------
- Performs a cluster function. It inhibits (sets to 0) all
- neurons in the cluster except the one which is closest to
- the value 1.0. This neuron is set to 1.0. The passed
- variable is assigned the certainty to which the closest
- neuron felt it matched the pattern
- ----------------------------------------------------------*/
- float certainty_cluster(certainty)
- float *certainty;
- {
- int i;
- float highest = 0.0;
- int closest = -1;
-
- for(i=0; i<Mind.n_hidden; i++)
- {
- if(Mind.h_layer[i].value > highest)
- {
- closest = i;
- highest = Mind.h_layer[i].value;
- }
- }
- if(closest == -1) /* All are equally likely - choose the first */
- {
- closest = 0;
- }
-
- *certainty = Mind.h_layer[closest].value * 100.0;
-
- /*
- Cause just enough feedback to the neuron which is closest
- to being "on" so that it is "on". That is set it "on"
- All others are given negative feedback to force them to
- zero. (set them to zero).
- */
- for( i = 0; i < Mind.n_hidden; i++)
- {
- if (i == closest) Mind.h_layer[i].value = 1.0;
- else Mind.h_layer[i].value = 0.0;
- }
- }
-
-
-
-
- [LISTING FIVE]
-
- #ifndef _NEURAL_
- #define _NERUAL_
-
- #define MAX_NEURONS 35
-
- #define HIDDEN 1
- #define OUTPUT 2
-
- /* Type definition for neurons and neural networks */
-
- typedef struct {
- float value;
- } NEURON;
-
- typedef struct {
- int n_input;
- int n_hidden;
- int n_output;
- float *certainty;
- float (*cluster_fun)();
- float (*act_fun)();
- float (*user_in_fun)();
- float (*result_fun)();
- NEURON i_layer[MAX_NEURONS];
- NEURON h_layer[MAX_NEURONS];
- NEURON o_layer[MAX_NEURONS];
- } MIND;
-
- typedef struct {
- float weight;
- } WEIGHTS;
-
- typedef struct
- {
- char string[80];
- int count;
- } PROMPT;
-
- /* Global Variables */
-
- EXTERN MIND Mind;
- EXTERN WEIGHTS Input_to_hidden[MAX_NEURONS][MAX_NEURONS];
- EXTERN WEIGHTS Hidden_to_output[MAX_NEURONS][MAX_NEURONS];
- EXTERN PROMPT Prompt;
-
- /* Functions */
-
- float weighted_sum();
- float pass();
- float prompted();
- float print_binary_state();
- float certainty_fun();
- int activate_mind();
-
- /* Pseudo-functions */
-
- #define set_act_fun(f) Mind.act_fun = f
- #define set_user_in_fun(f) Mind.user_in_fun = f
- #define set_back_prop_fun(f) Mind.back_prop_fun = f
- #define set_result_fun(f) Mind.result_fun = f
- #define set_cluster_fun(f, x) Mind.cluster_fun = f; Mind.certainty = x
-
- #endif
-
-
-
- [LISTING SIX]
-
- Board:
- board.c (neural.h)
- neurlib.c (neural.h)
-
- Logic:
- logic.c (neural.h)
- neurlib.c (neural.h)
-
- OCR:
- ocr.c (neural.h)
- neurlib.c (neural.h)
-
-