diff --git a/Makefile b/Makefile index 40bfcecb..cdf200c5 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -GPU=1 -OPENCV=1 +GPU=0 +OPENCV=0 DEBUG=0 ARCH= --gpu-architecture=compute_20 --gpu-code=compute_20 @@ -12,7 +12,7 @@ CC=gcc NVCC=nvcc OPTS=-Ofast LDFLAGS= -lm -pthread -lstdc++ -COMMON= -I/usr/local/cuda/include/ +COMMON= CFLAGS=-Wall -Wfatal-errors ifeq ($(DEBUG), 1) @@ -29,7 +29,7 @@ COMMON+= `pkg-config --cflags opencv` endif ifeq ($(GPU), 1) -COMMON+= -DGPU +COMMON+= -DGPU -I/usr/local/cuda/include/ CFLAGS+= -DGPU LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand endif diff --git a/cfg/darknet.cfg b/cfg/darknet.cfg index 64aab1ed..0b3c46c7 100644 --- a/cfg/darknet.cfg +++ b/cfg/darknet.cfg @@ -1,5 +1,5 @@ [net] -batch=256 +batch=128 subdivisions=1 height=256 width=256 @@ -8,10 +8,10 @@ momentum=0.9 decay=0.0005 learning_rate=0.01 -policy=step -scale=.1 -step=100000 -max_batches=400000 +policy=sigmoid +gamma=.00002 +step=400000 +max_batches=800000 [crop] crop_height=224 diff --git a/cfg/yolo.cfg b/cfg/yolo.cfg index 88176a65..ab46729c 100644 --- a/cfg/yolo.cfg +++ b/cfg/yolo.cfg @@ -206,4 +206,5 @@ coords=4 rescore=0 joint=0 objectness=1 +background=0 diff --git a/src/box.c b/src/box.c index 6045d9a7..b99300d3 100644 --- a/src/box.c +++ b/src/box.c @@ -2,6 +2,16 @@ #include #include +box float_to_box(float *f) +{ + box b; + b.x = f[0]; + b.y = f[1]; + b.w = f[2]; + b.h = f[3]; + return b; +} + dbox derivative(box a, box b) { dbox d; diff --git a/src/box.h b/src/box.h index f7ef36fd..9b57fb45 100644 --- a/src/box.h +++ b/src/box.h @@ -9,6 +9,7 @@ typedef struct{ float dx, dy, dw, dh; } dbox; +box float_to_box(float *f); float box_iou(box a, box b); float box_rmse(box a, box b); dbox diou(box a, box b); diff --git a/src/compare.c b/src/compare.c index 0408f800..74c1cf54 100644 --- a/src/compare.c +++ b/src/compare.c @@ -241,7 +241,8 @@ void BattleRoyaleWithCheese(char *filename, char *weightfile) srand(time(0)); set_batch_network(&net, 1); - list *plist = get_paths("data/compare.sort.list"); + //list *plist = get_paths("data/compare.sort.list"); + list *plist = get_paths("data/compare.cat.list"); //list *plist = get_paths("data/compare.val.old"); char **paths = (char **)list_to_array(plist); int N = plist->size; @@ -256,15 +257,16 @@ void BattleRoyaleWithCheese(char *filename, char *weightfile) } int round; clock_t time=clock(); - for(round = 1; round <= 40; ++round){ + for(round = 1; round <= 500; ++round){ clock_t round_time=clock(); printf("Round: %d\n", round); qsort(boxes, N, sizeof(sortable_bbox), elo_comparator); sorta_shuffle(boxes, N, sizeof(sortable_bbox), 10); + shuffle(boxes, N, sizeof(sortable_bbox)); for(i = 0; i < N/2; ++i){ bbox_fight(boxes+i*2, boxes+i*2+1); } - if(round >= 4){ + if(round >= 4 && 0){ qsort(boxes, N, sizeof(sortable_bbox), elo_comparator); if(round == 4){ N = N/2; @@ -275,9 +277,11 @@ void BattleRoyaleWithCheese(char *filename, char *weightfile) printf("Round: %f secs, %d remaining\n", sec(clock()-round_time), N); } qsort(boxes, N, sizeof(sortable_bbox), elo_comparator); + FILE *outfp = fopen("results/battle.log", "w"); for(i = 0; i < N; ++i){ - printf("%s %f\n", boxes[i].filename, boxes[i].elo); + fprintf(outfp, "%s %f\n", boxes[i].filename, boxes[i].elo); } + fclose(outfp); printf("Tournament in %d compares, %f secs\n", total_compares, sec(clock()-time)); } diff --git a/src/layer.h b/src/layer.h index 1eb73512..d13cdbfa 100644 --- a/src/layer.h +++ b/src/layer.h @@ -60,6 +60,11 @@ typedef struct { float beta; float kappa; + float coord_scale; + float object_scale; + float noobject_scale; + float class_scale; + int dontload; float probability; diff --git a/src/parser.c b/src/parser.c index 53e84615..7ea1b3ff 100644 --- a/src/parser.c +++ b/src/parser.c @@ -182,10 +182,14 @@ region_layer parse_region(list *options, size_params params) int num = option_find_int(options, "num", 1); int side = option_find_int(options, "side", 7); region_layer layer = make_region_layer(params.batch, params.inputs, num, side, classes, coords, rescore); - int softmax = option_find_int(options, "softmax", 0); - int sqrt = option_find_int(options, "sqrt", 0); - layer.softmax = softmax; - layer.sqrt = sqrt; + + layer.softmax = option_find_int(options, "softmax", 0); + layer.sqrt = option_find_int(options, "sqrt", 0); + + layer.coord_scale = option_find_float(options, "coord_scale", 1); + layer.object_scale = option_find_float(options, "object_scale", 1); + layer.noobject_scale = option_find_float(options, "noobject_scale", 1); + layer.class_scale = option_find_float(options, "class_scale", 1); return layer; } diff --git a/src/region_layer.c b/src/region_layer.c index d65c1a87..ecb89c64 100644 --- a/src/region_layer.c +++ b/src/region_layer.c @@ -44,15 +44,20 @@ void forward_region_layer(const region_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)); - for(i = 0; i < l.batch*locations; ++i){ - int index = i*((1+l.coords)*l.n + l.classes); - if(l.softmax){ - activate_array(l.output + index, l.n*(1+l.coords), LOGISTIC); - int offset = l.n*(1+l.coords); - softmax_array(l.output + index + offset, l.classes, - l.output + index + offset); + 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, + l.output + index + offset); + } + int offset = locations*l.classes; + activate_array(l.output + index + offset, locations*l.n*(1+l.coords), LOGISTIC); } } + if(state.train){ float avg_iou = 0; float avg_cat = 0; @@ -62,94 +67,91 @@ void forward_region_layer(const region_layer l, network_state state) *(l.cost) = 0; int size = l.inputs * l.batch; memset(l.delta, 0, size * sizeof(float)); - for (i = 0; i < l.batch*locations; ++i) { - int index = i*((1+l.coords)*l.n + l.classes); - for(j = 0; j < l.n; ++j){ - int prob_index = index + j*(1 + l.coords); - l.delta[prob_index] = (1./l.n)*(0-l.output[prob_index]); - if(l.softmax){ - l.delta[prob_index] = 1./(l.n*l.side)*(0-l.output[prob_index]); - } - *(l.cost) += (1./l.n)*pow(l.output[prob_index], 2); - //printf("%f\n", l.output[prob_index]); - avg_anyobj += l.output[prob_index]; - } - - int truth_index = i*(1 + l.coords + l.classes); - int best_index = -1; - float best_iou = 0; - float best_rmse = 4; - - int bg = !state.truth[truth_index]; - if(bg) { - continue; - } - - int class_index = index + l.n*(1+l.coords); - for(j = 0; j < l.classes; ++j) { - l.delta[class_index+j] = state.truth[truth_index+1+j] - l.output[class_index+j]; - *(l.cost) += 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]; - } - truth_index += l.classes + 1; - box truth = {state.truth[truth_index+0], state.truth[truth_index+1], state.truth[truth_index+2], state.truth[truth_index+3]}; - truth.x /= l.side; - truth.y /= l.side; - - for(j = 0; j < l.n; ++j){ - int out_index = index + j*(1+l.coords); - box out = {l.output[out_index+1], l.output[out_index+2], l.output[out_index+3], l.output[out_index+4]}; - - out.x /= l.side; - out.y /= l.side; - if (l.sqrt){ - out.w = out.w*out.w; - out.h = out.h*out.h; + 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]; } - 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; + int best_index = -1; + float best_iou = 0; + float best_rmse = 4; + + 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]; + } + + 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; } - }else{ - if(rmse < best_rmse){ - best_rmse = rmse; - best_index = j; + + 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 in_index = index + best_index*(1+l.coords); - *(l.cost) -= pow(l.output[in_index], 2); - *(l.cost) += pow(1-l.output[in_index], 2); - avg_obj += l.output[in_index]; - l.delta[in_index+0] = (1.-l.output[in_index]); - if(l.softmax){ - l.delta[in_index+0] = 5*(1.-l.output[in_index]); - } - //printf("%f\n", l.output[in_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+0] = l.object_scale * (1.-l.output[p_index]); - l.delta[in_index+1] = 5*(state.truth[truth_index+0] - l.output[in_index+1]); - l.delta[in_index+2] = 5*(state.truth[truth_index+1] - l.output[in_index+2]); - if(l.sqrt){ - l.delta[in_index+3] = 5*(sqrt(state.truth[truth_index+2]) - l.output[in_index+3]); - l.delta[in_index+4] = 5*(sqrt(state.truth[truth_index+3]) - l.output[in_index+4]); - }else{ - l.delta[in_index+3] = 5*(state.truth[truth_index+2] - l.output[in_index+3]); - l.delta[in_index+4] = 5*(state.truth[truth_index+3] - l.output[in_index+4]); - } + if(l.rescore){ + l.delta[p_index+0] = l.object_scale * (best_iou - l.output[p_index]); + } - *(l.cost) += pow(1-best_iou, 2); - avg_iou += best_iou; - ++count; + int box_index = index + locations*(l.classes + l.n) + (i*l.n + best_index) * l.coords; + int tbox_index = truth_index + 1 + l.classes; + 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-best_iou, 2); + avg_iou += best_iou; + ++count; + } if(l.softmax){ - gradient_array(l.output + index, l.n*(1+l.coords), LOGISTIC, l.delta + index); + gradient_array(l.output + index + locations*l.classes, locations*l.n*(1+l.coords), + LOGISTIC, l.delta + index + locations*l.classes); } } - printf("Avg IOU: %f, Avg Cat Pred: %f, Avg Obj: %f, Avg Any: %f, count: %d\n", avg_iou/count, avg_cat/count, avg_obj/count, avg_anyobj/(l.batch*locations*l.n), count); + printf("Region Avg IOU: %f, Avg Cat Pred: %f, Avg Obj: %f, Avg Any: %f, count: %d\n", avg_iou/count, avg_cat/count, avg_obj/count, avg_anyobj/(l.batch*locations*l.n), count); } } diff --git a/src/stb_image_write.h b/src/stb_image_write.h index 10489707..f5250b31 100644 --- a/src/stb_image_write.h +++ b/src/stb_image_write.h @@ -279,7 +279,7 @@ void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scra { unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; unsigned char rgbe[4]; - float linear[3]; + float linear[3] = {0}; int x; scanlineheader[2] = (width&0xff00)>>8; diff --git a/src/swag.c b/src/swag.c index 4dcf36bf..1398192d 100644 --- a/src/swag.c +++ b/src/swag.c @@ -77,7 +77,7 @@ void train_swag(char *cfgfile, char *weightfile) int classes = l.classes; list *plist = get_paths(train_images); - int N = plist->size; + //int N = plist->size; char **paths = (char **)list_to_array(plist); load_args args = {0};