void JoinCascador::Snapshot() const { int stage_idx = current_stage_idx; int cart_idx = current_cart_idx; char buff1[256]; char buff2[256]; time_t t = time(NULL); strftime(buff1, sizeof(buff1), "%Y%m%d-%H%M%S", localtime(&t)); sprintf(buff2, "../model/jda_tmp_%s_stage_%d_cart_%d.model", \ buff1, stage_idx + 1, cart_idx + 1); FILE* fd = fopen(buff2, "wb"); JDA_Assert(fd, "Can not open a temp file to save the model"); SerializeTo(fd); fclose(fd); }
void JoinCascador::SerializeFrom(FILE* fd) { int tmp; fread(&YO, sizeof(YO), 1, fd); fread(&tmp, sizeof(int), 1, fd); JDA_Assert(tmp == T, "T is wrong!"); fread(&tmp, sizeof(int), 1, fd); JDA_Assert(tmp == K, "K is wrong!"); fread(&tmp, sizeof(int), 1, fd); JDA_Assert(tmp == landmark_n, "landmark_n is wrong!"); fread(&tmp, sizeof(int), 1, fd); JDA_Assert(tmp == tree_depth, "tree_depth is wrong!"); fread(&tmp, sizeof(int), 1, fd); JDA_Assert(0 <= tmp && tmp <= T, "current_stage_idx out of range"); current_stage_idx = tmp; fread(&tmp, sizeof(int), 1, fd); JDA_Assert(-1 <= tmp && tmp < K, "current_cart_idx out of range"); current_cart_idx = tmp; // mean shape mean_shape.create(1, 2 * landmark_n); fread(mean_shape.ptr<double>(0), sizeof(double), mean_shape.cols, fd); for (int t = 0; t < T; t++) { BoostCart& btcart = btcarts[t]; for (int k = 0; k < K; k++) { Cart& cart = btcart.carts[k]; cart.SerializeFrom(fd); } // global regression parameters double* w_ptr; const int w_rows = landmark_n * 2; const int w_cols = K * (1 << (tree_depth - 1)); for (int i = 0; i < w_rows; i++) { w_ptr = btcart.w.ptr<double>(i); fread(w_ptr, sizeof(double), w_cols, fd); } } fread(&YO, sizeof(YO), 1, fd); }
/*! * \brief draw the distribution of scores * \note scores should be in order */ static void draw_density_graph(vector<double>& pos_scores, vector<double>& neg_scores, \ const int n = 100, const int rows = 20) { JDA_Assert(n < 115, "number of bins should be less than 150"); JDA_Assert(rows < 100, "graph rows should be less than 100"); double s_max = max(pos_scores[0], neg_scores[0]); int pos_size = pos_scores.size(); int neg_size = neg_scores.size(); double s_min = min(pos_scores[pos_size - 1], neg_scores[neg_size - 1]); vector<int> pos_bin(n, 0); vector<int> neg_bin(n, 0); double delta = (s_max - s_min) / n + 1e-9; double th = s_max - delta; // calc bin int bin_idx = 0; for (int i = 0; i < pos_size; i++) { if (pos_scores[i] >= th) { pos_bin[bin_idx]++; } else { i--; bin_idx++; th -= delta; } } th = s_max - delta; bin_idx = 0; for (int i = 0; i < neg_size; i++) { if (neg_scores[i] >= th) { neg_bin[bin_idx]++; } else { i--; bin_idx++; th -= delta; } } // enlargre local detail double max_bin_rate = 0; double min_bin_rate = 1; for (int i = 0; i < n; i++) { if (pos_bin[i] > 0) { double bin_rate = pos_bin[i] / double(pos_size); if (bin_rate > max_bin_rate) max_bin_rate = bin_rate; if (bin_rate < min_bin_rate) min_bin_rate = bin_rate; } if (neg_bin[i] > 0) { double bin_rate = neg_bin[i] / double(neg_size); if (bin_rate > max_bin_rate) max_bin_rate = bin_rate; if (bin_rate < min_bin_rate) min_bin_rate = bin_rate; } } max_bin_rate += 1e-5; min_bin_rate -= 1e-5; double range = max_bin_rate - min_bin_rate + 1e-18; // draw graph int graph[100][120] = { 0 }; for (int i = 0; i < n; i++) { if (pos_bin[i]>0) { int density = int((pos_bin[i] / double(pos_size) - min_bin_rate) / range * rows); graph[density][i] += 1; } if (neg_bin[i] > 0) { int density = int((neg_bin[i] / double(neg_size) - min_bin_rate) / range * rows); graph[density][i] += 2; } } // render graph for (int c = 0; c < n + 8; c++) { printf("="); } printf("\n"); char var[5] = { ' ', '+', 'x', '*' }; for (int r = rows - 1; r >= 0; r--) { printf("%06.2lf%% ", (double(r + 1) / rows * range + min_bin_rate) * 100); for (int c = 0; c < n; c++) { printf("%c", var[graph[r][c]]); } printf("\n"); } for (int c = 0; c < n + 8; c++) { printf("="); } printf("\n"); }
Config::Config() { jsmn::Object json_config = jsmn::parse("../config.json"); // model meta data T = json_config["T"].unwrap<Number>(); K = json_config["K"].unwrap<Number>(); landmark_n = json_config["landmark_n"].unwrap<Number>(); tree_depth = json_config["tree_depth"].unwrap<Number>(); shift_size = json_config["random_shift"].unwrap<Number>(); use_gini = json_config["classification"]["gini"].unwrap<Boolean>(); bool use_entropy = json_config["classification"]["entropy"].unwrap<Boolean>(); JDA_Assert(!(use_gini && use_entropy), "gini and entropy shouldn\'t be both true"); JDA_Assert(use_gini || use_entropy, "gini and entropy shouldn\'t be both false"); // image size jsmn::Object& image_size_config = json_config["image_size"].unwrap<Object>(); multi_scale = image_size_config["multi_scale"].unwrap<Boolean>(); img_o_size = image_size_config["origin_size"].unwrap<Number>(); img_h_size = image_size_config["half_size"].unwrap<Number>(); img_q_size = image_size_config["quarter_size"].unwrap<Number>(); // hard negative mining jsmn::Object& mining_config = json_config["hard_negative_mining"].unwrap<Object>(); x_step = mining_config["x_step"].unwrap<Number>(); y_step = mining_config["y_step"].unwrap<Number>(); scale_factor = mining_config["scale"].unwrap<Number>(); mining_pool_size = omp_get_max_threads(); esp = 2.2e-16; // stage parameters jsmn::Object& stages = json_config["stages"].unwrap<Object>(); this->feats.clear(); this->radius.clear(); this->probs.clear(); for (int i = 0; i < T; i++) { this->feats.push_back(stages["feature_pool_size"][i].unwrap<Number>()); this->nps.push_back(stages["neg_pos_ratio"][i].unwrap<Number>()); this->radius.push_back(stages["random_sample_radius"][i].unwrap<Number>()); this->probs.push_back(stages["classification_p"][i].unwrap<Number>()); this->recall.push_back(stages["recall"][i].unwrap<Number>()); } // data jsmn::Object& data = json_config["data"].unwrap<Object>(); train_pos_txt = data["face"].unwrap<jsmn::String>(); test_pos_txt = "../data/test.txt"; train_neg_txt = data["background"].unwrap<jsmn::String>(); test_neg_txt = "../data/test_nega.txt"; detection_txt = "../data/detection.txt"; // status if (json_config["phase"].unwrap<jsmn::String>() == "train") phase = 0; else phase = 1; tmp_model = json_config["tmp_model"].unwrap<jsmn::String>(); snapshot_iter = json_config["snapshot_iter"].unwrap<Number>(); // fddb benchmark jsmn::Object& fddb = json_config["fddb"].unwrap<Object>(); fddb_result = fddb["out"].unwrap<Boolean>(); fddb_nms = fddb["nms"].unwrap<Boolean>(); fddb_minimum_size = fddb["minimum_size"].unwrap<Number>(); fddb_x_step = fddb["x_step"].unwrap<Number>(); fdbb_y_step = fddb["y_step"].unwrap<Number>(); fddb_scale_factor = fddb["scale"].unwrap<Number>(); fddb_overlap = fddb["overlap"].unwrap<Number>(); }
Config::Config(){ jsmn::Object json_config = jsmn::parse("../config.json"); // model meta data T = json_config["T"].unwrap<Number>(); K = json_config["K"].unwrap<Number>(); landmark_n = json_config["landmark_n"].unwrap<Number>(); tree_depth = json_config["tree_depth"].unwrap<Number>(); shift_size = json_config["random_shift"].unwrap<Number>(); // image size jsmn::Object& image_size_config = json_config["image_size"].unwrap<Object>(); multi_scale = image_size_config["multi_scale"].unwrap<Boolean>(); img_o_size = image_size_config["origin_size"].unwrap<Number>(); img_h_size = image_size_config["half_size"].unwrap<Number>(); img_q_size = image_size_config["quarter_size"].unwrap<Number>(); // hard negative mining jsmn::Object& mining_config = json_config["hard_negative_mining"].unwrap< Object>(); mining_factor = mining_config["factor"].unwrap<Number>(); mining_min_size = mining_config["min_size"].unwrap<Number>(); mining_step_ratio = mining_config["step_ratio"].unwrap<Number>(); mining_th = mining_config["mining_th"].unwrap<Number>(); esp = 2.2e-16; // stage parameters jsmn::Object& stages = json_config["stages"].unwrap<Object>(); this->feats.clear(); this->radius.clear(); this->probs.clear(); for(int i = 0; i < T; i++){ this->feats.push_back(stages["feature_pool_size"][i].unwrap<Number>()); this->nps.push_back(stages["neg_pos_ratio"][i].unwrap<Number>()); this->radius.push_back(stages["random_sample_radius"][i].unwrap<Number>()); this->probs.push_back(stages["classification_p"][i].unwrap<Number>()); this->recall.push_back(stages["recall"][i].unwrap<Number>()); } // data jsmn::Object& data = json_config["data"].unwrap<Object>(); use_hard = data["use_hard"].unwrap<Boolean>(); face_txt = data["face"].unwrap<jsmn::String>(); test_txt = data["test"].unwrap<jsmn::String>(); jsmn::Array& neg_list = data["background"].unwrap<jsmn::Array>(); bg_txts.resize(neg_list.size()); for(int i = 0; i < neg_list.size(); i++){ bg_txts[i] = neg_list[i].unwrap<jsmn::String>(); } // status resume_model = json_config["resume_model"].unwrap<jsmn::String>(); snapshot_iter = json_config["snapshot_iter"].unwrap<Number>(); // fddb benchmark jsmn::Object& fddb = json_config["fddb"].unwrap<Object>(); fddb_dir = fddb["dir"].unwrap<jsmn::String>(); fddb_result = fddb["out"].unwrap<Boolean>(); fddb_nms = fddb["nms"].unwrap<Boolean>(); fddb_minimum_size = fddb["minimum_size"].unwrap<Number>(); fddb_step = fddb["step"].unwrap<Number>(); fddb_scale_factor = fddb["scale"].unwrap<Number>(); fddb_overlap = fddb["overlap"].unwrap<Number>(); fddb_draw_score = fddb["draw_score"].unwrap<Boolean>(); fddb_draw_shape = fddb["draw_shape"].unwrap<Boolean>(); fddb_detect_method = fddb["method"].unwrap<Number>(); // cart jsmn::Object& cart = json_config["cart"].unwrap<Object>(); restart_on = cart["restart"]["on"].unwrap<Boolean>(); jsmn::Array& ths = cart["restart"]["th"].unwrap<Array>(); restart_th.resize(ths.size()); for(int i = 0; i < restart_th.size(); i++){ restart_th[i] = ths[i].unwrap<Number>(); } restart_times = cart["restart"]["times"].unwrap<Number>(); // face augment jsmn::Object& face = json_config["face"].unwrap<Object>(); face_augment_on = face["online_augment"].unwrap<Boolean>(); symmetric_landmarks.resize(2); int offset = face["symmetric_landmarks"]["offset"].unwrap<Number>(); jsmn::Array& left = face["symmetric_landmarks"]["left"].unwrap<Array>(); jsmn::Array& right = face["symmetric_landmarks"]["right"].unwrap<Array>(); JDA_Assert(left.size() == right.size(), "Symmetric left and right landmarks are not equal size"); symmetric_landmarks[0].resize(left.size()); symmetric_landmarks[1].resize(right.size()); for(int i = 0; i < left.size(); i++){ symmetric_landmarks[0][i] = left[i].unwrap<Number>() - offset; symmetric_landmarks[1][i] = right[i].unwrap<Number>() - offset; } // pupils jsmn::Object& pupils = face["pupils"].unwrap<Object>(); offset = pupils["offset"].unwrap<Number>(); jsmn::Array& pupils_left = pupils["left"].unwrap<Array>(); jsmn::Array& pupils_right = pupils["right"].unwrap<Array>(); left_pupils.resize(pupils_left.size()); right_pupils.resize(pupils_right.size()); for(int i = 0; i < pupils_left.size(); i++){ left_pupils[i] = pupils_left[i].unwrap<Number>() - offset; } for(int i = 0; i < pupils_right.size(); i++){ right_pupils[i] = pupils_right[i].unwrap<Number>() - offset; } // random generator pool int rng_size = 2 * omp_get_max_threads(); rng_pool.reserve(rng_size); for(int i = 0; i < rng_size; i++){ rng_pool.push_back(RNG(cv::getTickCount())); } }