Examples: query, "exact match", wildcard*, wild?ard, wild*rd
Fuzzy search: cake~ (finds cakes, bake)
Term boost: "red velvet"^4, chocolate^2
Field grouping: tags:(+work -"fun-stuff")
Escaping: Escape characters +-&|!(){}[]^"~*?:\ with \, e.g. \+
Range search: properties.timestamp:[1587729413488 TO *] (inclusive), properties.title:{A TO Z}(excluding A and Z)
Combinations: chocolate AND vanilla, chocolate OR vanilla, (chocolate OR vanilla) NOT "vanilla pudding"
Field search: properties.title:"The Title" AND text
Answered
Hi, I Have Some Questions About Hyperparameter Optimization. We Have A Setup Where We Use Pytorchlightning Cli With Clearml For Experiment Tracking And Hyperparameter Optimization. Now, All Our Configurations Are Config-File Based. Sometime We Have Linke

Hi,

I have some questions about hyperparameter optimization. We have a setup where we use PytorchLightning CLI with ClearML for experiment tracking and hyperparameter optimization.
Now, all our configurations are config-file based. Sometime we have linked arguments, like the example below from the Lightning CLI docs:
` model:
encoder_layers: 12
decoder_layers:

  • ${model.encoder_layers}
  • 4 This is all well and good when running experiments manually. However, things get complicated if I wanted to do a topology search on this (very simple, granted) model; I can easily make ClearML treat encoder_layers as a hyperparameter, but the variables are no longer linked when they hit ClearML. I would then see Args/model.encoder_layers: 12 and Args/model.decoder_layers: 12 . Is there any way to link hyperparameters in the HyperParameterOptimizer ` ?

It seems like a general enough issue, that changes to one hyperparameter could have static dependencies for other configs, say output_channels == intput_channels for an encoder-decoder pair.

  
  
Posted one year ago
Votes Newest

Answers 7


Hi,
I encountered similar problem. The solution was quite difficult to find, but finally we managed to update our HPO section with hyperparameters like this: https://clearml.slack.com/archives/CTK20V944/p1641372134329200?thread_ts=1640010570.080900&cid=CTK20V944
Hope this helps.

  
  
Posted one year ago

Hi CurvedHedgehog15 , thanks for replying!
I guess that one could modify the config with variable interpolation (similar to how it's done in YAML, e.g. ${encoder.layers} ) - however, it seems to be quite invasive to specify that in our trainer script 😞

  
  
Posted one year ago

I don't have issues with setting the hyperparameters - I just would like to link changes to one hyperparameter (eg. encoder.layers ) to another parameter (e.g. http://decoder.in _layers ) when optimizing over encoder.layer

  
  
Posted one year ago

Oh, sorry, I wrongly understand your issue. 😞
But it is the interesting one!
What comes to my mind, that https://clear.ml/docs/latest/docs/references/sdk/hpo_parameters_parameterset#class-automationparameterset can be required when there is a link between two variables. But I have never tested it and I am not ClearML developer, so do not take this advice too seriously. 🙂 Hoperfully, someone more ClearML experienced will respond you.

  
  
Posted one year ago

Hi GiganticMole91 ,

Can you please elaborate on this part?
I can easily make ClearML treat encoder_layers as a hyperparameter, but the variables are no longer linked when they hit ClearML. I would then see Args/model.encoder_layers: 12 and Args/model.decoder_layers: 12. Is there any way to link hyperparameters in the HyperParameterOptimizer ?What are you seeing in the UI and what were you expecting to see?

  
  
Posted one year ago

Hi CostlyOstrich36
What I'm seeing is expected behavior:

In my toy example, I have a VAE which is defined by a YAML config file and parsed with PytorchLightning CLI. Part of the config defines the latent dimension (n_latents) and the number of input channels of the decoder (in_channels). These two values needs to be the same. When I just use the Lightning CLI, I can use variable interpolation with OmegaConf like this:
class_path: mymodel.VAE init_args: {...} bottleneck: class_path: mymodel.Bottleneck init_args: in_channels: ${init_args.encoder.init_args.out_channels} n_latents: 256 decoder: class_path: mymodel.Decoder init_args: in_channels: ${init_args.bottleneck.init_args.n_latents} {...}The trouble is that the variables are already inserted when ClearML updates the associated Task for training the VAE.

In the base-task for my optimization I then see this in the UI (Configuration/Hyper parameters):
Args/fit.model.init_args.bottleneck.init_args.n_latents: 256
Args/fit.model.init_args.decoder. http://init_args.in _channels: 256
which is as expected.

When I then setup a hyperparameter optimization job and I would like to modify n_latents of my bottleneck, the number of input channels of the decoder has to be changed to the same values that was sampled for n_latents and thats my issue 🙂

Was that more clear (albeit longer)?

Edit: I have played around with a LinkedParameter, which held both a main name and linked_arg and was subclassed from clearml.automation.parameters.Parameter, but the parameters seem to be simple placeholders for the optimizer classes (e.g. in _convert_hyper_parameters_to_optuna in clearml.automation.optuna )

  
  
Posted one year ago

Hi again CostlyOstrich36 ,

I just wanted to share what ended up working for me. Basically I worked it out both for Hydra (thanks CurvedHedgehog15 ) and for PytorchLightningCLI.

So, for PL-CLI, I used this construct so we don't have to modify our training scripts based on our experiment tracker

` from pytorch_lightning.utilities.cli import LightningCLI
from clearml import Task

class MyCLI(LightningCLI):
def before_instantiate_classes(self) -> None:
# init the task
task = Task.init()

    # Connect the config to the task
    # type(self.config) -> jsonargparse.Namespace
    cfg_dict = self.config.as_dict()
    cfg_dict = task.connect(cfg_dict)
    cfg_dict = cfg_dict._to_dict()
    self.config = jsonargparse.Namespace(**cfg_dict)

if name == "main":
MyCLI(...) One could also inherit from the SaveConfigCallback to have it upload the config.yaml to ClearML 🙂 Then, when hp-optimizing the model with HyperParameterOptimizer you can use ParameterSet([{"General/encoder_layers": x, "General/decoder_layers.0": x} for x in range(64, 512, 64)]) to work around the variable interpolation in the config file ( decoder_layers.0 = ${encoder_layers} ). This would be equivalent to UniformIntegerParameterRange("encoder_layers", min_value=64, max_value=512, step_size=64) ` .

For Hydra, things are easier, but I had to use http://OmegaConf.to _container instead of http://OmegaConf.to _object to preserve the variable interpolation strings:

` @hydra(...)
def main(config: DictConfig) -> None:
# Init the task
task = Task.init(...)

# Connect the config to ClearML
out_config = OmegaConf.to_container(config)
out_config = task.connect(out_config, "HPO")
out_config = out_config._to_dict()
config= OmegaConf.create(out_config)

# Upload the config file to ClearML
task.upload_artifact(
    "config file", HydraConfig.get().run.dir + "/.hydra/config.yaml"
) `
  
  
Posted one year ago
652 Views
7 Answers
one year ago
one year ago
Tags