Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| This script runs a hyperparameter tuning process for a multi-object tracking (MOT) tracker using Ray Tune. | |
| It loads the tracker configuration from a YAML file, sets up the search space for hyperparameters, and evaluates | |
| the tracker to optimize selected metrics (e.g., MOTA, HOTA, IDF1). | |
| """ | |
| import os | |
| from pathlib import Path | |
| import yaml | |
| # Check required packages | |
| from boxmot.utils.checks import RequirementsChecker | |
| checker = RequirementsChecker() | |
| checker.check_packages(('ray[tune]',)) # Install ray[tune] if not already present | |
| import ray | |
| from ray import tune | |
| from ray.air import RunConfig | |
| from boxmot.utils.checks import RequirementsChecker | |
| from boxmot.utils import EXAMPLES, TRACKER_CONFIGS, ROOT, NUM_THREADS | |
| from tracking.val import ( | |
| run_generate_dets_embs, | |
| run_generate_mot_results, | |
| run_trackeval, | |
| parse_opt as parse_optt, | |
| download_mot_eval_tools | |
| ) | |
| class Tracker: | |
| """ | |
| Encapsulates the evaluation of a tracking configuration. | |
| """ | |
| def __init__(self, opt): | |
| self.opt = opt | |
| def objective_function(self, config: dict) -> dict: | |
| """ | |
| Evaluates a given tracker configuration. | |
| Args: | |
| config (dict): A dictionary of tracker hyperparameters. | |
| Returns: | |
| dict: Combined evaluation metrics extracted from run_trackeval. | |
| """ | |
| # Ensure evaluation tools are available | |
| download_mot_eval_tools(self.opt.val_tools_path) | |
| # Generate MOT-compliant results with the specified tracker parameters | |
| run_generate_mot_results(self.opt, config) | |
| # Retrieve evaluation metrics (e.g., MOTA, HOTA, IDF1) | |
| results = run_trackeval(self.opt) | |
| # Extract only the desired objective results | |
| combined_results = {key: results.get(key) for key in self.opt.objectives} | |
| return combined_results | |
| def load_yaml_config(tracking_method: str) -> dict: | |
| """ | |
| Loads the YAML configuration file for the given tracking method. | |
| Args: | |
| tracking_method (str): Name of the tracking method. | |
| Returns: | |
| dict: Configuration parameters loaded from the YAML file. | |
| """ | |
| config_path = TRACKER_CONFIGS / f"{tracking_method}.yaml" | |
| with open(config_path, 'r') as file: | |
| config = yaml.safe_load(file) | |
| return config | |
| def yaml_to_search_space(config: dict) -> dict: | |
| """ | |
| Converts a YAML configuration dictionary to a Ray Tune search space. | |
| Args: | |
| config (dict): YAML configuration parameters. | |
| Returns: | |
| dict: A dictionary representing the search space for hyperparameters. | |
| """ | |
| search_space = {} | |
| for param, details in config.items(): | |
| search_type = details.get('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 | |
| def main(): | |
| # Parse options and set necessary paths | |
| 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] | |
| # Load YAML configuration and convert it to a Ray Tune search space | |
| yaml_config = load_yaml_config(opt.tracking_method) | |
| search_space = yaml_to_search_space(yaml_config) | |
| # Create a Tracker instance | |
| tracker = Tracker(opt) | |
| # Generate detection and embedding files required for evaluation | |
| run_generate_dets_embs(opt) | |
| # Define a wrapper for the objective function for Ray Tune | |
| def tune_wrapper(config): | |
| return tracker.objective_function(config) | |
| results_dir = os.path.abspath("ray/") | |
| # Set up and run the hyperparameter tuning using Ray Tune | |
| tuner = tune.Tuner( | |
| tune.with_resources(tune_wrapper, {"cpu": NUM_THREADS, "gpu": 0}), | |
| param_space=search_space, | |
| tune_config=tune.TuneConfig(num_samples=opt.n_trials), | |
| run_config=RunConfig(storage_path=results_dir) | |
| ) | |
| tuner.fit() | |
| # Print the tuning results | |
| print(tuner.get_results()) | |
| if __name__ == "__main__": | |
| main() | |