Programmatic space search with a focus on flexibility
Project description
superparams
a Pythonic approach to Hyperparameter Search. Using built-in dataclasses, as they are flexible, typed, easily-serialisable, and are a dict in the places you need them.
I like to think of it as the repetitive back-logic for flexible, fast searching of any search space.
Usage
from dataclasses import dataclass
from hyperparameters import GridSearch, search
@dataclass
class Hyperparams(GridSearch):
epochs :int = 3
batch_size :int = search([16, 32])
learning_rate :float = search([1e-5, 2e-5])
def run(self):
''' Run this setting of parameters '''
results = dict(batch=self.batch_size, lr=self.learning_rate)
print(results)
# automatically save results in a parquet file by returning them
return results
This inherits a bunch of useful attributes, and constructs an iterator.
for h in Hyperparams():
print(h)
# Outputs:
# Hyperparams(epochs=3, batch_size=16, learning_rate=1e-05)
# Hyperparams(epochs=3, batch_size=16, learning_rate=2e-05)
# Hyperparams(epochs=3, batch_size=32, learning_rate=1e-05)
# Hyperparams(epochs=3, batch_size=32, learning_rate=2e-05)
Flexibility
Dataclasses don't require Java-style repetitive constructors. To modify your hyperparameter combination, simply instantiate it as follows.
Hyperparams(epochs=search([1,2,3]))
# Search 3 dimensions, total 12 combinations
# epochs: [1, 2, 3]
# batch_size: [16, 32]
# learning_rate: [1e-05, 2e-05]
Multiprocessing
You can run multiple settings on multiple processes.
params = Hyperparams()
params.run_all(num_proc = os.cpu_count() - 2)
[!WARNING] Python-native
multiprocessingshares theHyperparamsdata with each process by pickling it!. This is woefully inefficient, and poses a massive bottleneck if sharing >50MB data. Consider refactoring such that eachrunmethod instantiates this data itself.In the future, I may do a refactor that shares the data more efficiently; but this is not trivial in Python.
Also note that Experiment objects have access to concurrency-related fields initialised by superparams. These are:
rank: the process id of this experiment setting, i.e.rank in {0,1,2,3}ifn_proc = 4.n_proc: parameter passed to then_procfield.
Installation
A single file for now. Just copy it over.
TODO
-
cli fn to run
experiment exp.RQ1. -
Encapsulate current
__main__into a class, so the user can just addpython # some/path/to/custom/experiments/__main__.py from superparams import entrypoint entrypoint() -
smarter experiment lookup: users may want to have a single file for all their experiments, or spread it into different folders.
experiment RQ1runs all experiments in the fileRQ1.pyexperiment index.RQ1runs the experimentRQ1in the fileindex.py, or the fileRQ1.pyin the folderexperiments/index.
-
dataclassesimprovements -
get rid of this annoying
@dataclassannotation -
provide a
valuemethod to replacefieldpattern; do we assume immutability? -
check compatitibility with
python=3.10, python=3.11. -
testing -
actual functional correctness tests
Alternatives
Any decent package should list viable alternatives. Here are some that I considered, but ended up building this package instead.
- wandb sweeps is best used for Bayesian hyperparameter search to optimise a DL model; but requires specifying settings in JSON files.
- ray tune enables SOTA algorithms like PBT (similar to genetic optimisation) and HyperBand/ASHA (large population with early stopping), and allows for relatively unsupervised optimisation by specifying a search space and objective in Python. It is also compatible with Keras Hyperopt and Pytorch Optuna.
- orion is similar to ray tune, but more or less a wrapper around an argument parser you need to set up yourself (so you have to specify everything in plain-text cli commands).
I think of superparams as more open-ended than ray-tune: there may not be a direct objective to optimise as the right objective is not yet established. And, by allowing everything to be specified in a single Python dataclass, you maintain flexibility by not assuming that the entire optimisation is a black-box. To me, it is valuable to be able to specify all parameters and logic in a single place, completely in lsp-understandable python; which also means everything can be version-tracked.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file superparams-0.0.2.tar.gz.
File metadata
- Download URL: superparams-0.0.2.tar.gz
- Upload date:
- Size: 4.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.4.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f023e63be4677b4b9324bb289cad6c10b3a875778b2103b8ffe0212ff390f573
|
|
| MD5 |
323171c1ab7db261278439c885058a78
|
|
| BLAKE2b-256 |
7efa2df8926cbbe0c318a86260f37bc64a12d29dcda5cf30079e572847a5990b
|
File details
Details for the file superparams-0.0.2-py3-none-any.whl.
File metadata
- Download URL: superparams-0.0.2-py3-none-any.whl
- Upload date:
- Size: 5.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.4.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a038276d627f90a00fb061841167d0d1df86e0b03c5608ba5ec73b9c784d5ea0
|
|
| MD5 |
9fc84583317f57af81f9ebca99bb40ad
|
|
| BLAKE2b-256 |
fe30c0a248fab779d9d315e8930d74f384ccb5ce8e3e7f12eea5c6a53263519d
|