Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -396,6 +396,7 @@ Note that if `initial_custom` option is given then `initial_random` is ignored.
}
```
However, use this option with caution as it could have unintended consequences.
- *log_progress*: `True` or `False` (default: `True`). When `True`, Mango logs optimization progress with a tqdm-based progress bar and per-iteration best scores. Set this to `False` to suppress progress logging, which is useful in CI environments or when you want cleaner logs.



Expand Down
20 changes: 20 additions & 0 deletions development.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,4 +7,24 @@ poetry config pypi-token.pypi <api_token>
> poetry version [major, minor, patch]
> poetry build
> poetry publish
```

### Local development: virtualenv and tests

Create a virtual environment in the project root:
```shell
python3 -m venv venv
```

Activate it from **fish**:
```shell
source ./venv/bin/activate.fish
```

Install development dependencies and run the test suite:
```shell
pip install --upgrade pip
pip install poetry
poetry install
pytest
```
Empty file modifiedexamples/__init__.py
100755 → 100644
Empty file.
Empty file modifiedexamples/classifiers/__init__.py
100755 → 100644
Empty file.
Empty file modifiedmango/domain/__init__.py
100755 → 100644
Empty file.
13 changes: 10 additions & 3 deletions mango/metatuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ class MetaTuner:
class Config:
n_iter: int = 20
n_init: int = 2
log_progress: bool = True

def __init__(self, param_dict_list, objective_list, **kwargs):
self.param_dict_list = param_dict_list
Expand All@@ -30,6 +31,7 @@ def __init__(self, param_dict_list, objective_list, **kwargs):
# adjustable parameters
self.num_of_iterations = self.config.n_iter
self.initial_random = self.config.n_init
self.log_progress = self.config.log_progress

# list of GPR for each objective
self.gpr_list = []
Expand DownExpand Up@@ -222,9 +224,13 @@ def runExponentialTuner(self):
# print(Optimizer_exploration)

# Now run the optimization iterations
pbar = tqdm(range(self.num_of_iterations))
iterator = (
tqdm(range(self.num_of_iterations))
if self.log_progress
else range(self.num_of_iterations)
)

for itr in pbar:
for itr in iterator:
# next values of x returned from individual function
# Values in x are dependent on types of param dict, so using a list
x_values_list = []
Expand DownExpand Up@@ -375,7 +381,8 @@ def runExponentialTuner(self):
Optimizer_exploration[i] + 1.1 * self.exploration_rate
)

pbar.set_description(": Best score: %s" % max_val_y)
if self.log_progress:
tqdm.write(": Best score: %s" % max_val_y)

# print(itr, s_values_list, Optimizer_iteration, Optimizer_exploration, max_val_y)#, Y_dict_array[selected_obj])

Expand Down
Empty file modifiedmango/optimizer/__init__.py
100755 → 100644
Empty file.
23 changes: 17 additions & 6 deletions mango/tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,6 +45,7 @@ class TunerConfig:
constraint: Callable = None
param_sampler: Callable = parameter_sampler
scale_params: bool = False
log_progress: bool = True

def __post_init__(self):
if self.optimizer not in self.valid_optimizers:
Expand DownExpand Up@@ -202,8 +203,12 @@ def runBayesianOptimizer(self):
X_domain_np = self.ds.convert_GP_space(domain_list)

# running the iterations
pbar = tqdm(range(self.config.num_iteration))
for _ in pbar:
iterator = (
tqdm(range(self.config.num_iteration))
if self.config.log_progress
else range(self.config.num_iteration)
)
for _ in iterator:

# adding a Minimum exploration to explore independent of UCB
if random.random() < self.config.exploration:
Expand DownExpand Up@@ -284,7 +289,8 @@ def runBayesianOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand All@@ -307,8 +313,12 @@ def runRandomOptimizer(self):
random_hyper_parameters = self.ds.get_random_sample(n_iterations * batch_size)

# running the iterations
pbar = tqdm(range(0, len(random_hyper_parameters), batch_size))
for idx in pbar:
iterator = (
tqdm(range(0, len(random_hyper_parameters), batch_size))
if self.config.log_progress
else range(0, len(random_hyper_parameters), batch_size)
)
for idx in iterator:
# getting batch by batch random values to try
batch_hyper_parameters = random_hyper_parameters[idx : idx + batch_size]
X_list, Y_list = self.runUserObjective(batch_hyper_parameters)
Expand All@@ -327,7 +337,8 @@ def runRandomOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand Down
50 changes: 50 additions & 0 deletions tests/test_tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@

from mango.domain.domain_space import DomainSpace
from mango import Tuner, scheduler
import mango.tuner as tuner_mod
from scipy.stats import uniform, dirichlet

# Simple param_dict
Expand DownExpand Up@@ -156,6 +157,55 @@ def check(results, error_msg):
check(results, "error while minimizing random")


def test_log_progress_flag(monkeypatch):
"""log_progress controls use of tqdm in the optimizer."""

class DummyTqdm:
def __init__(self):
self.iter_calls = 0
self.write_calls = 0

def __call__(self, iterable, *args, **kwargs):
# mimic tqdm(iterable) by returning the iterable unchanged
self.iter_calls += 1
return iterable

def write(self, *args, **kwargs):
self.write_calls += 1

dummy_tqdm = DummyTqdm()
monkeypatch.setattr(tuner_mod, "tqdm", dummy_tqdm)

param_dict = dict(x=range(-2, 3))

def objfunc(p_list):
# trivial, fast objective
return [0.0 for _ in p_list]

# When log_progress is False, tqdm should not be used
tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=False),
)
tuner.run()
assert dummy_tqdm.iter_calls == 0
assert dummy_tqdm.write_calls == 0

# When log_progress is True, tqdm should be used
dummy_tqdm.iter_calls = 0
dummy_tqdm.write_calls = 0

tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=True),
)
tuner.run()
assert dummy_tqdm.iter_calls > 0
assert dummy_tqdm.write_calls > 0


def test_convex():
param_dict = {
"x": range(-100, 10),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
added option to disable progress logs by tihom · Pull Request #122 · ARM-software/mango · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -396,6 +396,7 @@ Note that if `initial_custom` option is given then `initial_random` is ignored.
}
```
However, use this option with caution as it could have unintended consequences.
- *log_progress*: `True` or `False` (default: `True`). When `True`, Mango logs optimization progress with a tqdm-based progress bar and per-iteration best scores. Set this to `False` to suppress progress logging, which is useful in CI environments or when you want cleaner logs.



Expand Down
20 changes: 20 additions & 0 deletions development.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,4 +7,24 @@ poetry config pypi-token.pypi <api_token>
> poetry version [major, minor, patch]
> poetry build
> poetry publish
```

### Local development: virtualenv and tests

Create a virtual environment in the project root:
```shell
python3 -m venv venv
```

Activate it from **fish**:
```shell
source ./venv/bin/activate.fish
```

Install development dependencies and run the test suite:
```shell
pip install --upgrade pip
pip install poetry
poetry install
pytest
```
Empty file modifiedexamples/__init__.py
100755 → 100644
Empty file.
Empty file modifiedexamples/classifiers/__init__.py
100755 → 100644
Empty file.
Empty file modifiedmango/domain/__init__.py
100755 → 100644
Empty file.
13 changes: 10 additions & 3 deletions mango/metatuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ class MetaTuner:
class Config:
n_iter: int = 20
n_init: int = 2
log_progress: bool = True

def __init__(self, param_dict_list, objective_list, **kwargs):
self.param_dict_list = param_dict_list
Expand All@@ -30,6 +31,7 @@ def __init__(self, param_dict_list, objective_list, **kwargs):
# adjustable parameters
self.num_of_iterations = self.config.n_iter
self.initial_random = self.config.n_init
self.log_progress = self.config.log_progress

# list of GPR for each objective
self.gpr_list = []
Expand DownExpand Up@@ -222,9 +224,13 @@ def runExponentialTuner(self):
# print(Optimizer_exploration)

# Now run the optimization iterations
pbar = tqdm(range(self.num_of_iterations))
iterator = (
tqdm(range(self.num_of_iterations))
if self.log_progress
else range(self.num_of_iterations)
)

for itr in pbar:
for itr in iterator:
# next values of x returned from individual function
# Values in x are dependent on types of param dict, so using a list
x_values_list = []
Expand DownExpand Up@@ -375,7 +381,8 @@ def runExponentialTuner(self):
Optimizer_exploration[i] + 1.1 * self.exploration_rate
)

pbar.set_description(": Best score: %s" % max_val_y)
if self.log_progress:
tqdm.write(": Best score: %s" % max_val_y)

# print(itr, s_values_list, Optimizer_iteration, Optimizer_exploration, max_val_y)#, Y_dict_array[selected_obj])

Expand Down
Empty file modifiedmango/optimizer/__init__.py
100755 → 100644
Empty file.
23 changes: 17 additions & 6 deletions mango/tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,6 +45,7 @@ class TunerConfig:
constraint: Callable = None
param_sampler: Callable = parameter_sampler
scale_params: bool = False
log_progress: bool = True

def __post_init__(self):
if self.optimizer not in self.valid_optimizers:
Expand DownExpand Up@@ -202,8 +203,12 @@ def runBayesianOptimizer(self):
X_domain_np = self.ds.convert_GP_space(domain_list)

# running the iterations
pbar = tqdm(range(self.config.num_iteration))
for _ in pbar:
iterator = (
tqdm(range(self.config.num_iteration))
if self.config.log_progress
else range(self.config.num_iteration)
)
for _ in iterator:

# adding a Minimum exploration to explore independent of UCB
if random.random() < self.config.exploration:
Expand DownExpand Up@@ -284,7 +289,8 @@ def runBayesianOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand All@@ -307,8 +313,12 @@ def runRandomOptimizer(self):
random_hyper_parameters = self.ds.get_random_sample(n_iterations * batch_size)

# running the iterations
pbar = tqdm(range(0, len(random_hyper_parameters), batch_size))
for idx in pbar:
iterator = (
tqdm(range(0, len(random_hyper_parameters), batch_size))
if self.config.log_progress
else range(0, len(random_hyper_parameters), batch_size)
)
for idx in iterator:
# getting batch by batch random values to try
batch_hyper_parameters = random_hyper_parameters[idx : idx + batch_size]
X_list, Y_list = self.runUserObjective(batch_hyper_parameters)
Expand All@@ -327,7 +337,8 @@ def runRandomOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand Down
50 changes: 50 additions & 0 deletions tests/test_tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@

from mango.domain.domain_space import DomainSpace
from mango import Tuner, scheduler
import mango.tuner as tuner_mod
from scipy.stats import uniform, dirichlet

# Simple param_dict
Expand DownExpand Up@@ -156,6 +157,55 @@ def check(results, error_msg):
check(results, "error while minimizing random")


def test_log_progress_flag(monkeypatch):
"""log_progress controls use of tqdm in the optimizer."""

class DummyTqdm:
def __init__(self):
self.iter_calls = 0
self.write_calls = 0

def __call__(self, iterable, *args, **kwargs):
# mimic tqdm(iterable) by returning the iterable unchanged
self.iter_calls += 1
return iterable

def write(self, *args, **kwargs):
self.write_calls += 1

dummy_tqdm = DummyTqdm()
monkeypatch.setattr(tuner_mod, "tqdm", dummy_tqdm)

param_dict = dict(x=range(-2, 3))

def objfunc(p_list):
# trivial, fast objective
return [0.0 for _ in p_list]

# When log_progress is False, tqdm should not be used
tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=False),
)
tuner.run()
assert dummy_tqdm.iter_calls == 0
assert dummy_tqdm.write_calls == 0

# When log_progress is True, tqdm should be used
dummy_tqdm.iter_calls = 0
dummy_tqdm.write_calls = 0

tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=True),
)
tuner.run()
assert dummy_tqdm.iter_calls > 0
assert dummy_tqdm.write_calls > 0


def test_convex():
param_dict = {
"x": range(-100, 10),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' added option to disable progress logs by tihom · Pull Request #122 · ARM-software/mango · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -396,6 +396,7 @@ Note that if `initial_custom` option is given then `initial_random` is ignored.
}
```
However, use this option with caution as it could have unintended consequences.
- *log_progress*: `True` or `False` (default: `True`). When `True`, Mango logs optimization progress with a tqdm-based progress bar and per-iteration best scores. Set this to `False` to suppress progress logging, which is useful in CI environments or when you want cleaner logs.



Expand Down
20 changes: 20 additions & 0 deletions development.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,4 +7,24 @@ poetry config pypi-token.pypi <api_token>
> poetry version [major, minor, patch]
> poetry build
> poetry publish
```

### Local development: virtualenv and tests

Create a virtual environment in the project root:
```shell
python3 -m venv venv
```

Activate it from **fish**:
```shell
source ./venv/bin/activate.fish
```

Install development dependencies and run the test suite:
```shell
pip install --upgrade pip
pip install poetry
poetry install
pytest
```
Empty file modifiedexamples/__init__.py
100755 → 100644
Empty file.
Empty file modifiedexamples/classifiers/__init__.py
100755 → 100644
Empty file.
Empty file modifiedmango/domain/__init__.py
100755 → 100644
Empty file.
13 changes: 10 additions & 3 deletions mango/metatuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ class MetaTuner:
class Config:
n_iter: int = 20
n_init: int = 2
log_progress: bool = True

def __init__(self, param_dict_list, objective_list, **kwargs):
self.param_dict_list = param_dict_list
Expand All@@ -30,6 +31,7 @@ def __init__(self, param_dict_list, objective_list, **kwargs):
# adjustable parameters
self.num_of_iterations = self.config.n_iter
self.initial_random = self.config.n_init
self.log_progress = self.config.log_progress

# list of GPR for each objective
self.gpr_list = []
Expand DownExpand Up@@ -222,9 +224,13 @@ def runExponentialTuner(self):
# print(Optimizer_exploration)

# Now run the optimization iterations
pbar = tqdm(range(self.num_of_iterations))
iterator = (
tqdm(range(self.num_of_iterations))
if self.log_progress
else range(self.num_of_iterations)
)

for itr in pbar:
for itr in iterator:
# next values of x returned from individual function
# Values in x are dependent on types of param dict, so using a list
x_values_list = []
Expand DownExpand Up@@ -375,7 +381,8 @@ def runExponentialTuner(self):
Optimizer_exploration[i] + 1.1 * self.exploration_rate
)

pbar.set_description(": Best score: %s" % max_val_y)
if self.log_progress:
tqdm.write(": Best score: %s" % max_val_y)

# print(itr, s_values_list, Optimizer_iteration, Optimizer_exploration, max_val_y)#, Y_dict_array[selected_obj])

Expand Down
Empty file modifiedmango/optimizer/__init__.py
100755 → 100644
Empty file.
23 changes: 17 additions & 6 deletions mango/tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,6 +45,7 @@ class TunerConfig:
constraint: Callable = None
param_sampler: Callable = parameter_sampler
scale_params: bool = False
log_progress: bool = True

def __post_init__(self):
if self.optimizer not in self.valid_optimizers:
Expand DownExpand Up@@ -202,8 +203,12 @@ def runBayesianOptimizer(self):
X_domain_np = self.ds.convert_GP_space(domain_list)

# running the iterations
pbar = tqdm(range(self.config.num_iteration))
for _ in pbar:
iterator = (
tqdm(range(self.config.num_iteration))
if self.config.log_progress
else range(self.config.num_iteration)
)
for _ in iterator:

# adding a Minimum exploration to explore independent of UCB
if random.random() < self.config.exploration:
Expand DownExpand Up@@ -284,7 +289,8 @@ def runBayesianOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand All@@ -307,8 +313,12 @@ def runRandomOptimizer(self):
random_hyper_parameters = self.ds.get_random_sample(n_iterations * batch_size)

# running the iterations
pbar = tqdm(range(0, len(random_hyper_parameters), batch_size))
for idx in pbar:
iterator = (
tqdm(range(0, len(random_hyper_parameters), batch_size))
if self.config.log_progress
else range(0, len(random_hyper_parameters), batch_size)
)
for idx in iterator:
# getting batch by batch random values to try
batch_hyper_parameters = random_hyper_parameters[idx : idx + batch_size]
X_list, Y_list = self.runUserObjective(batch_hyper_parameters)
Expand All@@ -327,7 +337,8 @@ def runRandomOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand Down
50 changes: 50 additions & 0 deletions tests/test_tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@

from mango.domain.domain_space import DomainSpace
from mango import Tuner, scheduler
import mango.tuner as tuner_mod
from scipy.stats import uniform, dirichlet

# Simple param_dict
Expand DownExpand Up@@ -156,6 +157,55 @@ def check(results, error_msg):
check(results, "error while minimizing random")


def test_log_progress_flag(monkeypatch):
"""log_progress controls use of tqdm in the optimizer."""

class DummyTqdm:
def __init__(self):
self.iter_calls = 0
self.write_calls = 0

def __call__(self, iterable, *args, **kwargs):
# mimic tqdm(iterable) by returning the iterable unchanged
self.iter_calls += 1
return iterable

def write(self, *args, **kwargs):
self.write_calls += 1

dummy_tqdm = DummyTqdm()
monkeypatch.setattr(tuner_mod, "tqdm", dummy_tqdm)

param_dict = dict(x=range(-2, 3))

def objfunc(p_list):
# trivial, fast objective
return [0.0 for _ in p_list]

# When log_progress is False, tqdm should not be used
tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=False),
)
tuner.run()
assert dummy_tqdm.iter_calls == 0
assert dummy_tqdm.write_calls == 0

# When log_progress is True, tqdm should be used
dummy_tqdm.iter_calls = 0
dummy_tqdm.write_calls = 0

tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=True),
)
tuner.run()
assert dummy_tqdm.iter_calls > 0
assert dummy_tqdm.write_calls > 0


def test_convex():
param_dict = {
"x": range(-100, 10),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' added option to disable progress logs by tihom · Pull Request #122 · ARM-software/mango · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -396,6 +396,7 @@ Note that if `initial_custom` option is given then `initial_random` is ignored.
}
```
However, use this option with caution as it could have unintended consequences.
- *log_progress*: `True` or `False` (default: `True`). When `True`, Mango logs optimization progress with a tqdm-based progress bar and per-iteration best scores. Set this to `False` to suppress progress logging, which is useful in CI environments or when you want cleaner logs.



Expand Down
20 changes: 20 additions & 0 deletions development.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,4 +7,24 @@ poetry config pypi-token.pypi <api_token>
> poetry version [major, minor, patch]
> poetry build
> poetry publish
```

### Local development: virtualenv and tests

Create a virtual environment in the project root:
```shell
python3 -m venv venv
```

Activate it from **fish**:
```shell
source ./venv/bin/activate.fish
```

Install development dependencies and run the test suite:
```shell
pip install --upgrade pip
pip install poetry
poetry install
pytest
```
Empty file modifiedexamples/__init__.py
100755 → 100644
Empty file.
Empty file modifiedexamples/classifiers/__init__.py
100755 → 100644
Empty file.
Empty file modifiedmango/domain/__init__.py
100755 → 100644
Empty file.
13 changes: 10 additions & 3 deletions mango/metatuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ class MetaTuner:
class Config:
n_iter: int = 20
n_init: int = 2
log_progress: bool = True

def __init__(self, param_dict_list, objective_list, **kwargs):
self.param_dict_list = param_dict_list
Expand All@@ -30,6 +31,7 @@ def __init__(self, param_dict_list, objective_list, **kwargs):
# adjustable parameters
self.num_of_iterations = self.config.n_iter
self.initial_random = self.config.n_init
self.log_progress = self.config.log_progress

# list of GPR for each objective
self.gpr_list = []
Expand DownExpand Up@@ -222,9 +224,13 @@ def runExponentialTuner(self):
# print(Optimizer_exploration)

# Now run the optimization iterations
pbar = tqdm(range(self.num_of_iterations))
iterator = (
tqdm(range(self.num_of_iterations))
if self.log_progress
else range(self.num_of_iterations)
)

for itr in pbar:
for itr in iterator:
# next values of x returned from individual function
# Values in x are dependent on types of param dict, so using a list
x_values_list = []
Expand DownExpand Up@@ -375,7 +381,8 @@ def runExponentialTuner(self):
Optimizer_exploration[i] + 1.1 * self.exploration_rate
)

pbar.set_description(": Best score: %s" % max_val_y)
if self.log_progress:
tqdm.write(": Best score: %s" % max_val_y)

# print(itr, s_values_list, Optimizer_iteration, Optimizer_exploration, max_val_y)#, Y_dict_array[selected_obj])

Expand Down
Empty file modifiedmango/optimizer/__init__.py
100755 → 100644
Empty file.
23 changes: 17 additions & 6 deletions mango/tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,6 +45,7 @@ class TunerConfig:
constraint: Callable = None
param_sampler: Callable = parameter_sampler
scale_params: bool = False
log_progress: bool = True

def __post_init__(self):
if self.optimizer not in self.valid_optimizers:
Expand DownExpand Up@@ -202,8 +203,12 @@ def runBayesianOptimizer(self):
X_domain_np = self.ds.convert_GP_space(domain_list)

# running the iterations
pbar = tqdm(range(self.config.num_iteration))
for _ in pbar:
iterator = (
tqdm(range(self.config.num_iteration))
if self.config.log_progress
else range(self.config.num_iteration)
)
for _ in iterator:

# adding a Minimum exploration to explore independent of UCB
if random.random() < self.config.exploration:
Expand DownExpand Up@@ -284,7 +289,8 @@ def runBayesianOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand All@@ -307,8 +313,12 @@ def runRandomOptimizer(self):
random_hyper_parameters = self.ds.get_random_sample(n_iterations * batch_size)

# running the iterations
pbar = tqdm(range(0, len(random_hyper_parameters), batch_size))
for idx in pbar:
iterator = (
tqdm(range(0, len(random_hyper_parameters), batch_size))
if self.config.log_progress
else range(0, len(random_hyper_parameters), batch_size)
)
for idx in iterator:
# getting batch by batch random values to try
batch_hyper_parameters = random_hyper_parameters[idx : idx + batch_size]
X_list, Y_list = self.runUserObjective(batch_hyper_parameters)
Expand All@@ -327,7 +337,8 @@ def runRandomOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand Down
50 changes: 50 additions & 0 deletions tests/test_tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@

from mango.domain.domain_space import DomainSpace
from mango import Tuner, scheduler
import mango.tuner as tuner_mod
from scipy.stats import uniform, dirichlet

# Simple param_dict
Expand DownExpand Up@@ -156,6 +157,55 @@ def check(results, error_msg):
check(results, "error while minimizing random")


def test_log_progress_flag(monkeypatch):
"""log_progress controls use of tqdm in the optimizer."""

class DummyTqdm:
def __init__(self):
self.iter_calls = 0
self.write_calls = 0

def __call__(self, iterable, *args, **kwargs):
# mimic tqdm(iterable) by returning the iterable unchanged
self.iter_calls += 1
return iterable

def write(self, *args, **kwargs):
self.write_calls += 1

dummy_tqdm = DummyTqdm()
monkeypatch.setattr(tuner_mod, "tqdm", dummy_tqdm)

param_dict = dict(x=range(-2, 3))

def objfunc(p_list):
# trivial, fast objective
return [0.0 for _ in p_list]

# When log_progress is False, tqdm should not be used
tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=False),
)
tuner.run()
assert dummy_tqdm.iter_calls == 0
assert dummy_tqdm.write_calls == 0

# When log_progress is True, tqdm should be used
dummy_tqdm.iter_calls = 0
dummy_tqdm.write_calls = 0

tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=True),
)
tuner.run()
assert dummy_tqdm.iter_calls > 0
assert dummy_tqdm.write_calls > 0


def test_convex():
param_dict = {
"x": range(-100, 10),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' added option to disable progress logs by tihom · Pull Request #122 · ARM-software/mango · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -396,6 +396,7 @@ Note that if `initial_custom` option is given then `initial_random` is ignored.
}
```
However, use this option with caution as it could have unintended consequences.
- *log_progress*: `True` or `False` (default: `True`). When `True`, Mango logs optimization progress with a tqdm-based progress bar and per-iteration best scores. Set this to `False` to suppress progress logging, which is useful in CI environments or when you want cleaner logs.



Expand Down
20 changes: 20 additions & 0 deletions development.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,4 +7,24 @@ poetry config pypi-token.pypi <api_token>
> poetry version [major, minor, patch]
> poetry build
> poetry publish
```

### Local development: virtualenv and tests

Create a virtual environment in the project root:
```shell
python3 -m venv venv
```

Activate it from **fish**:
```shell
source ./venv/bin/activate.fish
```

Install development dependencies and run the test suite:
```shell
pip install --upgrade pip
pip install poetry
poetry install
pytest
```
Empty file modifiedexamples/__init__.py
100755 → 100644
Empty file.
Empty file modifiedexamples/classifiers/__init__.py
100755 → 100644
Empty file.
Empty file modifiedmango/domain/__init__.py
100755 → 100644
Empty file.
13 changes: 10 additions & 3 deletions mango/metatuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ class MetaTuner:
class Config:
n_iter: int = 20
n_init: int = 2
log_progress: bool = True

def __init__(self, param_dict_list, objective_list, **kwargs):
self.param_dict_list = param_dict_list
Expand All@@ -30,6 +31,7 @@ def __init__(self, param_dict_list, objective_list, **kwargs):
# adjustable parameters
self.num_of_iterations = self.config.n_iter
self.initial_random = self.config.n_init
self.log_progress = self.config.log_progress

# list of GPR for each objective
self.gpr_list = []
Expand DownExpand Up@@ -222,9 +224,13 @@ def runExponentialTuner(self):
# print(Optimizer_exploration)

# Now run the optimization iterations
pbar = tqdm(range(self.num_of_iterations))
iterator = (
tqdm(range(self.num_of_iterations))
if self.log_progress
else range(self.num_of_iterations)
)

for itr in pbar:
for itr in iterator:
# next values of x returned from individual function
# Values in x are dependent on types of param dict, so using a list
x_values_list = []
Expand DownExpand Up@@ -375,7 +381,8 @@ def runExponentialTuner(self):
Optimizer_exploration[i] + 1.1 * self.exploration_rate
)

pbar.set_description(": Best score: %s" % max_val_y)
if self.log_progress:
tqdm.write(": Best score: %s" % max_val_y)

# print(itr, s_values_list, Optimizer_iteration, Optimizer_exploration, max_val_y)#, Y_dict_array[selected_obj])

Expand Down
Empty file modifiedmango/optimizer/__init__.py
100755 → 100644
Empty file.
23 changes: 17 additions & 6 deletions mango/tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,6 +45,7 @@ class TunerConfig:
constraint: Callable = None
param_sampler: Callable = parameter_sampler
scale_params: bool = False
log_progress: bool = True

def __post_init__(self):
if self.optimizer not in self.valid_optimizers:
Expand DownExpand Up@@ -202,8 +203,12 @@ def runBayesianOptimizer(self):
X_domain_np = self.ds.convert_GP_space(domain_list)

# running the iterations
pbar = tqdm(range(self.config.num_iteration))
for _ in pbar:
iterator = (
tqdm(range(self.config.num_iteration))
if self.config.log_progress
else range(self.config.num_iteration)
)
for _ in iterator:

# adding a Minimum exploration to explore independent of UCB
if random.random() < self.config.exploration:
Expand DownExpand Up@@ -284,7 +289,8 @@ def runBayesianOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand All@@ -307,8 +313,12 @@ def runRandomOptimizer(self):
random_hyper_parameters = self.ds.get_random_sample(n_iterations * batch_size)

# running the iterations
pbar = tqdm(range(0, len(random_hyper_parameters), batch_size))
for idx in pbar:
iterator = (
tqdm(range(0, len(random_hyper_parameters), batch_size))
if self.config.log_progress
else range(0, len(random_hyper_parameters), batch_size)
)
for idx in iterator:
# getting batch by batch random values to try
batch_hyper_parameters = random_hyper_parameters[idx : idx + batch_size]
X_list, Y_list = self.runUserObjective(batch_hyper_parameters)
Expand All@@ -327,7 +337,8 @@ def runRandomOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand Down
50 changes: 50 additions & 0 deletions tests/test_tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@

from mango.domain.domain_space import DomainSpace
from mango import Tuner, scheduler
import mango.tuner as tuner_mod
from scipy.stats import uniform, dirichlet

# Simple param_dict
Expand DownExpand Up@@ -156,6 +157,55 @@ def check(results, error_msg):
check(results, "error while minimizing random")


def test_log_progress_flag(monkeypatch):
"""log_progress controls use of tqdm in the optimizer."""

class DummyTqdm:
def __init__(self):
self.iter_calls = 0
self.write_calls = 0

def __call__(self, iterable, *args, **kwargs):
# mimic tqdm(iterable) by returning the iterable unchanged
self.iter_calls += 1
return iterable

def write(self, *args, **kwargs):
self.write_calls += 1

dummy_tqdm = DummyTqdm()
monkeypatch.setattr(tuner_mod, "tqdm", dummy_tqdm)

param_dict = dict(x=range(-2, 3))

def objfunc(p_list):
# trivial, fast objective
return [0.0 for _ in p_list]

# When log_progress is False, tqdm should not be used
tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=False),
)
tuner.run()
assert dummy_tqdm.iter_calls == 0
assert dummy_tqdm.write_calls == 0

# When log_progress is True, tqdm should be used
dummy_tqdm.iter_calls = 0
dummy_tqdm.write_calls = 0

tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=True),
)
tuner.run()
assert dummy_tqdm.iter_calls > 0
assert dummy_tqdm.write_calls > 0


def test_convex():
param_dict = {
"x": range(-100, 10),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' added option to disable progress logs by tihom · Pull Request #122 · ARM-software/mango · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -396,6 +396,7 @@ Note that if `initial_custom` option is given then `initial_random` is ignored.
}
```
However, use this option with caution as it could have unintended consequences.
- *log_progress*: `True` or `False` (default: `True`). When `True`, Mango logs optimization progress with a tqdm-based progress bar and per-iteration best scores. Set this to `False` to suppress progress logging, which is useful in CI environments or when you want cleaner logs.



Expand Down
20 changes: 20 additions & 0 deletions development.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,4 +7,24 @@ poetry config pypi-token.pypi <api_token>
> poetry version [major, minor, patch]
> poetry build
> poetry publish
```

### Local development: virtualenv and tests

Create a virtual environment in the project root:
```shell
python3 -m venv venv
```

Activate it from **fish**:
```shell
source ./venv/bin/activate.fish
```

Install development dependencies and run the test suite:
```shell
pip install --upgrade pip
pip install poetry
poetry install
pytest
```
Empty file modifiedexamples/__init__.py
100755 → 100644
Empty file.
Empty file modifiedexamples/classifiers/__init__.py
100755 → 100644
Empty file.
Empty file modifiedmango/domain/__init__.py
100755 → 100644
Empty file.
13 changes: 10 additions & 3 deletions mango/metatuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ class MetaTuner:
class Config:
n_iter: int = 20
n_init: int = 2
log_progress: bool = True

def __init__(self, param_dict_list, objective_list, **kwargs):
self.param_dict_list = param_dict_list
Expand All@@ -30,6 +31,7 @@ def __init__(self, param_dict_list, objective_list, **kwargs):
# adjustable parameters
self.num_of_iterations = self.config.n_iter
self.initial_random = self.config.n_init
self.log_progress = self.config.log_progress

# list of GPR for each objective
self.gpr_list = []
Expand DownExpand Up@@ -222,9 +224,13 @@ def runExponentialTuner(self):
# print(Optimizer_exploration)

# Now run the optimization iterations
pbar = tqdm(range(self.num_of_iterations))
iterator = (
tqdm(range(self.num_of_iterations))
if self.log_progress
else range(self.num_of_iterations)
)

for itr in pbar:
for itr in iterator:
# next values of x returned from individual function
# Values in x are dependent on types of param dict, so using a list
x_values_list = []
Expand DownExpand Up@@ -375,7 +381,8 @@ def runExponentialTuner(self):
Optimizer_exploration[i] + 1.1 * self.exploration_rate
)

pbar.set_description(": Best score: %s" % max_val_y)
if self.log_progress:
tqdm.write(": Best score: %s" % max_val_y)

# print(itr, s_values_list, Optimizer_iteration, Optimizer_exploration, max_val_y)#, Y_dict_array[selected_obj])

Expand Down
Empty file modifiedmango/optimizer/__init__.py
100755 → 100644
Empty file.
23 changes: 17 additions & 6 deletions mango/tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,6 +45,7 @@ class TunerConfig:
constraint: Callable = None
param_sampler: Callable = parameter_sampler
scale_params: bool = False
log_progress: bool = True

def __post_init__(self):
if self.optimizer not in self.valid_optimizers:
Expand DownExpand Up@@ -202,8 +203,12 @@ def runBayesianOptimizer(self):
X_domain_np = self.ds.convert_GP_space(domain_list)

# running the iterations
pbar = tqdm(range(self.config.num_iteration))
for _ in pbar:
iterator = (
tqdm(range(self.config.num_iteration))
if self.config.log_progress
else range(self.config.num_iteration)
)
for _ in iterator:

# adding a Minimum exploration to explore independent of UCB
if random.random() < self.config.exploration:
Expand DownExpand Up@@ -284,7 +289,8 @@ def runBayesianOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand All@@ -307,8 +313,12 @@ def runRandomOptimizer(self):
random_hyper_parameters = self.ds.get_random_sample(n_iterations * batch_size)

# running the iterations
pbar = tqdm(range(0, len(random_hyper_parameters), batch_size))
for idx in pbar:
iterator = (
tqdm(range(0, len(random_hyper_parameters), batch_size))
if self.config.log_progress
else range(0, len(random_hyper_parameters), batch_size)
)
for idx in iterator:
# getting batch by batch random values to try
batch_hyper_parameters = random_hyper_parameters[idx : idx + batch_size]
X_list, Y_list = self.runUserObjective(batch_hyper_parameters)
Expand All@@ -327,7 +337,8 @@ def runRandomOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand Down
50 changes: 50 additions & 0 deletions tests/test_tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@

from mango.domain.domain_space import DomainSpace
from mango import Tuner, scheduler
import mango.tuner as tuner_mod
from scipy.stats import uniform, dirichlet

# Simple param_dict
Expand DownExpand Up@@ -156,6 +157,55 @@ def check(results, error_msg):
check(results, "error while minimizing random")


def test_log_progress_flag(monkeypatch):
"""log_progress controls use of tqdm in the optimizer."""

class DummyTqdm:
def __init__(self):
self.iter_calls = 0
self.write_calls = 0

def __call__(self, iterable, *args, **kwargs):
# mimic tqdm(iterable) by returning the iterable unchanged
self.iter_calls += 1
return iterable

def write(self, *args, **kwargs):
self.write_calls += 1

dummy_tqdm = DummyTqdm()
monkeypatch.setattr(tuner_mod, "tqdm", dummy_tqdm)

param_dict = dict(x=range(-2, 3))

def objfunc(p_list):
# trivial, fast objective
return [0.0 for _ in p_list]

# When log_progress is False, tqdm should not be used
tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=False),
)
tuner.run()
assert dummy_tqdm.iter_calls == 0
assert dummy_tqdm.write_calls == 0

# When log_progress is True, tqdm should be used
dummy_tqdm.iter_calls = 0
dummy_tqdm.write_calls = 0

tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=True),
)
tuner.run()
assert dummy_tqdm.iter_calls > 0
assert dummy_tqdm.write_calls > 0


def test_convex():
param_dict = {
"x": range(-100, 10),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' added option to disable progress logs by tihom · Pull Request #122 · ARM-software/mango · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -396,6 +396,7 @@ Note that if `initial_custom` option is given then `initial_random` is ignored.
}
```
However, use this option with caution as it could have unintended consequences.
- *log_progress*: `True` or `False` (default: `True`). When `True`, Mango logs optimization progress with a tqdm-based progress bar and per-iteration best scores. Set this to `False` to suppress progress logging, which is useful in CI environments or when you want cleaner logs.



Expand Down
20 changes: 20 additions & 0 deletions development.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,4 +7,24 @@ poetry config pypi-token.pypi <api_token>
> poetry version [major, minor, patch]
> poetry build
> poetry publish
```

### Local development: virtualenv and tests

Create a virtual environment in the project root:
```shell
python3 -m venv venv
```

Activate it from **fish**:
```shell
source ./venv/bin/activate.fish
```

Install development dependencies and run the test suite:
```shell
pip install --upgrade pip
pip install poetry
poetry install
pytest
```
Empty file modifiedexamples/__init__.py
100755 → 100644
Empty file.
Empty file modifiedexamples/classifiers/__init__.py
100755 → 100644
Empty file.
Empty file modifiedmango/domain/__init__.py
100755 → 100644
Empty file.
13 changes: 10 additions & 3 deletions mango/metatuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ class MetaTuner:
class Config:
n_iter: int = 20
n_init: int = 2
log_progress: bool = True

def __init__(self, param_dict_list, objective_list, **kwargs):
self.param_dict_list = param_dict_list
Expand All@@ -30,6 +31,7 @@ def __init__(self, param_dict_list, objective_list, **kwargs):
# adjustable parameters
self.num_of_iterations = self.config.n_iter
self.initial_random = self.config.n_init
self.log_progress = self.config.log_progress

# list of GPR for each objective
self.gpr_list = []
Expand DownExpand Up@@ -222,9 +224,13 @@ def runExponentialTuner(self):
# print(Optimizer_exploration)

# Now run the optimization iterations
pbar = tqdm(range(self.num_of_iterations))
iterator = (
tqdm(range(self.num_of_iterations))
if self.log_progress
else range(self.num_of_iterations)
)

for itr in pbar:
for itr in iterator:
# next values of x returned from individual function
# Values in x are dependent on types of param dict, so using a list
x_values_list = []
Expand DownExpand Up@@ -375,7 +381,8 @@ def runExponentialTuner(self):
Optimizer_exploration[i] + 1.1 * self.exploration_rate
)

pbar.set_description(": Best score: %s" % max_val_y)
if self.log_progress:
tqdm.write(": Best score: %s" % max_val_y)

# print(itr, s_values_list, Optimizer_iteration, Optimizer_exploration, max_val_y)#, Y_dict_array[selected_obj])

Expand Down
Empty file modifiedmango/optimizer/__init__.py
100755 → 100644
Empty file.
23 changes: 17 additions & 6 deletions mango/tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,6 +45,7 @@ class TunerConfig:
constraint: Callable = None
param_sampler: Callable = parameter_sampler
scale_params: bool = False
log_progress: bool = True

def __post_init__(self):
if self.optimizer not in self.valid_optimizers:
Expand DownExpand Up@@ -202,8 +203,12 @@ def runBayesianOptimizer(self):
X_domain_np = self.ds.convert_GP_space(domain_list)

# running the iterations
pbar = tqdm(range(self.config.num_iteration))
for _ in pbar:
iterator = (
tqdm(range(self.config.num_iteration))
if self.config.log_progress
else range(self.config.num_iteration)
)
for _ in iterator:

# adding a Minimum exploration to explore independent of UCB
if random.random() < self.config.exploration:
Expand DownExpand Up@@ -284,7 +289,8 @@ def runBayesianOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand All@@ -307,8 +313,12 @@ def runRandomOptimizer(self):
random_hyper_parameters = self.ds.get_random_sample(n_iterations * batch_size)

# running the iterations
pbar = tqdm(range(0, len(random_hyper_parameters), batch_size))
for idx in pbar:
iterator = (
tqdm(range(0, len(random_hyper_parameters), batch_size))
if self.config.log_progress
else range(0, len(random_hyper_parameters), batch_size)
)
for idx in iterator:
# getting batch by batch random values to try
batch_hyper_parameters = random_hyper_parameters[idx : idx + batch_size]
X_list, Y_list = self.runUserObjective(batch_hyper_parameters)
Expand All@@ -327,7 +337,8 @@ def runRandomOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand Down
50 changes: 50 additions & 0 deletions tests/test_tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@

from mango.domain.domain_space import DomainSpace
from mango import Tuner, scheduler
import mango.tuner as tuner_mod
from scipy.stats import uniform, dirichlet

# Simple param_dict
Expand DownExpand Up@@ -156,6 +157,55 @@ def check(results, error_msg):
check(results, "error while minimizing random")


def test_log_progress_flag(monkeypatch):
"""log_progress controls use of tqdm in the optimizer."""

class DummyTqdm:
def __init__(self):
self.iter_calls = 0
self.write_calls = 0

def __call__(self, iterable, *args, **kwargs):
# mimic tqdm(iterable) by returning the iterable unchanged
self.iter_calls += 1
return iterable

def write(self, *args, **kwargs):
self.write_calls += 1

dummy_tqdm = DummyTqdm()
monkeypatch.setattr(tuner_mod, "tqdm", dummy_tqdm)

param_dict = dict(x=range(-2, 3))

def objfunc(p_list):
# trivial, fast objective
return [0.0 for _ in p_list]

# When log_progress is False, tqdm should not be used
tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=False),
)
tuner.run()
assert dummy_tqdm.iter_calls == 0
assert dummy_tqdm.write_calls == 0

# When log_progress is True, tqdm should be used
dummy_tqdm.iter_calls = 0
dummy_tqdm.write_calls = 0

tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=True),
)
tuner.run()
assert dummy_tqdm.iter_calls > 0
assert dummy_tqdm.write_calls > 0


def test_convex():
param_dict = {
"x": range(-100, 10),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); added option to disable progress logs by tihom · Pull Request #122 · ARM-software/mango · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -396,6 +396,7 @@ Note that if `initial_custom` option is given then `initial_random` is ignored.
}
```
However, use this option with caution as it could have unintended consequences.
- *log_progress*: `True` or `False` (default: `True`). When `True`, Mango logs optimization progress with a tqdm-based progress bar and per-iteration best scores. Set this to `False` to suppress progress logging, which is useful in CI environments or when you want cleaner logs.



Expand Down
20 changes: 20 additions & 0 deletions development.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,4 +7,24 @@ poetry config pypi-token.pypi <api_token>
> poetry version [major, minor, patch]
> poetry build
> poetry publish
```

### Local development: virtualenv and tests

Create a virtual environment in the project root:
```shell
python3 -m venv venv
```

Activate it from **fish**:
```shell
source ./venv/bin/activate.fish
```

Install development dependencies and run the test suite:
```shell
pip install --upgrade pip
pip install poetry
poetry install
pytest
```
Empty file modifiedexamples/__init__.py
100755 → 100644
Empty file.
Empty file modifiedexamples/classifiers/__init__.py
100755 → 100644
Empty file.
Empty file modifiedmango/domain/__init__.py
100755 → 100644
Empty file.
13 changes: 10 additions & 3 deletions mango/metatuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,6 +22,7 @@ class MetaTuner:
class Config:
n_iter: int = 20
n_init: int = 2
log_progress: bool = True

def __init__(self, param_dict_list, objective_list, **kwargs):
self.param_dict_list = param_dict_list
Expand All@@ -30,6 +31,7 @@ def __init__(self, param_dict_list, objective_list, **kwargs):
# adjustable parameters
self.num_of_iterations = self.config.n_iter
self.initial_random = self.config.n_init
self.log_progress = self.config.log_progress

# list of GPR for each objective
self.gpr_list = []
Expand DownExpand Up@@ -222,9 +224,13 @@ def runExponentialTuner(self):
# print(Optimizer_exploration)

# Now run the optimization iterations
pbar = tqdm(range(self.num_of_iterations))
iterator = (
tqdm(range(self.num_of_iterations))
if self.log_progress
else range(self.num_of_iterations)
)

for itr in pbar:
for itr in iterator:
# next values of x returned from individual function
# Values in x are dependent on types of param dict, so using a list
x_values_list = []
Expand DownExpand Up@@ -375,7 +381,8 @@ def runExponentialTuner(self):
Optimizer_exploration[i] + 1.1 * self.exploration_rate
)

pbar.set_description(": Best score: %s" % max_val_y)
if self.log_progress:
tqdm.write(": Best score: %s" % max_val_y)

# print(itr, s_values_list, Optimizer_iteration, Optimizer_exploration, max_val_y)#, Y_dict_array[selected_obj])

Expand Down
Empty file modifiedmango/optimizer/__init__.py
100755 → 100644
Empty file.
23 changes: 17 additions & 6 deletions mango/tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,6 +45,7 @@ class TunerConfig:
constraint: Callable = None
param_sampler: Callable = parameter_sampler
scale_params: bool = False
log_progress: bool = True

def __post_init__(self):
if self.optimizer not in self.valid_optimizers:
Expand DownExpand Up@@ -202,8 +203,12 @@ def runBayesianOptimizer(self):
X_domain_np = self.ds.convert_GP_space(domain_list)

# running the iterations
pbar = tqdm(range(self.config.num_iteration))
for _ in pbar:
iterator = (
tqdm(range(self.config.num_iteration))
if self.config.log_progress
else range(self.config.num_iteration)
)
for _ in iterator:

# adding a Minimum exploration to explore independent of UCB
if random.random() < self.config.exploration:
Expand DownExpand Up@@ -284,7 +289,8 @@ def runBayesianOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand All@@ -307,8 +313,12 @@ def runRandomOptimizer(self):
random_hyper_parameters = self.ds.get_random_sample(n_iterations * batch_size)

# running the iterations
pbar = tqdm(range(0, len(random_hyper_parameters), batch_size))
for idx in pbar:
iterator = (
tqdm(range(0, len(random_hyper_parameters), batch_size))
if self.config.log_progress
else range(0, len(random_hyper_parameters), batch_size)
)
for idx in iterator:
# getting batch by batch random values to try
batch_hyper_parameters = random_hyper_parameters[idx : idx + batch_size]
X_list, Y_list = self.runUserObjective(batch_hyper_parameters)
Expand All@@ -327,7 +337,8 @@ def runRandomOptimizer(self):
results["objective_values"] = -1 * results["objective_values"]
results["best_objective"] = -1 * results["best_objective"]

pbar.set_description("Best score: %s" % results["best_objective"])
if self.config.log_progress:
tqdm.write("Best score: %s" % results["best_objective"])

# check if early stop criteria has been met
if self.config.early_stop(results):
Expand Down
50 changes: 50 additions & 0 deletions tests/test_tuner.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@

from mango.domain.domain_space import DomainSpace
from mango import Tuner, scheduler
import mango.tuner as tuner_mod
from scipy.stats import uniform, dirichlet

# Simple param_dict
Expand DownExpand Up@@ -156,6 +157,55 @@ def check(results, error_msg):
check(results, "error while minimizing random")


def test_log_progress_flag(monkeypatch):
"""log_progress controls use of tqdm in the optimizer."""

class DummyTqdm:
def __init__(self):
self.iter_calls = 0
self.write_calls = 0

def __call__(self, iterable, *args, **kwargs):
# mimic tqdm(iterable) by returning the iterable unchanged
self.iter_calls += 1
return iterable

def write(self, *args, **kwargs):
self.write_calls += 1

dummy_tqdm = DummyTqdm()
monkeypatch.setattr(tuner_mod, "tqdm", dummy_tqdm)

param_dict = dict(x=range(-2, 3))

def objfunc(p_list):
# trivial, fast objective
return [0.0 for _ in p_list]

# When log_progress is False, tqdm should not be used
tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=False),
)
tuner.run()
assert dummy_tqdm.iter_calls == 0
assert dummy_tqdm.write_calls == 0

# When log_progress is True, tqdm should be used
dummy_tqdm.iter_calls = 0
dummy_tqdm.write_calls = 0

tuner = Tuner(
param_dict,
objfunc,
conf_dict=dict(num_iteration=3, initial_random=1, log_progress=True),
)
tuner.run()
assert dummy_tqdm.iter_calls > 0
assert dummy_tqdm.write_calls > 0


def test_convex():
param_dict = {
"x": range(-100, 10),
Expand Down
Loading