📄 fann.c
字号:
FANN_EXTERNAL struct fann *FANN_API fann_create_shortcut_array(unsigned int num_layers,
const unsigned int *layers)
{
struct fann_layer *layer_it, *layer_it2, *last_layer;
struct fann *ann;
struct fann_neuron *neuron_it, *neuron_it2 = 0;
unsigned int i;
unsigned int num_neurons_in, num_neurons_out;
#ifdef FIXEDFANN
unsigned int decimal_point;
unsigned int multiplier;
#endif
/* seed random */
#ifndef FANN_NO_SEED
fann_seed_rand();
#endif
/* allocate the general structure */
ann = fann_allocate_structure(num_layers);
if(ann == NULL)
{
fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM);
return NULL;
}
ann->connection_rate = 1;
ann->network_type = FANN_NETTYPE_SHORTCUT;
#ifdef FIXEDFANN
decimal_point = ann->decimal_point;
multiplier = ann->multiplier;
fann_update_stepwise(ann);
#endif
/* determine how many neurons there should be in each layer */
i = 0;
for(layer_it = ann->first_layer; layer_it != ann->last_layer; layer_it++)
{
/* we do not allocate room here, but we make sure that
* last_neuron - first_neuron is the number of neurons */
layer_it->first_neuron = NULL;
layer_it->last_neuron = layer_it->first_neuron + layers[i++];
if(layer_it == ann->first_layer)
{
/* there is a bias neuron in the first layer */
layer_it->last_neuron++;
}
ann->total_neurons += layer_it->last_neuron - layer_it->first_neuron;
}
ann->num_output = (ann->last_layer - 1)->last_neuron - (ann->last_layer - 1)->first_neuron;
ann->num_input = ann->first_layer->last_neuron - ann->first_layer->first_neuron - 1;
/* allocate room for the actual neurons */
fann_allocate_neurons(ann);
if(ann->errno_f == FANN_E_CANT_ALLOCATE_MEM)
{
fann_destroy(ann);
return NULL;
}
#ifdef DEBUG
printf("creating fully shortcut connected network.\n");
printf("input\n");
printf(" layer : %d neurons, 1 bias\n",
ann->first_layer->last_neuron - ann->first_layer->first_neuron - 1);
#endif
num_neurons_in = ann->num_input;
last_layer = ann->last_layer;
for(layer_it = ann->first_layer + 1; layer_it != last_layer; layer_it++)
{
num_neurons_out = layer_it->last_neuron - layer_it->first_neuron;
/* Now split out the connections on the different neurons */
for(i = 0; i != num_neurons_out; i++)
{
layer_it->first_neuron[i].first_con = ann->total_connections;
ann->total_connections += num_neurons_in + 1;
layer_it->first_neuron[i].last_con = ann->total_connections;
layer_it->first_neuron[i].activation_function = FANN_SIGMOID_STEPWISE;
#ifdef FIXEDFANN
layer_it->first_neuron[i].activation_steepness = ann->multiplier / 2;
#else
layer_it->first_neuron[i].activation_steepness = 0.5;
#endif
}
#ifdef DEBUG
printf(" layer : %d neurons, 0 bias\n", num_neurons_out);
#endif
/* used in the next run of the loop */
num_neurons_in += num_neurons_out;
}
fann_allocate_connections(ann);
if(ann->errno_f == FANN_E_CANT_ALLOCATE_MEM)
{
fann_destroy(ann);
return NULL;
}
/* Connections are created from all neurons to all neurons in later layers
*/
num_neurons_in = ann->num_input + 1;
for(layer_it = ann->first_layer + 1; layer_it != last_layer; layer_it++)
{
for(neuron_it = layer_it->first_neuron; neuron_it != layer_it->last_neuron; neuron_it++)
{
i = neuron_it->first_con;
for(layer_it2 = ann->first_layer; layer_it2 != layer_it; layer_it2++)
{
for(neuron_it2 = layer_it2->first_neuron; neuron_it2 != layer_it2->last_neuron;
neuron_it2++)
{
ann->weights[i] = (fann_type) fann_random_weight();
ann->connections[i] = neuron_it2;
i++;
}
}
}
num_neurons_in += layer_it->last_neuron - layer_it->first_neuron;
}
#ifdef DEBUG
printf("output\n");
#endif
return ann;
}
FANN_EXTERNAL fann_type *FANN_API fann_run(struct fann * ann, fann_type * input)
{
struct fann_neuron *neuron_it, *last_neuron, *neurons, **neuron_pointers;
unsigned int i, num_connections, num_input, num_output;
fann_type neuron_sum, *output;
fann_type *weights;
struct fann_layer *layer_it, *last_layer;
unsigned int activation_function;
fann_type steepness;
/* store some variabels local for fast access */
struct fann_neuron *first_neuron = ann->first_layer->first_neuron;
#ifdef FIXEDFANN
int multiplier = ann->multiplier;
unsigned int decimal_point = ann->decimal_point;
/* values used for the stepwise linear sigmoid function */
fann_type r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0;
fann_type v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
fann_type last_steepness = 0;
unsigned int last_activation_function = 0;
#else
fann_type max_sum;
#endif
/* first set the input */
num_input = ann->num_input;
for(i = 0; i != num_input; i++)
{
#ifdef FIXEDFANN
if(fann_abs(input[i]) > multiplier)
{
printf
("Warning input number %d is out of range -%d - %d with value %d, integer overflow may occur.\n",
i, multiplier, multiplier, input[i]);
}
#endif
first_neuron[i].value = input[i];
}
/* Set the bias neuron in the input layer */
#ifdef FIXEDFANN
(ann->first_layer->last_neuron - 1)->value = multiplier;
#else
(ann->first_layer->last_neuron - 1)->value = 1;
#endif
last_layer = ann->last_layer;
for(layer_it = ann->first_layer + 1; layer_it != last_layer; layer_it++)
{
last_neuron = layer_it->last_neuron;
for(neuron_it = layer_it->first_neuron; neuron_it != last_neuron; neuron_it++)
{
if(neuron_it->first_con == neuron_it->last_con)
{
/* bias neurons */
#ifdef FIXEDFANN
neuron_it->value = multiplier;
#else
neuron_it->value = 1;
#endif
continue;
}
activation_function = neuron_it->activation_function;
steepness = neuron_it->activation_steepness;
neuron_sum = 0;
num_connections = neuron_it->last_con - neuron_it->first_con;
weights = ann->weights + neuron_it->first_con;
if(ann->connection_rate >= 1)
{
if(ann->network_type == FANN_NETTYPE_SHORTCUT)
{
neurons = ann->first_layer->first_neuron;
}
else
{
neurons = (layer_it - 1)->first_neuron;
}
/* unrolled loop start */
i = num_connections & 3; /* same as modulo 4 */
switch (i)
{
case 3:
neuron_sum += fann_mult(weights[2], neurons[2].value);
case 2:
neuron_sum += fann_mult(weights[1], neurons[1].value);
case 1:
neuron_sum += fann_mult(weights[0], neurons[0].value);
case 0:
break;
}
for(; i != num_connections; i += 4)
{
neuron_sum +=
fann_mult(weights[i], neurons[i].value) +
fann_mult(weights[i + 1], neurons[i + 1].value) +
fann_mult(weights[i + 2], neurons[i + 2].value) +
fann_mult(weights[i + 3], neurons[i + 3].value);
}
/* unrolled loop end */
/*
* for(i = 0;i != num_connections; i++){
* printf("%f += %f*%f, ", neuron_sum, weights[i], neurons[i].value);
* neuron_sum += fann_mult(weights[i], neurons[i].value);
* }
*/
}
else
{
neuron_pointers = ann->connections + neuron_it->first_con;
i = num_connections & 3; /* same as modulo 4 */
switch (i)
{
case 3:
neuron_sum += fann_mult(weights[2], neuron_pointers[2]->value);
case 2:
neuron_sum += fann_mult(weights[1], neuron_pointers[1]->value);
case 1:
neuron_sum += fann_mult(weights[0], neuron_pointers[0]->value);
case 0:
break;
}
for(; i != num_connections; i += 4)
{
neuron_sum +=
fann_mult(weights[i], neuron_pointers[i]->value) +
fann_mult(weights[i + 1], neuron_pointers[i + 1]->value) +
fann_mult(weights[i + 2], neuron_pointers[i + 2]->value) +
fann_mult(weights[i + 3], neuron_pointers[i + 3]->value);
}
}
#ifdef FIXEDFANN
neuron_it->sum = fann_mult(steepness, neuron_sum);
if(activation_function != last_activation_function || steepness != last_steepness)
{
switch (activation_function)
{
case FANN_SIGMOID:
case FANN_SIGMOID_STEPWISE:
r1 = ann->sigmoid_results[0];
r2 = ann->sigmoid_results[1];
r3 = ann->sigmoid_results[2];
r4 = ann->sigmoid_results[3];
r5 = ann->sigmoid_results[4];
r6 = ann->sigmoid_results[5];
v1 = ann->sigmoid_values[0] / steepness;
v2 = ann->sigmoid_values[1] / steepness;
v3 = ann->sigmoid_values[2] / steepness;
v4 = ann->sigmoid_values[3] / steepness;
v5 = ann->sigmoid_values[4] / steepness;
v6 = ann->sigmoid_values[5] / steepness;
break;
case FANN_SIGMOID_SYMMETRIC:
case FANN_SIGMOID_SYMMETRIC_STEPWISE:
r1 = ann->sigmoid_symmetric_results[0];
r2 = ann->sigmoid_symmetric_results[1];
r3 = ann->sigmoid_symmetric_results[2];
r4 = ann->sigmoid_symmetric_results[3];
r5 = ann->sigmoid_symmetric_results[4];
r6 = ann->sigmoid_symmetric_results[5];
v1 = ann->sigmoid_symmetric_values[0] / steepness;
v2 = ann->sigmoid_symmetric_values[1] / steepness;
v3 = ann->sigmoid_symmetric_values[2] / steepness;
v4 = ann->sigmoid_symmetric_values[3] / steepness;
v5 = ann->sigmoid_symmetric_values[4] / steepness;
v6 = ann->sigmoid_symmetric_values[5] / steepness;
break;
case FANN_THRESHOLD:
break;
}
}
switch (activation_function)
{
case FANN_SIGMOID:
case FANN_SIGMOID_STEPWISE:
neuron_it->value =
(fann_type) fann_stepwise(v1, v2, v3, v4, v5, v6, r1, r2, r3, r4, r5, r6, 0,
multiplier, neuron_sum);
break;
case FANN_SIGMOID_SYMMETRIC:
case FANN_SIGMOID_SYMMETRIC_STEPWISE:
neuron_it->value =
(fann_type) fann_stepwise(v1, v2, v3, v4, v5, v6, r1, r2, r3, r4, r5, r6,
-multiplier, multiplier, neuron_sum);
break;
case FANN_THRESHOLD:
neuron_it->value = (fann_type) ((neuron_sum < 0) ? 0 : multiplier);
break;
case FANN_THRESHOLD_SYMMETRIC:
neuron_it->value = (fann_type) ((neuron_sum < 0) ? -multiplier : multiplier);
break;
case FANN_LINEAR:
neuron_it->value = neuron_sum;
break;
case FANN_LINEAR_PIECE:
neuron_it->value = (fann_type)((neuron_sum < 0) ? 0 : (neuron_sum > multiplier) ? multiplier : neuron_sum);
break;
case FANN_LINEAR_PIECE_SYMMETRIC:
neuron_it->value = (fann_type)((neuron_sum < -multiplier) ? -multiplier : (neuron_sum > multiplier) ? multiplier : neuron_sum);
break;
case FANN_ELLIOT:
case FANN_ELLIOT_SYMMETRIC:
case FANN_GAUSSIAN:
case FANN_GAUSSIAN_SYMMETRIC:
case FANN_GAUSSIAN_STEPWISE:
case FANN_SIN_SYMMETRIC:
case FANN_COS_SYMMETRIC:
fann_error((struct fann_error *) ann, FANN_E_CANT_USE_ACTIVATION);
break;
}
last_steepness = steepness;
last_activation_function = activation_function;
#else
neuron_sum = fann_mult(steepness, neuron_sum);
max_sum = 150/steepness;
if(neuron_sum > max_sum)
neuron_sum = max_sum;
else if(neuron_sum < -max_sum)
neuron_sum = -max_sum;
neuron_it->sum = neuron_sum;
fann_activation_switch(ann, activation_function, neuron_sum, neuron_it->value);
#endif
}
}
/* set the output */
output = ann->output;
num_output = ann->num_output;
neurons = (ann->last_layer - 1)->first_neuron;
for(i = 0; i != num_output; i++)
{
output[i] = neurons[i].value;
}
return ann->output;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -