📄 backprop.c
字号:
/*PAGE Introduction
backprop.c
Dwayne Phillips
August 1992
April 1994 - resumed work
The functions in this file implement the
backpropogation neural network.
NOTES: Dimensions of arrays
m = number of inputs
n = number of layers of neurons
o = number of outputs
p = number of neurons in each layer
input layer x = 1 X m
The weights between
input and first neurons win = m X p
outputs of the hidden
layers h = p X n
The weights between
hidden layers whid = (n-1) X p X p
The weights between last
neurons and output wout = p X o
output layer y = o X 1
the target target = o x 1
output layer error delta = o x 1
Note
Because of problems with malloc and 2 and 3
dimensional arrays, I will use 1 dimensional
arrays for everything.
For example, if there is an a[2][3], I will
make it a[6] with the elements stored as:
0 1 2
3 4 5
For array[a][b], element [i][j] is:
array[(i*b) + j]
If there is an a[3][2][5], I will make it
a[30] with the elements stored as:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
25 26 27 28 29
For array[a][b][c], element [i][j][k] is:
array[(i*b*c) + (j*c) + k]
5-18-94 Let's use Widrow's method
which does not use the weight_delta
arrays. Those are used in the momentum
variation to backpropogation. Widrow
also describes that technique.
5-20-94 ASCII Text Files
This program can read many of the user inputs
from ASCII text files. This makes it easier
on the user sometimes. Instead of typing in
everything everytime, you type it into an
ASCII file once using any old text editor.
This feature works for entering the program
parameters and also for entering arrays of
input and target data.
5-21-94 The data_sets variable
In the input and training modes you have more
than one set of input and target data. The
working mode only has one data set. The tmp_x
and tmp_target variables hold all the data sets
and you copy one data set at a time into
x and target.
5-30-94 I needed to remove all the references
to the h_file since it is not used.
5-30-94 This program only uses the sigmoid
function. It does not use any of the other
functions so I need to remove the references
to the other function types.
*/
/*PAGE Includes and defines
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
typedef float ELEMENT;
#define FILL 33.33
#define LENGTH 80
#define TWOMU 0.7
#define MIN_ERROR 0.02
#define TRAINING_LIMIT 99999
#undef ACTIVATE_TEST
#undef INIT_TEST
#undef SUM_TEST
#undef MAT_MUL_TEST
#undef INPUT_LAYER_TEST
#undef TEST_3D_COPY
#undef TEST_1D_COPY
#undef TEST_2D_COPY
#undef INNER_TEST
#undef OUTPUT_LAYER_TEST
#undef FORWARD_TEST
#undef FILE_TEST
#define NORMAL_INPUT
#undef DEBUG
void malloc_2d();
void malloc_3d();
void vector_sum_of_products();
void initialize_2d_weights();
void initialize_3d_weights();
void display_2d_weights();
void display_3d_weights();
void matrix_multiply();
void input_layer();
void inner_layers();
void output_layer();
void fill_array();
void zero_array();
void copy_3d_to_2d();
void copy_2d_to_1d();
void copy_1d_to_2d();
void apply_function();
void lower_case_string();
void get_program_parameters();
void get_array_from_user();
void write_to_file();
void read_from_file();
void output_layer_error();
void neuron_deltas();
void change_output_weights();
void change_hidden_weights();
void change_input_weights();
void file_input_parameters();
FILE *open_file();
ELEMENT activation_function();
ELEMENT el_abs();
int error_is_acceptable();
/***************************************************/
/***************************************************/
/*PAGE main
*/
main(argc, argv)
int argc;
char *argv[];
{
char in_file_name[LENGTH],
mode[LENGTH],
out_file_name[LENGTH],
target_file_name[LENGTH],
type[LENGTH],
whid_file_name[LENGTH],
win_file_name[LENGTH],
wout_file_name[LENGTH];
FILE *in_file,
*out_file,
*target_file,
*whid_file,
*win_file,
*wout_file;
int big_pass = 0,
changing_weights = 1,
data_sets = 1,
i = 0,
m = 0,
n = 0,
o = 0,
p = 0,
still_training = 1,
this_data_set = 0,
training_all_data_sets = 1;
ELEMENT *delta,
*h,
*h_delta,
*target,
*tmp_target,
*tmp_x,
*x,
*y,
*whid,
*win,
*wout;
unsigned long training_pass = 0;
get_program_parameters(mode,
&m,
&n,
&o,
&p,
&data_sets,
type,
in_file_name,
out_file_name,
target_file_name,
whid_file_name,
win_file_name,
wout_file_name);
/*********************************
*
* Malloc each of the arrays
*
**********************************/
x = (ELEMENT *)
malloc((int)(m) * sizeof(ELEMENT));
y = (ELEMENT *)
malloc((int)(o) * sizeof(ELEMENT));
delta = (ELEMENT *)
malloc((int)(o) * sizeof(ELEMENT));
target = (ELEMENT *)
malloc((int)(o) * sizeof(ELEMENT));
win = (ELEMENT *)
malloc((int)(m*p) * sizeof(ELEMENT));
wout = (ELEMENT *)
malloc((int)(p*o) * sizeof(ELEMENT));
h = (ELEMENT *)
malloc((int)(p*n) * sizeof(ELEMENT));
h_delta = (ELEMENT *)
malloc((int)(p*n) * sizeof(ELEMENT));
whid = (ELEMENT *)
malloc((int)
((n-1)*p*p) * sizeof(ELEMENT));
tmp_x = (ELEMENT *)
malloc((int)
(m*data_sets) * sizeof(ELEMENT));
tmp_target = (ELEMENT *)
malloc((int)
(o*data_sets) * sizeof(ELEMENT));
/*********************************
*
* Modes of operation
*
**********************************/
/*********************************
*
* Input
*
**********************************/
if( (strncmp(mode, "input", 3) == 0)){
in_file = open_file(in_file_name, "w+b");
target_file = open_file(target_file_name,"w+b");
printf("\n\nEnter the inputs");
get_array_from_user(tmp_x, m*data_sets);
printf("\n\nEnter the targets");
get_array_from_user(tmp_target, o*data_sets);
write_to_file(tmp_x, m*data_sets, in_file);
write_to_file(tmp_target,
o*data_sets,
target_file);
fclose(in_file);
fclose(target_file);
} /* ends if input */
/*********************************
*
* Training
*
**********************************/
if( (strncmp(mode, "training", 3) == 0)){
in_file = open_file(in_file_name, "r+b");
target_file = open_file(target_file_name,"r+b");
win_file = open_file(win_file_name, "w+b");
whid_file = open_file(whid_file_name, "w+b");
wout_file = open_file(wout_file_name, "w+b");
read_from_file(tmp_x,
m*data_sets,
in_file);
read_from_file(tmp_target,
o*data_sets,
target_file);
initialize_2d_weights(win, m, p);
initialize_2d_weights(wout, p, o);
initialize_3d_weights(whid, (n-1), p, p);
changing_weights = 1;
while(changing_weights){
printf("\n\n\nbig pass %d training pass %ld ----------------------------",
big_pass++, training_pass);
changing_weights = 0;
this_data_set = 0;
training_all_data_sets = 1;
while(training_all_data_sets){
for(i=0; i<m; i++)
x[i] = tmp_x[i + m*this_data_set];
for(i=0; i<o; i++)
target[i] =
tmp_target[i + o*this_data_set];
still_training = 1;
while(still_training){
input_layer(h, x, win, m, p, n, type);
inner_layers(h, whid, p, n, type);
output_layer(h, wout, y, p, n, o,type);
output_layer_error(y, target, delta,o);
#ifdef NEVER
printf("\n\nPass %d, input is", training_pass);
display_2d_weights(x, 1, m);
printf("\n\ntarget is");
display_2d_weights(target, 1, o);
printf("\n\toutput is");
display_2d_weights(y, 1, o);
printf("\n\tdelta is");
display_2d_weights(delta, 1, o);
gets(string);
#endif
if( (error_is_acceptable(delta, o)) ||
(training_pass > TRAINING_LIMIT))
still_training = 0;
else{
changing_weights = 1;
training_pass++;
neuron_deltas(h, h_delta, delta,
whid, wout, n, o, p);
change_output_weights(wout, delta,
h, n, o, p);
change_hidden_weights(whid, h,
h_delta, n,p);
change_input_weights(x, win,h_delta,
m, n, p);
} /* ends else still_training */
} /* ends while still_training */
printf("\n\nFinished training data set %d --- training pass %ld",
this_data_set, training_pass);
printf("\nThis is the result");
display_2d_weights(y, 1, o);
printf("\nThis is the target ");
display_2d_weights(target, 1, o);
printf("\nThis is the delta");
display_2d_weights(delta, 1, o);
this_data_set++;
if(this_data_set >= data_sets)
training_all_data_sets = 0;
} /* ends while training_all_data_sets */
} /* ends while changing_weights */
write_to_file(win, m*p, win_file);
write_to_file(whid, (n-1)*p*p, whid_file);
write_to_file(wout, p*o, wout_file);
fclose(in_file);
fclose(target_file);
fclose(win_file);
fclose(whid_file);
fclose(wout_file);
} /* ends if training */
/*********************************
*
* Working
*
**********************************/
if( (strncmp(mode, "working", 3) == 0)){
printf("\nHey this is the working mode!");
in_file = open_file(in_file_name, "r+b");
out_file = open_file(out_file_name,"w+b");
win_file = open_file(win_file_name, "r+b");
whid_file = open_file(whid_file_name, "r+b");
wout_file = open_file(wout_file_name, "r+b");
read_from_file(x, m, in_file);
read_from_file(win, m*p, win_file);
read_from_file(whid, (n-1)*p*p, whid_file);
read_from_file(wout, p*o, wout_file);
input_layer(h, x, win, m, p, n, type);
inner_layers(h, whid, p, n, type);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -