Skip to content

Commit

Permalink
Merge pull request #20 from ujh/genann-binary-format
Browse files Browse the repository at this point in the history
Binary format for storing ANNs
  • Loading branch information
ujh authored Feb 13, 2025
2 parents df654c3 + 7eb433a commit ef799e2
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 14 deletions.
2 changes: 1 addition & 1 deletion engine/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
evo
persist.txt
persist.*
test
3 changes: 1 addition & 2 deletions engine/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,5 @@ test: $(OBJS) test.o
$(CC) $(CFLAGS) -o $@ -c $<

clean:
$(RM) *.o *.dep
$(RM) *.o *.dep persist.*
$(RM) evo test

Binary file modified engine/example.ann
Binary file not shown.
4 changes: 2 additions & 2 deletions engine/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ void allocate_ann(char *ann_save_file) {
if (ann_save_file == NULL) {
ann = genann_init(input_size, 5, points * 10, output_size);
} else {
FILE *fd = fopen(ann_save_file, "r");
ann = genann_read(fd);
FILE *fd = fopen(ann_save_file, "rb");
ann = genann_binary_read(fd);
fclose(fd);
}

Expand Down
27 changes: 27 additions & 0 deletions engine/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,32 @@ void persist() {
genann_free(second);
}

void binary_persist() {
genann *first = genann_init(1000, 5, 50, 10);

FILE *out = fopen("persist.bin", "wb");
genann_binary_write(first, out);
fclose(out);


FILE *in = fopen("persist.bin", "rb");
genann *second = genann_binary_read(in);
fclose(in);

lequal(first->inputs, second->inputs);
lequal(first->hidden_layers, second->hidden_layers);
lequal(first->hidden, second->hidden);
lequal(first->outputs, second->outputs);
lequal(first->total_weights, second->total_weights);

int i;
for (i = 0; i < first->total_weights; ++i) {
lok(first->weight[i] == second->weight[i]);
}

genann_free(first);
genann_free(second);
}

void copy() {
genann *first = genann_init(1000, 5, 50, 10);
Expand Down Expand Up @@ -265,6 +291,7 @@ int main(int argc, char *argv[])
lrun("train or", train_or);
lrun("train xor", train_xor);
lrun("persist", persist);
lrun("binary_persist", binary_persist);
lrun("copy", copy);
lrun("sigmoid", sigmoid);

Expand Down
8 changes: 4 additions & 4 deletions evolve/evolve.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ genann **load_nns(char *ann1_name, char *ann2_name) {
genann **anns = malloc(2 * sizeof(genann *));

printf("Loading %s ...", ann1_name);
FILE *fd = fopen(ann1_name, "r");
anns[0] = genann_read(fd);
FILE *fd = fopen(ann1_name, "rb");
anns[0] = genann_binary_read(fd);
fclose(fd);
printf("\nLoading %s ...", ann2_name);
fd = fopen(ann2_name, "r");
anns[1] = genann_read(fd);
fd = fopen(ann2_name, "rb");
anns[1] = genann_binary_read(fd);
fclose(fd);
printf("\n");

Expand Down
4 changes: 2 additions & 2 deletions evolve/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ int main(int argc, char **argv) {
}

printf("Saving output to child.ann ...");
FILE *fd = fopen("child.ann", "w");
genann_write(child, fd);
FILE *fd = fopen("child.ann", "wb");
genann_binary_write(child, fd);
fclose(fd);
printf("\n");
}
4 changes: 2 additions & 2 deletions initial-population/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ int main(int argc, char **argv) {
printf("\r%d/%d", i, population_size);
sprintf(buffer, "%04d.ann", i);

FILE *fd = fopen(buffer, "w");
FILE *fd = fopen(buffer, "wb");
genann *ann = genann_init(inputs, hidden_layers, hidden, outputs);
genann_write(ann, fd);
genann_binary_write(ann, fd);
genann_free(ann);
fclose(fd);
}
Expand Down
36 changes: 35 additions & 1 deletion lib/genann.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,32 @@ genann *genann_read(FILE *in) {
return ann;
}

genann *genann_binary_read(FILE *in) {
int config[4];
int rc;

rc = fread(config, sizeof(int), 4, in);
if (rc < 4) {
perror("fread");
return NULL;
}

genann *ann = genann_init(config[0], config[1], config[2], config[3]);

int i;
for (i = 0; i < ann->total_weights; ++i) {
rc = fread(ann->weight + i, sizeof(double), 1, in);
if (rc < 1) {
perror("fscanf");
genann_free(ann);

return NULL;
}
}

return ann;
}


genann *genann_copy(genann const *ann) {
const int size = sizeof(genann) + sizeof(double) * (ann->total_weights + ann->total_neurons + (ann->total_neurons - ann->inputs));
Expand Down Expand Up @@ -402,4 +428,12 @@ void genann_write(genann const *ann, FILE *out) {
}
}


void genann_binary_write(const genann *ann, FILE *out) {
int config[4];
config[0] = ann->inputs;
config[1] = ann->hidden_layers;
config[2] = ann->hidden;
config[3] = ann->outputs;
fwrite(config, sizeof(int), 4, out);
fwrite(ann->weight, sizeof(double), ann->total_weights, out);
}
5 changes: 5 additions & 0 deletions lib/genann.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs);
/* Creates ANN from file saved with genann_write. */
genann *genann_read(FILE *in);

/* Creates ANN from file saved with genann_binary_write. */
genann *genann_binary_read(FILE *in);

/* Sets weights randomly. Called by init. */
void genann_randomize(genann *ann);

Expand All @@ -92,6 +95,8 @@ void genann_train(genann const *ann, double const *inputs, double const *desired

/* Saves the ann. */
void genann_write(genann const *ann, FILE *out);
/* Saves the ann in a binary format. */
void genann_binary_write(genann const *ann, FILE *out);

void genann_init_sigmoid_lookup(const genann *ann);
double genann_act_sigmoid(const genann *ann, double a);
Expand Down

0 comments on commit ef799e2

Please sign in to comment.