Some bug fixes, random stuff
29 files modified
1 files added
| | |
| | | GPU=1 |
| | | OPENCV=1 |
| | | GPU=0 |
| | | OPENCV=0 |
| | | DEBUG=0 |
| | | |
| | | ARCH= --gpu-architecture=compute_20 --gpu-code=compute_20 |
| | | ARCH= -arch sm_52 |
| | | |
| | | VPATH=./src/ |
| | | EXEC=darknet |
| | |
| | | |
| | | CC=gcc |
| | | NVCC=nvcc |
| | | OPTS=-O2 |
| | | OPTS=-Ofast |
| | | LDFLAGS= -lm -pthread -lstdc++ |
| | | COMMON= -I/usr/local/cuda/include/ |
| | | CFLAGS=-Wall -Wfatal-errors |
| | |
| | | LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand |
| | | endif |
| | | |
| | | OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o darknet.o detection_layer.o imagenet.o captcha.o route_layer.o writing.o box.o nightmare.o normalization_layer.o avgpool_layer.o coco.o dice.o yolo.o region_layer.o |
| | | OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o darknet.o detection_layer.o imagenet.o captcha.o route_layer.o writing.o box.o nightmare.o normalization_layer.o avgpool_layer.o coco.o dice.o yolo.o region_layer.o layer.o |
| | | ifeq ($(GPU), 1) |
| | | OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o softmax_layer_kernels.o network_kernels.o avgpool_layer_kernels.o |
| | | endif |
| | |
| | | return box_intersection(a, b)/box_union(a, b); |
| | | } |
| | | |
| | | float box_rmse(box a, box b) |
| | | { |
| | | return sqrt(pow(a.x-b.x, 2) + |
| | | pow(a.y-b.y, 2) + |
| | | pow(a.w-b.w, 2) + |
| | | pow(a.h-b.h, 2)); |
| | | } |
| | | |
| | | dbox dintersect(box a, box b) |
| | | { |
| | | float w = overlap(a.x, a.w, b.x, b.w); |
| | |
| | | return dd; |
| | | } |
| | | |
| | | void do_nms(box *boxes, float **probs, int num_boxes, int classes, float thresh) |
| | | void do_nms(box *boxes, float **probs, int total, int classes, float thresh) |
| | | { |
| | | int i, j, k; |
| | | for(i = 0; i < num_boxes*num_boxes; ++i){ |
| | | for(i = 0; i < total; ++i){ |
| | | int any = 0; |
| | | for(k = 0; k < classes; ++k) any = any || (probs[i][k] > 0); |
| | | if(!any) { |
| | | continue; |
| | | } |
| | | for(j = i+1; j < num_boxes*num_boxes; ++j){ |
| | | for(j = i+1; j < total; ++j){ |
| | | if (box_iou(boxes[i], boxes[j]) > thresh){ |
| | | for(k = 0; k < classes; ++k){ |
| | | if (probs[i][k] < probs[j][k]) probs[i][k] = 0; |
| | |
| | | } dbox; |
| | | |
| | | float box_iou(box a, box b); |
| | | float box_rmse(box a, box b); |
| | | dbox diou(box a, box b); |
| | | void do_nms(box *boxes, float **probs, int num_boxes, int classes, float thresh); |
| | | void do_nms(box *boxes, float **probs, int total, int classes, float thresh); |
| | | box decode_box(box b, box anchor); |
| | | box encode_box(box b, box anchor); |
| | | |
| | |
| | | |
| | | void draw_coco(image im, float *pred, int side, char *label) |
| | | { |
| | | int classes = 81; |
| | | int classes = 1; |
| | | int elems = 4+classes; |
| | | int j; |
| | | int r, c; |
| | |
| | | for(c = 0; c < side; ++c){ |
| | | j = (r*side + c) * elems; |
| | | int class = max_index(pred+j, classes); |
| | | if (class == 0) continue; |
| | | if (pred[j+class] > 0.2){ |
| | | int width = pred[j+class]*5 + 1; |
| | | printf("%f %s\n", pred[j+class], coco_classes[class-1]); |
| | | printf("%f %s\n", pred[j+class], "object"); //coco_classes[class-1]); |
| | | float red = get_color(0,class,classes); |
| | | float green = get_color(1,class,classes); |
| | | float blue = get_color(2,class,classes); |
| | |
| | | j += classes; |
| | | |
| | | box predict = {pred[j+0], pred[j+1], pred[j+2], pred[j+3]}; |
| | | box anchor = {(c+.5)/side, (r+.5)/side, .5, .5}; |
| | | box decode = decode_box(predict, anchor); |
| | | predict.x = (predict.x+c)/side; |
| | | predict.y = (predict.y+r)/side; |
| | | |
| | | draw_bbox(im, decode, width, red, green, blue); |
| | | draw_bbox(im, predict, width, red, green, blue); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | void train_coco(char *cfgfile, char *weightfile) |
| | | { |
| | | char *train_images = "/home/pjreddie/data/coco/train.txt"; |
| | | //char *train_images = "/home/pjreddie/data/coco/train.txt"; |
| | | char *train_images = "/home/pjreddie/data/voc/test/train.txt"; |
| | | char *backup_directory = "/home/pjreddie/backup/"; |
| | | srand(time(0)); |
| | | data_seed = time(0); |
| | |
| | | int i = net.seen/imgs; |
| | | data train, buffer; |
| | | |
| | | int classes = 81; |
| | | int side = 7; |
| | | |
| | | layer l = net.layers[net.n - 1]; |
| | | |
| | | int side = l.side; |
| | | int classes = l.classes; |
| | | |
| | | list *plist = get_paths(train_images); |
| | | int N = plist->size; |
| | |
| | | printf("Loaded: %lf seconds\n", sec(clock()-time)); |
| | | |
| | | /* |
| | | image im = float_to_image(net.w, net.h, 3, train.X.vals[114]); |
| | | image im = float_to_image(net.w, net.h, 3, train.X.vals[113]); |
| | | image copy = copy_image(im); |
| | | draw_coco(copy, train.y.vals[114], 7, "truth"); |
| | | draw_coco(copy, train.y.vals[113], 7, "truth"); |
| | | cvWaitKey(0); |
| | | free_image(copy); |
| | | */ |
| | |
| | | avg_loss = avg_loss*.9 + loss*.1; |
| | | |
| | | printf("%d: %f, %f avg, %lf seconds, %d images\n", i, loss, avg_loss, sec(clock()-time), i*imgs); |
| | | if((i-1)*imgs <= 80*N && i*imgs > N*80){ |
| | | fprintf(stderr, "First stage done.\n"); |
| | | if((i-1)*imgs <= N && i*imgs > N){ |
| | | fprintf(stderr, "First stage done\n"); |
| | | net.learning_rate *= 10; |
| | | char buff[256]; |
| | | sprintf(buff, "%s/%s_first_stage.weights", backup_directory, base); |
| | | save_weights(net, buff); |
| | | return; |
| | | } |
| | | |
| | | if((i-1)*imgs <= 80*N && i*imgs > N*80){ |
| | | fprintf(stderr, "Second stage done.\n"); |
| | | char buff[256]; |
| | | sprintf(buff, "%s/%s_second_stage.weights", backup_directory, base); |
| | | save_weights(net, buff); |
| | | } |
| | | if(i%1000==0){ |
| | | char buff[256]; |
| | |
| | | save_weights(net, buff); |
| | | } |
| | | |
| | | void convert_cocos(float *predictions, int classes, int objectness, int background, int num_boxes, int w, int h, float thresh, float **probs, box *boxes) |
| | | void get_probs(float *predictions, int total, int classes, int inc, float **probs) |
| | | { |
| | | int i,j; |
| | | int per_box = 4+classes+(background || objectness); |
| | | for (i = 0; i < num_boxes*num_boxes; ++i){ |
| | | float scale = 1; |
| | | if(objectness) scale = 1-predictions[i*per_box]; |
| | | int offset = i*per_box+(background||objectness); |
| | | for (i = 0; i < total; ++i){ |
| | | int index = i*inc; |
| | | float scale = predictions[index]; |
| | | probs[i][0] = scale; |
| | | for(j = 0; j < classes; ++j){ |
| | | float prob = scale*predictions[offset+j]; |
| | | probs[i][j] = scale*predictions[index+j+1]; |
| | | } |
| | | } |
| | | } |
| | | void get_boxes(float *predictions, int n, int num_boxes, int per_box, box *boxes) |
| | | { |
| | | int i,j; |
| | | for (i = 0; i < num_boxes*num_boxes; ++i){ |
| | | for(j = 0; j < n; ++j){ |
| | | int index = i*n+j; |
| | | int offset = index*per_box; |
| | | int row = i / num_boxes; |
| | | int col = i % num_boxes; |
| | | boxes[index].x = (predictions[offset + 0] + col) / num_boxes; |
| | | boxes[index].y = (predictions[offset + 1] + row) / num_boxes; |
| | | boxes[index].w = predictions[offset + 2]; |
| | | boxes[index].h = predictions[offset + 3]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | void convert_cocos(float *predictions, int classes, int num_boxes, int num, int w, int h, float thresh, float **probs, box *boxes) |
| | | { |
| | | int i,j; |
| | | int per_box = 4+classes; |
| | | for (i = 0; i < num_boxes*num_boxes*num; ++i){ |
| | | int offset = i*per_box; |
| | | for(j = 0; j < classes; ++j){ |
| | | float prob = predictions[offset+j]; |
| | | probs[i][j] = (prob > thresh) ? prob : 0; |
| | | } |
| | | int row = i / num_boxes; |
| | | int col = i % num_boxes; |
| | | offset += classes; |
| | | boxes[i].x = (predictions[offset + 0] + col) / num_boxes * w; |
| | | boxes[i].y = (predictions[offset + 1] + row) / num_boxes * h; |
| | | boxes[i].w = pow(predictions[offset + 2], 2) * w; |
| | | boxes[i].h = pow(predictions[offset + 3], 2) * h; |
| | | boxes[i].x = (predictions[offset + 0] + col) / num_boxes; |
| | | boxes[i].y = (predictions[offset + 1] + row) / num_boxes; |
| | | boxes[i].w = predictions[offset + 2]; |
| | | boxes[i].h = predictions[offset + 3]; |
| | | } |
| | | } |
| | | |
| | |
| | | return atoi(p+1); |
| | | } |
| | | |
| | | void validate_recall(char *cfgfile, char *weightfile) |
| | | { |
| | | network net = parse_network_cfg(cfgfile); |
| | | if(weightfile){ |
| | | load_weights(&net, weightfile); |
| | | } |
| | | set_batch_network(&net, 1); |
| | | fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); |
| | | srand(time(0)); |
| | | |
| | | char *val_images = "/home/pjreddie/data/voc/test/2007_test.txt"; |
| | | list *plist = get_paths(val_images); |
| | | char **paths = (char **)list_to_array(plist); |
| | | |
| | | layer l = net.layers[net.n - 1]; |
| | | |
| | | int num_boxes = l.side; |
| | | int num = l.n; |
| | | int classes = l.classes; |
| | | |
| | | int j; |
| | | |
| | | box *boxes = calloc(num_boxes*num_boxes*num, sizeof(box)); |
| | | float **probs = calloc(num_boxes*num_boxes*num, sizeof(float *)); |
| | | for(j = 0; j < num_boxes*num_boxes*num; ++j) probs[j] = calloc(classes+1, sizeof(float *)); |
| | | |
| | | int N = plist->size; |
| | | int i=0; |
| | | int k; |
| | | |
| | | float iou_thresh = .5; |
| | | float thresh = .1; |
| | | int total = 0; |
| | | int correct = 0; |
| | | float avg_iou = 0; |
| | | int nms = 0; |
| | | int proposals = 0; |
| | | |
| | | for (i = 0; i < N; ++i) { |
| | | char *path = paths[i]; |
| | | image orig = load_image_color(path, 0, 0); |
| | | image resized = resize_image(orig, net.w, net.h); |
| | | |
| | | float *X = resized.data; |
| | | float *predictions = network_predict(net, X); |
| | | get_boxes(predictions+1+classes, num, num_boxes, 5+classes, boxes); |
| | | get_probs(predictions, num*num_boxes*num_boxes, classes, 5+classes, probs); |
| | | if (nms) do_nms(boxes, probs, num*num_boxes*num_boxes, (classes>0) ? classes : 1, iou_thresh); |
| | | |
| | | char *labelpath = find_replace(path, "images", "labels"); |
| | | labelpath = find_replace(labelpath, "JPEGImages", "labels"); |
| | | labelpath = find_replace(labelpath, ".jpg", ".txt"); |
| | | labelpath = find_replace(labelpath, ".JPEG", ".txt"); |
| | | |
| | | int num_labels = 0; |
| | | box_label *truth = read_boxes(labelpath, &num_labels); |
| | | for(k = 0; k < num_boxes*num_boxes*num; ++k){ |
| | | if(probs[k][0] > thresh){ |
| | | ++proposals; |
| | | } |
| | | } |
| | | for (j = 0; j < num_labels; ++j) { |
| | | ++total; |
| | | box t = {truth[j].x, truth[j].y, truth[j].w, truth[j].h}; |
| | | float best_iou = 0; |
| | | for(k = 0; k < num_boxes*num_boxes*num; ++k){ |
| | | float iou = box_iou(boxes[k], t); |
| | | if(probs[k][0] > thresh && iou > best_iou){ |
| | | best_iou = iou; |
| | | } |
| | | } |
| | | avg_iou += best_iou; |
| | | if(best_iou > iou_thresh){ |
| | | ++correct; |
| | | } |
| | | } |
| | | free(truth); |
| | | free_image(orig); |
| | | free_image(resized); |
| | | fprintf(stderr, "%5d %5d %5d\tRPs/Img: %.2f\tIOU: %.2f%%\tRecall:%.2f%%\n", i, correct, total, (float)proposals/(i+1), avg_iou*100/total, 100.*correct/total); |
| | | } |
| | | } |
| | | |
| | | void extract_boxes(char *cfgfile, char *weightfile) |
| | | { |
| | | network net = parse_network_cfg(cfgfile); |
| | | if(weightfile){ |
| | | load_weights(&net, weightfile); |
| | | } |
| | | set_batch_network(&net, 1); |
| | | fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); |
| | | srand(time(0)); |
| | | |
| | | char *val_images = "/home/pjreddie/data/voc/test/train.txt"; |
| | | list *plist = get_paths(val_images); |
| | | char **paths = (char **)list_to_array(plist); |
| | | |
| | | layer l = net.layers[net.n - 1]; |
| | | |
| | | int num_boxes = l.side; |
| | | int num = l.n; |
| | | int classes = l.classes; |
| | | |
| | | int j; |
| | | |
| | | box *boxes = calloc(num_boxes*num_boxes*num, sizeof(box)); |
| | | float **probs = calloc(num_boxes*num_boxes*num, sizeof(float *)); |
| | | for(j = 0; j < num_boxes*num_boxes*num; ++j) probs[j] = calloc(classes+1, sizeof(float *)); |
| | | |
| | | int N = plist->size; |
| | | int i=0; |
| | | int k; |
| | | |
| | | int count = 0; |
| | | float iou_thresh = .1; |
| | | |
| | | for (i = 0; i < N; ++i) { |
| | | fprintf(stderr, "%5d %5d\n", i, count); |
| | | char *path = paths[i]; |
| | | image orig = load_image_color(path, 0, 0); |
| | | image resized = resize_image(orig, net.w, net.h); |
| | | |
| | | float *X = resized.data; |
| | | float *predictions = network_predict(net, X); |
| | | get_boxes(predictions+1+classes, num, num_boxes, 5+classes, boxes); |
| | | get_probs(predictions, num*num_boxes*num_boxes, classes, 5+classes, probs); |
| | | |
| | | char *labelpath = find_replace(path, "images", "labels"); |
| | | labelpath = find_replace(labelpath, "JPEGImages", "labels"); |
| | | labelpath = find_replace(labelpath, ".jpg", ".txt"); |
| | | labelpath = find_replace(labelpath, ".JPEG", ".txt"); |
| | | |
| | | int num_labels = 0; |
| | | box_label *truth = read_boxes(labelpath, &num_labels); |
| | | FILE *label = stdin; |
| | | for(k = 0; k < num_boxes*num_boxes*num; ++k){ |
| | | int overlaps = 0; |
| | | for (j = 0; j < num_labels; ++j) { |
| | | box t = {truth[j].x, truth[j].y, truth[j].w, truth[j].h}; |
| | | float iou = box_iou(boxes[k], t); |
| | | if (iou > iou_thresh){ |
| | | if (!overlaps) { |
| | | char buff[256]; |
| | | sprintf(buff, "/home/pjreddie/extracted/labels/%d.txt", count); |
| | | label = fopen(buff, "w"); |
| | | overlaps = 1; |
| | | } |
| | | fprintf(label, "%d %f\n", truth[j].id, iou); |
| | | } |
| | | } |
| | | if (overlaps) { |
| | | char buff[256]; |
| | | sprintf(buff, "/home/pjreddie/extracted/imgs/%d", count++); |
| | | int dx = (boxes[k].x - boxes[k].w/2) * orig.w; |
| | | int dy = (boxes[k].y - boxes[k].h/2) * orig.h; |
| | | int w = boxes[k].w * orig.w; |
| | | int h = boxes[k].h * orig.h; |
| | | image cropped = crop_image(orig, dx, dy, w, h); |
| | | image sized = resize_image(cropped, 224, 224); |
| | | #ifdef OPENCV |
| | | save_image_jpg(sized, buff); |
| | | #endif |
| | | free_image(sized); |
| | | free_image(cropped); |
| | | fclose(label); |
| | | } |
| | | } |
| | | free(truth); |
| | | free_image(orig); |
| | | free_image(resized); |
| | | } |
| | | } |
| | | |
| | | void validate_coco(char *cfgfile, char *weightfile) |
| | | { |
| | | network net = parse_network_cfg(cfgfile); |
| | |
| | | load_weights(&net, weightfile); |
| | | } |
| | | set_batch_network(&net, 1); |
| | | detection_layer layer = get_network_detection_layer(net); |
| | | fprintf(stderr, "Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); |
| | | srand(time(0)); |
| | | |
| | |
| | | list *plist = get_paths("data/coco_val_5k.list"); |
| | | char **paths = (char **)list_to_array(plist); |
| | | |
| | | int classes = layer.classes; |
| | | int objectness = layer.objectness; |
| | | int background = layer.background; |
| | | int num_boxes = sqrt(get_detection_layer_locations(layer)); |
| | | int num_boxes = 9; |
| | | int num = 4; |
| | | int classes = 1; |
| | | |
| | | int j; |
| | | char buff[1024]; |
| | |
| | | FILE *fp = fopen(buff, "w"); |
| | | fprintf(fp, "[\n"); |
| | | |
| | | box *boxes = calloc(num_boxes*num_boxes, sizeof(box)); |
| | | float **probs = calloc(num_boxes*num_boxes, sizeof(float *)); |
| | | for(j = 0; j < num_boxes*num_boxes; ++j) probs[j] = calloc(classes, sizeof(float *)); |
| | | box *boxes = calloc(num_boxes*num_boxes*num, sizeof(box)); |
| | | float **probs = calloc(num_boxes*num_boxes*num, sizeof(float *)); |
| | | for(j = 0; j < num_boxes*num_boxes*num; ++j) probs[j] = calloc(classes, sizeof(float *)); |
| | | |
| | | int m = plist->size; |
| | | int i=0; |
| | |
| | | float *predictions = network_predict(net, X); |
| | | int w = val[t].w; |
| | | int h = val[t].h; |
| | | convert_cocos(predictions, classes, objectness, background, num_boxes, w, h, thresh, probs, boxes); |
| | | convert_cocos(predictions, classes, num_boxes, num, w, h, thresh, probs, boxes); |
| | | if (nms) do_nms(boxes, probs, num_boxes, classes, iou_thresh); |
| | | print_cocos(fp, image_id, boxes, probs, num_boxes, classes, w, h); |
| | | free_image(val[t]); |
| | |
| | | char *filename = (argc > 5) ? argv[5]: 0; |
| | | if(0==strcmp(argv[2], "test")) test_coco(cfg, weights, filename); |
| | | else if(0==strcmp(argv[2], "train")) train_coco(cfg, weights); |
| | | else if(0==strcmp(argv[2], "valid")) validate_coco(cfg, weights); |
| | | else if(0==strcmp(argv[2], "extract")) extract_boxes(cfg, weights); |
| | | else if(0==strcmp(argv[2], "valid")) validate_recall(cfg, weights); |
| | | } |
| | |
| | | cuda_free(l->delta_gpu); |
| | | cuda_free(l->output_gpu); |
| | | |
| | | l->col_image_gpu = cuda_make_array(0, out_h*out_w*l->size*l->size*l->c); |
| | | l->delta_gpu = cuda_make_array(0, l->batch*out_h*out_w*l->n); |
| | | l->output_gpu = cuda_make_array(0, l->batch*out_h*out_w*l->n); |
| | | l->col_image_gpu = cuda_make_array(l->col_image, out_h*out_w*l->size*l->size*l->c); |
| | | l->delta_gpu = cuda_make_array(l->delta, l->batch*out_h*out_w*l->n); |
| | | l->output_gpu = cuda_make_array(l->output, l->batch*out_h*out_w*l->n); |
| | | #endif |
| | | } |
| | | |
| | |
| | | int i; |
| | | for(i = 0; i < l.n; ++i){ |
| | | filters[i] = copy_image(get_convolutional_filter(l, i)); |
| | | normalize_image(filters[i]); |
| | | //normalize_image(filters[i]); |
| | | } |
| | | return filters; |
| | | } |
| | |
| | | l.output = calloc(crop_width*crop_height * c*batch, sizeof(float)); |
| | | #ifdef GPU |
| | | l.output_gpu = cuda_make_array(l.output, crop_width*crop_height*c*batch); |
| | | l.rand_gpu = cuda_make_array(0, l.batch*8); |
| | | l.rand_gpu = cuda_make_array(0, l.batch*8); |
| | | #endif |
| | | return l; |
| | | } |
| | |
| | | |
| | | void check_error(cudaError_t status) |
| | | { |
| | | cudaError_t status2 = cudaGetLastError(); |
| | | if (status != cudaSuccess) |
| | | { |
| | | const char *s = cudaGetErrorString(status); |
| | |
| | | snprintf(buffer, 256, "CUDA Error: %s", s); |
| | | error(buffer); |
| | | } |
| | | if (status2 != cudaSuccess) |
| | | { |
| | | const char *s = cudaGetErrorString(status); |
| | | char buffer[256]; |
| | | printf("CUDA Error Prev: %s\n", s); |
| | | assert(0); |
| | | snprintf(buffer, 256, "CUDA Error Prev: %s", s); |
| | | error(buffer); |
| | | } |
| | | } |
| | | |
| | | dim3 cuda_gridsize(size_t n){ |
| | |
| | | save_weights_upto(net, outfile, max); |
| | | } |
| | | |
| | | void stacked(char *cfgfile, char *weightfile, char *outfile) |
| | | { |
| | | gpu_index = -1; |
| | | network net = parse_network_cfg(cfgfile); |
| | | if(weightfile){ |
| | | load_weights(&net, weightfile); |
| | | } |
| | | net.seen = 0; |
| | | save_weights_double(net, outfile); |
| | | } |
| | | |
| | | #include "convolutional_layer.h" |
| | | void rescale_net(char *cfgfile, char *weightfile, char *outfile) |
| | | { |
| | |
| | | gpu_index = -1; |
| | | #else |
| | | if(gpu_index >= 0){ |
| | | cudaSetDevice(gpu_index); |
| | | cudaError_t status = cudaSetDevice(gpu_index); |
| | | check_error(status); |
| | | } |
| | | #endif |
| | | |
| | |
| | | rescale_net(argv[2], argv[3], argv[4]); |
| | | } else if (0 == strcmp(argv[1], "partial")){ |
| | | partial(argv[2], argv[3], argv[4], atoi(argv[5])); |
| | | } else if (0 == strcmp(argv[1], "stacked")){ |
| | | stacked(argv[2], argv[3], argv[4]); |
| | | } else if (0 == strcmp(argv[1], "visualize")){ |
| | | visualize(argv[2], (argc > 3) ? argv[3] : 0); |
| | | } else if (0 == strcmp(argv[1], "imtest")){ |
| | |
| | | #include "data.h" |
| | | #include "utils.h" |
| | | #include "image.h" |
| | | #include "cuda.h" |
| | | |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | |
| | | return X; |
| | | } |
| | | |
| | | typedef struct{ |
| | | int id; |
| | | float x,y,w,h; |
| | | float left, right, top, bottom; |
| | | } box_label; |
| | | |
| | | box_label *read_boxes(char *filename, int *n) |
| | | { |
| | | box_label *boxes = calloc(1, sizeof(box_label)); |
| | |
| | | void fill_truth_region(char *path, float *truth, int classes, int num_boxes, int flip, float dx, float dy, float sx, float sy) |
| | | { |
| | | char *labelpath = find_replace(path, "images", "labels"); |
| | | labelpath = find_replace(labelpath, "JPEGImages", "labels"); |
| | | labelpath = find_replace(labelpath, ".jpg", ".txt"); |
| | | labelpath = find_replace(labelpath, ".JPEG", ".txt"); |
| | | int count = 0; |
| | |
| | | int id; |
| | | int i; |
| | | |
| | | for(i = 0; i < num_boxes*num_boxes*(4+classes); i += 4+classes){ |
| | | truth[i] = 1; |
| | | } |
| | | |
| | | for(i = 0; i < count; ++i){ |
| | | x = boxes[i].x; |
| | | y = boxes[i].y; |
| | | w = boxes[i].w; |
| | | h = boxes[i].h; |
| | | for (i = 0; i < count; ++i) { |
| | | x = boxes[i].x; |
| | | y = boxes[i].y; |
| | | w = boxes[i].w; |
| | | h = boxes[i].h; |
| | | id = boxes[i].id; |
| | | |
| | | if (x <= 0 || x >= 1 || y <= 0 || y >= 1) continue; |
| | | if (w < .01 || h < .01) continue; |
| | | |
| | | int col = (int)(x*num_boxes); |
| | | int row = (int)(y*num_boxes); |
| | | |
| | | float xa = (col+.5)/num_boxes; |
| | | float ya = (row+.5)/num_boxes; |
| | | float wa = .5; |
| | | float ha = .5; |
| | | x = x*num_boxes - col; |
| | | y = y*num_boxes - row; |
| | | |
| | | float tx = (x - xa) / wa; |
| | | float ty = (y - ya) / ha; |
| | | float tw = log2(w/wa); |
| | | float th = log2(h/ha); |
| | | |
| | | int index = (col+row*num_boxes)*(4+classes); |
| | | if(!truth[index]) continue; |
| | | truth[index] = 0; |
| | | truth[index+id+1] = 1; |
| | | int index = (col+row*num_boxes)*(5+classes); |
| | | if (truth[index]) continue; |
| | | truth[index++] = 1; |
| | | if (classes) truth[index+id] = 1; |
| | | index += classes; |
| | | truth[index++] = tx; |
| | | truth[index++] = ty; |
| | | truth[index++] = tw; |
| | | truth[index++] = th; |
| | | truth[index++] = x; |
| | | truth[index++] = y; |
| | | truth[index++] = w; |
| | | truth[index++] = h; |
| | | } |
| | | free(boxes); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | data load_data_region(int n, char **paths, int m, int classes, int w, int h, int num_boxes) |
| | | data load_data_region(int n, char **paths, int m, int w, int h, int size, int classes) |
| | | { |
| | | char **random_paths = get_random_paths(paths, n, m); |
| | | int i; |
| | |
| | | d.X.vals = calloc(d.X.rows, sizeof(float*)); |
| | | d.X.cols = h*w*3; |
| | | |
| | | int k = num_boxes*num_boxes*(4+classes); |
| | | int k = size*size*(5+classes); |
| | | d.y = make_matrix(n, k); |
| | | for(i = 0; i < n; ++i){ |
| | | image orig = load_image_color(random_paths[i], 0, 0); |
| | |
| | | if(flip) flip_image(sized); |
| | | d.X.vals[i] = sized.data; |
| | | |
| | | fill_truth_region(random_paths[i], d.y.vals[i], classes, num_boxes, flip, dx, dy, 1./sx, 1./sy); |
| | | fill_truth_region(random_paths[i], d.y.vals[i], classes, size, flip, dx, dy, 1./sx, 1./sy); |
| | | |
| | | free_image(orig); |
| | | free_image(cropped); |
| | |
| | | return d; |
| | | } |
| | | |
| | | data load_data_compare(int n, char **paths, int m, int classes, int w, int h) |
| | | { |
| | | char **random_paths = get_random_paths(paths, 2*n, m); |
| | | int i; |
| | | data d; |
| | | d.shallow = 0; |
| | | |
| | | d.X.rows = n; |
| | | d.X.vals = calloc(d.X.rows, sizeof(float*)); |
| | | d.X.cols = h*w*6; |
| | | |
| | | int k = 2*(classes); |
| | | d.y = make_matrix(n, k); |
| | | for(i = 0; i < n; ++i){ |
| | | image im1 = load_image_color(random_paths[i*2], w, h); |
| | | image im2 = load_image_color(random_paths[i*2+1], w, h); |
| | | |
| | | d.X.vals[i] = calloc(d.X.cols, sizeof(float)); |
| | | memcpy(d.X.vals[i], im1.data, h*w*3*sizeof(float)); |
| | | memcpy(d.X.vals[i] + h*w*3, im2.data, h*w*3*sizeof(float)); |
| | | |
| | | //char *imlabel1 = find_replace(random_paths[i*2], "imgs", "labels"); |
| | | //char *imlabel2 = find_replace(random_paths[i*2+1], "imgs", "labels"); |
| | | |
| | | free_image(im1); |
| | | free_image(im2); |
| | | } |
| | | free(random_paths); |
| | | return d; |
| | | } |
| | | |
| | | data load_data_detection(int n, char **paths, int m, int classes, int w, int h, int num_boxes, int background) |
| | | { |
| | | char **random_paths = get_random_paths(paths, n, m); |
| | |
| | | |
| | | void *load_thread(void *ptr) |
| | | { |
| | | |
| | | #ifdef GPU |
| | | cudaError_t status = cudaSetDevice(gpu_index); |
| | | check_error(status); |
| | | #endif |
| | | |
| | | printf("Loading data: %d\n", rand_r(&data_seed)); |
| | | load_args a = *(struct load_args*)ptr; |
| | | if (a.type == CLASSIFICATION_DATA){ |
| | |
| | | } else if (a.type == DETECTION_DATA){ |
| | | *a.d = load_data_detection(a.n, a.paths, a.m, a.classes, a.w, a.h, a.num_boxes, a.background); |
| | | } else if (a.type == REGION_DATA){ |
| | | *a.d = load_data_region(a.n, a.paths, a.m, a.classes, a.w, a.h, a.num_boxes); |
| | | *a.d = load_data_region(a.n, a.paths, a.m, a.w, a.h, a.num_boxes, a.classes); |
| | | } else if (a.type == IMAGE_DATA){ |
| | | *(a.im) = load_image_color(a.path, 0, 0); |
| | | *(a.resized) = resize_image(*(a.im), a.w, a.h); |
| | |
| | | int n; |
| | | int m; |
| | | char **labels; |
| | | int k; |
| | | int h; |
| | | int w; |
| | | int nh; |
| | |
| | | data_type type; |
| | | } load_args; |
| | | |
| | | typedef struct{ |
| | | int id; |
| | | float x,y,w,h; |
| | | float left, right, top, bottom; |
| | | } box_label; |
| | | |
| | | void free_data(data d); |
| | | |
| | | pthread_t load_data_in_thread(load_args args); |
| | |
| | | data load_data(char **paths, int n, int m, char **labels, int k, int w, int h); |
| | | data load_data_detection(int n, char **paths, int m, int classes, int w, int h, int num_boxes, int background); |
| | | |
| | | box_label *read_boxes(char *filename, int *n); |
| | | data load_cifar10_data(char *filename); |
| | | data load_all_cifar10(); |
| | | |
| | |
| | | l.output = calloc(batch*outputs, sizeof(float)); |
| | | l.delta = calloc(batch*outputs, sizeof(float)); |
| | | #ifdef GPU |
| | | l.output_gpu = cuda_make_array(0, batch*outputs); |
| | | l.delta_gpu = cuda_make_array(0, batch*outputs); |
| | | l.output_gpu = cuda_make_array(l.output, batch*outputs); |
| | | l.delta_gpu = cuda_make_array(l.delta, batch*outputs); |
| | | #endif |
| | | |
| | | fprintf(stderr, "Detection Layer\n"); |
| | |
| | | if(!success) fprintf(stderr, "Failed to write image %s\n", buff); |
| | | } |
| | | |
| | | /* |
| | | void save_image_cv(image p, char *name) |
| | | { |
| | | int x,y,k; |
| | | image copy = copy_image(p); |
| | | //normalize_image(copy); |
| | | #ifdef OPENCV |
| | | void save_image_jpg(image p, char *name) |
| | | { |
| | | int x,y,k; |
| | | |
| | | char buff[256]; |
| | | //sprintf(buff, "%s (%d)", name, windows); |
| | | sprintf(buff, "%s.png", name); |
| | | char buff[256]; |
| | | sprintf(buff, "%s.jpg", name); |
| | | |
| | | IplImage *disp = cvCreateImage(cvSize(p.w,p.h), IPL_DEPTH_8U, p.c); |
| | | int step = disp->widthStep; |
| | | for(y = 0; y < p.h; ++y){ |
| | | for(x = 0; x < p.w; ++x){ |
| | | for(k= 0; k < p.c; ++k){ |
| | | disp->imageData[y*step + x*p.c + k] = (unsigned char)(get_pixel(copy,x,y,k)*255); |
| | | IplImage *disp = cvCreateImage(cvSize(p.w,p.h), IPL_DEPTH_8U, p.c); |
| | | int step = disp->widthStep; |
| | | for(y = 0; y < p.h; ++y){ |
| | | for(x = 0; x < p.w; ++x){ |
| | | for(k= 0; k < p.c; ++k){ |
| | | disp->imageData[y*step + x*p.c + k] = (unsigned char)(get_pixel(p,x,y,k)*255); |
| | | } |
| | | } |
| | | } |
| | | cvSaveImage(buff, disp,0); |
| | | cvReleaseImage(&disp); |
| | | } |
| | | } |
| | | } |
| | | free_image(copy); |
| | | cvSaveImage(buff, disp,0); |
| | | cvReleaseImage(&disp); |
| | | } |
| | | */ |
| | | #endif |
| | | |
| | | void show_image_layers(image p, char *name) |
| | | { |
| | |
| | | void show_images(image *ims, int n, char *window) |
| | | { |
| | | image m = collapse_images_vert(ims, n); |
| | | /* |
| | | int w = 448; |
| | | int h = ((float)m.h/m.w) * 448; |
| | | if(h > 896){ |
| | |
| | | w = ((float)m.w/m.h) * 896; |
| | | } |
| | | image sized = resize_image(m, w, h); |
| | | */ |
| | | normalize_image(m); |
| | | image sized = resize_image(m, m.w, m.h); |
| | | save_image(sized, window); |
| | | show_image(sized, window); |
| | | free_image(sized); |
| | |
| | | void show_image_layers(image p, char *name); |
| | | void show_image_collapsed(image p, char *name); |
| | | |
| | | #ifdef OPENCV |
| | | void save_image_jpg(image p, char *name); |
| | | #endif |
| | | |
| | | void print_image(image m); |
| | | |
| | | image make_image(int w, int h, int c); |
| | |
| | | printf("Learning Rate: %g, Momentum: %g, Decay: %g\n", net.learning_rate, net.momentum, net.decay); |
| | | //net.seen=0; |
| | | int imgs = 1024; |
| | | int i = net.seen/imgs; |
| | | char **labels = get_labels("data/inet.labels.list"); |
| | | list *plist = get_paths("/data/imagenet/cls.train.list"); |
| | | char **paths = (char **)list_to_array(plist); |
| | | printf("%d\n", plist->size); |
| | | int N = plist->size; |
| | | clock_t time; |
| | | pthread_t load_thread; |
| | | data train; |
| | |
| | | args.paths = paths; |
| | | args.classes = 1000; |
| | | args.n = imgs; |
| | | args.m = plist->size; |
| | | args.m = N; |
| | | args.labels = labels; |
| | | args.d = &buffer; |
| | | args.type = CLASSIFICATION_DATA; |
| | | |
| | | load_thread = load_data_in_thread(args); |
| | | int epoch = net.seen/N; |
| | | while(1){ |
| | | ++i; |
| | | time=clock(); |
| | | pthread_join(load_thread, 0); |
| | | train = buffer; |
| | |
| | | net.seen += imgs; |
| | | if(avg_loss == -1) avg_loss = loss; |
| | | avg_loss = avg_loss*.9 + loss*.1; |
| | | printf("%d: %f, %f avg, %lf seconds, %d images\n", i, loss, avg_loss, sec(clock()-time), net.seen); |
| | | printf("%.3f: %f, %f avg, %lf seconds, %d images\n", (float)net.seen/N, loss, avg_loss, sec(clock()-time), net.seen); |
| | | free_data(train); |
| | | if((i % 30000) == 0) net.learning_rate *= .1; |
| | | if(i%1000==0){ |
| | | if(net.seen/N > epoch){ |
| | | epoch = net.seen/N; |
| | | char buff[256]; |
| | | sprintf(buff, "%s/%s_%d.weights",backup_directory,base, i); |
| | | sprintf(buff, "%s/%s_%d.weights",backup_directory,base, epoch); |
| | | save_weights(net, buff); |
| | | if(epoch%22 == 0) net.learning_rate *= .1; |
| | | } |
| | | } |
| | | pthread_join(load_thread, 0); |
| | | free_data(buffer); |
| | | free_network(net); |
| | | free_ptrs((void**)labels, 1000); |
| | | free_ptrs((void**)paths, plist->size); |
| | | free_list(plist); |
| | | free(base); |
| | | } |
| | | |
| | | void validate_imagenet(char *filename, char *weightfile) |
| New file |
| | |
| | | #include "layer.h" |
| | | #include "cuda.h" |
| | | #include <stdlib.h> |
| | | |
| | | void free_layer(layer l) |
| | | { |
| | | if(l.type == DROPOUT){ |
| | | if(l.rand) free(l.rand); |
| | | #ifdef GPU |
| | | if(l.rand_gpu) cuda_free(l.rand_gpu); |
| | | #endif |
| | | return; |
| | | } |
| | | if(l.indexes) free(l.indexes); |
| | | if(l.rand) free(l.rand); |
| | | if(l.cost) free(l.cost); |
| | | if(l.filters) free(l.filters); |
| | | if(l.filter_updates) free(l.filter_updates); |
| | | if(l.biases) free(l.biases); |
| | | if(l.bias_updates) free(l.bias_updates); |
| | | if(l.weights) free(l.weights); |
| | | if(l.weight_updates) free(l.weight_updates); |
| | | if(l.col_image) free(l.col_image); |
| | | if(l.input_layers) free(l.input_layers); |
| | | if(l.input_sizes) free(l.input_sizes); |
| | | if(l.delta) free(l.delta); |
| | | if(l.output) free(l.output); |
| | | if(l.squared) free(l.squared); |
| | | if(l.norms) free(l.norms); |
| | | |
| | | #ifdef GPU |
| | | if(l.indexes_gpu) cuda_free((float *)l.indexes_gpu); |
| | | if(l.filters_gpu) cuda_free(l.filters_gpu); |
| | | if(l.filter_updates_gpu) cuda_free(l.filter_updates_gpu); |
| | | if(l.col_image_gpu) cuda_free(l.col_image_gpu); |
| | | if(l.weights_gpu) cuda_free(l.weights_gpu); |
| | | if(l.biases_gpu) cuda_free(l.biases_gpu); |
| | | if(l.weight_updates_gpu) cuda_free(l.weight_updates_gpu); |
| | | if(l.bias_updates_gpu) cuda_free(l.bias_updates_gpu); |
| | | if(l.output_gpu) cuda_free(l.output_gpu); |
| | | if(l.delta_gpu) cuda_free(l.delta_gpu); |
| | | if(l.rand_gpu) cuda_free(l.rand_gpu); |
| | | if(l.squared_gpu) cuda_free(l.squared_gpu); |
| | | if(l.norms_gpu) cuda_free(l.norms_gpu); |
| | | #endif |
| | | } |
| | |
| | | int n; |
| | | int groups; |
| | | int size; |
| | | int side; |
| | | int stride; |
| | | int pad; |
| | | int crop_width; |
| | |
| | | |
| | | float probability; |
| | | float scale; |
| | | |
| | | int *indexes; |
| | | float *rand; |
| | | float *cost; |
| | |
| | | #endif |
| | | } layer; |
| | | |
| | | void free_layer(layer); |
| | | |
| | | #endif |
| | |
| | | cuda_free(l->output_gpu); |
| | | cuda_free(l->delta_gpu); |
| | | l->indexes_gpu = cuda_make_int_array(output_size); |
| | | l->output_gpu = cuda_make_array(0, output_size); |
| | | l->delta_gpu = cuda_make_array(0, output_size); |
| | | l->output_gpu = cuda_make_array(l->output, output_size); |
| | | l->delta_gpu = cuda_make_array(l->delta, output_size); |
| | | #endif |
| | | } |
| | | |
| | |
| | | return acc; |
| | | } |
| | | |
| | | |
| | | void free_network(network net) |
| | | { |
| | | int i; |
| | | for(i = 0; i < net.n; ++i){ |
| | | free_layer(net.layers[i]); |
| | | } |
| | | free(net.layers); |
| | | #ifdef GPU |
| | | if(*net.input_gpu) cuda_free(*net.input_gpu); |
| | | if(*net.truth_gpu) cuda_free(*net.truth_gpu); |
| | | if(net.input_gpu) free(net.input_gpu); |
| | | if(net.truth_gpu) free(net.truth_gpu); |
| | | #endif |
| | | } |
| | |
| | | void backward_network_gpu(network net, network_state state); |
| | | #endif |
| | | |
| | | void free_network(network net); |
| | | void compare_networks(network n1, network n2, data d); |
| | | char *get_layer_string(LAYER_TYPE a); |
| | | |
| | |
| | | extern "C" { |
| | | #include <stdio.h> |
| | | #include <time.h> |
| | | #include <assert.h> |
| | | |
| | | #include "network.h" |
| | | #include "image.h" |
| | |
| | | |
| | | #ifdef GPU |
| | | state.input = cuda_make_array(im.data, im.w*im.h*im.c); |
| | | state.delta = cuda_make_array(0, im.w*im.h*im.c); |
| | | state.delta = cuda_make_array(im.data, im.w*im.h*im.c); |
| | | |
| | | forward_network_gpu(*net, state); |
| | | copy_ongpu(last.outputs, last.output_gpu, 1, last.delta_gpu, 1); |
| | |
| | | layer.inputs = w*h*c; |
| | | layer.outputs = layer.inputs; |
| | | #ifdef GPU |
| | | layer.output_gpu = cuda_make_array(0, h * w * c * batch); |
| | | layer.delta_gpu = cuda_make_array(0, h * w * c * batch); |
| | | layer.squared_gpu = cuda_make_array(0, h * w * c * batch); |
| | | layer.norms_gpu = cuda_make_array(0, h * w * c * batch); |
| | | layer.output_gpu = cuda_make_array(layer.output, h * w * c * batch); |
| | | layer.delta_gpu = cuda_make_array(layer.delta, h * w * c * batch); |
| | | layer.squared_gpu = cuda_make_array(layer.squared, h * w * c * batch); |
| | | layer.norms_gpu = cuda_make_array(layer.norms, h * w * c * batch); |
| | | #endif |
| | | return layer; |
| | | } |
| | |
| | | cuda_free(layer->delta_gpu); |
| | | cuda_free(layer->squared_gpu); |
| | | cuda_free(layer->norms_gpu); |
| | | layer->output_gpu = cuda_make_array(0, h * w * c * batch); |
| | | layer->delta_gpu = cuda_make_array(0, h * w * c * batch); |
| | | layer->squared_gpu = cuda_make_array(0, h * w * c * batch); |
| | | layer->norms_gpu = cuda_make_array(0, h * w * c * batch); |
| | | layer->output_gpu = cuda_make_array(layer->output, h * w * c * batch); |
| | | layer->delta_gpu = cuda_make_array(layer->delta, h * w * c * batch); |
| | | layer->squared_gpu = cuda_make_array(layer->squared, h * w * c * batch); |
| | | layer->norms_gpu = cuda_make_array(layer->norms, h * w * c * batch); |
| | | #endif |
| | | } |
| | | |
| | |
| | | int classes = option_find_int(options, "classes", 1); |
| | | int rescore = option_find_int(options, "rescore", 0); |
| | | int num = option_find_int(options, "num", 1); |
| | | region_layer layer = make_region_layer(params.batch, params.inputs, num, classes, coords, rescore); |
| | | int side = option_find_int(options, "side", 7); |
| | | region_layer layer = make_region_layer(params.batch, params.inputs, num, side, classes, coords, rescore); |
| | | return layer; |
| | | } |
| | | |
| | |
| | | |
| | | n = n->next; |
| | | int count = 0; |
| | | free_section(s); |
| | | while(n){ |
| | | fprintf(stderr, "%d: ", count); |
| | | s = (section *)n->val; |
| | |
| | | return sections; |
| | | } |
| | | |
| | | void save_weights_double(network net, char *filename) |
| | | { |
| | | fprintf(stderr, "Saving doubled weights to %s\n", filename); |
| | | FILE *fp = fopen(filename, "w"); |
| | | if(!fp) file_error(filename); |
| | | |
| | | fwrite(&net.learning_rate, sizeof(float), 1, fp); |
| | | fwrite(&net.momentum, sizeof(float), 1, fp); |
| | | fwrite(&net.decay, sizeof(float), 1, fp); |
| | | fwrite(&net.seen, sizeof(int), 1, fp); |
| | | |
| | | int i,j,k; |
| | | for(i = 0; i < net.n; ++i){ |
| | | layer l = net.layers[i]; |
| | | if(l.type == CONVOLUTIONAL){ |
| | | #ifdef GPU |
| | | if(gpu_index >= 0){ |
| | | pull_convolutional_layer(l); |
| | | } |
| | | #endif |
| | | float zero = 0; |
| | | fwrite(l.biases, sizeof(float), l.n, fp); |
| | | fwrite(l.biases, sizeof(float), l.n, fp); |
| | | |
| | | for (j = 0; j < l.n; ++j){ |
| | | int index = j*l.c*l.size*l.size; |
| | | fwrite(l.filters+index, sizeof(float), l.c*l.size*l.size, fp); |
| | | for (k = 0; k < l.c*l.size*l.size; ++k) fwrite(&zero, sizeof(float), 1, fp); |
| | | } |
| | | for (j = 0; j < l.n; ++j){ |
| | | int index = j*l.c*l.size*l.size; |
| | | for (k = 0; k < l.c*l.size*l.size; ++k) fwrite(&zero, sizeof(float), 1, fp); |
| | | fwrite(l.filters+index, sizeof(float), l.c*l.size*l.size, fp); |
| | | } |
| | | } |
| | | } |
| | | fclose(fp); |
| | | } |
| | | |
| | | void save_weights_upto(network net, char *filename, int cutoff) |
| | | { |
| | | fprintf(stderr, "Saving weights to %s\n", filename); |
| | |
| | | void save_network(network net, char *filename); |
| | | void save_weights(network net, char *filename); |
| | | void save_weights_upto(network net, char *filename, int cutoff); |
| | | void save_weights_double(network net, char *filename); |
| | | void load_weights(network *net, char *filename); |
| | | void load_weights_upto(network *net, char *filename, int cutoff); |
| | | |
| | |
| | | #include "cuda.h" |
| | | #include "utils.h" |
| | | #include <stdio.h> |
| | | #include <assert.h> |
| | | #include <string.h> |
| | | #include <stdlib.h> |
| | | |
| | | int get_region_layer_locations(region_layer l) |
| | | { |
| | | return l.inputs / (l.classes+l.coords); |
| | | } |
| | | |
| | | region_layer make_region_layer(int batch, int inputs, int n, int classes, int coords, int rescore) |
| | | region_layer make_region_layer(int batch, int inputs, int n, int side, int classes, int coords, int rescore) |
| | | { |
| | | region_layer l = {0}; |
| | | l.type = REGION; |
| | |
| | | l.classes = classes; |
| | | l.coords = coords; |
| | | l.rescore = rescore; |
| | | l.side = side; |
| | | assert(side*side*l.coords*l.n == inputs); |
| | | l.cost = calloc(1, sizeof(float)); |
| | | int outputs = inputs; |
| | | int outputs = l.n*5*side*side; |
| | | l.outputs = outputs; |
| | | l.output = calloc(batch*outputs, sizeof(float)); |
| | | l.delta = calloc(batch*outputs, sizeof(float)); |
| | | l.delta = calloc(batch*inputs, sizeof(float)); |
| | | #ifdef GPU |
| | | l.output_gpu = cuda_make_array(0, batch*outputs); |
| | | l.delta_gpu = cuda_make_array(0, batch*outputs); |
| | | #endif |
| | | l.output_gpu = cuda_make_array(l.output, batch*outputs); |
| | | l.delta_gpu = cuda_make_array(l.delta, batch*inputs); |
| | | #endif |
| | | |
| | | fprintf(stderr, "Region Layer\n"); |
| | | srand(0); |
| | |
| | | |
| | | void forward_region_layer(const region_layer l, network_state state) |
| | | { |
| | | int locations = get_region_layer_locations(l); |
| | | int locations = l.side*l.side; |
| | | int i,j; |
| | | for(i = 0; i < l.batch*locations; ++i){ |
| | | int index = i*(l.classes + l.coords); |
| | | int mask = (!state.truth || !state.truth[index]); |
| | | for(j = 0; j < l.n; ++j){ |
| | | int in_index = i*l.n*l.coords + j*l.coords; |
| | | int out_index = i*l.n*5 + j*5; |
| | | |
| | | for(j = 0; j < l.classes; ++j){ |
| | | l.output[index+j] = state.input[index+j]; |
| | | } |
| | | float prob = state.input[in_index+0]; |
| | | float x = state.input[in_index+1]; |
| | | float y = state.input[in_index+2]; |
| | | float w = state.input[in_index+3]; |
| | | float h = state.input[in_index+4]; |
| | | /* |
| | | float min_w = state.input[in_index+5]; |
| | | float max_w = state.input[in_index+6]; |
| | | float min_h = state.input[in_index+7]; |
| | | float max_h = state.input[in_index+8]; |
| | | */ |
| | | |
| | | softmax_array(l.output + index, l.classes, l.output + index); |
| | | index += l.classes; |
| | | l.output[out_index+0] = prob; |
| | | l.output[out_index+1] = x; |
| | | l.output[out_index+2] = y; |
| | | l.output[out_index+3] = w; |
| | | l.output[out_index+4] = h; |
| | | |
| | | for(j = 0; j < l.coords; ++j){ |
| | | l.output[index+j] = mask*state.input[index+j]; |
| | | } |
| | | } |
| | | if(state.train){ |
| | | float avg_iou = 0; |
| | | int count = 0; |
| | | *(l.cost) = 0; |
| | | int size = l.outputs * l.batch; |
| | | int size = l.inputs * l.batch; |
| | | memset(l.delta, 0, size * sizeof(float)); |
| | | for (i = 0; i < l.batch*locations; ++i) { |
| | | int offset = i*(l.classes+l.coords); |
| | | int bg = state.truth[offset]; |
| | | for (j = offset; j < offset+l.classes; ++j) { |
| | | //*(l.cost) += pow(state.truth[j] - l.output[j], 2); |
| | | //l.delta[j] = state.truth[j] - l.output[j]; |
| | | |
| | | for(j = 0; j < l.n; ++j){ |
| | | int in_index = i*l.n*l.coords + j*l.coords; |
| | | l.delta[in_index+0] = .1*(0-state.input[in_index+0]); |
| | | } |
| | | |
| | | box anchor = {0,0,.5,.5}; |
| | | box truth_code = {state.truth[j+0], state.truth[j+1], state.truth[j+2], state.truth[j+3]}; |
| | | box out_code = {l.output[j+0], l.output[j+1], l.output[j+2], l.output[j+3]}; |
| | | box out = decode_box(out_code, anchor); |
| | | box truth = decode_box(truth_code, anchor); |
| | | int truth_index = i*5; |
| | | int best_index = -1; |
| | | float best_iou = 0; |
| | | float best_rmse = 4; |
| | | |
| | | int bg = !state.truth[truth_index]; |
| | | if(bg) continue; |
| | | //printf("Box: %f %f %f %f\n", truth.x, truth.y, truth.w, truth.h); |
| | | //printf("Code: %f %f %f %f\n", truth_code.x, truth_code.y, truth_code.w, truth_code.h); |
| | | //printf("Pred : %f %f %f %f\n", out.x, out.y, out.w, out.h); |
| | | // printf("Pred Code: %f %f %f %f\n", out_code.x, out_code.y, out_code.w, out_code.h); |
| | | float iou = box_iou(out, truth); |
| | | avg_iou += iou; |
| | | ++count; |
| | | |
| | | /* |
| | | *(l.cost) += pow((1-iou), 2); |
| | | l.delta[j+0] = (state.truth[j+0] - l.output[j+0]); |
| | | l.delta[j+1] = (state.truth[j+1] - l.output[j+1]); |
| | | l.delta[j+2] = (state.truth[j+2] - l.output[j+2]); |
| | | l.delta[j+3] = (state.truth[j+3] - l.output[j+3]); |
| | | */ |
| | | box truth = {state.truth[truth_index+1], state.truth[truth_index+2], state.truth[truth_index+3], state.truth[truth_index+4]}; |
| | | truth.x /= l.side; |
| | | truth.y /= l.side; |
| | | |
| | | for (j = offset+l.classes; j < offset+l.classes+l.coords; ++j) { |
| | | //*(l.cost) += pow(state.truth[j] - l.output[j], 2); |
| | | //l.delta[j] = state.truth[j] - l.output[j]; |
| | | float diff = state.truth[j] - l.output[j]; |
| | | if (fabs(diff) < 1){ |
| | | l.delta[j] = diff; |
| | | *(l.cost) += .5*pow(state.truth[j] - l.output[j], 2); |
| | | } else { |
| | | l.delta[j] = (diff > 0) ? 1 : -1; |
| | | *(l.cost) += fabs(diff) - .5; |
| | | for(j = 0; j < l.n; ++j){ |
| | | int out_index = i*l.n*5 + j*5; |
| | | box out = {l.output[out_index+1], l.output[out_index+2], l.output[out_index+3], l.output[out_index+4]}; |
| | | |
| | | //printf("\n%f %f %f %f %f\n", l.output[out_index+0], out.x, out.y, out.w, out.h); |
| | | |
| | | out.x /= l.side; |
| | | out.y /= l.side; |
| | | |
| | | float iou = box_iou(out, truth); |
| | | float rmse = box_rmse(out, truth); |
| | | if(best_iou > 0 || iou > 0){ |
| | | if(iou > best_iou){ |
| | | best_iou = iou; |
| | | best_index = j; |
| | | } |
| | | }else{ |
| | | if(rmse < best_rmse){ |
| | | best_rmse = rmse; |
| | | best_index = j; |
| | | } |
| | | } |
| | | //l.delta[j] = state.truth[j] - l.output[j]; |
| | | } |
| | | printf("%d", best_index); |
| | | //int out_index = i*l.n*5 + best_index*5; |
| | | //box out = {l.output[out_index+1], l.output[out_index+2], l.output[out_index+3], l.output[out_index+4]}; |
| | | int in_index = i*l.n*l.coords + best_index*l.coords; |
| | | |
| | | l.delta[in_index+0] = (1-state.input[in_index+0]); |
| | | l.delta[in_index+1] = state.truth[truth_index+1] - state.input[in_index+1]; |
| | | l.delta[in_index+2] = state.truth[truth_index+2] - state.input[in_index+2]; |
| | | l.delta[in_index+3] = state.truth[truth_index+3] - state.input[in_index+3]; |
| | | l.delta[in_index+4] = state.truth[truth_index+4] - state.input[in_index+4]; |
| | | /* |
| | | l.delta[in_index+5] = 0 - state.input[in_index+5]; |
| | | l.delta[in_index+6] = 1 - state.input[in_index+6]; |
| | | l.delta[in_index+7] = 0 - state.input[in_index+7]; |
| | | l.delta[in_index+8] = 1 - state.input[in_index+8]; |
| | | */ |
| | | |
| | | /* |
| | | if(l.rescore){ |
| | | for (j = offset; j < offset+l.classes; ++j) { |
| | | if(state.truth[j]) state.truth[j] = iou; |
| | | l.delta[j] = state.truth[j] - l.output[j]; |
| | | } |
| | | } |
| | | */ |
| | | float x = state.input[in_index+1]; |
| | | float y = state.input[in_index+2]; |
| | | float w = state.input[in_index+3]; |
| | | float h = state.input[in_index+4]; |
| | | float min_w = state.input[in_index+5]; |
| | | float max_w = state.input[in_index+6]; |
| | | float min_h = state.input[in_index+7]; |
| | | float max_h = state.input[in_index+8]; |
| | | */ |
| | | |
| | | |
| | | avg_iou += best_iou; |
| | | ++count; |
| | | } |
| | | printf("Avg IOU: %f\n", avg_iou/count); |
| | | printf("\nAvg IOU: %f %d\n", avg_iou/count, count); |
| | | } |
| | | } |
| | | |
| | | void backward_region_layer(const region_layer l, network_state state) |
| | | { |
| | | axpy_cpu(l.batch*l.inputs, 1, l.delta_gpu, 1, state.delta, 1); |
| | | //copy_cpu(l.batch*l.inputs, l.delta_gpu, 1, state.delta, 1); |
| | | axpy_cpu(l.batch*l.inputs, 1, l.delta, 1, state.delta, 1); |
| | | //copy_cpu(l.batch*l.inputs, l.delta, 1, state.delta, 1); |
| | | } |
| | | |
| | | #ifdef GPU |
| | |
| | | cpu_state.input = in_cpu; |
| | | forward_region_layer(l, cpu_state); |
| | | cuda_push_array(l.output_gpu, l.output, l.batch*l.outputs); |
| | | cuda_push_array(l.delta_gpu, l.delta, l.batch*l.outputs); |
| | | cuda_push_array(l.delta_gpu, l.delta, l.batch*l.inputs); |
| | | free(cpu_state.input); |
| | | if(cpu_state.truth) free(cpu_state.truth); |
| | | } |
| | |
| | | |
| | | typedef layer region_layer; |
| | | |
| | | region_layer make_region_layer(int batch, int inputs, int n, int classes, int coords, int rescore); |
| | | region_layer make_region_layer(int batch, int inputs, int n, int size, int classes, int coords, int rescore); |
| | | void forward_region_layer(const region_layer l, network_state state); |
| | | void backward_region_layer(const region_layer l, network_state state); |
| | | |
| | |
| | | fprintf(stderr, "\n"); |
| | | l.outputs = outputs; |
| | | l.inputs = outputs; |
| | | l.delta = calloc(outputs*batch, sizeof(float)); |
| | | l.delta = calloc(outputs*batch, sizeof(float)); |
| | | l.output = calloc(outputs*batch, sizeof(float));; |
| | | #ifdef GPU |
| | | l.delta_gpu = cuda_make_array(0, outputs*batch); |
| | | l.output_gpu = cuda_make_array(0, outputs*batch); |
| | | l.delta_gpu = cuda_make_array(l.delta, outputs*batch); |
| | | l.output_gpu = cuda_make_array(l.output, outputs*batch); |
| | | #endif |
| | | return l; |
| | | } |
| | |
| | | s[len-offset] = '\0'; |
| | | } |
| | | |
| | | void free_ptrs(void **ptrs, int n) |
| | | { |
| | | int i; |
| | | for(i = 0; i < n; ++i) free(ptrs[i]); |
| | | free(ptrs); |
| | | } |
| | | |
| | | char *fgetl(FILE *fp) |
| | | { |
| | | if(feof(fp)) return 0; |
| | |
| | | |
| | | #define SECRET_NUM -1234 |
| | | |
| | | void free_ptrs(void **ptrs, int n); |
| | | char *basecfg(char *cfgfile); |
| | | int alphanum_to_int(char c); |
| | | char int_to_alphanum(int i); |
| | |
| | | |
| | | pthread_join(load_thread, 0); |
| | | free_data(buffer); |
| | | args.background = background; |
| | | load_thread = load_data_in_thread(args); |
| | | } |
| | | |
| | |
| | | int w = val[t].w; |
| | | int h = val[t].h; |
| | | convert_yolo_detections(predictions, classes, objectness, background, num_boxes, w, h, thresh, probs, boxes); |
| | | if (nms) do_nms(boxes, probs, num_boxes, classes, iou_thresh); |
| | | if (nms) do_nms(boxes, probs, num_boxes*num_boxes, classes, iou_thresh); |
| | | print_yolo_detections(fps, id, boxes, probs, num_boxes, classes, w, h); |
| | | free(id); |
| | | free_image(val[t]); |