From 6c794f9e2f9dca94b75223a55bbd1b6cbf3e766b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Brostr=C3=B6m?= Date: Mon, 23 Sep 2024 14:11:54 +0200 Subject: [PATCH 1/3] new configs folder --- boxmot/configs/defaults/__init__.py | 1 + boxmot/configs/{ => defaults}/botsort.yaml | 0 boxmot/configs/{ => defaults}/bytetrack.yaml | 0 boxmot/configs/{ => defaults}/deepocsort.yaml | 0 boxmot/configs/{ => defaults}/hybridsort.yaml | 0 boxmot/configs/{ => defaults}/imprassoc.yaml | 0 boxmot/configs/{ => defaults}/ocsort.yaml | 0 boxmot/configs/{ => defaults}/strongsort.yaml | 0 boxmot/tracker_zoo.py | 4 ++-- boxmot/utils/__init__.py | 2 +- 10 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 boxmot/configs/defaults/__init__.py rename boxmot/configs/{ => defaults}/botsort.yaml (100%) rename boxmot/configs/{ => defaults}/bytetrack.yaml (100%) rename boxmot/configs/{ => defaults}/deepocsort.yaml (100%) rename boxmot/configs/{ => defaults}/hybridsort.yaml (100%) rename boxmot/configs/{ => defaults}/imprassoc.yaml (100%) rename boxmot/configs/{ => defaults}/ocsort.yaml (100%) rename boxmot/configs/{ => defaults}/strongsort.yaml (100%) diff --git a/boxmot/configs/defaults/__init__.py b/boxmot/configs/defaults/__init__.py new file mode 100644 index 0000000000..4f7a4d0f1f --- /dev/null +++ b/boxmot/configs/defaults/__init__.py @@ -0,0 +1 @@ +# Mikel Broström 🔥 Yolo Tracking 🧾 AGPL-3.0 license diff --git a/boxmot/configs/botsort.yaml b/boxmot/configs/defaults/botsort.yaml similarity index 100% rename from boxmot/configs/botsort.yaml rename to boxmot/configs/defaults/botsort.yaml diff --git a/boxmot/configs/bytetrack.yaml b/boxmot/configs/defaults/bytetrack.yaml similarity index 100% rename from boxmot/configs/bytetrack.yaml rename to boxmot/configs/defaults/bytetrack.yaml diff --git a/boxmot/configs/deepocsort.yaml b/boxmot/configs/defaults/deepocsort.yaml similarity index 100% rename from boxmot/configs/deepocsort.yaml rename to boxmot/configs/defaults/deepocsort.yaml diff --git a/boxmot/configs/hybridsort.yaml b/boxmot/configs/defaults/hybridsort.yaml similarity index 100% rename from boxmot/configs/hybridsort.yaml rename to boxmot/configs/defaults/hybridsort.yaml diff --git a/boxmot/configs/imprassoc.yaml b/boxmot/configs/defaults/imprassoc.yaml similarity index 100% rename from boxmot/configs/imprassoc.yaml rename to boxmot/configs/defaults/imprassoc.yaml diff --git a/boxmot/configs/ocsort.yaml b/boxmot/configs/defaults/ocsort.yaml similarity index 100% rename from boxmot/configs/ocsort.yaml rename to boxmot/configs/defaults/ocsort.yaml diff --git a/boxmot/configs/strongsort.yaml b/boxmot/configs/defaults/strongsort.yaml similarity index 100% rename from boxmot/configs/strongsort.yaml rename to boxmot/configs/defaults/strongsort.yaml diff --git a/boxmot/tracker_zoo.py b/boxmot/tracker_zoo.py index 82fe748a7d..72285c79e0 100644 --- a/boxmot/tracker_zoo.py +++ b/boxmot/tracker_zoo.py @@ -1,11 +1,11 @@ # Mikel Broström 🔥 Yolo Tracking 🧾 AGPL-3.0 license import yaml -from boxmot.utils import BOXMOT +from boxmot.utils import BOXMOT, TRACKER_CONFIGS def get_tracker_config(tracker_type): """Returns the path to the tracker configuration file.""" - return BOXMOT / 'configs' / f'{tracker_type}.yaml' + return TRACKER_CONFIGS / f'{tracker_type}.yaml' def create_tracker(tracker_type, tracker_config=None, reid_weights=None, device=None, half=None, per_class=None, evolve_param_dict=None): """ diff --git a/boxmot/utils/__init__.py b/boxmot/utils/__init__.py index c3a15a2649..830eb9740a 100644 --- a/boxmot/utils/__init__.py +++ b/boxmot/utils/__init__.py @@ -11,7 +11,7 @@ DATA = ROOT / 'data' BOXMOT = ROOT / "boxmot" EXAMPLES = ROOT / "tracking" -TRACKER_CONFIGS = ROOT / "boxmot" / "configs" +TRACKER_CONFIGS = ROOT / "boxmot" / "defaults" / "configs" WEIGHTS = ROOT / "tracking" / "weights" REQUIREMENTS = ROOT / "requirements.txt" From eb5ec90f17ced84ba16e257ef7414084c5054252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Brostr=C3=B6m?= Date: Mon, 23 Sep 2024 14:18:03 +0200 Subject: [PATCH 2/3] new configs folder --- boxmot/utils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boxmot/utils/__init__.py b/boxmot/utils/__init__.py index 830eb9740a..238a1e9d38 100644 --- a/boxmot/utils/__init__.py +++ b/boxmot/utils/__init__.py @@ -11,7 +11,7 @@ DATA = ROOT / 'data' BOXMOT = ROOT / "boxmot" EXAMPLES = ROOT / "tracking" -TRACKER_CONFIGS = ROOT / "boxmot" / "defaults" / "configs" +TRACKER_CONFIGS = ROOT / "boxmot" / "configs" / "defaults" WEIGHTS = ROOT / "tracking" / "weights" REQUIREMENTS = ROOT / "requirements.txt" From 2365346ec39a79a4f45c85eed08dafd4bda7772b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikel=20Brostr=C3=B6m?= Date: Mon, 23 Sep 2024 14:33:41 +0200 Subject: [PATCH 3/3] search spaces now in yaml files --- boxmot/configs/search/__init__.py | 1 + boxmot/configs/search/botsort.yaml | 37 ++++++++ boxmot/configs/search/bytetrack.yaml | 13 +++ boxmot/configs/search/deepocsort.yaml | 61 +++++++++++++ boxmot/configs/search/hybridsort.yaml | 41 +++++++++ boxmot/configs/search/imprassoc.yaml | 49 ++++++++++ boxmot/configs/search/ocsort.yaml | 37 ++++++++ boxmot/configs/search/strongsort.yaml | 29 ++++++ boxmot/utils/__init__.py | 1 + tracking/evolve.py | 123 +++++++------------------- 10 files changed, 302 insertions(+), 90 deletions(-) create mode 100644 boxmot/configs/search/__init__.py create mode 100644 boxmot/configs/search/botsort.yaml create mode 100644 boxmot/configs/search/bytetrack.yaml create mode 100644 boxmot/configs/search/deepocsort.yaml create mode 100644 boxmot/configs/search/hybridsort.yaml create mode 100644 boxmot/configs/search/imprassoc.yaml create mode 100644 boxmot/configs/search/ocsort.yaml create mode 100644 boxmot/configs/search/strongsort.yaml diff --git a/boxmot/configs/search/__init__.py b/boxmot/configs/search/__init__.py new file mode 100644 index 0000000000..4f7a4d0f1f --- /dev/null +++ b/boxmot/configs/search/__init__.py @@ -0,0 +1 @@ +# Mikel Broström 🔥 Yolo Tracking 🧾 AGPL-3.0 license diff --git a/boxmot/configs/search/botsort.yaml b/boxmot/configs/search/botsort.yaml new file mode 100644 index 0000000000..71ea1c7763 --- /dev/null +++ b/boxmot/configs/search/botsort.yaml @@ -0,0 +1,37 @@ +# botsort_search_space.yaml + +track_high_thresh: + type: uniform + range: [0.3, 0.7] + +track_low_thresh: + type: uniform + range: [0.1, 0.3] + +new_track_thresh: + type: uniform + range: [0.1, 0.8] + +track_buffer: + type: randint + range: [20, 81] + +match_thresh: + type: uniform + range: [0.1, 0.9] + +proximity_thresh: + type: uniform + range: [0.25, 0.75] + +appearance_thresh: + type: uniform + range: [0.1, 0.8] + +cmc_method: + type: choice + options: ['sparseOptFlow'] + +frame_rate: + type: choice + options: [30] diff --git a/boxmot/configs/search/bytetrack.yaml b/boxmot/configs/search/bytetrack.yaml new file mode 100644 index 0000000000..c1249cc468 --- /dev/null +++ b/boxmot/configs/search/bytetrack.yaml @@ -0,0 +1,13 @@ +# bytetrack_search_space.yaml + +track_thresh: + type: uniform + range: [0.4, 0.6] + +track_buffer: + type: randint + range: [10, 61, 10] # The upper bound is exclusive, step size of 10 + +match_thresh: + type: uniform + range: [0.7, 0.9] \ No newline at end of file diff --git a/boxmot/configs/search/deepocsort.yaml b/boxmot/configs/search/deepocsort.yaml new file mode 100644 index 0000000000..1badbe2573 --- /dev/null +++ b/boxmot/configs/search/deepocsort.yaml @@ -0,0 +1,61 @@ +# deepocsort_search_space.yaml + +det_thresh: + type: uniform + range: [0.3, 0.6] + +max_age: + type: randint + range: [10, 61, 10] # The upper bound is exclusive, step size of 10 + +min_hits: + type: randint + range: [1, 6] # The upper bound is exclusive + +iou_thresh: + type: uniform + range: [0.1, 0.4] + +delta_t: + type: randint + range: [1, 6] # The upper bound is exclusive + +asso_func: + type: choice + options: ['iou', 'giou'] + +inertia: + type: uniform + range: [0.1, 0.4] + +w_association_emb: + type: uniform + range: [0.5, 0.9] + +alpha_fixed_emb: + type: uniform + range: [0.9, 0.999] + +aw_param: + type: uniform + range: [0.3, 0.7] + +embedding_off: + type: choice + options: [True, False] + +cmc_off: + type: choice + options: [True, False] + +aw_off: + type: choice + options: [True, False] + +Q_xy_scaling: + type: uniform + range: [0.01, 1] + +Q_s_scaling: + type: uniform + range: [0.0001, 1] diff --git a/boxmot/configs/search/hybridsort.yaml b/boxmot/configs/search/hybridsort.yaml new file mode 100644 index 0000000000..677968e5bb --- /dev/null +++ b/boxmot/configs/search/hybridsort.yaml @@ -0,0 +1,41 @@ +# hybridsort_search_space.yaml + +det_thresh: + type: uniform + range: [0, 0.6] + +max_age: + type: randint + range: [10, 151, 10] # The upper bound is exclusive, step size of 10 + +min_hits: + type: randint + range: [1, 6] # The upper bound is exclusive + +delta_t: + type: randint + range: [1, 6] # The upper bound is exclusive + +asso_func: + type: choice + options: ['iou', 'giou', 'diou'] + +iou_thresh: + type: uniform + range: [0.1, 0.4] + +inertia: + type: uniform + range: [0.1, 0.4] + +TCM_first_step_weight: + type: uniform + range: [0, 0.5] + +longterm_reid_weight: + type: uniform + range: [0, 0.5] + +use_byte: + type: choice + options: [True, False] \ No newline at end of file diff --git a/boxmot/configs/search/imprassoc.yaml b/boxmot/configs/search/imprassoc.yaml new file mode 100644 index 0000000000..9fb5e7c175 --- /dev/null +++ b/boxmot/configs/search/imprassoc.yaml @@ -0,0 +1,49 @@ +# imprassoc_search_space.yaml + +track_high_thresh: + type: uniform + range: [0.3, 0.7] + +track_low_thresh: + type: uniform + range: [0.1, 0.3] + +new_track_thresh: + type: uniform + range: [0.1, 0.8] + +track_buffer: + type: qrandint + range: [20, 80, 10] # The upper bound is exclusive, step size of 10 + +match_thresh: + type: uniform + range: [0.1, 0.9] + +second_match_thresh: + type: uniform + range: [0.1, 0.4] + +overlap_thresh: + type: uniform + range: [0.3, 0.6] + +proximity_thresh: + type: uniform + range: [0.1, 0.8] + +appearance_thresh: + type: uniform + range: [0.1, 0.8] + +cmc_method: + type: choice + options: ['sparseOptFlow'] + +frame_rate: + type: choice + options: [30] + +lambda_: + type: uniform + range: [0.97, 0.995] diff --git a/boxmot/configs/search/ocsort.yaml b/boxmot/configs/search/ocsort.yaml new file mode 100644 index 0000000000..70f2437651 --- /dev/null +++ b/boxmot/configs/search/ocsort.yaml @@ -0,0 +1,37 @@ +# ocsort_search_space.yaml + +det_thresh: + type: uniform + range: [0, 0.6] + +max_age: + type: grid_search + values: [10, 20, 30, 40, 50, 60] # Discrete values using grid search + +min_hits: + type: grid_search + values: [1, 2, 3, 4, 5] # Discrete values using grid search + +delta_t: + type: grid_search + values: [1, 2, 3, 4, 5] # Discrete values using grid search + +asso_func: + type: choice + options: ['iou', 'giou', 'centroid'] + +use_byte: + type: choice + options: [True, False] + +inertia: + type: uniform + range: [0.1, 0.4] + +Q_xy_scaling: + type: loguniform + range: [0.01, 1] + +Q_s_scaling: + type: loguniform + range: [0.0001, 1] \ No newline at end of file diff --git a/boxmot/configs/search/strongsort.yaml b/boxmot/configs/search/strongsort.yaml new file mode 100644 index 0000000000..357fcb4456 --- /dev/null +++ b/boxmot/configs/search/strongsort.yaml @@ -0,0 +1,29 @@ +# strongsort_search_space.yaml + +ema_alpha: + type: uniform + range: [0.7, 0.95] + +max_cos_dist: + type: uniform + range: [0.1, 0.4] + +max_iou_dist: + type: uniform + range: [0.5, 0.95] + +max_age: + type: randint + range: [10, 151] # The upper bound is exclusive + +n_init: + type: randint + range: [1, 4] # The upper bound is exclusive + +mc_lambda: + type: uniform + range: [0.90, 0.999] + +nn_budget: + type: choice + options: [100] \ No newline at end of file diff --git a/boxmot/utils/__init__.py b/boxmot/utils/__init__.py index 238a1e9d38..004f91476b 100644 --- a/boxmot/utils/__init__.py +++ b/boxmot/utils/__init__.py @@ -12,6 +12,7 @@ BOXMOT = ROOT / "boxmot" EXAMPLES = ROOT / "tracking" TRACKER_CONFIGS = ROOT / "boxmot" / "configs" / "defaults" +TRACKER_SEARCH_SPACES = ROOT / "boxmot" / "configs" / "search" WEIGHTS = ROOT / "tracking" / "weights" REQUIREMENTS = ROOT / "requirements.txt" diff --git a/tracking/evolve.py b/tracking/evolve.py index d3f550c865..3661889062 100644 --- a/tracking/evolve.py +++ b/tracking/evolve.py @@ -4,7 +4,7 @@ from pathlib import Path from boxmot.utils.checks import RequirementsChecker -from boxmot.utils import EXAMPLES +from boxmot.utils import EXAMPLES, TRACKER_SEARCH_SPACES from tracking.val import ( run_generate_dets_embs, run_generate_mot_results, @@ -38,103 +38,46 @@ def objective_function(self, config): combined_results = {key: results.get(key) for key in self.opt.objectives} return combined_results + +def load_yaml_config(tracking_method): + config_path = TRACKER_SEARCH_SPACES / f"{tracking_method}.yaml" # Example: 'botsort_search_space.yaml' + with open(config_path, 'r') as file: + config = yaml.safe_load(file) + return config + + # Define the search space for hyperparameters -def get_search_space(tracking_method): - if tracking_method == 'strongsort': - search_space = { - "ema_alpha": tune.uniform(0.7, 0.95), - "max_cos_dist": tune.uniform(0.1, 0.4), - "max_iou_dist": tune.uniform(0.5, 0.95), - "max_age": tune.randint(10, 151), # The upper bound is exclusive in randint - "n_init": tune.randint(1, 4), # The upper bound is exclusive in randint - "mc_lambda": tune.uniform(0.90, 0.999), - "nn_budget": tune.choice([100]), - } - elif tracking_method == 'hybridsort': - search_space = { - "det_thresh": tune.uniform(0, 0.6), - "max_age": tune.randint(10, 151, 10), # The upper bound is exclusive in randint - "min_hits": tune.randint(1, 6), # The upper bound is exclusive in randint - "delta_t": tune.randint(1, 6), # The upper bound is exclusive in randint - "asso_func": tune.choice(['iou', 'giou', 'diou']), - "iou_thresh": tune.uniform(0.1, 0.4), - "inertia": tune.uniform(0.1, 0.4), - "TCM_first_step_weight": tune.uniform(0, 0.5), - "longterm_reid_weight": tune.uniform(0, 0.5), - "use_byte": tune.choice([True, False]) - } - elif tracking_method == 'botsort': - search_space = { - "track_high_thresh": tune.uniform(0.3, 0.7), - "track_low_thresh": tune.uniform(0.1, 0.3), - "new_track_thresh": tune.uniform(0.1, 0.8), - "track_buffer": tune.randint(20, 81, 10), # The upper bound is exclusive in randint - "match_thresh": tune.uniform(0.1, 0.9), - "proximity_thresh": tune.uniform(0.25, 0.75), - "appearance_thresh": tune.uniform(0.1, 0.8), - "cmc_method": tune.choice(['sparseOptFlow']), - "frame_rate": tune.choice([30]), - "lambda_": tune.uniform(0.97, 0.995) - } - elif tracking_method == 'bytetrack': - search_space = { - "track_thresh": tune.uniform(0.4, 0.6), - "track_buffer": tune.randint(10, 61, 10), # The upper bound is exclusive in randint - "match_thresh": tune.uniform(0.7, 0.9) - } - elif tracking_method == 'ocsort': - search_space = { - "det_thresh": tune.uniform(0, 0.6), - "max_age": tune.grid_search([10, 20, 30, 40, 50, 60]), # Since step is 10, using grid_search for these discrete values - "min_hits": tune.grid_search([1, 2, 3, 4, 5]), # Since step is 1, using grid_search for these discrete values - "delta_t": tune.grid_search([1, 2, 3, 4, 5]), # Since step is 1, using grid_search for these discrete values - "asso_func": tune.choice(['iou', 'giou', 'centroid']), - "use_byte": tune.choice([True, False]), - "inertia": tune.uniform(0.1, 0.4), - "Q_xy_scaling": tune.loguniform(0.01, 1), - "Q_s_scaling": tune.loguniform(0.0001, 1) - } - elif tracking_method == 'deepocsort': - search_space = { - "det_thresh": tune.uniform(0.3, 0.6), # Changed from int to uniform since it seems to be a float range - "max_age": tune.randint(10, 61, 10), # The upper bound is exclusive in randint - "min_hits": tune.randint(1, 6), # The upper bound is exclusive in randint - "iou_thresh": tune.uniform(0.1, 0.4), - "delta_t": tune.randint(1, 6), # The upper bound is exclusive in randint - "asso_func": tune.choice(['iou', 'giou']), - "inertia": tune.uniform(0.1, 0.4), - "w_association_emb": tune.uniform(0.5, 0.9), - "alpha_fixed_emb": tune.uniform(0.9, 0.999), - "aw_param": tune.uniform(0.3, 0.7), - "embedding_off": tune.choice([True, False]), - "cmc_off": tune.choice([True, False]), - "aw_off": tune.choice([True, False]), - "Q_xy_scaling": tune.uniform(0.01, 1), - "Q_s_scaling": tune.uniform(0.0001, 1) - } - elif tracking_method == 'imprassoc': - search_space = { - "track_high_thresh": tune.uniform(0.3, 0.7), - "track_low_thresh": tune.uniform(0.1, 0.3), - "new_track_thresh": tune.uniform(0.1, 0.8), - "track_buffer": tune.qrandint(20, 80, 10), # The upper bound is exclusive in randint - "match_thresh": tune.uniform(0.1, 0.9), - "second_match_thresh": tune.uniform(0.1, 0.4), - "overlap_thresh": tune.uniform(0.3, 0.6), - "proximity_thresh": tune.uniform(0.1, 0.8), - "appearance_thresh": tune.uniform(0.1, 0.8), - "cmc_method": tune.choice(['sparseOptFlow']), - "frame_rate": tune.choice([30]), - "lambda_": tune.uniform(0.97, 0.995) - } +def yaml_to_search_space(config): + search_space = {} + for param, details in config.items(): + search_type = details['type'] + if search_type == 'uniform': + search_space[param] = tune.uniform(*details['range']) + elif search_type == 'randint': + search_space[param] = tune.randint(*details['range']) + elif search_type == 'qrandint': + search_space[param] = tune.qrandint(*details['range']) + elif search_type == 'choice': + search_space[param] = tune.choice(details['options']) + elif search_type == 'grid_search': + search_space[param] = tune.grid_search(details['values']) + elif search_type == 'loguniform': + search_space[param] = tune.loguniform(*details['range']) return search_space + opt = parse_optt() opt.val_tools_path = EXAMPLES / 'val_utils' opt.source = Path(opt.source).resolve() opt.yolo_model = [Path(y).resolve() for y in opt.yolo_model] opt.reid_model = [Path(r).resolve() for r in opt.reid_model] -search_space = get_search_space(opt.tracking_method) + +# Load the appropriate YAML configuration +yaml_config = load_yaml_config(opt.tracking_method) + +# Convert YAML config to Ray Tune search space +search_space = yaml_to_search_space(yaml_config) + tracker = Tracker(opt, search_space) run_generate_dets_embs(opt)