#include "project.h" #include #include #include /** * Create a new neural network. * * Creates a neural network with the given number of input, hidden, and output * nodes and returns a struct representing the network. */ net* create_network(int num_inputs, int num_hidden, int num_outputs) { neuron *inputs, *outputs, *hidden; int i, j; outputs = (neuron*) malloc(num_outputs*sizeof(neuron)); hidden = (neuron*) malloc(num_hidden*sizeof(neuron)); inputs = (neuron*) malloc(num_inputs*sizeof(neuron)); srand(1); for (i = 0; i < num_outputs; i++) { outputs[i].num_weights = num_hidden; outputs[i].weights = (edge*) malloc(num_hidden*sizeof(edge)); for (j = 0; j < num_hidden; j++) { outputs[i].weights[j].source = &(hidden[j]); outputs[i].weights[j].weight = ((double)rand()) / RAND_MAX; //printf("from hidden %i to output %i weight %f\n", j, i, outputs[i].weights[j].weight); } } for (i = 0; i < num_hidden; i++) { hidden[i].num_weights = num_inputs; hidden[i].weights = (edge*) malloc(num_inputs*sizeof(edge)); for (j = 0; j < num_inputs; j++) { hidden[i].weights[j].source = &(inputs[j]); hidden[i].weights[j].weight = ((double)rand()) / RAND_MAX; //printf("from input %i to hidden %i weight %f\n", j, i, hidden[i].weights[j].weight); } } net* network = (net*) malloc(sizeof(net)); network->inputs = inputs; network->hidden = hidden; network->outputs = outputs; network->num_inputs = num_inputs; network->num_hidden = num_hidden; network->num_outputs = num_outputs; return network; } /** * Process a neural network's input data. * * Takes an array of doubles as the network's input. The length of the array * should be the same as the number of input nodes in the neural network. If * the array has fewer items than the network has inputs, this function WILL * read over the end of the array. * * It then propagates the values through the neural network. Each layer is * processed in succession: all of the nodes to which it is connected are * multiplied by the weights of their respective connections and the values are * summed. The sum is passed through a scaling function and stored as the * node's value. */ void process_inputs(net* n, double inputs[]) { int i, j; for (i=0; i < n->num_inputs; i++) { n->inputs[i].value = rescale(inputs[i]); //printf("input %i value %f scaled to %f\n", i, inputs[i], n->inputs[i].value); } for (i=0; i < n->num_hidden; i++) { n->hidden[i].value = 0; for (j=0; j < n->hidden[i].num_weights; j++) { n->hidden[i].value += n->hidden[i].weights[j].source->value * n->hidden[i].weights[j].weight; } n->hidden[i].value = rescale(n->hidden[i].value); //printf("hidden %i scaled to %f\n", i, n->hidden[i].value); } for (i=0; i < n->num_outputs; i++) { n->outputs[i].value = 0; for (j=0; j < n->outputs[i].num_weights; j++) { n->outputs[i].value += n->outputs[i].weights[j].source->value * n->outputs[i].weights[j].weight; } n->outputs[i].value = rescale(n->outputs[i].value); //printf("output %i scaled to %f\n", i, n->outputs[i].value); } } /** * Retrieve an output from a neural network. * * Gets the nth output. */ double get_output(net* n, int output) { return n->outputs[output].value; } /** * Scale an input data value. */ double input_scale(double value) { //printf("%f\n", value); return value / 255; } /** * Scale a neuron's value. * * Uses a sigmoid function. Currently the logistic function. */ double rescale(double value) { return 1 / (1 + exp(-value)); }