mirror of https://github.com/AlexeyAB/darknet.git
parent
d7286c2732
commit
2db9fbef2b
29 changed files with 1287 additions and 270 deletions
@ -0,0 +1,8 @@ |
||||
[conn] |
||||
input = 1690 |
||||
output = 20 |
||||
activation=relu |
||||
|
||||
[conn] |
||||
output = 1 |
||||
activation=relu |
@ -0,0 +1,108 @@ |
||||
#include "data.h" |
||||
#include "list.h" |
||||
#include "utils.h" |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
batch make_batch(int n, int k) |
||||
{ |
||||
batch b; |
||||
b.n = n; |
||||
if(k < 3) k = 1; |
||||
b.images = calloc(n, sizeof(image)); |
||||
b.truth = calloc(n, sizeof(double *)); |
||||
int i; |
||||
for(i =0 ; i < n; ++i) b.truth[i] = calloc(k, sizeof(double)); |
||||
return b; |
||||
} |
||||
|
||||
list *get_paths(char *filename) |
||||
{ |
||||
char *path; |
||||
FILE *file = fopen(filename, "r"); |
||||
list *lines = make_list(); |
||||
while((path=fgetl(file))){ |
||||
list_insert(lines, path); |
||||
} |
||||
fclose(file); |
||||
return lines; |
||||
} |
||||
|
||||
int get_truth(char *path) |
||||
{ |
||||
if(strstr(path, "dog")) return 1; |
||||
return 0; |
||||
} |
||||
|
||||
batch load_list(list *paths) |
||||
{ |
||||
char *path; |
||||
batch data = make_batch(paths->size, 2); |
||||
node *n = paths->front; |
||||
int i; |
||||
for(i = 0; i < data.n; ++i){ |
||||
path = (char *)n->val; |
||||
data.images[i] = load_image(path); |
||||
data.truth[i][0] = get_truth(path); |
||||
n = n->next; |
||||
} |
||||
return data; |
||||
} |
||||
|
||||
batch get_all_data(char *filename) |
||||
{ |
||||
list *paths = get_paths(filename); |
||||
batch b = load_list(paths); |
||||
free_list_contents(paths); |
||||
free_list(paths); |
||||
return b; |
||||
} |
||||
|
||||
void free_batch(batch b) |
||||
{ |
||||
int i; |
||||
for(i = 0; i < b.n; ++i){ |
||||
free_image(b.images[i]); |
||||
free(b.truth[i]); |
||||
} |
||||
free(b.images); |
||||
free(b.truth); |
||||
} |
||||
|
||||
batch get_batch(char *filename, int curr, int total) |
||||
{ |
||||
list *plist = get_paths(filename); |
||||
char **paths = (char **)list_to_array(plist); |
||||
int i; |
||||
int start = curr*plist->size/total; |
||||
int end = (curr+1)*plist->size/total; |
||||
batch b = make_batch(end-start, 2); |
||||
for(i = start; i < end; ++i){ |
||||
b.images[i-start] = load_image(paths[i]); |
||||
b.truth[i-start][0] = get_truth(paths[i]); |
||||
} |
||||
free_list_contents(plist); |
||||
free_list(plist); |
||||
free(paths); |
||||
return b; |
||||
} |
||||
|
||||
batch random_batch(char *filename, int n) |
||||
{ |
||||
list *plist = get_paths(filename); |
||||
char **paths = (char **)list_to_array(plist); |
||||
int i; |
||||
batch b = make_batch(n, 2); |
||||
for(i = 0; i < n; ++i){ |
||||
int index = rand()%plist->size; |
||||
b.images[i] = load_image(paths[index]); |
||||
normalize_image(b.images[i]); |
||||
b.truth[i][0] = get_truth(paths[index]); |
||||
} |
||||
free_list_contents(plist); |
||||
free_list(plist); |
||||
free(paths); |
||||
return b; |
||||
} |
@ -0,0 +1,18 @@ |
||||
#ifndef DATA_H |
||||
#define DATA_H |
||||
|
||||
#include "image.h" |
||||
|
||||
typedef struct{ |
||||
int n; |
||||
image *images; |
||||
double **truth; |
||||
} batch; |
||||
|
||||
batch get_all_data(char *filename); |
||||
batch random_batch(char *filename, int n); |
||||
batch get_batch(char *filename, int curr, int total); |
||||
void free_batch(batch b); |
||||
|
||||
|
||||
#endif |
@ -0,0 +1,90 @@ |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include "list.h" |
||||
|
||||
list *make_list() |
||||
{ |
||||
list *l = malloc(sizeof(list)); |
||||
l->size = 0; |
||||
l->front = 0; |
||||
l->back = 0; |
||||
return l; |
||||
} |
||||
|
||||
void transfer_node(list *s, list *d, node *n) |
||||
{ |
||||
node *prev, *next; |
||||
prev = n->prev; |
||||
next = n->next; |
||||
if(prev) prev->next = next; |
||||
if(next) next->prev = prev; |
||||
--s->size; |
||||
if(s->front == n) s->front = next; |
||||
if(s->back == n) s->back = prev; |
||||
} |
||||
|
||||
void *list_pop(list *l){ |
||||
if(!l->back) return 0; |
||||
node *b = l->back; |
||||
void *val = b->val; |
||||
l->back = b->prev; |
||||
if(l->back) l->back->next = 0; |
||||
free(b); |
||||
--l->size; |
||||
|
||||
return val; |
||||
} |
||||
|
||||
void list_insert(list *l, void *val) |
||||
{ |
||||
node *new = malloc(sizeof(node)); |
||||
new->val = val; |
||||
new->next = 0; |
||||
|
||||
if(!l->back){ |
||||
l->front = new; |
||||
new->prev = 0; |
||||
}else{ |
||||
l->back->next = new; |
||||
new->prev = l->back; |
||||
} |
||||
l->back = new; |
||||
++l->size; |
||||
} |
||||
|
||||
void free_node(node *n) |
||||
{ |
||||
node *next; |
||||
while(n) { |
||||
next = n->next; |
||||
free(n); |
||||
n = next; |
||||
} |
||||
} |
||||
|
||||
void free_list(list *l) |
||||
{ |
||||
free_node(l->front); |
||||
free(l); |
||||
} |
||||
|
||||
void free_list_contents(list *l) |
||||
{ |
||||
node *n = l->front; |
||||
while(n){ |
||||
free(n->val); |
||||
n = n->next; |
||||
} |
||||
} |
||||
|
||||
void **list_to_array(list *l) |
||||
{ |
||||
void **a = calloc(l->size, sizeof(void*)); |
||||
int count = 0; |
||||
node *n = l->front; |
||||
while(n){ |
||||
a[count++] = n->val; |
||||
n = n->next; |
||||
} |
||||
return a; |
||||
} |
@ -0,0 +1,26 @@ |
||||
#ifndef LIST_H |
||||
#define LIST_H |
||||
|
||||
typedef struct node{ |
||||
void *val; |
||||
struct node *next; |
||||
struct node *prev; |
||||
} node; |
||||
|
||||
typedef struct list{ |
||||
int size; |
||||
node *front; |
||||
node *back; |
||||
} list; |
||||
|
||||
list *make_list(); |
||||
int list_find(list *l, void *val); |
||||
|
||||
void list_insert(list *, void *); |
||||
|
||||
void **list_to_array(list *l); |
||||
|
||||
void free_list(list *l); |
||||
void free_list_contents(list *l); |
||||
|
||||
#endif |
@ -0,0 +1,106 @@ |
||||
#include "matrix.h" |
||||
#include "utils.h" |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <assert.h> |
||||
#include <math.h> |
||||
|
||||
void free_matrix(matrix m) |
||||
{ |
||||
int i; |
||||
for(i = 0; i < m.rows; ++i) free(m.vals[i]); |
||||
free(m.vals); |
||||
} |
||||
|
||||
matrix make_matrix(int rows, int cols) |
||||
{ |
||||
matrix m; |
||||
m.rows = rows; |
||||
m.cols = cols; |
||||
m.vals = calloc(m.rows, sizeof(double *)); |
||||
int i; |
||||
for(i = 0; i < m.rows; ++i) m.vals[i] = calloc(m.cols, sizeof(double)); |
||||
return m; |
||||
} |
||||
|
||||
matrix hold_out_matrix(matrix *m, int n) |
||||
{ |
||||
int i; |
||||
matrix h; |
||||
h.rows = n; |
||||
h.cols = m->cols; |
||||
h.vals = calloc(h.rows, sizeof(double *)); |
||||
for(i = 0; i < n; ++i){ |
||||
int index = rand()%m->rows; |
||||
h.vals[i] = m->vals[index]; |
||||
m->vals[index] = m->vals[--(m->rows)]; |
||||
} |
||||
return h; |
||||
} |
||||
|
||||
double *pop_column(matrix *m, int c) |
||||
{ |
||||
double *col = calloc(m->rows, sizeof(double)); |
||||
int i, j; |
||||
for(i = 0; i < m->rows; ++i){ |
||||
col[i] = m->vals[i][c]; |
||||
for(j = c; j < m->cols-1; ++j){ |
||||
m->vals[i][j] = m->vals[i][j+1]; |
||||
} |
||||
} |
||||
--m->cols; |
||||
return col; |
||||
} |
||||
|
||||
matrix csv_to_matrix(char *filename) |
||||
{ |
||||
FILE *fp = fopen(filename, "r"); |
||||
if(!fp) file_error(filename); |
||||
|
||||
matrix m; |
||||
m.cols = -1; |
||||
|
||||
char *line; |
||||
|
||||
int n = 0; |
||||
int size = 1024; |
||||
m.vals = calloc(size, sizeof(double*)); |
||||
while((line = fgetl(fp))){ |
||||
if(m.cols == -1) m.cols = count_fields(line); |
||||
if(n == size){ |
||||
size *= 2; |
||||
m.vals = realloc(m.vals, size*sizeof(double*)); |
||||
} |
||||
m.vals[n] = parse_fields(line, m.cols); |
||||
free(line); |
||||
++n; |
||||
} |
||||
m.vals = realloc(m.vals, n*sizeof(double*)); |
||||
m.rows = n; |
||||
return m; |
||||
} |
||||
|
||||
void print_matrix(matrix m) |
||||
{ |
||||
int i, j; |
||||
printf("%d X %d Matrix:\n",m.rows, m.cols); |
||||
printf(" __"); |
||||
for(j = 0; j < 16*m.cols-1; ++j) printf(" "); |
||||
printf("__ \n"); |
||||
|
||||
printf("| "); |
||||
for(j = 0; j < 16*m.cols-1; ++j) printf(" "); |
||||
printf(" |\n"); |
||||
|
||||
for(i = 0; i < m.rows; ++i){ |
||||
printf("| "); |
||||
for(j = 0; j < m.cols; ++j){ |
||||
printf("%15.7f ", m.vals[i][j]); |
||||
} |
||||
printf(" |\n"); |
||||
} |
||||
printf("|__"); |
||||
for(j = 0; j < 16*m.cols-1; ++j) printf(" "); |
||||
printf("__|\n"); |
||||
} |
@ -0,0 +1,17 @@ |
||||
#ifndef MATRIX_H |
||||
#define MATRIX_H |
||||
typedef struct matrix{ |
||||
int rows, cols; |
||||
double **vals; |
||||
} matrix; |
||||
|
||||
matrix make_matrix(int rows, int cols); |
||||
void free_matrix(matrix m); |
||||
void print_matrix(matrix m); |
||||
|
||||
matrix csv_to_matrix(char *filename); |
||||
matrix hold_out_matrix(matrix *m, int n); |
||||
|
||||
double *pop_column(matrix *m, int c); |
||||
|
||||
#endif |
@ -1,24 +1,41 @@ |
||||
#include "maxpool_layer.h" |
||||
#include <stdio.h> |
||||
|
||||
image get_maxpool_image(maxpool_layer layer) |
||||
{ |
||||
int h = (layer.h-1)/layer.stride + 1; |
||||
int w = (layer.w-1)/layer.stride + 1; |
||||
int c = layer.c; |
||||
return double_to_image(h,w,c,layer.output); |
||||
} |
||||
|
||||
maxpool_layer *make_maxpool_layer(int h, int w, int c, int stride) |
||||
{ |
||||
printf("Maxpool Layer: %d x %d x %d image, %d stride\n", h,w,c,stride); |
||||
maxpool_layer *layer = calloc(1, sizeof(maxpool_layer)); |
||||
layer->h = h; |
||||
layer->w = w; |
||||
layer->c = c; |
||||
layer->stride = stride; |
||||
layer->output = make_image((h-1)/stride+1, (w-1)/stride+1, c); |
||||
layer->output = calloc(((h-1)/stride+1) * ((w-1)/stride+1) * c, sizeof(double)); |
||||
layer->delta = calloc(((h-1)/stride+1) * ((w-1)/stride+1) * c, sizeof(double)); |
||||
return layer; |
||||
} |
||||
|
||||
void run_maxpool_layer(const image input, const maxpool_layer layer) |
||||
void forward_maxpool_layer(const maxpool_layer layer, double *in) |
||||
{ |
||||
image input = double_to_image(layer.h, layer.w, layer.c, in); |
||||
image output = get_maxpool_image(layer); |
||||
int i,j,k; |
||||
for(i = 0; i < layer.output.h*layer.output.w*layer.output.c; ++i) layer.output.data[i] = -DBL_MAX; |
||||
for(i = 0; i < input.h; ++i){ |
||||
for(j = 0; j < input.w; ++j){ |
||||
for(k = 0; k < input.c; ++k){ |
||||
for(i = 0; i < output.h*output.w*output.c; ++i) output.data[i] = -DBL_MAX; |
||||
for(k = 0; k < input.c; ++k){ |
||||
for(i = 0; i < input.h; ++i){ |
||||
for(j = 0; j < input.w; ++j){ |
||||
double val = get_pixel(input, i, j, k); |
||||
double cur = get_pixel(layer.output, i/layer.stride, j/layer.stride, k); |
||||
if(val > cur) set_pixel(layer.output, i/layer.stride, j/layer.stride, k, val); |
||||
double cur = get_pixel(output, i/layer.stride, j/layer.stride, k); |
||||
if(val > cur) set_pixel(output, i/layer.stride, j/layer.stride, k, val); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
@ -0,0 +1,68 @@ |
||||
#include <stdlib.h> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include "option_list.h" |
||||
|
||||
typedef struct{ |
||||
char *key; |
||||
char *val; |
||||
int used; |
||||
} kvp; |
||||
|
||||
void option_insert(list *l, char *key, char *val) |
||||
{ |
||||
kvp *p = malloc(sizeof(kvp)); |
||||
p->key = key; |
||||
p->val = val; |
||||
p->used = 0; |
||||
list_insert(l, p); |
||||
} |
||||
|
||||
void option_unused(list *l) |
||||
{ |
||||
node *n = l->front; |
||||
while(n){ |
||||
kvp *p = (kvp *)n->val; |
||||
if(!p->used){ |
||||
fprintf(stderr, "Unused field: '%s = %s'\n", p->key, p->val); |
||||
} |
||||
n = n->next; |
||||
} |
||||
} |
||||
|
||||
char *option_find(list *l, char *key) |
||||
{ |
||||
node *n = l->front; |
||||
while(n){ |
||||
kvp *p = (kvp *)n->val; |
||||
if(strcmp(p->key, key) == 0){ |
||||
p->used = 1; |
||||
return p->val; |
||||
} |
||||
n = n->next; |
||||
} |
||||
return 0; |
||||
} |
||||
char *option_find_str(list *l, char *key, char *def) |
||||
{ |
||||
char *v = option_find(l, key); |
||||
if(v) return v; |
||||
fprintf(stderr, "%s: Using default '%s'\n", key, def); |
||||
return def; |
||||
} |
||||
|
||||
int option_find_int(list *l, char *key, int def) |
||||
{ |
||||
char *v = option_find(l, key); |
||||
if(v) return atoi(v); |
||||
fprintf(stderr, "%s: Using default '%d'\n", key, def); |
||||
return def; |
||||
} |
||||
|
||||
double option_find_double(list *l, char *key, double def) |
||||
{ |
||||
char *v = option_find(l, key); |
||||
if(v) return atof(v); |
||||
fprintf(stderr, "%s: Using default '%lf'\n", key, def); |
||||
return def; |
||||
} |
@ -0,0 +1,12 @@ |
||||
#ifndef OPTION_LIST_H |
||||
#define OPTION_LIST_H |
||||
#include "list.h" |
||||
|
||||
void option_insert(list *l, char *key, char *val); |
||||
char *option_find(list *l, char *key); |
||||
char *option_find_str(list *l, char *key, char *def); |
||||
int option_find_int(list *l, char *key, int def); |
||||
double option_find_double(list *l, char *key, double def); |
||||
void option_unused(list *l); |
||||
|
||||
#endif |
@ -0,0 +1,168 @@ |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
|
||||
#include "parser.h" |
||||
#include "activations.h" |
||||
#include "convolutional_layer.h" |
||||
#include "connected_layer.h" |
||||
#include "maxpool_layer.h" |
||||
#include "list.h" |
||||
#include "option_list.h" |
||||
#include "utils.h" |
||||
|
||||
typedef struct{ |
||||
char *type; |
||||
list *options; |
||||
}section; |
||||
|
||||
int is_convolutional(section *s); |
||||
int is_connected(section *s); |
||||
int is_maxpool(section *s); |
||||
list *read_cfg(char *filename); |
||||
|
||||
|
||||
network parse_network_cfg(char *filename) |
||||
{ |
||||
list *sections = read_cfg(filename); |
||||
network net = make_network(sections->size); |
||||
|
||||
node *n = sections->front; |
||||
int count = 0; |
||||
while(n){ |
||||
section *s = (section *)n->val; |
||||
list *options = s->options; |
||||
if(is_convolutional(s)){ |
||||
int h,w,c; |
||||
int n = option_find_int(options, "filters",1); |
||||
int size = option_find_int(options, "size",1); |
||||
int stride = option_find_int(options, "stride",1); |
||||
char *activation_s = option_find_str(options, "activation", "sigmoid"); |
||||
ACTIVATION activation = get_activation(activation_s); |
||||
if(count == 0){ |
||||
h = option_find_int(options, "height",1); |
||||
w = option_find_int(options, "width",1); |
||||
c = option_find_int(options, "channels",1); |
||||
}else{ |
||||
image m = get_network_image_layer(net, count-1); |
||||
h = m.h; |
||||
w = m.w; |
||||
c = m.c; |
||||
if(h == 0) error("Layer before convolutional layer must output image."); |
||||
} |
||||
convolutional_layer *layer = make_convolutional_layer(h,w,c,n,size,stride, activation); |
||||
net.types[count] = CONVOLUTIONAL; |
||||
net.layers[count] = layer; |
||||
option_unused(options); |
||||
} |
||||
else if(is_connected(s)){ |
||||
int input; |
||||
int output = option_find_int(options, "output",1); |
||||
char *activation_s = option_find_str(options, "activation", "sigmoid"); |
||||
ACTIVATION activation = get_activation(activation_s); |
||||
if(count == 0){ |
||||
input = option_find_int(options, "input",1); |
||||
}else{ |
||||
input = get_network_output_size_layer(net, count-1); |
||||
} |
||||
connected_layer *layer = make_connected_layer(input, output, activation); |
||||
net.types[count] = CONNECTED; |
||||
net.layers[count] = layer; |
||||
option_unused(options); |
||||
}else if(is_maxpool(s)){ |
||||
int h,w,c; |
||||
int stride = option_find_int(options, "stride",1); |
||||
//char *activation_s = option_find_str(options, "activation", "sigmoid");
|
||||
if(count == 0){ |
||||
h = option_find_int(options, "height",1); |
||||
w = option_find_int(options, "width",1); |
||||
c = option_find_int(options, "channels",1); |
||||
}else{ |
||||
image m = get_network_image_layer(net, count-1); |
||||
h = m.h; |
||||
w = m.w; |
||||
c = m.c; |
||||
if(h == 0) error("Layer before convolutional layer must output image."); |
||||
} |
||||
maxpool_layer *layer = make_maxpool_layer(h,w,c,stride); |
||||
net.types[count] = MAXPOOL; |
||||
net.layers[count] = layer; |
||||
option_unused(options); |
||||
}else{ |
||||
fprintf(stderr, "Type not recognized: %s\n", s->type); |
||||
} |
||||
++count; |
||||
n = n->next; |
||||
}
|
||||
return net; |
||||
} |
||||
|
||||
int is_convolutional(section *s) |
||||
{ |
||||
return (strcmp(s->type, "[conv]")==0 |
||||
|| strcmp(s->type, "[convolutional]")==0); |
||||
} |
||||
int is_connected(section *s) |
||||
{ |
||||
return (strcmp(s->type, "[conn]")==0 |
||||
|| strcmp(s->type, "[connected]")==0); |
||||
} |
||||
int is_maxpool(section *s) |
||||
{ |
||||
return (strcmp(s->type, "[max]")==0 |
||||
|| strcmp(s->type, "[maxpool]")==0); |
||||
} |
||||
|
||||
int read_option(char *s, list *options) |
||||
{ |
||||
int i; |
||||
int len = strlen(s); |
||||
char *val = 0; |
||||
for(i = 0; i < len; ++i){ |
||||
if(s[i] == '='){ |
||||
s[i] = '\0'; |
||||
val = s+i+1; |
||||
break; |
||||
} |
||||
} |
||||
if(i == len-1) return 0; |
||||
char *key = s; |
||||
option_insert(options, key, val); |
||||
return 1; |
||||
} |
||||
|
||||
list *read_cfg(char *filename) |
||||
{ |
||||
FILE *file = fopen(filename, "r"); |
||||
if(file == 0) file_error(filename); |
||||
char *line; |
||||
int nu = 0; |
||||
list *sections = make_list(); |
||||
section *current = 0; |
||||
while((line=fgetl(file)) != 0){ |
||||
++ nu; |
||||
strip(line); |
||||
switch(line[0]){ |
||||
case '[': |
||||
current = malloc(sizeof(section)); |
||||
list_insert(sections, current); |
||||
current->options = make_list(); |
||||
current->type = line; |
||||
break; |
||||
case '\0': |
||||
case '#': |
||||
case ';': |
||||
free(line); |
||||
break; |
||||
default: |
||||
if(!read_option(line, current->options)){ |
||||
printf("Config file error line %d, could parse: %s\n", nu, line); |
||||
free(line); |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
fclose(file); |
||||
return sections; |
||||
} |
||||
|
@ -0,0 +1,7 @@ |
||||
#ifndef PARSER_H |
||||
#define PARSER_H |
||||
#include "network.h" |
||||
|
||||
network parse_network_cfg(char *filename); |
||||
|
||||
#endif |
@ -0,0 +1,147 @@ |
||||
#include "utils.h" |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <math.h> |
||||
|
||||
void error(char *s) |
||||
{ |
||||
fprintf(stderr, "Error: %s\n", s); |
||||
exit(0); |
||||
} |
||||
|
||||
void malloc_error() |
||||
{ |
||||
fprintf(stderr, "Malloc error\n"); |
||||
exit(-1); |
||||
} |
||||
|
||||
void file_error(char *s) |
||||
{ |
||||
fprintf(stderr, "Couldn't open file: %s\n", s); |
||||
exit(0); |
||||
} |
||||
|
||||
list *split_str(char *s, char delim) |
||||
{ |
||||
int i; |
||||
int len = strlen(s); |
||||
list *l = make_list(); |
||||
list_insert(l, s); |
||||
for(i = 0; i < len; ++i){ |
||||
if(s[i] == delim){ |
||||
s[i] = '\0'; |
||||
list_insert(l, &(s[i+1])); |
||||
} |
||||
} |
||||
return l; |
||||
} |
||||
|
||||
void strip(char *s) |
||||
{ |
||||
int i; |
||||
int len = strlen(s); |
||||
int offset = 0; |
||||
for(i = 0; i < len; ++i){ |
||||
char c = s[i]; |
||||
if(c==' '||c=='\t'||c=='\n') ++offset; |
||||
else s[i-offset] = c; |
||||
} |
||||
s[len-offset] = '\0'; |
||||
} |
||||
|
||||
void strip_char(char *s, char bad) |
||||
{ |
||||
int i; |
||||
int len = strlen(s); |
||||
int offset = 0; |
||||
for(i = 0; i < len; ++i){ |
||||
char c = s[i]; |
||||
if(c==bad) ++offset; |
||||
else s[i-offset] = c; |
||||
} |
||||
s[len-offset] = '\0'; |
||||
} |
||||
|
||||
char *fgetl(FILE *fp) |
||||
{ |
||||
if(feof(fp)) return 0; |
||||
int size = 512; |
||||
char *line = malloc(size*sizeof(char)); |
||||
if(!fgets(line, size, fp)){ |
||||
free(line); |
||||
return 0; |
||||
} |
||||
|
||||
int curr = strlen(line); |
||||
|
||||
while(line[curr-1]!='\n'){ |
||||
size *= 2; |
||||
line = realloc(line, size*sizeof(char)); |
||||
if(!line) malloc_error(); |
||||
fgets(&line[curr], size-curr, fp); |
||||
curr = strlen(line); |
||||
} |
||||
line[curr-1] = '\0'; |
||||
|
||||
return line; |
||||
} |
||||
|
||||
char *copy_string(char *s) |
||||
{ |
||||
char *copy = malloc(strlen(s)+1); |
||||
strncpy(copy, s, strlen(s)+1); |
||||
return copy; |
||||
} |
||||
|
||||
list *parse_csv_line(char *line) |
||||
{ |
||||
list *l = make_list(); |
||||
char *c, *p; |
||||
int in = 0; |
||||
for(c = line, p = line; *c != '\0'; ++c){ |
||||
if(*c == '"') in = !in; |
||||
else if(*c == ',' && !in){ |
||||
*c = '\0'; |
||||
list_insert(l, copy_string(p)); |
||||
p = c+1; |
||||
} |
||||
} |
||||
list_insert(l, copy_string(p)); |
||||
return l; |
||||
} |
||||
|
||||
int count_fields(char *line) |
||||
{ |
||||
int count = 0; |
||||
int done = 0; |
||||
char *c; |
||||
for(c = line; !done; ++c){ |
||||
done = (*c == '\0'); |
||||
if(*c == ',' || done) ++count; |
||||
} |
||||
return count; |
||||
} |
||||
|
||||
double *parse_fields(char *line, int n) |
||||
{ |
||||
double *field = calloc(n, sizeof(double)); |
||||
char *c, *p, *end; |
||||
int count = 0; |
||||
int done = 0; |
||||
for(c = line, p = line; !done; ++c){ |
||||
done = (*c == '\0'); |
||||
if(*c == ',' || done){ |
||||
*c = '\0'; |
||||
field[count] = strtod(p, &end); |
||||
if(p == c) field[count] = nan(""); |
||||
if(end != c && (end != c-1 || *end != '\r')) field[count] = nan(""); //DOS file formats!
|
||||
p = c+1; |
||||
++count; |
||||
} |
||||
} |
||||
return field; |
||||
} |
||||
|
||||
|
||||
|
@ -0,0 +1,18 @@ |
||||
#ifndef UTILS_H |
||||
#define UTILS_H |
||||
#include <stdio.h> |
||||
#include "list.h" |
||||
|
||||
void error(char *s); |
||||
void malloc_error(); |
||||
void file_error(char *s); |
||||
void strip(char *s); |
||||
void strip_char(char *s, char bad); |
||||
list *split_str(char *s, char delim); |
||||
char *fgetl(FILE *fp); |
||||
list *parse_csv_line(char *line); |
||||
char *copy_string(char *s); |
||||
int count_fields(char *line); |
||||
double *parse_fields(char *line, int n); |
||||
#endif |
||||
|
@ -0,0 +1,37 @@ |
||||
[conv] |
||||
width=200 |
||||
height=200 |
||||
channels=3 |
||||
filters=10 |
||||
size=3 |
||||
stride=2 |
||||
activation=relu |
||||
|
||||
[maxpool] |
||||
stride=2 |
||||
|
||||
[conv] |
||||
filters=10 |
||||
size=10 |
||||
stride=2 |
||||
activation=relu |
||||
|
||||
[maxpool] |
||||
stride=2 |
||||
|
||||
[conv] |
||||
filters=10 |
||||
size=10 |
||||
stride=2 |
||||
activation=relu |
||||
|
||||
[maxpool] |
||||
stride=2 |
||||
|
||||
[conn] |
||||
output = 10 |
||||
activation=relu |
||||
|
||||
[conn] |
||||
output = 1 |
||||
activation=relu |
@ -0,0 +1,8 @@ |
||||
[conn] |
||||
input=1 |
||||
output = 20 |
||||
activation=sigmoid |
||||
|
||||
[conn] |
||||
output = 1 |
||||
activation=sigmoid |
@ -0,0 +1,29 @@ |
||||
[conv] |
||||
width=200 |
||||
height=200 |
||||
channels=3 |
||||
filters=10 |
||||
size=15 |
||||
stride=2 |
||||
activation=relu |
||||
|
||||
[maxpool] |
||||
stride=2 |
||||
|
||||
[conv] |
||||
filters=10 |
||||
size=5 |
||||
stride=1 |
||||
activation=relu |
||||
|
||||
[maxpool] |
||||
stride=2 |
||||
|
||||
[conv] |
||||
filters=10 |
||||
size=3 |
||||
stride=1 |
||||
activation=relu |
||||
|
||||
[maxpool] |
||||
stride=2 |
Loading…
Reference in new issue