morphml 1.0.0__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 morphml might be problematic. Click here for more details.
- morphml/__init__.py +14 -0
- morphml/api/__init__.py +26 -0
- morphml/api/app.py +326 -0
- morphml/api/auth.py +193 -0
- morphml/api/client.py +338 -0
- morphml/api/models.py +132 -0
- morphml/api/rate_limit.py +192 -0
- morphml/benchmarking/__init__.py +36 -0
- morphml/benchmarking/comparison.py +430 -0
- morphml/benchmarks/__init__.py +56 -0
- morphml/benchmarks/comparator.py +409 -0
- morphml/benchmarks/datasets.py +280 -0
- morphml/benchmarks/metrics.py +199 -0
- morphml/benchmarks/openml_suite.py +201 -0
- morphml/benchmarks/problems.py +289 -0
- morphml/benchmarks/suite.py +318 -0
- morphml/cli/__init__.py +5 -0
- morphml/cli/commands/experiment.py +329 -0
- morphml/cli/main.py +457 -0
- morphml/cli/quickstart.py +312 -0
- morphml/config.py +278 -0
- morphml/constraints/__init__.py +19 -0
- morphml/constraints/handler.py +205 -0
- morphml/constraints/predicates.py +285 -0
- morphml/core/__init__.py +3 -0
- morphml/core/crossover.py +449 -0
- morphml/core/dsl/README.md +359 -0
- morphml/core/dsl/__init__.py +72 -0
- morphml/core/dsl/ast_nodes.py +364 -0
- morphml/core/dsl/compiler.py +318 -0
- morphml/core/dsl/layers.py +368 -0
- morphml/core/dsl/lexer.py +336 -0
- morphml/core/dsl/parser.py +455 -0
- morphml/core/dsl/search_space.py +386 -0
- morphml/core/dsl/syntax.py +199 -0
- morphml/core/dsl/type_system.py +361 -0
- morphml/core/dsl/validator.py +386 -0
- morphml/core/graph/__init__.py +40 -0
- morphml/core/graph/edge.py +124 -0
- morphml/core/graph/graph.py +507 -0
- morphml/core/graph/mutations.py +409 -0
- morphml/core/graph/node.py +196 -0
- morphml/core/graph/serialization.py +361 -0
- morphml/core/graph/visualization.py +431 -0
- morphml/core/objectives/__init__.py +20 -0
- morphml/core/search/__init__.py +33 -0
- morphml/core/search/individual.py +252 -0
- morphml/core/search/parameters.py +453 -0
- morphml/core/search/population.py +375 -0
- morphml/core/search/search_engine.py +340 -0
- morphml/distributed/__init__.py +76 -0
- morphml/distributed/fault_tolerance.py +497 -0
- morphml/distributed/health_monitor.py +348 -0
- morphml/distributed/master.py +709 -0
- morphml/distributed/proto/README.md +224 -0
- morphml/distributed/proto/__init__.py +74 -0
- morphml/distributed/proto/worker.proto +170 -0
- morphml/distributed/proto/worker_pb2.py +79 -0
- morphml/distributed/proto/worker_pb2_grpc.py +423 -0
- morphml/distributed/resource_manager.py +416 -0
- morphml/distributed/scheduler.py +567 -0
- morphml/distributed/storage/__init__.py +33 -0
- morphml/distributed/storage/artifacts.py +381 -0
- morphml/distributed/storage/cache.py +366 -0
- morphml/distributed/storage/checkpointing.py +329 -0
- morphml/distributed/storage/database.py +459 -0
- morphml/distributed/worker.py +549 -0
- morphml/evaluation/__init__.py +5 -0
- morphml/evaluation/heuristic.py +237 -0
- morphml/exceptions.py +55 -0
- morphml/execution/__init__.py +5 -0
- morphml/execution/local_executor.py +350 -0
- morphml/integrations/__init__.py +28 -0
- morphml/integrations/jax_adapter.py +206 -0
- morphml/integrations/pytorch_adapter.py +530 -0
- morphml/integrations/sklearn_adapter.py +206 -0
- morphml/integrations/tensorflow_adapter.py +230 -0
- morphml/logging_config.py +93 -0
- morphml/meta_learning/__init__.py +66 -0
- morphml/meta_learning/architecture_similarity.py +277 -0
- morphml/meta_learning/experiment_database.py +240 -0
- morphml/meta_learning/knowledge_base/__init__.py +19 -0
- morphml/meta_learning/knowledge_base/embedder.py +179 -0
- morphml/meta_learning/knowledge_base/knowledge_base.py +313 -0
- morphml/meta_learning/knowledge_base/meta_features.py +265 -0
- morphml/meta_learning/knowledge_base/vector_store.py +271 -0
- morphml/meta_learning/predictors/__init__.py +27 -0
- morphml/meta_learning/predictors/ensemble.py +221 -0
- morphml/meta_learning/predictors/gnn_predictor.py +552 -0
- morphml/meta_learning/predictors/learning_curve.py +231 -0
- morphml/meta_learning/predictors/proxy_metrics.py +261 -0
- morphml/meta_learning/strategy_evolution/__init__.py +27 -0
- morphml/meta_learning/strategy_evolution/adaptive_optimizer.py +226 -0
- morphml/meta_learning/strategy_evolution/bandit.py +276 -0
- morphml/meta_learning/strategy_evolution/portfolio.py +230 -0
- morphml/meta_learning/transfer.py +581 -0
- morphml/meta_learning/warm_start.py +286 -0
- morphml/optimizers/__init__.py +74 -0
- morphml/optimizers/adaptive_operators.py +399 -0
- morphml/optimizers/bayesian/__init__.py +52 -0
- morphml/optimizers/bayesian/acquisition.py +387 -0
- morphml/optimizers/bayesian/base.py +319 -0
- morphml/optimizers/bayesian/gaussian_process.py +635 -0
- morphml/optimizers/bayesian/smac.py +534 -0
- morphml/optimizers/bayesian/tpe.py +411 -0
- morphml/optimizers/differential_evolution.py +220 -0
- morphml/optimizers/evolutionary/__init__.py +61 -0
- morphml/optimizers/evolutionary/cma_es.py +416 -0
- morphml/optimizers/evolutionary/differential_evolution.py +556 -0
- morphml/optimizers/evolutionary/encoding.py +426 -0
- morphml/optimizers/evolutionary/particle_swarm.py +449 -0
- morphml/optimizers/genetic_algorithm.py +486 -0
- morphml/optimizers/gradient_based/__init__.py +22 -0
- morphml/optimizers/gradient_based/darts.py +550 -0
- morphml/optimizers/gradient_based/enas.py +585 -0
- morphml/optimizers/gradient_based/operations.py +474 -0
- morphml/optimizers/gradient_based/utils.py +601 -0
- morphml/optimizers/hill_climbing.py +169 -0
- morphml/optimizers/multi_objective/__init__.py +56 -0
- morphml/optimizers/multi_objective/indicators.py +504 -0
- morphml/optimizers/multi_objective/nsga2.py +647 -0
- morphml/optimizers/multi_objective/visualization.py +427 -0
- morphml/optimizers/nsga2.py +308 -0
- morphml/optimizers/random_search.py +172 -0
- morphml/optimizers/simulated_annealing.py +181 -0
- morphml/plugins/__init__.py +35 -0
- morphml/plugins/custom_evaluator_example.py +81 -0
- morphml/plugins/custom_optimizer_example.py +63 -0
- morphml/plugins/plugin_system.py +454 -0
- morphml/reports/__init__.py +30 -0
- morphml/reports/generator.py +362 -0
- morphml/tracking/__init__.py +7 -0
- morphml/tracking/experiment.py +309 -0
- morphml/tracking/logger.py +301 -0
- morphml/tracking/reporter.py +357 -0
- morphml/utils/__init__.py +6 -0
- morphml/utils/checkpoint.py +189 -0
- morphml/utils/comparison.py +390 -0
- morphml/utils/export.py +407 -0
- morphml/utils/progress.py +392 -0
- morphml/utils/validation.py +392 -0
- morphml/version.py +7 -0
- morphml/visualization/__init__.py +50 -0
- morphml/visualization/analytics.py +423 -0
- morphml/visualization/architecture_diagrams.py +353 -0
- morphml/visualization/architecture_plot.py +223 -0
- morphml/visualization/convergence_plot.py +174 -0
- morphml/visualization/crossover_viz.py +386 -0
- morphml/visualization/graph_viz.py +338 -0
- morphml/visualization/pareto_plot.py +149 -0
- morphml/visualization/plotly_dashboards.py +422 -0
- morphml/visualization/population.py +309 -0
- morphml/visualization/progress.py +260 -0
- morphml-1.0.0.dist-info/METADATA +434 -0
- morphml-1.0.0.dist-info/RECORD +158 -0
- morphml-1.0.0.dist-info/WHEEL +4 -0
- morphml-1.0.0.dist-info/entry_points.txt +3 -0
- morphml-1.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""Hill Climbing optimizer for NAS.
|
|
2
|
+
|
|
3
|
+
Local search strategy that iteratively improves a single architecture
|
|
4
|
+
by exploring its neighborhood through mutations.
|
|
5
|
+
|
|
6
|
+
Example:
|
|
7
|
+
>>> from morphml.optimizers import HillClimbing
|
|
8
|
+
>>>
|
|
9
|
+
>>> hc = HillClimbing(search_space=space, max_iterations=100)
|
|
10
|
+
>>> best = hc.optimize(evaluator=my_evaluator)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Callable, List, Optional
|
|
14
|
+
|
|
15
|
+
from morphml.core.dsl.search_space import SearchSpace
|
|
16
|
+
from morphml.core.graph import GraphMutator, ModelGraph
|
|
17
|
+
from morphml.core.search import Individual
|
|
18
|
+
from morphml.exceptions import OptimizerError
|
|
19
|
+
from morphml.logging_config import get_logger
|
|
20
|
+
|
|
21
|
+
logger = get_logger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class HillClimbing:
|
|
25
|
+
"""
|
|
26
|
+
Hill Climbing optimizer for Neural Architecture Search.
|
|
27
|
+
|
|
28
|
+
Iteratively improves a single architecture by:
|
|
29
|
+
1. Mutating the current architecture
|
|
30
|
+
2. Evaluating the mutated version
|
|
31
|
+
3. Accepting if better
|
|
32
|
+
4. Repeating until no improvement
|
|
33
|
+
|
|
34
|
+
Simple but effective for refinement and local optimization.
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
search_space: SearchSpace for initialization
|
|
38
|
+
max_iterations: Maximum number of iterations
|
|
39
|
+
current: Current best individual
|
|
40
|
+
history: List of fitness values over iterations
|
|
41
|
+
|
|
42
|
+
Example:
|
|
43
|
+
>>> hc = HillClimbing(
|
|
44
|
+
... search_space=space,
|
|
45
|
+
... max_iterations=100,
|
|
46
|
+
... patience=10
|
|
47
|
+
... )
|
|
48
|
+
>>> best = hc.optimize(evaluator)
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
search_space: SearchSpace,
|
|
54
|
+
max_iterations: int = 100,
|
|
55
|
+
patience: int = 10,
|
|
56
|
+
num_mutations: int = 3,
|
|
57
|
+
mutation_rate: float = 0.3,
|
|
58
|
+
**kwargs,
|
|
59
|
+
):
|
|
60
|
+
"""
|
|
61
|
+
Initialize Hill Climbing optimizer.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
search_space: SearchSpace for initialization
|
|
65
|
+
max_iterations: Maximum iterations
|
|
66
|
+
patience: Stop if no improvement for N iterations
|
|
67
|
+
num_mutations: Number of mutations per neighbor
|
|
68
|
+
mutation_rate: Mutation rate for GraphMutator
|
|
69
|
+
**kwargs: Additional configuration
|
|
70
|
+
"""
|
|
71
|
+
self.search_space = search_space
|
|
72
|
+
self.max_iterations = max_iterations
|
|
73
|
+
self.patience = patience
|
|
74
|
+
self.num_mutations = num_mutations
|
|
75
|
+
self.mutation_rate = mutation_rate
|
|
76
|
+
|
|
77
|
+
self.mutator = GraphMutator()
|
|
78
|
+
self.current: Optional[Individual] = None
|
|
79
|
+
self.history: List[float] = []
|
|
80
|
+
|
|
81
|
+
logger.info(f"Created HillClimbing: max_iterations={max_iterations}, patience={patience}")
|
|
82
|
+
|
|
83
|
+
def optimize(self, evaluator: Callable[[ModelGraph], float]) -> Individual:
|
|
84
|
+
"""
|
|
85
|
+
Run hill climbing optimization.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
evaluator: Function to evaluate fitness
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Best individual found
|
|
92
|
+
|
|
93
|
+
Raises:
|
|
94
|
+
OptimizerError: If optimization fails
|
|
95
|
+
"""
|
|
96
|
+
try:
|
|
97
|
+
# Initialize with random architecture
|
|
98
|
+
logger.info("Initializing hill climbing")
|
|
99
|
+
init_graph = self.search_space.sample()
|
|
100
|
+
self.current = Individual(init_graph)
|
|
101
|
+
fitness = evaluator(self.current.graph)
|
|
102
|
+
self.current.set_fitness(fitness)
|
|
103
|
+
self.history.append(fitness)
|
|
104
|
+
|
|
105
|
+
logger.info(f"Initial fitness: {fitness:.4f}")
|
|
106
|
+
|
|
107
|
+
iterations_without_improvement = 0
|
|
108
|
+
iteration = 0
|
|
109
|
+
|
|
110
|
+
while iteration < self.max_iterations:
|
|
111
|
+
iteration += 1
|
|
112
|
+
|
|
113
|
+
# Generate neighbor by mutation
|
|
114
|
+
mutated_graph = self.mutator.mutate(
|
|
115
|
+
self.current.graph,
|
|
116
|
+
mutation_rate=self.mutation_rate,
|
|
117
|
+
max_mutations=self.num_mutations,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Evaluate neighbor
|
|
121
|
+
neighbor = Individual(mutated_graph)
|
|
122
|
+
neighbor_fitness = evaluator(neighbor.graph)
|
|
123
|
+
neighbor.set_fitness(neighbor_fitness)
|
|
124
|
+
|
|
125
|
+
# Accept if better
|
|
126
|
+
if neighbor_fitness > self.current.fitness:
|
|
127
|
+
self.current = neighbor
|
|
128
|
+
self.history.append(neighbor_fitness)
|
|
129
|
+
iterations_without_improvement = 0
|
|
130
|
+
logger.info(f"Iteration {iteration}: Improved to {neighbor_fitness:.4f}")
|
|
131
|
+
else:
|
|
132
|
+
self.history.append(self.current.fitness)
|
|
133
|
+
iterations_without_improvement += 1
|
|
134
|
+
|
|
135
|
+
# Check patience
|
|
136
|
+
if iterations_without_improvement >= self.patience:
|
|
137
|
+
logger.info(f"Stopping: No improvement for {self.patience} iterations")
|
|
138
|
+
break
|
|
139
|
+
|
|
140
|
+
if iteration % 10 == 0:
|
|
141
|
+
logger.debug(
|
|
142
|
+
f"Iteration {iteration}/{self.max_iterations}: "
|
|
143
|
+
f"fitness={self.current.fitness:.4f}"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
logger.info(f"Hill climbing complete: Best fitness = {self.current.fitness:.4f}")
|
|
147
|
+
|
|
148
|
+
return self.current
|
|
149
|
+
|
|
150
|
+
except Exception as e:
|
|
151
|
+
logger.error(f"Hill climbing failed: {e}")
|
|
152
|
+
raise OptimizerError(f"Hill climbing optimization failed: {e}") from e
|
|
153
|
+
|
|
154
|
+
def get_history(self) -> List[float]:
|
|
155
|
+
"""Get optimization history."""
|
|
156
|
+
return self.history
|
|
157
|
+
|
|
158
|
+
def reset(self) -> None:
|
|
159
|
+
"""Reset optimizer state."""
|
|
160
|
+
self.current = None
|
|
161
|
+
self.history.clear()
|
|
162
|
+
logger.info("Hill climbing reset")
|
|
163
|
+
|
|
164
|
+
def __repr__(self) -> str:
|
|
165
|
+
"""String representation."""
|
|
166
|
+
return (
|
|
167
|
+
f"HillClimbing(max_iterations={self.max_iterations}, "
|
|
168
|
+
f"current_fitness={self.current.fitness if self.current else None})"
|
|
169
|
+
)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Multi-objective optimization algorithms.
|
|
2
|
+
|
|
3
|
+
This module implements algorithms for optimizing multiple conflicting objectives
|
|
4
|
+
simultaneously, discovering Pareto-optimal solutions.
|
|
5
|
+
|
|
6
|
+
Algorithms:
|
|
7
|
+
- NSGA-II (Non-dominated Sorting Genetic Algorithm II)
|
|
8
|
+
- Pareto dominance and ranking
|
|
9
|
+
- Quality indicators (Hypervolume, IGD, Spacing, Spread)
|
|
10
|
+
- Visualization tools
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
>>> from morphml.optimizers.multi_objective import NSGA2Optimizer, optimize_with_nsga2
|
|
14
|
+
>>> optimizer = NSGA2Optimizer(
|
|
15
|
+
... search_space=space,
|
|
16
|
+
... config={
|
|
17
|
+
... 'population_size': 100,
|
|
18
|
+
... 'objectives': [
|
|
19
|
+
... {'name': 'accuracy', 'maximize': True},
|
|
20
|
+
... {'name': 'latency', 'maximize': False}
|
|
21
|
+
... ]
|
|
22
|
+
... }
|
|
23
|
+
... )
|
|
24
|
+
>>> pareto_front = optimizer.optimize(evaluator)
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from morphml.optimizers.multi_objective.indicators import (
|
|
28
|
+
QualityIndicators,
|
|
29
|
+
calculate_all_indicators,
|
|
30
|
+
compare_pareto_fronts,
|
|
31
|
+
)
|
|
32
|
+
from morphml.optimizers.multi_objective.nsga2 import (
|
|
33
|
+
MultiObjectiveIndividual,
|
|
34
|
+
NSGA2Optimizer,
|
|
35
|
+
optimize_with_nsga2,
|
|
36
|
+
)
|
|
37
|
+
from morphml.optimizers.multi_objective.visualization import (
|
|
38
|
+
ParetoVisualizer,
|
|
39
|
+
quick_visualize_2d,
|
|
40
|
+
quick_visualize_3d,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
# Core optimizer
|
|
45
|
+
"NSGA2Optimizer",
|
|
46
|
+
"MultiObjectiveIndividual",
|
|
47
|
+
"optimize_with_nsga2",
|
|
48
|
+
# Quality indicators
|
|
49
|
+
"QualityIndicators",
|
|
50
|
+
"calculate_all_indicators",
|
|
51
|
+
"compare_pareto_fronts",
|
|
52
|
+
# Visualization
|
|
53
|
+
"ParetoVisualizer",
|
|
54
|
+
"quick_visualize_2d",
|
|
55
|
+
"quick_visualize_3d",
|
|
56
|
+
]
|