ivoryos 1.3.6__py3-none-any.whl → 1.3.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ivoryos might be problematic. Click here for more details.
- ivoryos/optimizer/nimo_optimizer.py +162 -0
- ivoryos/version.py +1 -1
- {ivoryos-1.3.6.dist-info → ivoryos-1.3.7.dist-info}/METADATA +1 -1
- {ivoryos-1.3.6.dist-info → ivoryos-1.3.7.dist-info}/RECORD +7 -6
- {ivoryos-1.3.6.dist-info → ivoryos-1.3.7.dist-info}/WHEEL +0 -0
- {ivoryos-1.3.6.dist-info → ivoryos-1.3.7.dist-info}/licenses/LICENSE +0 -0
- {ivoryos-1.3.6.dist-info → ivoryos-1.3.7.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
### ivoryos/optimizers/nimo_optimizer.py
|
|
2
|
+
import itertools
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from ivoryos.optimizer.base_optimizer import OptimizerBase
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class NIMOOptimizer(OptimizerBase):
|
|
10
|
+
def __init__(self, experiment_name:str, parameter_space: list, objective_config: list, optimizer_config: dict, datapath:str):
|
|
11
|
+
"""
|
|
12
|
+
:param experiment_name: arbitrary name
|
|
13
|
+
:param parameter_space: list of parameter names
|
|
14
|
+
[
|
|
15
|
+
{"name": "param_1", "type": "range", "bounds": [1.0, 2.0], "value_type": "float"},
|
|
16
|
+
{"name": "param_2", "type": "choice", "bounds": ["a", "b", "c"], "value_type": "str"},
|
|
17
|
+
{"name": "param_3", "type": "range", "bounds": [0 10], "value_type": "int"},
|
|
18
|
+
]
|
|
19
|
+
:param objective_config: objective configuration
|
|
20
|
+
[
|
|
21
|
+
{"name": "obj_1", "minimize": True, "weight": 1},
|
|
22
|
+
{"name": "obj_2", "minimize": False, "weight": 1}
|
|
23
|
+
]
|
|
24
|
+
:param optimizer_config: optimizer configuration
|
|
25
|
+
optimizer_config={
|
|
26
|
+
"step_1": {"model": "Random", "num_samples": 10},
|
|
27
|
+
"step_2": {"model": "BOTorch"}
|
|
28
|
+
}
|
|
29
|
+
"""
|
|
30
|
+
self.current_step = 0
|
|
31
|
+
self.experiment_name = experiment_name
|
|
32
|
+
self.parameter_space = parameter_space
|
|
33
|
+
self.objective_config = objective_config
|
|
34
|
+
self.optimizer_config = optimizer_config
|
|
35
|
+
|
|
36
|
+
super().__init__(experiment_name, parameter_space, objective_config, optimizer_config, datapath)
|
|
37
|
+
|
|
38
|
+
step_1 = optimizer_config.get("step_1", {})
|
|
39
|
+
step_2 = optimizer_config.get("step_2", {})
|
|
40
|
+
self.step_1_generator = step_1.get("model", "RE")
|
|
41
|
+
self.step_1_batch_num = step_1.get("num_samples", 1)
|
|
42
|
+
self.step_2_generator = step_2.get("model", "PDC")
|
|
43
|
+
self.candidates = os.path.join(self.datapath, f"{self.experiment_name}_candidates.csv")
|
|
44
|
+
self.proposals = os.path.join(self.datapath, f"{self.experiment_name}_proposals.csv")
|
|
45
|
+
self.n_objectives = len(self.objective_config)
|
|
46
|
+
self._create_candidates_csv()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _create_candidates_csv(self):
|
|
50
|
+
# Extract parameter names and their possible values
|
|
51
|
+
import pandas as pd
|
|
52
|
+
import nimo
|
|
53
|
+
if os.path.exists(self.candidates) and nimo.history(self.candidates, self.n_objectives):
|
|
54
|
+
return
|
|
55
|
+
param_names = [p["name"] for p in self.parameter_space]
|
|
56
|
+
|
|
57
|
+
param_values = []
|
|
58
|
+
for p in self.parameter_space:
|
|
59
|
+
if p["type"] == "choice" and isinstance(p["bounds"], list):
|
|
60
|
+
param_values.append(p["bounds"])
|
|
61
|
+
elif p["type"] == "range" and len(p["bounds"]) == 2:
|
|
62
|
+
low, high = p["bounds"]
|
|
63
|
+
num_points = 10 # you can customize this granularity
|
|
64
|
+
step = (high - low) / (num_points - 1)
|
|
65
|
+
param_values.append([round(low + i * step, 4) for i in range(num_points)])
|
|
66
|
+
else:
|
|
67
|
+
raise ValueError(f"Unsupported parameter format: {p}")
|
|
68
|
+
|
|
69
|
+
# Generate all possible combinations
|
|
70
|
+
combos = list(itertools.product(*param_values))
|
|
71
|
+
|
|
72
|
+
# Create a DataFrame with parameter columns
|
|
73
|
+
df = pd.DataFrame(combos, columns=param_names)
|
|
74
|
+
|
|
75
|
+
# Add empty objective columns
|
|
76
|
+
for obj in self.objective_config:
|
|
77
|
+
df[obj["name"]] = ""
|
|
78
|
+
|
|
79
|
+
# Save to CSV
|
|
80
|
+
df.to_csv(self.candidates, index=False)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def suggest(self, n=1):
|
|
84
|
+
import pandas as pd
|
|
85
|
+
import nimo
|
|
86
|
+
method = self.step_1_generator if self.current_step <= self.step_1_batch_num else self.step_2_generator
|
|
87
|
+
nimo.selection(method = method,
|
|
88
|
+
input_file = self.candidates,
|
|
89
|
+
output_file = self.proposals,
|
|
90
|
+
num_objectives = self.n_objectives,
|
|
91
|
+
num_proposals = n)
|
|
92
|
+
self.current_step += 1
|
|
93
|
+
# Read proposals from CSV file
|
|
94
|
+
proposals_df = pd.read_csv(self.proposals)
|
|
95
|
+
# Get parameter names
|
|
96
|
+
param_names = [p["name"] for p in self.parameter_space]
|
|
97
|
+
# Convert proposals to list of parameter dictionaries
|
|
98
|
+
proposals = []
|
|
99
|
+
for _, row in proposals_df.iterrows():
|
|
100
|
+
proposal = {name: row[name] for name in param_names}
|
|
101
|
+
proposals.append(proposal)
|
|
102
|
+
return proposals[0] if n == 1 else proposals
|
|
103
|
+
|
|
104
|
+
def _convert_observation_to_list(self, obs: dict) -> list:
|
|
105
|
+
obj_names = [o["name"] for o in self.objective_config]
|
|
106
|
+
return [obs.get(name, None) for name in obj_names]
|
|
107
|
+
|
|
108
|
+
def observe(self, results: dict):
|
|
109
|
+
"""
|
|
110
|
+
observe single output, nimo obj input is [1,2,3] or [[1, 2], [1, 2], [1, 2]] for MO
|
|
111
|
+
:param results: {"objective_name": "value"}
|
|
112
|
+
"""
|
|
113
|
+
import nimo
|
|
114
|
+
nimo_objective_values = [self._convert_observation_to_list(results)]
|
|
115
|
+
|
|
116
|
+
nimo.output_update(input_file=self.proposals,
|
|
117
|
+
output_file=self.candidates,
|
|
118
|
+
num_objectives=self.n_objectives,
|
|
119
|
+
objective_values=nimo_objective_values)
|
|
120
|
+
|
|
121
|
+
def append_existing_data(self, existing_data):
|
|
122
|
+
# TODO, history is part of the candidate file, we probably won't need this
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def get_schema():
|
|
128
|
+
return {
|
|
129
|
+
"parameter_types": ["choice"],
|
|
130
|
+
"multiple_objectives": True,
|
|
131
|
+
"optimizer_config": {
|
|
132
|
+
"step_1": {"model": ["RE", "ES", "PDC"], "num_samples": 5},
|
|
133
|
+
"step_2": {"model": ["PHYSBO", "BLOX", "PTR", "SLESA", "BOMP", "COMBI"]}
|
|
134
|
+
},
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
if __name__ == "__main__":
|
|
141
|
+
parameter_space = [
|
|
142
|
+
{"name": "silica", "type": "choice", "bounds": [100], "value_type": "float"},
|
|
143
|
+
{"name": "water", "type": "choice", "bounds": [900, 800, 750, 700, 650, 600, 550, 500], "value_type": "float"},
|
|
144
|
+
{"name": "PVA", "type": "choice", "bounds": [0, 0.005, 0.0075, 0.01, 0.05, 0.075, 0.1], "value_type": "float"},
|
|
145
|
+
{"name": "SDS", "type": "choice", "bounds": [0], "value_type": "float"},
|
|
146
|
+
{"name": "DTAB", "type": "choice", "bounds": [0, 0.005, 0.0075, 0.01, 0.05, 0.075, 0.1], "value_type": "float"},
|
|
147
|
+
{"name": "PVP", "type": "choice", "bounds": [0], "value_type": "float"},
|
|
148
|
+
]
|
|
149
|
+
objective_config = [
|
|
150
|
+
{"name": "objective", "minimize": False, "weight": 1},
|
|
151
|
+
|
|
152
|
+
]
|
|
153
|
+
optimizer_config = {
|
|
154
|
+
"step_1": {"model": "RE", "num_samples": 10},
|
|
155
|
+
"step_2": {"model": "PDC"}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
nimo_optimizer = NIMOOptimizer(experiment_name="example_experiment", optimizer_config=optimizer_config, parameter_space=parameter_space, objective_config=objective_config)
|
|
159
|
+
nimo_optimizer.suggest(n=1)
|
|
160
|
+
nimo_optimizer.observe(
|
|
161
|
+
results={"objective": 1.0}
|
|
162
|
+
)
|
ivoryos/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "1.3.
|
|
1
|
+
__version__ = "1.3.7"
|
|
@@ -3,10 +3,11 @@ ivoryos/app.py,sha256=G6kzEOVzCduj7Fc2r1rMbMFHgDzZQV0lC20Oxps7RSM,4839
|
|
|
3
3
|
ivoryos/config.py,sha256=y3RxNjiIola9tK7jg-mHM8EzLMwiLwOzoisXkDvj0gA,2174
|
|
4
4
|
ivoryos/server.py,sha256=Idr41Boa8rPsh3bVJ8xy2Flwfxa1Xu6f2T0oMp4qBEk,7121
|
|
5
5
|
ivoryos/socket_handlers.py,sha256=VWVWiIdm4jYAutwGu6R0t1nK5MuMyOCL0xAnFn06jWQ,1302
|
|
6
|
-
ivoryos/version.py,sha256=
|
|
6
|
+
ivoryos/version.py,sha256=9peaXOar2qezOPJEKG6cD_A0aaXrzdVN8h-v6fBoBEk,22
|
|
7
7
|
ivoryos/optimizer/ax_optimizer.py,sha256=k7RzhNMjh3MseOE-_FADVX72lYLDyXz-XE3juSBRWTk,7116
|
|
8
8
|
ivoryos/optimizer/base_optimizer.py,sha256=gNBX9m3RxoYklwEBkqeDGZlU7c6e9e5kN0ZeTtnxnCE,2044
|
|
9
9
|
ivoryos/optimizer/baybe_optimizer.py,sha256=EdrrRiYO-IOx610cPXiQhH4qG8knUP0uiZ0YoyaGIU8,7954
|
|
10
|
+
ivoryos/optimizer/nimo_optimizer.py,sha256=J1nR1gMI4LqOkKqqdc5Pq7r3e3R8QQTJ-TZ9l9GVPQE,6696
|
|
10
11
|
ivoryos/optimizer/registry.py,sha256=dLMo5cszcwa06hfBxdINQIGpkHtRe5-J3J7t76Jq6X0,306
|
|
11
12
|
ivoryos/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
13
|
ivoryos/routes/api/api.py,sha256=97Y7pqTwOaWgZgI5ovEPxEBm6Asrt0Iy0VhBkVp2xqA,2304
|
|
@@ -96,8 +97,8 @@ ivoryos/utils/script_runner.py,sha256=gIYdTEFNWZFmPf9cf31y3wAUKUeJk_qnjohYDKevWN
|
|
|
96
97
|
ivoryos/utils/serilize.py,sha256=lkBhkz8r2bLmz2_xOb0c4ptSSOqjIu6krj5YYK4Nvj8,6784
|
|
97
98
|
ivoryos/utils/task_runner.py,sha256=xiMzK8gQ0mHsg0A1Ah8fmXe3azpaJh4hJiQJLHA11ZQ,3682
|
|
98
99
|
ivoryos/utils/utils.py,sha256=dIc4BO55eS3lCA0nhbIncS5d7sLaKZy5hJS1I_Sm45o,14949
|
|
99
|
-
ivoryos-1.3.
|
|
100
|
-
ivoryos-1.3.
|
|
101
|
-
ivoryos-1.3.
|
|
102
|
-
ivoryos-1.3.
|
|
103
|
-
ivoryos-1.3.
|
|
100
|
+
ivoryos-1.3.7.dist-info/licenses/LICENSE,sha256=p2c8S8i-8YqMpZCJnadLz1-ofxnRMILzz6NCMIypRag,1084
|
|
101
|
+
ivoryos-1.3.7.dist-info/METADATA,sha256=b4vaTs88sF290jix6Yiwlw0RbwIVUoNiDUg2KfjTWXM,8516
|
|
102
|
+
ivoryos-1.3.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
103
|
+
ivoryos-1.3.7.dist-info/top_level.txt,sha256=FRIWWdiEvRKqw-XfF_UK3XV0CrnNb6EmVbEgjaVazRM,8
|
|
104
|
+
ivoryos-1.3.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|