From bc902b277e9131cc169751056786de5393da737d Mon Sep 17 00:00:00 2001 From: Joseph Redmon Date: Mon, 24 Feb 2014 12:21:31 -0800 Subject: [PATCH] Imagenet Features\! --- src/data.c | 1 + src/image.c | 23 ++++++++-- src/image.h | 1 + src/network.c | 55 ++++++++++++----------- src/softmax_layer.c | 4 +- src/tests.c | 105 +++++++++++++++++++++++++++++++++++++------- 6 files changed, 141 insertions(+), 48 deletions(-) diff --git a/src/data.c b/src/data.c index 85c37946..f44f5daf 100644 --- a/src/data.c +++ b/src/data.c @@ -10,6 +10,7 @@ list *get_paths(char *filename) { char *path; FILE *file = fopen(filename, "r"); + if(!file) file_error(filename); list *lines = make_list(); while((path=fgetl(file))){ list_insert(lines, path); diff --git a/src/image.c b/src/image.c index fad454d7..16679776 100644 --- a/src/image.c +++ b/src/image.c @@ -4,6 +4,21 @@ int windows = 0; +image image_distance(image a, image b) +{ + int i,j; + image dist = make_image(a.h, a.w, 1); + for(i = 0; i < a.c; ++i){ + for(j = 0; j < a.h*a.w; ++j){ + dist.data[j] += pow(a.data[i*a.h*a.w+j]-b.data[i*a.h*a.w+j],2); + } + } + for(j = 0; j < a.h*a.w; ++j){ + dist.data[j] = sqrt(dist.data[j]); + } + return dist; +} + void subtract_image(image a, image b) { int i; @@ -370,9 +385,11 @@ image load_image(char *filename, int h, int w) printf("Cannot load file image %s\n", filename); exit(0); } - IplImage *resized = resizeImage(src, h, w, 1); - cvReleaseImage(&src); - src = resized; + if(h && w ){ + IplImage *resized = resizeImage(src, h, w, 1); + cvReleaseImage(&src); + src = resized; + } image out = ipl_to_image(src); cvReleaseImage(&src); return out; diff --git a/src/image.h b/src/image.h index 0d7d6e2e..9f7d74d4 100644 --- a/src/image.h +++ b/src/image.h @@ -10,6 +10,7 @@ typedef struct { float *data; } image; +image image_distance(image a, image b); void scale_image(image m, float s); void add_scalar_image(image m, float s); void normalize_image(image p); diff --git a/src/network.c b/src/network.c index f5fea607..b2fc9225 100644 --- a/src/network.c +++ b/src/network.c @@ -21,18 +21,18 @@ network make_network(int n) return net; } -void print_convolutional_cfg(FILE *fp, convolutional_layer *l) +void print_convolutional_cfg(FILE *fp, convolutional_layer *l, int first) { int i; - fprintf(fp, "[convolutional]\n" - "height=%d\n" - "width=%d\n" - "channels=%d\n" - "filters=%d\n" + fprintf(fp, "[convolutional]\n"); + if(first) fprintf(fp, "height=%d\n" + "width=%d\n" + "channels=%d\n", + l->h, l->w, l->c); + fprintf(fp, "filters=%d\n" "size=%d\n" "stride=%d\n" "activation=%s\n", - l->h, l->w, l->c, l->n, l->size, l->stride, get_activation_string(l->activation)); fprintf(fp, "data="); @@ -40,14 +40,14 @@ void print_convolutional_cfg(FILE *fp, convolutional_layer *l) for(i = 0; i < l->n*l->c*l->size*l->size; ++i) fprintf(fp, "%g,", l->filters[i]); fprintf(fp, "\n\n"); } -void print_connected_cfg(FILE *fp, connected_layer *l) +void print_connected_cfg(FILE *fp, connected_layer *l, int first) { int i; - fprintf(fp, "[connected]\n" - "input=%d\n" - "output=%d\n" + fprintf(fp, "[connected]\n"); + if(first) fprintf(fp, "input=%d\n", l->inputs); + fprintf(fp, "output=%d\n" "activation=%s\n", - l->inputs, l->outputs, + l->outputs, get_activation_string(l->activation)); fprintf(fp, "data="); for(i = 0; i < l->outputs; ++i) fprintf(fp, "%g,", l->biases[i]); @@ -55,22 +55,21 @@ void print_connected_cfg(FILE *fp, connected_layer *l) fprintf(fp, "\n\n"); } -void print_maxpool_cfg(FILE *fp, maxpool_layer *l) +void print_maxpool_cfg(FILE *fp, maxpool_layer *l, int first) { - fprintf(fp, "[maxpool]\n" - "height=%d\n" - "width=%d\n" - "channels=%d\n" - "stride=%d\n\n", - l->h, l->w, l->c, - l->stride); + fprintf(fp, "[maxpool]\n"); + if(first) fprintf(fp, "height=%d\n" + "width=%d\n" + "channels=%d\n", + l->h, l->w, l->c); + fprintf(fp, "stride=%d\n\n", l->stride); } -void print_softmax_cfg(FILE *fp, softmax_layer *l) +void print_softmax_cfg(FILE *fp, softmax_layer *l, int first) { - fprintf(fp, "[softmax]\n" - "input=%d\n\n", - l->inputs); + fprintf(fp, "[softmax]\n"); + if(first) fprintf(fp, "input=%d\n", l->inputs); + fprintf(fp, "\n"); } void save_network(network net, char *filename) @@ -81,13 +80,13 @@ void save_network(network net, char *filename) for(i = 0; i < net.n; ++i) { if(net.types[i] == CONVOLUTIONAL) - print_convolutional_cfg(fp, (convolutional_layer *)net.layers[i]); + print_convolutional_cfg(fp, (convolutional_layer *)net.layers[i], i==0); else if(net.types[i] == CONNECTED) - print_connected_cfg(fp, (connected_layer *)net.layers[i]); + print_connected_cfg(fp, (connected_layer *)net.layers[i], i==0); else if(net.types[i] == MAXPOOL) - print_maxpool_cfg(fp, (maxpool_layer *)net.layers[i]); + print_maxpool_cfg(fp, (maxpool_layer *)net.layers[i], i==0); else if(net.types[i] == SOFTMAX) - print_softmax_cfg(fp, (softmax_layer *)net.layers[i]); + print_softmax_cfg(fp, (softmax_layer *)net.layers[i], i==0); } fclose(fp); } diff --git a/src/softmax_layer.c b/src/softmax_layer.c index 79375de5..b6b7ff35 100644 --- a/src/softmax_layer.c +++ b/src/softmax_layer.c @@ -36,9 +36,9 @@ void forward_softmax_layer(const softmax_layer layer, float *input) } for(i = 0; i < layer.inputs; ++i){ sum += exp(input[i]-largest); - printf("%f, ", input[i]); + //printf("%f, ", input[i]); } - printf("\n"); + //printf("\n"); if(sum) sum = largest+log(sum); else sum = largest-100; for(i = 0; i < layer.inputs; ++i){ diff --git a/src/tests.c b/src/tests.c index c72e900b..91ee4bf9 100644 --- a/src/tests.c +++ b/src/tests.c @@ -188,37 +188,64 @@ void test_data() free_data(train); } -void test_full() +void train_full() { - network net = parse_network_cfg("full.cfg"); + network net = parse_network_cfg("cfg/imagenet.cfg"); srand(2222222); - int i = 800; + int i = 0; char *labels[] = {"cat","dog"}; float lr = .00001; float momentum = .9; float decay = 0.01; - while(i++ < 1000 || 1){ - visualize_network(net); - cvWaitKey(100); - data train = load_data_image_pathfile_random("train_paths.txt", 1000, labels, 2, 256, 256); + while(1){ + i += 1000; + data train = load_data_image_pathfile_random("images/assira/train.list", 1000, labels, 2, 256, 256); image im = float_to_image(256, 256, 3,train.X.vals[0]); - show_image(im, "input"); - cvWaitKey(100); + //visualize_network(net); + //cvWaitKey(100); + //show_image(im, "input"); + //cvWaitKey(100); //scale_data_rows(train, 1./255.); normalize_data_rows(train); clock_t start = clock(), end; - float loss = train_network_sgd(net, train, 100, lr, momentum, decay); + float loss = train_network_sgd(net, train, 1000, lr, momentum, decay); end = clock(); printf("%d: %f, Time: %lf seconds, LR: %f, Momentum: %f, Decay: %f\n", i, loss, (float)(end-start)/CLOCKS_PER_SEC, lr, momentum, decay); free_data(train); - if(i%100==0){ + if(i%10000==0){ char buff[256]; - sprintf(buff, "backup_%d.cfg", i); - //save_network(net, buff); + sprintf(buff, "cfg/assira_backup_%d.cfg", i); + save_network(net, buff); } //lr *= .99; } } +void test_full() +{ + network net = parse_network_cfg("cfg/backup_1300.cfg"); + srand(2222222); + int i,j; + int total = 100; + char *labels[] = {"cat","dog"}; + FILE *fp = fopen("preds.txt","w"); + for(i = 0; i < total; ++i){ + visualize_network(net); + cvWaitKey(100); + data test = load_data_image_pathfile_part("images/assira/test.list", i, total, labels, 2, 256, 256); + image im = float_to_image(256, 256, 3,test.X.vals[0]); + show_image(im, "input"); + cvWaitKey(100); + normalize_data_rows(test); + for(j = 0; j < test.X.rows; ++j){ + float *x = test.X.vals[j]; + forward_network(net, x); + int class = get_predicted_class_network(net); + fprintf(fp, "%d\n", class); + } + free_data(test); + } + fclose(fp); +} void test_nist() { @@ -398,6 +425,7 @@ void train_VOC() int voc_size(int x) { + x = x-1+3; x = x-1+3; x = x-1+3; x = (x-1)*2+1; @@ -411,13 +439,14 @@ image features_output_size(network net, IplImage *src, int outh, int outw) { int h = voc_size(outh); int w = voc_size(outw); + printf("%d %d\n", h, w); IplImage *sized = cvCreateImage(cvSize(w,h), src->depth, src->nChannels); cvResize(src, sized, CV_INTER_LINEAR); image im = ipl_to_image(sized); reset_network_size(net, im.h, im.w, im.c); forward_network(net, im.data); - image out = get_network_image_layer(net, 5); + image out = get_network_image_layer(net, 6); //printf("%d %d\n%d %d\n", outh, out.h, outw, out.w); free_image(im); cvReleaseImage(&sized); @@ -500,7 +529,7 @@ void features_VOC(int part, int total) void features_VOC_image(char *image_file, char *image_dir, char *out_dir) { int i,j; - network net = parse_network_cfg("cfg/voc_features.cfg"); + network net = parse_network_cfg("cfg/imagenet.cfg"); char image_path[1024]; sprintf(image_path, "%s%s",image_dir, image_file); char out_path[1024]; @@ -557,8 +586,54 @@ void features_VOC_image(char *image_file, char *image_dir, char *out_dir) cvReleaseImage(&src); } +void test_distribution() +{ + IplImage* img = 0; + if( (img = cvLoadImage("im_small.jpg",-1)) == 0 ) file_error("im_small.jpg"); + network net = parse_network_cfg("cfg/voc_features.cfg"); + int h = img->height/8-2; + int w = img->width/8-2; + image out = features_output_size(net, img, h, w); + int c = out.c; + out.c = 1; + show_image(out, "output"); + out.c = c; + image input = ipl_to_image(img); + show_image(input, "input"); + CvScalar s; + int i,j; + image affects = make_image(input.h, input.w, 1); + int count = 0; + for(i = 0; iheight; i += 1){ + for(j = 0; j < img->width; j += 1){ + IplImage *copy = cvCloneImage(img); + s=cvGet2D(copy,i,j); // get the (i,j) pixel value + printf("%d/%d\n", count++, img->height*img->width); + s.val[0]=0; + s.val[1]=0; + s.val[2]=0; + cvSet2D(copy,i,j,s); // set the (i,j) pixel value + image mod = features_output_size(net, copy, h, w); + image dist = image_distance(out, mod); + show_image(affects, "affects"); + cvWaitKey(1); + cvReleaseImage(©); + //affects.data[i*affects.w + j] += dist.data[3*dist.w+5]; + affects.data[i*affects.w + j] += dist.data[1*dist.w+1]; + free_image(mod); + free_image(dist); + } + } + show_image(affects, "Origins"); + cvWaitKey(0); + cvWaitKey(0); +} + + int main(int argc, char *argv[]) { + //train_full(); + //test_distribution(); //feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); //test_blas();