ExperimentLog API Reference#
This page documents public methods of ExperimentLog, Experiment, and ConfigIter beyond what is covered in the Running Experiments.
ExperimentLog#
Field manipulation#
derive_field(new_field_name, fn, *fn_arg_fields, is_index=False)#
Adds a new computed field by applying fn to existing fields.
# Categorical field from a numeric one
log.derive_field('lr_group', lambda lr: 'high' if lr > 0.01 else 'low', 'lr', is_index=True)
# Derived from multiple fields
log.derive_field('effective_lr', lambda lr, bs: lr * bs / 256, 'lr', 'batch_size')
Parameters:
new_field_name(str)Name for the new column.
fn(callable)Function receiving the values of
fn_arg_fieldsas positional arguments.*fn_arg_fields(str)Names of existing fields to pass into
fn.is_index(bool)If
True, the new field becomes a grid (index) field. Default:False.
drop_fields(field_names)#
Removes fields from the log. Works on static, grid (index), and metric (column) fields.
log.drop_fields(['train_loss', 'unused_metric'])
log.drop_fields(['seed']) # remove a grid field
rename_fields(name_map)#
Renames fields across static, grid, and metric fields.
log.rename_fields({'val_accuracy': 'val_acc', 'learning_rate': 'lr'})
Querying#
isin(config) / config in log#
Checks whether a configuration exists in the log. Both forms are equivalent:
config = {'seed': 1, 'lr': 0.01, 'optimizer': 'adam'}
log.isin(config)
config in log
get_metric(config) / log[config]#
Retrieves metric values for a specific configuration:
config = {'seed': 1, 'lr': 0.01, 'optimizer': 'adam'}
metrics = log[config]
# {'train_loss': [...], 'val_accuracy': [...]}
is_same_exp(other)#
Checks whether two logs have the same configuration fields (both static and grid), regardless of values. Useful before merging.
if log_a.is_same_exp(log_b):
log_a.merge(log_b)
grid_dict()#
Returns a dictionary mapping each grid field to its unique values:
log.grid_dict()
# {'seed': [1, 2, 3], 'lr': [0.001, 0.01, 0.1]}
Data transformation#
melt_and_explode_metric(df=None, step=None, dropna=True)#
Converts from wide format (one column per metric, list values per step) to long format (one row per metric per step). This is the standard preprocessing step before plotting.
df_long = log.melt_and_explode_metric() # all steps
df_last = log.melt_and_explode_metric(step=-1) # last step only
Returns a DataFrame with new columns: metric (name), metric_value (scalar), step (1-indexed), and total_steps.
drop_duplicates()#
Removes duplicate entries. Identical duplicates are auto-removed; conflicting duplicates trigger an interactive CLI prompt.
log.drop_duplicates()
Experiment#
Experiment.resplit_logs(exp_folder_path, target_split=1, save_backup=True)#
Re-partitions split log files into a new number of splits.
from malet.experiment import Experiment
Experiment.resplit_logs('./experiments/my_exp', target_split=1) # merge into one
Experiment.resplit_logs('./experiments/my_exp', target_split=4) # re-split into 4
exp_folder_path(str)Path to the experiment folder.
target_split(int)Number of output splits.
1merges into a singlelog.tsv.save_backup(bool)Save a backup as
logs_backup.tsvbefore resplitting. Default:True.
Experiment.set_log_status_as_failed(exp_folder_path)#
Marks all R (running) configs as F (failed). Useful for recovering from crashed jobs. See Intermediate Checkpointing for details on run status values.
Experiment.set_log_status_as_failed('./experiments/my_exp')
ConfigIter#
ConfigIter.filter_iter(filt_fn)#
Filters the configuration iterator in-place using a predicate function.
from malet.experiment import ConfigIter
configs = ConfigIter('exp_config.yaml')
configs.filter_iter(lambda i, d: d['lr'] > 0.001) # keep configs where lr > 0.001
configs.filter_iter(lambda i, d: i % 2 == 0) # keep even-indexed configs
filt_fn(callable)Function taking
(index, config_dict), returnsTrueto keep.
ConfigIter.grid_dict (property)#
Returns a dictionary mapping each grid field to its unique values:
configs = ConfigIter('exp_config.yaml')
configs.grid_dict
# {'seed': [1, 2, 3], 'lr': [0.001, 0.01, 0.1], 'optimizer': ['sgd', 'adam']}
Indexing and slicing#
ConfigIter supports len(), integer indexing, and slicing:
configs = ConfigIter('exp_config.yaml')
len(configs) # total number of configs
configs[0] # first config
configs[-1] # last config
configs[10:20] # slice of configs