Skip to content

Commit

Permalink
add usage of e and 10^ for exponent format as input for yaml file + n…
Browse files Browse the repository at this point in the history
…ew tests for optional type argument
  • Loading branch information
danrgll committed Dec 3, 2023
1 parent 5096129 commit e8d586c
Show file tree
Hide file tree
Showing 8 changed files with 404 additions and 109 deletions.
5 changes: 1 addition & 4 deletions src/neps/search_spaces/hyperparameters/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

import random
from copy import copy, deepcopy
from typing import Iterable
from typing import Iterable, Literal

import numpy as np
import numpy.typing as npt
from typing_extensions import Literal

from ..parameter import Parameter

Expand All @@ -32,9 +31,7 @@ def __init__(
self.upper = default
self.default_confidence_score = CATEGORICAL_CONFIDENCE_SCORES[default_confidence]
self.has_prior = self.default is not None

self.is_fidelity = is_fidelity

self.choices = list(choices)
self.num_choices = len(self.choices)
self.probabilities: list[npt.NDArray] = list(
Expand Down
3 changes: 1 addition & 2 deletions src/neps/search_spaces/hyperparameters/float.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import math
from copy import deepcopy
from typing import Literal

import numpy as np
import scipy.stats
from typing_extensions import Literal

from .numerical import NumericalParameter

Expand Down Expand Up @@ -37,7 +37,6 @@ def __init__(

if self.lower >= self.upper:
raise ValueError("Float parameter: bounds error (lower >= upper).")

self.log = log

if self.log:
Expand Down
350 changes: 278 additions & 72 deletions src/neps/search_spaces/search_space.py

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions tests/test_yaml_search_space/config_including_unknown_types.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
search_space:
learning_rate:
type: numerical
lower: 0.00001
upper: 0.1
log: true

num_epochs:
type: numerical
lower: 3
upper: 30
is_fidelity: True

optimizer:
type: numerical
choices: ["adam", "sgd", "rmsprop"]

dropout_rate:
type: numerical
value: 0.5
20 changes: 20 additions & 0 deletions tests/test_yaml_search_space/config_including_wrong_types.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
search_space:
learning_rate:
type: int
lower: 0.00001
upper: 0.1
log: true

num_epochs:
type: float
lower: 3
upper: 30
is_fidelity: True

optimizer:
type: cat
choices: ["adam", "sgd", "rmsprop"]

dropout_rate:
type: const
value: 0.5
1 change: 1 addition & 0 deletions tests/test_yaml_search_space/correct_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ search_space:
num_epochs:
lower: 3
upper: 30
log: false
is_fidelity: True

optimizer:
Expand Down
20 changes: 20 additions & 0 deletions tests/test_yaml_search_space/correct_config_including_types.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
search_space:
learning_rate:
type: float
lower: 0.00001
upper: 0.1
log: true

num_epochs:
type: int
lower: 3
upper: 30
is_fidelity: True

optimizer:
type: cat
choices: ["adam", "sgd", "rmsprop"]

dropout_rate:
type: const
value: 0.5
94 changes: 63 additions & 31 deletions tests/test_yaml_search_space/test_search_space.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
import pytest

from neps import CategoricalParameter, ConstantParameter, FloatParameter, IntegerParameter
from neps.search_spaces.search_space import pipeline_space_from_yaml
from neps.search_spaces.search_space import (
SearchSpaceFromYamlFileError,
pipeline_space_from_yaml,
)


@pytest.mark.yaml_api
def test_correct_yaml_file():
"""Test the function with a correctly formatted YAML file."""
pipeline_space = pipeline_space_from_yaml(
"tests/test_yaml_search_space/correct_config.yaml"
def test_correct_yaml_files():
def test_correct_yaml_file(path):
"""Test the function with a correctly formatted YAML file."""
pipeline_space = pipeline_space_from_yaml(path)
assert isinstance(pipeline_space, dict)
assert isinstance(pipeline_space["learning_rate"], FloatParameter)
assert pipeline_space["learning_rate"].lower == 0.00001
assert pipeline_space["learning_rate"].upper == 0.1
assert pipeline_space["learning_rate"].log is True
assert pipeline_space["optimizer"].is_fidelity is False
assert pipeline_space["learning_rate"].default is None
assert pipeline_space["learning_rate"].default_confidence_score == 0.5
assert isinstance(pipeline_space["num_epochs"], IntegerParameter)
assert pipeline_space["num_epochs"].lower == 3
assert pipeline_space["num_epochs"].upper == 30
assert pipeline_space["num_epochs"].log is False
assert pipeline_space["num_epochs"].is_fidelity is True
assert pipeline_space["num_epochs"].default is None
assert pipeline_space["num_epochs"].default_confidence_score == 0.5
assert isinstance(pipeline_space["optimizer"], CategoricalParameter)
assert pipeline_space["optimizer"].choices == ["adam", "sgd", "rmsprop"]
assert pipeline_space["optimizer"].is_fidelity is False
assert pipeline_space["optimizer"].default is None
assert pipeline_space["optimizer"].default_confidence_score == 2
assert isinstance(pipeline_space["dropout_rate"], ConstantParameter)
assert pipeline_space["dropout_rate"].value == 0.5
assert pipeline_space["dropout_rate"].is_fidelity is False

test_correct_yaml_file("tests/test_yaml_search_space/correct_config.yaml")
test_correct_yaml_file(
"tests/test_yaml_search_space/correct_config_including_types" ".yaml"
)
assert isinstance(pipeline_space, dict)
assert isinstance(pipeline_space["learning_rate"], FloatParameter)
assert pipeline_space["learning_rate"].lower == 0.00001
assert pipeline_space["learning_rate"].upper == 0.1
assert pipeline_space["learning_rate"].log is True
assert pipeline_space["optimizer"].is_fidelity is False
assert pipeline_space["learning_rate"].default is None
assert pipeline_space["learning_rate"].default_confidence_score == 0.5
assert isinstance(pipeline_space["num_epochs"], IntegerParameter)
assert pipeline_space["num_epochs"].lower == 3
assert pipeline_space["num_epochs"].upper == 30
assert pipeline_space["num_epochs"].log is False
assert pipeline_space["num_epochs"].is_fidelity is True
assert pipeline_space["num_epochs"].default is None
assert pipeline_space["num_epochs"].default_confidence_score == 0.5
assert isinstance(pipeline_space["optimizer"], CategoricalParameter)
assert pipeline_space["optimizer"].choices == ["adam", "sgd", "rmsprop"]
assert pipeline_space["optimizer"].is_fidelity is False
assert pipeline_space["optimizer"].default is None
assert pipeline_space["optimizer"].default_confidence_score == 2
assert isinstance(pipeline_space["dropout_rate"], ConstantParameter)
assert pipeline_space["dropout_rate"].value == 0.5
assert pipeline_space["dropout_rate"].is_fidelity is False


@pytest.mark.yaml_api
Expand Down Expand Up @@ -69,22 +76,47 @@ def test_correct_including_priors_yaml_file():
@pytest.mark.yaml_api
def test_incorrect_yaml_file():
"""Test the function with an incorrectly formatted YAML file."""
with pytest.raises(ValueError):
with pytest.raises(SearchSpaceFromYamlFileError) as excinfo:
pipeline_space_from_yaml("tests/test_yaml_search_space/incorrect_config.txt")
assert str(excinfo.value.exception_type == "ValueError")


@pytest.mark.yaml_api
def test_yaml_file_with_missing_key():
"""Test the function with a YAML file missing a required key."""
with pytest.raises(KeyError):
with pytest.raises(SearchSpaceFromYamlFileError) as excinfo:
pipeline_space_from_yaml("tests/test_yaml_search_space/missing_key_config.yml")
assert str(excinfo.value.exception_type == "KeyError")


@pytest.mark.yaml_api
def test_yaml_file_with_inconsistent_types():
"""Test the function with a YAML file having inconsistent types for
'lower' and 'upper'."""
with pytest.raises(TypeError):
with pytest.raises(SearchSpaceFromYamlFileError) as excinfo:
pipeline_space_from_yaml(
"tests/test_yaml_search_space/inconsistent_types_config.yml"
)
assert str(excinfo.value.exception_type == "TypeError")


@pytest.mark.yaml_api
def test_yaml_file_including_wrong_types():
"""Test the function with a YAML file that defines the wrong but existing type
int to float as an optional argument"""
with pytest.raises(SearchSpaceFromYamlFileError) as excinfo:
pipeline_space_from_yaml(
"tests/test_yaml_search_space/config_including_wrong_types.yaml"
)
assert str(excinfo.value.exception_type == "TypeError")


@pytest.mark.yaml_api
def test_yaml_file_including_unkown_types():
"""Test the function with a YAML file that defines an unknown type as an optional
argument"""
with pytest.raises(SearchSpaceFromYamlFileError) as excinfo:
pipeline_space_from_yaml(
"tests/test_yaml_search_space/config_including_unknown_types.yaml"
)
assert str(excinfo.value.exception_type == "TypeError")

0 comments on commit e8d586c

Please sign in to comment.