Design a search space before launching the sweep
Use Polyaxon matrices to choose parameter scales, separate meaningful combinations, and control the size of a hyperparameter sweep.
A useful sweep starts with parameters that change the experiment in meaningful ways. Some vary across orders of magnitude. Others apply only to one model family. Expressing every setting as an independent dimension can repeat equivalent recipes and spend runs on irrelevant differences.
Polyaxon matrices let you express the search directly: a grid for a finite product of values, a mapping for selected combinations, or random search for a fixed trial budget. The design belongs in the operation definition, alongside the component that consumes those parameters.
Our compute-budget guide covers the comparison contract, and the matched-seed walkthrough covers confirmation. Here we focus on the matrix itself, using short configuration excerpts and functions with expected results.
Give each parameter a clear role
Consider a study using scikit-learn's SGDClassifier, with loss="log_loss" and learning_rate="constant" fixed in the training component.
| Parameter | Role | Values in this example |
|---|---|---|
alpha | Regularization strength | 0.00001, 0.0001, 0.001 |
eta0 | Constant step size | 0.001, 0.01 |
penalty | Regularization family | l2 or elasticnet |
l1_ratio | Elastic Net mixing ratio | 0.25, 0.75, only in that branch |
The estimator reference documents that l1_ratio matters only for Elastic Net. It also explains that the default optimal schedule uses alpha in its step-size calculation and ignores eta0. Fixing the schedule to constant makes this study's parameter roles explicit.
The values are illustrative design choices. No training results or winning configuration are implied.
Express a finite space with a grid matrix
For L2, three regularization values and two step sizes produce six recipes. Add this matrix to an operation targeting your training component:
matrix:
kind: grid
concurrency: 2
params:
penalty:
kind: choice
value: [l2]
alpha:
kind: logspace
value: [-5, -3, 3]
eta0:
kind: choice
value: [0.001, 0.01]logspace uses exponent endpoints and a point count, with base 10 by default. Here it generates three values from ten to the power of −5 through ten to the power of −3. The explicit choice for eta0 supplies two step sizes. The parameter reference describes the available generators.
Expected search space, independent of scheduling order:
penalty | alpha | eta0 |
|---|---|---|
l2 | 0.00001 | 0.001 |
l2 | 0.00001 | 0.01 |
l2 | 0.0001 | 0.001 |
l2 | 0.0001 | 0.01 |
l2 | 0.001 | 0.001 |
l2 | 0.001 | 0.01 |
The grid matrix enumerates the product of those finite sets. concurrency: 2 limits concurrent child operations; it leaves the six-recipe design unchanged. Run limits or stopping rules can prevent a grid from completing its full space.
Keep conditional settings in their own branch
Adding both penalties and two mixing ratios to one Cartesian product gives 24 rows. For L2, changing the mixing ratio has no effect, so six rows repeat effective recipes. The library need not reject those rows for them to be redundant.
Define one grid per penalty instead. This short function returns a Polyaxon matrix ready to attach to an operation:
from polyaxon.schemas import V1GridSearch, V1HpChoice, V1HpLogSpace
def make_search_matrix(penalty):
if penalty not in {"l2", "elasticnet"}:
raise ValueError("Choose l2 or elasticnet")
params = {
"penalty": V1HpChoice(value=[penalty]),
"alpha": V1HpLogSpace(value=[-5, -3, 3]),
"eta0": V1HpChoice(value=[0.001, 0.01]),
}
if penalty == "elasticnet":
params["l1_ratio"] = V1HpChoice(value=[0.25, 0.75])
return V1GridSearch(params=params, concurrency=2)Expected result:
make_search_matrix("l2"): a grid describing 6 recipes, without anl1_ratiodimension.make_search_matrix("elasticnet"): a grid describing 12 recipes, including two mixing ratios.- The two operations together describe 18 distinct recipes. Calling the function only constructs a matrix; it does not submit runs.
These are separate matrices, each with its own concurrency setting. If both operations run simultaneously, their concurrency limits do not combine into a single two-run limit. Apply your queue or enclosing workflow's capacity controls to the combined workload.
The receiving component needs inputs matching the generated names and types. Make l1_ratio optional or give it a default, and use it only for Elastic Net. Keep the dataset, preprocessing, loss, learning-rate schedule, training budget, and scorer fixed across both operations.
Use a mapping for a deliberate shortlist
Sometimes you already know the combinations worth comparing. A mapping matrix passes each listed dictionary to the component as one recipe:
matrix:
kind: mapping
concurrency: 2
values:
- penalty: l2
alpha: 0.0001
eta0: 0.01
- penalty: elasticnet
alpha: 0.0001
eta0: 0.01
l1_ratio: 0.25
- penalty: elasticnet
alpha: 0.001
eta0: 0.001
l1_ratio: 0.75Expected result: three planned child operations with exactly those parameter combinations. A mapping does not take another Cartesian product across the rows. It is useful for a reviewed shortlist or combinations that cannot be expressed as independent choices.
These excerpts show the matrix portion of an operation. Connect it to an existing training component with the corresponding inputs, environment, data access, and training function. The full trainer is specific to your dataset and is not required to explain the space.
Choose scales and budgets deliberately
logspace makes multiplicative spacing explicit. Use it when the question concerns orders of magnitude; use a discrete choice when you want specific values. Zero, when it means disabling a mechanism, belongs in a separate explicit choice because a logarithmic scale cannot include it. Counts need valid integers, and proportions need values within their meaningful bounds.
When the finite space is larger than your trial budget, a random-search matrix can sample it. For example, this function reuses the Elastic Net space from make_search_matrix above:
from polyaxon.schemas import V1RandomSearch
def make_budgeted_search():
return V1RandomSearch(
params=make_search_matrix("elasticnet").params,
num_runs=8,
seed=23,
concurrency=2,
)Expected result: a random-search definition requesting eight configurations from the twelve possible Elastic Net recipes. The current implementation avoids duplicate suggestions in this finite space. The matrix seed controls search sampling; training randomness needs its own seed policy.
Count the work inside each child too. Eighteen recipes evaluated over five training seeds mean 90 fits before retries or additional confirmation. Preserve the submitted matrix and component revision with the study, then compare the actual child inputs and results. If you narrow the range later, record a new study definition.
Once the search produces a shortlist, use the planned confirmation across training seeds. The matrix explains which recipes received compute; the evaluation and confirmation protocol explains what their results justify.