Source code for probe_ably.core.utils.grid_model_factory

import glob
import importlib
import json
import os
import random
from typing import Any, Dict, List

import numpy as np
from probe_ably.core.models import AbstractModel


[docs]class GridModelFactory:
[docs] @staticmethod def create_models( model_class: str, num_models: int = 50, param_args: Dict = {} ) -> List[AbstractModel]: """Creates a list of models provided from static param ranges Args: model_class (str): Probing model class. For example: :code:`probe_ably.core.models.linear` num_models (int, optional): Number of Models to create. Defaults to 50. param_args (Dict, optional): Paramter ranges to choose from the model to create. Defaults to {}. Returns: List[AbstractModel]: Creates a Grid with the prescribed parameter ranges and returns list of models with size num_models by random initialization """ paths = glob.glob("./config/params/*.json") params = None for path in paths: with open(path, "r") as f: maybe_params = json.load(f) if model_class in maybe_params: params = maybe_params[model_class]["params"] break if not params: raise FileNotFoundError("No parameters specified, dear.") ModelClass = AbstractModel.subclasses[model_class] generated_params = dict() i = 0 for param in params: if param["type"] == "float_range": if param["name"] == "alpha": generated_params[param["name"]] = np.array( [0] + [ 2 ** x for x in np.linspace( start=-10, stop=3, num=(num_models - 1) ) ] ) else: generated_params[param["name"]] = np.random.uniform( low=float(param["options"][0]), high=float(param["options"][1]), size=(num_models,), ) elif param["type"] == "int_range": if param["name"] == "hidden_size": generated_params[param["name"]] = random.choices( list({int(2 ** x) for x in np.arange(5, 10, 0.01)}), k=num_models, ) else: generated_params[param["name"]] = random.choices( range(int(param["options"][0]), int(param["options"][1])), k=num_models, ) elif param["type"] == "categorical": value = np.random_choice(param["options"]) chosen_params_dict = dict() for i in range(num_models): chosen_params_dict[i] = dict() for key_name, values in generated_params.items(): chosen_params_dict[i][key_name] = values[i] models = [] for i in range(num_models): # chosen_params = choose_params(params) model = ModelClass({**chosen_params_dict[i], **param_args}) models.append(model) return models
def _choose_params(params: List[Dict]): "" names = [param["name"] for param in params] values = [_choose_one_param_value(param) for param in params] return dict(zip(names, values)) def _choose_one_param_value(param): "" if param["type"] == "float_range": value = random.uniform(float(param["options"][0]), float(param["options"][1])) elif param["type"] == "int_range": value = random.randint(int(param["options"][0]), int(param["options"][1])) elif param["type"] == "categorical": value = np.random_choice(param["options"]) else: raise ValueError(f"Invalid or no value options for parameter {params['name']}") try: if param["transform"] == "2**x": value = 2 ** (value) except KeyError: pass return value