void test_box() { test_dintersect(); test_dunion(); box a = {0, 0, 1, 1}; box dxa= {0+.00001, 0, 1, 1}; box dya= {0, 0+.00001, 1, 1}; box dwa= {0, 0, 1+.00001, 1}; box dha= {0, 0, 1, 1+.00001}; box b = {.5, 0, .2, .2}; float iou = box_iou(a,b); iou = (1-iou)*(1-iou); printf("%f\n", iou); dbox d = diou(a, b); printf("%f %f %f %f\n", d.dx, d.dy, d.dw, d.dh); float xiou = box_iou(dxa, b); float yiou = box_iou(dya, b); float wiou = box_iou(dwa, b); float hiou = box_iou(dha, b); xiou = ((1-xiou)*(1-xiou) - iou)/(.00001); yiou = ((1-yiou)*(1-yiou) - iou)/(.00001); wiou = ((1-wiou)*(1-wiou) - iou)/(.00001); hiou = ((1-hiou)*(1-hiou) - iou)/(.00001); printf("manual %f %f %f %f\n", xiou, yiou, wiou, hiou); }
void do_nms_sort(detection *dets, int total, int classes, float thresh) { int i, j, k; k = total-1; for(i = 0; i <= k; ++i){ if(dets[i].objectness == 0){ detection swap = dets[i]; dets[i] = dets[k]; dets[k] = swap; --k; --i; } } total = k+1; for(k = 0; k < classes; ++k){ for(i = 0; i < total; ++i){ dets[i].sort_class = k; } qsort(dets, total, sizeof(detection), nms_comparator); for(i = 0; i < total; ++i){ if(dets[i].prob[k] == 0) continue; box a = dets[i].bbox; for(j = i+1; j < total; ++j){ box b = dets[j].bbox; if (box_iou(a, b) > thresh){ dets[j].prob[k] = 0; } } } } }
float delta_region_box(box truth, float *x, float *biases, int n, int index, int i, int j, int w, int h, float *delta, float scale, int stride) { box pred = get_region_box(x, biases, n, index, i, j, w, h, stride); float iou = box_iou(pred, truth); float tx = (truth.x*w - i); float ty = (truth.y*h - j); float tw = log(truth.w*w / biases[2*n]); float th = log(truth.h*h / biases[2*n + 1]); delta[index + 0*stride] = scale * (tx - x[index + 0*stride]); delta[index + 1*stride] = scale * (ty - x[index + 1*stride]); delta[index + 2*stride] = scale * (tw - x[index + 2*stride]); delta[index + 3*stride] = scale * (th - x[index + 3*stride]); return iou; }
void do_nms(box *boxes, float **probs, int total, int classes, float thresh) { int i, j, k; 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 < 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; else probs[j][k] = 0; } } } } }
float delta_region_box(box truth, float *x, float *biases, int n, int index, int i, int j, int w, int h, float *delta, float scale) { box pred = get_region_box(x, biases, n, index, i, j, w, h); float iou = box_iou(pred, truth); float tx = (truth.x*w - i); float ty = (truth.y*h - j); float tw = log(truth.w / biases[2*n]); float th = log(truth.h / biases[2*n + 1]); if(DOABS){ tw = log(truth.w*w / biases[2*n]); th = log(truth.h*h / biases[2*n + 1]); } delta[index + 0] = scale * (tx - logistic_activate(x[index + 0])) * logistic_gradient(logistic_activate(x[index + 0])); delta[index + 1] = scale * (ty - logistic_activate(x[index + 1])) * logistic_gradient(logistic_activate(x[index + 1])); delta[index + 2] = scale * (tw - x[index + 2]); delta[index + 3] = scale * (th - x[index + 3]); return iou; }
void validate_detector_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)); list *plist = get_paths("data/voc.2007.test"); char **paths = (char **)list_to_array(plist); layer l = net.layers[net.n-1]; int classes = l.classes; int j, k; box *boxes = calloc(l.w*l.h*l.n, sizeof(box)); float **probs = calloc(l.w*l.h*l.n, sizeof(float *)); for(j = 0; j < l.w*l.h*l.n; ++j) probs[j] = calloc(classes, sizeof(float *)); int m = plist->size; int i=0; float thresh = .001; float iou_thresh = .5; float nms = .4; int total = 0; int correct = 0; int proposals = 0; float avg_iou = 0; for(i = 0; i < m; ++i){ char *path = paths[i]; image orig = load_image_color(path, 0, 0); image sized = resize_image(orig, net.w, net.h); char *id = basecfg(path); network_predict(net, sized.data); get_region_boxes(l, 1, 1, thresh, probs, boxes, 1, 0, .5); if (nms) do_nms(boxes, probs, l.w*l.h*l.n, 1, nms); char labelpath[4096]; find_replace(path, "images", "labels", labelpath); find_replace(labelpath, "JPEGImages", "labels", labelpath); find_replace(labelpath, ".jpg", ".txt", labelpath); find_replace(labelpath, ".JPEG", ".txt", labelpath); int num_labels = 0; box_label *truth = read_boxes(labelpath, &num_labels); for(k = 0; k < l.w*l.h*l.n; ++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 < l.w*l.h*l.n; ++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; } } 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); free(id); free_image(orig); free_image(sized); } }
void validate_yolo_classify(char *datacfg, char *cfgfile, char *weightfile) { list *options = read_data_cfg(datacfg); //char *train_list = option_find_str(options, "train", "data/train_list.txt"); //char *test_list = option_find_str(options, "test", "data/test_list.txt"); char *valid_list = option_find_str(options, "valid", "data/valid_list.txt"); //char *backup_directory = option_find_str(options, "backup", "/backup/"); //char *label_list = option_find_str(options, "labels", "data/labels_list.txt"); //int classes = option_find_int(options, "classes", 2); //char **labels = get_labels(label_list); 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 *base = "results/comp4_det_test_"; //list *plist = get_paths("data/voc.2007.test"); list *plist = get_paths(valid_list); char **paths = (char **)list_to_array(plist); layer l = net.layers[net.n-1]; int classes = l.classes; int square = l.sqrt; int side = l.side; int j, k; FILE **fps = calloc(classes, sizeof(FILE *)); for(j = 0; j < classes; ++j){ char buff[1024]; snprintf(buff, 1024, "%s%s.txt", base, voc_names[j]); fps[j] = fopen(buff, "w"); } box *boxes = calloc(side*side*l.n, sizeof(box)); float **probs = calloc(side*side*l.n, sizeof(float *)); for(j = 0; j < side*side*l.n; ++j) probs[j] = calloc(classes, sizeof(float *)); int m = plist->size; int i=0; //float thresh = .001; float thresh = .2; float iou_thresh = .5; //float nms = 0; float nms = 0.5; int total = 0; int correct = 0; int class_correct = 0; int proposals = 0; float avg_iou = 0; for(i = 0; i < m; ++i){ char *path = paths[i]; image orig = load_image_color(path, 0, 0); image sized = resize_image(orig, net.w, net.h); char *id = basecfg(path); float *predictions = network_predict(net, sized.data); convert_yolo_detections(predictions, classes, l.n, square, side, 1, 1, thresh, probs, boxes, 0); //if (nms) do_nms(boxes, probs, side*side*l.n, 1, nms); if (nms) do_nms(boxes, probs, side*side*l.n, classes, nms); 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"); labelpath = find_replace(labelpath, ".bmp", ".txt"); labelpath = find_replace(labelpath, ".dib", ".txt"); labelpath = find_replace(labelpath, ".jpe", ".txt"); labelpath = find_replace(labelpath, ".jp2", ".txt"); labelpath = find_replace(labelpath, ".png", ".txt"); labelpath = find_replace(labelpath, ".pbm", ".txt"); labelpath = find_replace(labelpath, ".pgm", ".txt"); labelpath = find_replace(labelpath, ".ppm", ".txt"); labelpath = find_replace(labelpath, ".sr", ".txt"); labelpath = find_replace(labelpath, ".ras", ".txt"); labelpath = find_replace(labelpath, ".tiff", ".txt"); labelpath = find_replace(labelpath, ".tif", ".txt"); int num_labels = 0; box_label *truth = read_boxes(labelpath, &num_labels); for(k = 0; k < side*side*l.n; ++k){ int class = max_index(probs[k], classes); float prob = probs[k][class]; //fprintf(stderr, "path=%s\t\tk=%d\tprob=%f\tclass=%d\n", path, k, prob, class); if(prob > 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; int pre_class = -1; for(k = 0; k < side*side*l.n; ++k){ float iou = box_iou(boxes[k], t); int class = max_index(probs[k], classes); float prob = probs[k][class]; //fprintf(stderr, "path=%s\t\tk=%d\tprob=%f\tclass=%d\n", path, k, prob, class); if(prob > thresh && iou > best_iou){ best_iou = iou; pre_class = class; } } avg_iou += best_iou; if(best_iou > iou_thresh){ ++correct; } if(pre_class == truth[j].id){ ++class_correct; } //fprintf(stderr, "true_class=%d\tpre_class=%d\n", truth[j].id, pre_class); } fprintf(stderr, "%5d %5d %5d\tRPs/Img: %.2f\tIOU: %.2f%%\tRecall:%.2f%%\t\tClassify:%.2f%%\n", i, correct, total, (float)proposals/(i+1), avg_iou*100/total, 100.*correct/total, 100.*class_correct/total); free(id); free_image(orig); free_image(sized); }
void forward_detection_layer(const detection_layer l, network_state state) { int in_i = 0; int out_i = 0; int locations = get_detection_layer_locations(l); int i,j; for(i = 0; i < l.batch*locations; ++i){ int mask = (!state.truth || state.truth[out_i + (l.background || l.objectness) + l.classes + 2]); float scale = 1; if(l.joint) scale = state.input[in_i++]; else if(l.objectness){ l.output[out_i++] = 1-state.input[in_i++]; scale = mask; } else if(l.background) l.output[out_i++] = scale*state.input[in_i++]; for(j = 0; j < l.classes; ++j){ l.output[out_i++] = scale*state.input[in_i++]; } if(l.objectness){ }else if(l.background){ softmax_array(l.output + out_i - l.classes-l.background, l.classes+l.background, l.output + out_i - l.classes-l.background); activate_array(state.input+in_i, l.coords, LOGISTIC); } for(j = 0; j < l.coords; ++j){ l.output[out_i++] = mask*state.input[in_i++]; } } float avg_iou = 0; int count = 0; if(l.does_cost && state.train){ *(l.cost) = 0; int size = get_detection_layer_output_size(l) * l.batch; memset(l.delta, 0, size * sizeof(float)); for (i = 0; i < l.batch*locations; ++i) { int classes = l.objectness+l.classes; int offset = i*(classes+l.coords); for (j = offset; j < offset+classes; ++j) { *(l.cost) += pow(state.truth[j] - l.output[j], 2); l.delta[j] = state.truth[j] - l.output[j]; } box truth; truth.x = state.truth[j+0]/7; truth.y = state.truth[j+1]/7; truth.w = pow(state.truth[j+2], 2); truth.h = pow(state.truth[j+3], 2); box out; out.x = l.output[j+0]/7; out.y = l.output[j+1]/7; out.w = pow(l.output[j+2], 2); out.h = pow(l.output[j+3], 2); if(!(truth.w*truth.h)) continue; float iou = box_iou(out, truth); avg_iou += iou; ++count; dbox delta = diou(out, truth); l.delta[j+0] = 10 * delta.dx/7; l.delta[j+1] = 10 * delta.dy/7; l.delta[j+2] = 10 * delta.dw * 2 * sqrt(out.w); l.delta[j+3] = 10 * delta.dh * 2 * sqrt(out.h); *(l.cost) += pow((1-iou), 2); l.delta[j+0] = 4 * (state.truth[j+0] - l.output[j+0]); l.delta[j+1] = 4 * (state.truth[j+1] - l.output[j+1]); l.delta[j+2] = 4 * (state.truth[j+2] - l.output[j+2]); l.delta[j+3] = 4 * (state.truth[j+3] - l.output[j+3]); if(l.rescore){ for (j = offset; j < offset+classes; ++j) { if(state.truth[j]) state.truth[j] = iou; l.delta[j] = state.truth[j] - l.output[j]; } } } printf("Avg IOU: %f\n", avg_iou/count); } }
void forward_region_layer(const region_layer l, network_state state) { int i,j,b,t,n; int size = l.coords + l.classes + 1; memcpy(l.output, state.input, l.outputs*l.batch*sizeof(float)); #ifndef GPU flatten(l.output, l.w*l.h, size*l.n, l.batch, 1); #endif for (b = 0; b < l.batch; ++b){ for(i = 0; i < l.h*l.w*l.n; ++i){ int index = size*i + b*l.outputs; l.output[index + 4] = logistic_activate(l.output[index + 4]); } } #ifndef GPU if (l.softmax_tree){ for (b = 0; b < l.batch; ++b){ for(i = 0; i < l.h*l.w*l.n; ++i){ int index = size*i + b*l.outputs; softmax_tree(l.output + index + 5, 1, 0, 1, l.softmax_tree, l.output + index + 5); } } } else if (l.softmax){ for (b = 0; b < l.batch; ++b){ for(i = 0; i < l.h*l.w*l.n; ++i){ int index = size*i + b*l.outputs; softmax(l.output + index + 5, l.classes, 1, l.output + index + 5, 1); } } } #endif if(!state.train) return; memset(l.delta, 0, l.outputs * l.batch * sizeof(float)); float avg_iou = 0; float recall = 0; float avg_cat = 0; float avg_obj = 0; float avg_anyobj = 0; int count = 0; int class_count = 0; *(l.cost) = 0; for (b = 0; b < l.batch; ++b) { if(l.softmax_tree){ int onlyclass_id = 0; for(t = 0; t < l.max_boxes; ++t){ box truth = float_to_box(state.truth + t*5 + b*l.truths); if(!truth.x) break; // continue; int class_id = state.truth[t*5 + b*l.truths + 4]; float maxp = 0; int maxi = 0; if(truth.x > 100000 && truth.y > 100000){ for(n = 0; n < l.n*l.w*l.h; ++n){ int index = size*n + b*l.outputs + 5; float scale = l.output[index-1]; float p = scale*get_hierarchy_probability(l.output + index, l.softmax_tree, class_id); if(p > maxp){ maxp = p; maxi = n; } } int index = size*maxi + b*l.outputs + 5; delta_region_class(l.output, l.delta, index, class_id, l.classes, l.softmax_tree, l.class_scale, &avg_cat, l.focal_loss); ++class_count; onlyclass_id = 1; break; } } if(onlyclass_id) continue; } for (j = 0; j < l.h; ++j) { for (i = 0; i < l.w; ++i) { for (n = 0; n < l.n; ++n) { int index = size*(j*l.w*l.n + i*l.n + n) + b*l.outputs; box pred = get_region_box(l.output, l.biases, n, index, i, j, l.w, l.h); float best_iou = 0; int best_class_id = -1; for(t = 0; t < l.max_boxes; ++t){ box truth = float_to_box(state.truth + t*5 + b*l.truths); int class_id = state.truth[t * 5 + b*l.truths + 4]; if (class_id >= l.classes) continue; // if label contains class_id more than number of classes in the cfg-file if(!truth.x) break; // continue; float iou = box_iou(pred, truth); if (iou > best_iou) { best_class_id = state.truth[t*5 + b*l.truths + 4]; best_iou = iou; } } avg_anyobj += l.output[index + 4]; l.delta[index + 4] = l.noobject_scale * ((0 - l.output[index + 4]) * logistic_gradient(l.output[index + 4])); if(l.classfix == -1) l.delta[index + 4] = l.noobject_scale * ((best_iou - l.output[index + 4]) * logistic_gradient(l.output[index + 4])); else{ if (best_iou > l.thresh) { l.delta[index + 4] = 0; if(l.classfix > 0){ delta_region_class(l.output, l.delta, index + 5, best_class_id, l.classes, l.softmax_tree, l.class_scale*(l.classfix == 2 ? l.output[index + 4] : 1), &avg_cat, l.focal_loss); ++class_count; } } } if(*(state.net.seen) < 12800){ box truth = {0}; truth.x = (i + .5)/l.w; truth.y = (j + .5)/l.h; truth.w = l.biases[2*n]; truth.h = l.biases[2*n+1]; if(DOABS){ truth.w = l.biases[2*n]/l.w; truth.h = l.biases[2*n+1]/l.h; } delta_region_box(truth, l.output, l.biases, n, index, i, j, l.w, l.h, l.delta, .01); } } } } for(t = 0; t < l.max_boxes; ++t){ box truth = float_to_box(state.truth + t*5 + b*l.truths); int class_id = state.truth[t * 5 + b*l.truths + 4]; if (class_id >= l.classes) { printf(" Warning: in txt-labels class_id=%d >= classes=%d in cfg-file. In txt-labels class_id should be [from 0 to %d] \n", class_id, l.classes, l.classes-1); getchar(); continue; // if label contains class_id more than number of classes in the cfg-file } if(!truth.x) break; // continue; float best_iou = 0; int best_index = 0; int best_n = 0; i = (truth.x * l.w); j = (truth.y * l.h); //printf("%d %f %d %f\n", i, truth.x*l.w, j, truth.y*l.h); box truth_shift = truth; truth_shift.x = 0; truth_shift.y = 0; //printf("index %d %d\n",i, j); for(n = 0; n < l.n; ++n){ int index = size*(j*l.w*l.n + i*l.n + n) + b*l.outputs; box pred = get_region_box(l.output, l.biases, n, index, i, j, l.w, l.h); if(l.bias_match){ pred.w = l.biases[2*n]; pred.h = l.biases[2*n+1]; if(DOABS){ pred.w = l.biases[2*n]/l.w; pred.h = l.biases[2*n+1]/l.h; } } //printf("pred: (%f, %f) %f x %f\n", pred.x, pred.y, pred.w, pred.h); pred.x = 0; pred.y = 0; float iou = box_iou(pred, truth_shift); if (iou > best_iou){ best_index = index; best_iou = iou; best_n = n; } } //printf("%d %f (%f, %f) %f x %f\n", best_n, best_iou, truth.x, truth.y, truth.w, truth.h); float iou = delta_region_box(truth, l.output, l.biases, best_n, best_index, i, j, l.w, l.h, l.delta, l.coord_scale); if(iou > .5) recall += 1; avg_iou += iou; //l.delta[best_index + 4] = iou - l.output[best_index + 4]; avg_obj += l.output[best_index + 4]; l.delta[best_index + 4] = l.object_scale * (1 - l.output[best_index + 4]) * logistic_gradient(l.output[best_index + 4]); if (l.rescore) { l.delta[best_index + 4] = l.object_scale * (iou - l.output[best_index + 4]) * logistic_gradient(l.output[best_index + 4]); } if (l.map) class_id = l.map[class_id]; delta_region_class(l.output, l.delta, best_index + 5, class_id, l.classes, l.softmax_tree, l.class_scale, &avg_cat, l.focal_loss); ++count; ++class_count; } } //printf("\n"); #ifndef GPU flatten(l.delta, l.w*l.h, size*l.n, l.batch, 0); #endif *(l.cost) = pow(mag_array(l.delta, l.outputs * l.batch), 2); printf("Region Avg IOU: %f, Class: %f, Obj: %f, No Obj: %f, Avg Recall: %f, count: %d\n", avg_iou/count, avg_cat/class_count, avg_obj/count, avg_anyobj/(l.w*l.h*l.n*l.batch), recall/count, count); }
void forward_detection_layer(const detection_layer l, network_state state) { int locations = l.side*l.side; int i,j; memcpy(l.output, state.input, l.outputs*l.batch*sizeof(float)); int b; if (l.softmax){ for(b = 0; b < l.batch; ++b){ int index = b*l.inputs; for (i = 0; i < locations; ++i) { int offset = i*l.classes; softmax_array(l.output + index + offset, l.classes, 1, l.output + index + offset); } } } if(state.train){ float avg_iou = 0; float avg_cat = 0; float avg_allcat = 0; float avg_obj = 0; float avg_anyobj = 0; int count = 0; *(l.cost) = 0; int size = l.inputs * l.batch; memset(l.delta, 0, size * sizeof(float)); for (b = 0; b < l.batch; ++b){ int index = b*l.inputs; for (i = 0; i < locations; ++i) { int truth_index = (b*locations + i)*(1+l.coords+l.classes); int is_obj = state.truth[truth_index]; for (j = 0; j < l.n; ++j) { int p_index = index + locations*l.classes + i*l.n + j; l.delta[p_index] = l.noobject_scale*(0 - l.output[p_index]); *(l.cost) += l.noobject_scale*pow(l.output[p_index], 2); avg_anyobj += l.output[p_index]; } int best_index = -1; float best_iou = 0; float best_rmse = 20; if (!is_obj){ continue; } int class_index = index + i*l.classes; for(j = 0; j < l.classes; ++j) { l.delta[class_index+j] = l.class_scale * (state.truth[truth_index+1+j] - l.output[class_index+j]); *(l.cost) += l.class_scale * pow(state.truth[truth_index+1+j] - l.output[class_index+j], 2); if(state.truth[truth_index + 1 + j]) avg_cat += l.output[class_index+j]; avg_allcat += l.output[class_index+j]; } box truth = float_to_box(state.truth + truth_index + 1 + l.classes); truth.x /= l.side; truth.y /= l.side; for(j = 0; j < l.n; ++j){ int box_index = index + locations*(l.classes + l.n) + (i*l.n + j) * l.coords; box out = float_to_box(l.output + box_index); out.x /= l.side; out.y /= l.side; if (l.sqrt){ out.w = out.w*out.w; out.h = out.h*out.h; } float iou = box_iou(out, truth); //iou = 0; 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; } } } if(l.forced){ if(truth.w*truth.h < .1){ best_index = 1; }else{ best_index = 0; } } if(l.random && *(state.net.seen) < 64000){ best_index = rand()%l.n; } int box_index = index + locations*(l.classes + l.n) + (i*l.n + best_index) * l.coords; int tbox_index = truth_index + 1 + l.classes; box out = float_to_box(l.output + box_index); out.x /= l.side; out.y /= l.side; if (l.sqrt) { out.w = out.w*out.w; out.h = out.h*out.h; } float iou = box_iou(out, truth); //printf("%d,", best_index); int p_index = index + locations*l.classes + i*l.n + best_index; *(l.cost) -= l.noobject_scale * pow(l.output[p_index], 2); *(l.cost) += l.object_scale * pow(1-l.output[p_index], 2); avg_obj += l.output[p_index]; l.delta[p_index] = l.object_scale * (1.-l.output[p_index]); if(l.rescore){ l.delta[p_index] = l.object_scale * (iou - l.output[p_index]); } l.delta[box_index+0] = l.coord_scale*(state.truth[tbox_index + 0] - l.output[box_index + 0]); l.delta[box_index+1] = l.coord_scale*(state.truth[tbox_index + 1] - l.output[box_index + 1]); l.delta[box_index+2] = l.coord_scale*(state.truth[tbox_index + 2] - l.output[box_index + 2]); l.delta[box_index+3] = l.coord_scale*(state.truth[tbox_index + 3] - l.output[box_index + 3]); if(l.sqrt){ l.delta[box_index+2] = l.coord_scale*(sqrt(state.truth[tbox_index + 2]) - l.output[box_index + 2]); l.delta[box_index+3] = l.coord_scale*(sqrt(state.truth[tbox_index + 3]) - l.output[box_index + 3]); } *(l.cost) += pow(1-iou, 2); avg_iou += iou; ++count; } } if(0){ float *costs = calloc(l.batch*locations*l.n, sizeof(float)); for (b = 0; b < l.batch; ++b) { int index = b*l.inputs; for (i = 0; i < locations; ++i) { for (j = 0; j < l.n; ++j) { int p_index = index + locations*l.classes + i*l.n + j; costs[b*locations*l.n + i*l.n + j] = l.delta[p_index]*l.delta[p_index]; } } } int indexes[100]; top_k(costs, l.batch*locations*l.n, 100, indexes); float cutoff = costs[indexes[99]]; for (b = 0; b < l.batch; ++b) { int index = b*l.inputs; for (i = 0; i < locations; ++i) { for (j = 0; j < l.n; ++j) { int p_index = index + locations*l.classes + i*l.n + j; if (l.delta[p_index]*l.delta[p_index] < cutoff) l.delta[p_index] = 0; } } } free(costs); } *(l.cost) = pow(mag_array(l.delta, l.outputs * l.batch), 2); if ( l.b_debug ) { printf("Detection Avg IOU: %f, Pos Cat: %f, All Cat: %f, Pos Obj: %f, Any Obj: %f, count: %d\n", avg_iou/count, avg_cat/count, avg_allcat/(count*l.classes), avg_obj/count, avg_anyobj/(l.batch*locations*l.n), count); } } }
void validate_coco_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 *base = "results/comp4_det_test_"; list *plist = get_paths("/home/pjreddie/data/voc/test/2007_test.txt"); char **paths = (char **)list_to_array(plist); layer l = net.layers[net.n-1]; int classes = l.classes; int square = l.sqrt; int side = l.side; int j, k; FILE **fps = calloc(classes, sizeof(FILE *)); for(j = 0; j < classes; ++j){ char buff[1024]; _snprintf(buff, 1024, "%s%s.txt", base, coco_classes[j]); fps[j] = fopen(buff, "w"); } box *boxes = calloc(side*side*l.n, sizeof(box)); float **probs = calloc(side*side*l.n, sizeof(float *)); for(j = 0; j < side*side*l.n; ++j) probs[j] = calloc(classes, sizeof(float *)); int m = plist->size; int i=0; float thresh = .001; int nms = 0; float iou_thresh = .5; float nms_thresh = .5; int total = 0; int correct = 0; int proposals = 0; float avg_iou = 0; for(i = 0; i < m; ++i){ char *path = paths[i]; image orig = load_image_color(path, 0, 0); image sized = resize_image(orig, net.w, net.h); char *id = basecfg(path); float *predictions = network_predict(net, sized.data); convert_detections(predictions, classes, l.n, square, side, 1, 1, thresh, probs, boxes, 1); if (nms) do_nms(boxes, probs, side*side*l.n, 1, nms_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 < side*side*l.n; ++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 < side*side*l.n; ++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; } } 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); free(id); free_image(orig); free_image(sized); } }
void validate_yolo_recall(char *cfg, char *weights) { network *net = load_network(cfg, weights, 0); 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 *base = "results/comp4_det_test_"; list *plist = get_paths("data/voc.2007.test"); char **paths = (char **)list_to_array(plist); layer l = net->layers[net->n-1]; int classes = l.classes; int side = l.side; int j, k; FILE **fps = calloc(classes, sizeof(FILE *)); for(j = 0; j < classes; ++j){ char buff[1024]; snprintf(buff, 1024, "%s%s.txt", base, voc_names[j]); fps[j] = fopen(buff, "w"); } int m = plist->size; int i=0; float thresh = .001; float iou_thresh = .5; float nms = 0; int total = 0; int correct = 0; int proposals = 0; float avg_iou = 0; for(i = 0; i < m; ++i){ char *path = paths[i]; image orig = load_image_color(path, 0, 0); image sized = resize_image(orig, net->w, net->h); char *id = basecfg(path); network_predict(net, sized.data); int nboxes = 0; detection *dets = get_network_boxes(net, orig.w, orig.h, thresh, 0, 0, 1, &nboxes); if (nms) do_nms_obj(dets, side*side*l.n, 1, nms); char labelpath[4096]; find_replace(path, "images", "labels", labelpath); find_replace(labelpath, "JPEGImages", "labels", labelpath); find_replace(labelpath, ".jpg", ".txt", labelpath); find_replace(labelpath, ".JPEG", ".txt", labelpath); int num_labels = 0; box_label *truth = read_boxes(labelpath, &num_labels); for(k = 0; k < side*side*l.n; ++k){ if(dets[k].objectness > 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 < side*side*l.n; ++k){ float iou = box_iou(dets[k].bbox, t); if(dets[k].objectness > thresh && iou > best_iou){ best_iou = iou; } } avg_iou += best_iou; if(best_iou > iou_thresh){ ++correct; } } 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); free_detections(dets, nboxes); free(id); free_image(orig); free_image(sized); } free_network( net ); }
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 = .3; 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, "/data/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, "/data/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_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 = 1; int proposals = 0; int save = 1; 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; if(save){ char buff[256]; sprintf(buff, "/data/extracted/nms_preds/%d", proposals); 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); sprintf(buff, "/data/extracted/nms_pred_boxes/%d.txt", proposals); char *im_id = basecfg(path); FILE *fp = fopen(buff, "w"); fprintf(fp, "%s %d %d %d %d\n", im_id, dx, dy, dx+w, dy+h); fclose(fp); free(im_id); } } } 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 forward_region_layer(const region_layer l, network_state state) { int locations = l.side*l.side; int i,j; for(i = 0; i < l.batch*locations; ++i){ 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; 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]; */ 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; } } if(state.train){ float avg_iou = 0; int count = 0; *(l.cost) = 0; int size = l.inputs * l.batch; memset(l.delta, 0, size * sizeof(float)); for (i = 0; i < l.batch*locations; ++i) { 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]); } 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; 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 = 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; } } } 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]; */ /* 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("\nAvg IOU: %f %d\n", avg_iou/count, count); } }
void validate_yolo_recall(char *cfgfile, char *weightfile, char *val_images, char *out_dir, float th, int log, int draw) { 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)); //create output directory if it does not exist struct stat st= {0}; if(stat(out_dir,&st)==-1){ fprintf(stderr,"Creating output directory\n"); mkdir(out_dir,0700); } char *base = out_dir; list *plist = get_paths(val_images); char **paths = (char **)list_to_array(plist); layer l = net.layers[net.n-1]; int classes = l.classes; int square = l.sqrt; //int side = l.side; int rows = l.rows; int cols = l.cols; int j, k; FILE **fps = calloc(classes, sizeof(FILE *)); for(j = 0; j < classes; ++j){ char buff[1024]; snprintf(buff, 1024, "%s%s.txt", base, voc_names[j]); fps[j] = fopen(buff, "w"); } box *boxes = calloc(rows*cols*l.n, sizeof(box)); float **probs = calloc(rows*cols*l.n, sizeof(float *)); for(j = 0; j < rows*cols*l.n; ++j) probs[j] = calloc(classes, sizeof(float *)); int m = plist->size; int i=0; float thresh = th; float iou_thresh[11] = {0.0,0.05,0.1,0.15,0.20,0.25,0.30,0.35,0.40,0.45,0.5}; float nms = 0.1; int total = 0; int correct[11] = {0,0,0,0,0,0,0,0,0,0,0}; int proposals = 0; float avg_iou = 0; Vector id_found; Vector id_invalid; initArray(&id_found,5); initArray(&id_invalid,5); for(i = 0; i < m; ++i){ char * image_path = strtok(paths[i]," "); char * label_path = strtok(NULL," "); image orig = load_image(image_path, 0, 0,net.c); image color; if(draw) color = load_image(image_path, 0, 0, 3); image sized = resize_image(orig, net.w, net.h); //char *id = basecfg(path); float *predictions = network_predict(net, sized.data); convert_detections(predictions, classes, l.n, square, rows, cols, 1, 1, thresh, probs, boxes, 0); if (nms) do_nms(boxes, probs, rows*cols*l.n, 1, nms); int num_labels = 0; box_label *truth = read_boxes(label_path, &num_labels); int old_p = proposals; for(k = 0; k < rows*cols*l.n; ++k){ if(probs[k][0] > thresh){ ++proposals; } } if(old_p!=proposals){ if(log){ char filename[256]; sprintf(filename, "%s/%d.txt", base,i); printf("log in file %s\n",filename); FILE * out = fopen(filename, "w"); fprintf(out,"W\tH\tX\tY\n"); for(k=0; k<rows*cols*l.n; ++k){ if(probs[k][0] > thresh){ fprintf(out, "%f\t%f\t%f\t%f\n",boxes[k].w,boxes[k].h,boxes[k].x,boxes[k].y); } } fclose(out); } if(draw){ draw_detections(color, l.rows*l.cols*l.n, thresh, boxes, probs, voc_names, voc_labels, CLASSNUM); show_image(color, "predictions"); #ifdef OPENCV cvWaitKey(0); //cvDestroyAllWindows(); #endif } } for (j = 0; j < num_labels; ++j) { ++total; while(id_found.used <= truth[j].id){ insertArray(&id_invalid,0); insertArray(&id_found,0); } if(truth[j].classe > CLASSNUM-1) id_invalid.array[truth[j].id]=1; box t = {truth[j].x, truth[j].y, truth[j].w, truth[j].h}; float best_iou = 0; for(k = 0; k < rows*cols*l.n; ++k){ float iou = box_iou(boxes[k], t); //find overlapping prediction if(iou > best_iou){ //find the predicted class float best_score = thresh; int best_class_index = -1; for(int c=0; c<CLASSNUM; c++){ if(probs[k][c]>best_score){ best_score = probs[k][c]; best_class_index = c; } } //check if it's good or not if(best_class_index == truth[j].classe) best_iou = iou; } } avg_iou += best_iou; for(int k=0; k<11; k++){ if(best_iou > iou_thresh[k]){ id_found.array[truth[j].id]=1; ++correct[k]; } } } if(i%10==0){ printf("\033[2J"); printf("\033[1;1H"); printf("#img\tPred\tTP\ttot\tRPs/Img\tAvg-IOU\tRecall\tPrecision\n"); printf("%5d\t%5d\t%5d\t%5d\t%.2f\t%.2f%%\t%.2f%%\t%.2f%%\n", i, proposals, correct[10], total, (float)proposals/(i+1), avg_iou*100/total, 100.*correct[10]/total, 100.*correct[10]/proposals); printf("IOU_th\tTP\tFP\tRecall\tPrecision\n"); for(int k=0; k<11; k++){ printf("%.2f%%\t%5d\t%5d\t%.2f%%\t%.2f%%\t\n", iou_thresh[k], correct[k], proposals-correct[k], 100.*correct[k]/total, 100.*correct[k]/proposals); } int found=0; int invalid = 0; for(int i=0; i<id_found.used; i++){ if(id_invalid.array[i]!=1) found+=id_found.array[i]; invalid+=id_invalid.array[i]; } printf("Founded: %d/%d\t%d\n", found, id_found.used-invalid,invalid); } //free(id); free_image(orig); free_image(sized); } for(j = 0; j < classes; ++j){ fprintf(fps[j],"IOU_th;TP;FP;Recall;Precision\n"); for(int k=0; k<11; k++){ fprintf(fps[j],"%.2f%%;%5d;%5d;%.2f%%;%.2f%%;\n", iou_thresh[k], correct[k], proposals-correct[k], 100.*correct[k]/total, 100.*correct[k]/proposals); } fprintf(fps[j], "\n\nFounded;Total;\n"); int found=0; int invalid = 0; for(int i=0; i<id_found.used; i++){ if(id_invalid.array[i]!=1) found+=id_found.array[i]; invalid+=id_invalid.array[i]; } fprintf(fps[j], "%d;%d;\n", found, id_found.used-invalid); fclose(fps[j]); } freeArray(&id_found); }