polystep 0.7.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.
- polystep/__init__.py +176 -0
- polystep/_compiled.py +334 -0
- polystep/_step_blockwise.py +994 -0
- polystep/_step_momentum.py +128 -0
- polystep/_step_monolithic.py +1070 -0
- polystep/adaptive_subspace.py +762 -0
- polystep/api.py +307 -0
- polystep/ask_tell.py +164 -0
- polystep/benchmarks/__init__.py +62 -0
- polystep/benchmarks/baselines.py +604 -0
- polystep/benchmarks/rl/__init__.py +13 -0
- polystep/benchmarks/rl/cartpole.py +260 -0
- polystep/benchmarks/rl/gym_evaluator.py +304 -0
- polystep/benchmarks/rl/metrics.py +53 -0
- polystep/benchmarks/rl/policies.py +133 -0
- polystep/benchmarks/utils.py +1262 -0
- polystep/blockwise.py +549 -0
- polystep/cma.py +400 -0
- polystep/cma_subspace.py +404 -0
- polystep/cost_nn.py +633 -0
- polystep/costs.py +86 -0
- polystep/dynamics.py +138 -0
- polystep/epsilon.py +217 -0
- polystep/geometry.py +410 -0
- polystep/hybrid_subspace.py +1335 -0
- polystep/layers/__init__.py +16 -0
- polystep/layers/attention.py +243 -0
- polystep/layers/rnn.py +276 -0
- polystep/objectives/__init__.py +25 -0
- polystep/objectives/base.py +77 -0
- polystep/objectives/synthetic.py +232 -0
- polystep/optimizer.py +1405 -0
- polystep/projection/__init__.py +5 -0
- polystep/projection/sparse.py +291 -0
- polystep/py.typed +0 -0
- polystep/quadratic_model.py +285 -0
- polystep/solver.py +654 -0
- polystep/solvers/__init__.py +34 -0
- polystep/solvers/_prelude.py +129 -0
- polystep/solvers/base.py +77 -0
- polystep/solvers/greedy.py +159 -0
- polystep/solvers/kl_softmax.py +200 -0
- polystep/solvers/sinkhorn.py +522 -0
- polystep/solvers/softmax.py +151 -0
- polystep/solvers/tempered_softmax.py +97 -0
- polystep/subspace.py +694 -0
- polystep/transform.py +365 -0
- polystep-0.7.0.dist-info/METADATA +285 -0
- polystep-0.7.0.dist-info/RECORD +52 -0
- polystep-0.7.0.dist-info/WHEEL +5 -0
- polystep-0.7.0.dist-info/licenses/LICENSE +191 -0
- polystep-0.7.0.dist-info/top_level.txt +1 -0
polystep/cma_subspace.py
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
"""CMAAdaptiveSubspace: CMA-ES covariance adaptation on top of AdaptiveSubspace.
|
|
2
|
+
|
|
3
|
+
Wraps an ``AdaptiveSubspace`` with the separable CMA-ES (sep-CMA-ES) variant
|
|
4
|
+
of the Covariance Matrix Adaptation Evolution Strategy. sep-CMA-ES uses a
|
|
5
|
+
diagonal covariance instead of a full one, reducing memory from O(n^2) to O(n)
|
|
6
|
+
and compute from O(n^3) to O(n) per update -- which is what makes it usable
|
|
7
|
+
in the high-dimensional subspaces that show up in neural network training.
|
|
8
|
+
|
|
9
|
+
Key CMA-ES concepts integrated:
|
|
10
|
+
|
|
11
|
+
1. **Evolution Paths (p_c, p_sigma)**: Cumulative sums of displacement directions
|
|
12
|
+
over generations. These track the "momentum" of the search and are used to
|
|
13
|
+
update covariance and step-size.
|
|
14
|
+
|
|
15
|
+
2. **Diagonal Covariance (C_diag)**: Per-dimension scaling of the search distribution.
|
|
16
|
+
Dimensions that consistently show movement get higher variance, allowing the
|
|
17
|
+
optimizer to stretch the search ellipsoid along productive directions.
|
|
18
|
+
|
|
19
|
+
3. **Cumulative Step-size Adaptation (CSA)**: Uses p_sigma to detect if steps are
|
|
20
|
+
too short (should increase sigma) or too long (should decrease sigma) relative
|
|
21
|
+
to what would be expected under random selection.
|
|
22
|
+
|
|
23
|
+
4. **Covariance Scaling**: The projection matrix P can be scaled by sqrt(C_diag)
|
|
24
|
+
to modify the effective search distribution in parameter space.
|
|
25
|
+
|
|
26
|
+
Design Decision:
|
|
27
|
+
CMA state (p_c, p_sigma, C_diag, sigma, generation) lives in ``SolverState``,
|
|
28
|
+
not in this class. This maintains JIT compatibility and enables checkpointing
|
|
29
|
+
of the full optimizer state. CMAAdaptiveSubspace only stores static config
|
|
30
|
+
(hyperparameters) and provides methods that operate on the state.
|
|
31
|
+
|
|
32
|
+
Example::
|
|
33
|
+
|
|
34
|
+
from polystep import AdaptiveSubspace, CMAAdaptiveSubspace, SolverState
|
|
35
|
+
import torch.nn as nn
|
|
36
|
+
|
|
37
|
+
model = nn.Linear(100, 10)
|
|
38
|
+
base = AdaptiveSubspace.auto_from_params(model)
|
|
39
|
+
cma_sub = CMAAdaptiveSubspace.from_adaptive_subspace(base)
|
|
40
|
+
|
|
41
|
+
# Initialize CMA state (store in SolverState)
|
|
42
|
+
cma_state = cma_sub.init_cma_state(device='cuda')
|
|
43
|
+
# cma_state = {'p_c': ..., 'p_sigma': ..., 'C_diag': ...}
|
|
44
|
+
|
|
45
|
+
# Apply covariance scaling to projection
|
|
46
|
+
P_scaled = cma_sub.apply_covariance_scaling(P, cma_state['C_diag'])
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
from __future__ import annotations
|
|
50
|
+
|
|
51
|
+
import math
|
|
52
|
+
from dataclasses import dataclass
|
|
53
|
+
from typing import Dict, Optional, Tuple, TYPE_CHECKING
|
|
54
|
+
|
|
55
|
+
import torch
|
|
56
|
+
|
|
57
|
+
from .adaptive_subspace import AdaptiveSubspace
|
|
58
|
+
|
|
59
|
+
from .cma import compute_cma_hyperparameters
|
|
60
|
+
|
|
61
|
+
if TYPE_CHECKING:
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass
|
|
66
|
+
class CMAAdaptiveSubspace:
|
|
67
|
+
"""CMA-ES enhanced adaptive subspace via composition.
|
|
68
|
+
|
|
69
|
+
Wraps an ``AdaptiveSubspace`` instance and adds CMA-ES hyperparameters
|
|
70
|
+
and covariance-related methods. The underlying AdaptiveSubspace handles
|
|
71
|
+
projection initialization, rotation, and core reconstruction operations.
|
|
72
|
+
|
|
73
|
+
CMA-ES hyperparameters are auto-computed from subspace_dim using the
|
|
74
|
+
standard Hansen formulas (see ``compute_cma_hyperparameters``).
|
|
75
|
+
|
|
76
|
+
Attributes:
|
|
77
|
+
base: The wrapped AdaptiveSubspace instance.
|
|
78
|
+
c_c: Learning rate for covariance evolution path update.
|
|
79
|
+
c_sigma: Learning rate for step-size evolution path update.
|
|
80
|
+
c_1: Learning rate for rank-one covariance update.
|
|
81
|
+
c_mu: Learning rate for rank-mu covariance update.
|
|
82
|
+
d_sigma: Damping factor for step-size adaptation.
|
|
83
|
+
expected_norm: Expected length of N(0,I) random vector (chi_n).
|
|
84
|
+
mu_eff: Effective population size for weighted recombination.
|
|
85
|
+
cov_min: Minimum allowed value for C_diag entries.
|
|
86
|
+
cov_max: Maximum allowed value for C_diag entries.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
base: AdaptiveSubspace
|
|
90
|
+
# CMA-ES hyperparameters (auto-computed from subspace_dim)
|
|
91
|
+
c_c: float = 0.0
|
|
92
|
+
c_sigma: float = 0.0
|
|
93
|
+
c_1: float = 0.0
|
|
94
|
+
c_mu: float = 0.0
|
|
95
|
+
d_sigma: float = 0.0
|
|
96
|
+
expected_norm: float = 0.0
|
|
97
|
+
mu_eff: float = 1.0
|
|
98
|
+
# Numerical stability bounds
|
|
99
|
+
cov_min: float = 1e-6
|
|
100
|
+
cov_max: float = 1e6
|
|
101
|
+
|
|
102
|
+
# ------------------------------------------------------------------
|
|
103
|
+
# Delegated properties
|
|
104
|
+
# ------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def full_dim(self) -> int:
|
|
108
|
+
"""Total flattened parameter count (delegated to base)."""
|
|
109
|
+
return self.base.full_dim
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def subspace_dim(self) -> int:
|
|
113
|
+
"""Subspace dimension / rank (delegated to base)."""
|
|
114
|
+
return self.base.subspace_dim
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def compression_ratio(self) -> float:
|
|
118
|
+
"""Compression ratio: subspace_dim / full_dim (delegated to base)."""
|
|
119
|
+
return self.base.compression_ratio
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def rotation_mode(self) -> str:
|
|
123
|
+
"""Rotation mode: 'random' or 'displacement' (delegated to base)."""
|
|
124
|
+
return self.base.rotation_mode
|
|
125
|
+
|
|
126
|
+
# ------------------------------------------------------------------
|
|
127
|
+
# Delegated methods
|
|
128
|
+
# ------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
def init_projection(
|
|
131
|
+
self,
|
|
132
|
+
generator: Optional[torch.Generator] = None,
|
|
133
|
+
device: Optional[torch.device] = None,
|
|
134
|
+
dtype: Optional[torch.dtype] = None,
|
|
135
|
+
) -> torch.Tensor:
|
|
136
|
+
"""Initialize projection matrix (delegated to base).
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
generator: Optional torch.Generator for reproducibility.
|
|
140
|
+
device: Target device for the projection matrix. If None, uses CPU.
|
|
141
|
+
dtype: Optional dtype for projection matrix. If None, uses float32.
|
|
142
|
+
Use bfloat16 for mixed precision mode to reduce memory.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Projection matrix P with shape (full_dim, subspace_dim).
|
|
146
|
+
"""
|
|
147
|
+
return self.base.init_projection(generator=generator, device=device, dtype=dtype)
|
|
148
|
+
|
|
149
|
+
def rotate(
|
|
150
|
+
self,
|
|
151
|
+
projection: torch.Tensor,
|
|
152
|
+
step: int,
|
|
153
|
+
total_steps: int,
|
|
154
|
+
displacement_history: Optional[torch.Tensor] = None,
|
|
155
|
+
generator: Optional[torch.Generator] = None,
|
|
156
|
+
# OT-bias mode inputs (forwarded to base.rotate; ignored otherwise)
|
|
157
|
+
transport_matrix: Optional[torch.Tensor] = None,
|
|
158
|
+
X_vertices: Optional[torch.Tensor] = None,
|
|
159
|
+
X_current: Optional[torch.Tensor] = None,
|
|
160
|
+
) -> torch.Tensor:
|
|
161
|
+
"""Rotate projection basis (delegated to base).
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
projection: Current projection matrix P.
|
|
165
|
+
step: Current optimization step.
|
|
166
|
+
total_steps: Total number of optimization steps.
|
|
167
|
+
displacement_history: Optional displacement history tensor.
|
|
168
|
+
generator: Optional torch.Generator for reproducibility.
|
|
169
|
+
transport_matrix: OT transport plan (only used when the wrapped
|
|
170
|
+
AdaptiveSubspace is in ``'ot_bias'`` rotation mode).
|
|
171
|
+
X_vertices: Polytope vertex positions (ot_bias mode only).
|
|
172
|
+
X_current: Current particle positions (ot_bias mode only).
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
New projection matrix P_new.
|
|
176
|
+
"""
|
|
177
|
+
return self.base.rotate(
|
|
178
|
+
projection,
|
|
179
|
+
step,
|
|
180
|
+
total_steps,
|
|
181
|
+
displacement_history,
|
|
182
|
+
generator,
|
|
183
|
+
transport_matrix=transport_matrix,
|
|
184
|
+
X_vertices=X_vertices,
|
|
185
|
+
X_current=X_current,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
def apply_perturbation(
|
|
189
|
+
self,
|
|
190
|
+
projection: torch.Tensor,
|
|
191
|
+
base_sd: Dict[str, torch.Tensor],
|
|
192
|
+
flat_subspace: torch.Tensor,
|
|
193
|
+
) -> Dict[str, torch.Tensor]:
|
|
194
|
+
"""Reconstruct full state_dict from base + subspace coords (delegated to base).
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
projection: Projection matrix P.
|
|
198
|
+
base_sd: Base state_dict.
|
|
199
|
+
flat_subspace: Subspace coordinate vector.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
New state_dict with perturbed parameters.
|
|
203
|
+
"""
|
|
204
|
+
return self.base.apply_perturbation(projection, base_sd, flat_subspace)
|
|
205
|
+
|
|
206
|
+
def reconstruct_batch(
|
|
207
|
+
self,
|
|
208
|
+
projection: torch.Tensor,
|
|
209
|
+
base_sd: Dict[str, torch.Tensor],
|
|
210
|
+
flat_subspace_batch: torch.Tensor,
|
|
211
|
+
) -> Dict[str, torch.Tensor]:
|
|
212
|
+
"""Vectorized reconstruction for N probe points (delegated to base).
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
projection: Projection matrix P.
|
|
216
|
+
base_sd: Base state_dict.
|
|
217
|
+
flat_subspace_batch: Batch of subspace coordinates (N, subspace_dim).
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
Dict with batched perturbed params {key: (N, *shape)}.
|
|
221
|
+
"""
|
|
222
|
+
return self.base.reconstruct_batch(projection, base_sd, flat_subspace_batch)
|
|
223
|
+
|
|
224
|
+
def absorb(
|
|
225
|
+
self,
|
|
226
|
+
projection: torch.Tensor,
|
|
227
|
+
base_sd: Dict[str, torch.Tensor],
|
|
228
|
+
flat_subspace: torch.Tensor,
|
|
229
|
+
) -> Tuple[Dict[str, torch.Tensor], torch.Tensor]:
|
|
230
|
+
"""Fold subspace perturbation into base weights (delegated to base).
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
projection: Projection matrix P.
|
|
234
|
+
base_sd: Base state_dict.
|
|
235
|
+
flat_subspace: Current subspace vector.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Tuple of (new_base_sd, zeroed_subspace_vector).
|
|
239
|
+
"""
|
|
240
|
+
return self.base.absorb(projection, base_sd, flat_subspace)
|
|
241
|
+
|
|
242
|
+
def should_absorb(self, stagnation_count: int, iteration: int) -> bool:
|
|
243
|
+
"""Check whether absorb should be triggered (delegated to base).
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
stagnation_count: Consecutive steps without improvement.
|
|
247
|
+
iteration: Current iteration number.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
True if absorb should be triggered.
|
|
251
|
+
"""
|
|
252
|
+
return self.base.should_absorb(stagnation_count, iteration)
|
|
253
|
+
|
|
254
|
+
# ------------------------------------------------------------------
|
|
255
|
+
# CMA-specific methods
|
|
256
|
+
# ------------------------------------------------------------------
|
|
257
|
+
|
|
258
|
+
def apply_covariance_scaling(
|
|
259
|
+
self,
|
|
260
|
+
projection: torch.Tensor,
|
|
261
|
+
C_diag: torch.Tensor,
|
|
262
|
+
) -> torch.Tensor:
|
|
263
|
+
"""Scale projection columns by sqrt(C_diag) for covariance-adapted sampling.
|
|
264
|
+
|
|
265
|
+
In CMA-ES, the search distribution is N(m, sigma^2 * C). With diagonal
|
|
266
|
+
covariance C = diag(C_diag), sampling x ~ N(m, sigma^2 * C) is equivalent
|
|
267
|
+
to sampling z ~ N(0, I) and computing x = m + sigma * C^{1/2} * z.
|
|
268
|
+
|
|
269
|
+
This method applies the C^{1/2} scaling to the projection matrix, so
|
|
270
|
+
that sampling in the original subspace coordinates and then projecting
|
|
271
|
+
gives the covariance-scaled effect in full parameter space.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
projection: Projection matrix P of shape (full_dim, subspace_dim).
|
|
275
|
+
C_diag: Diagonal covariance entries of shape (subspace_dim,).
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
Scaled projection P_scaled = P @ diag(sqrt(C_diag)).
|
|
279
|
+
"""
|
|
280
|
+
# Clamp C_diag for numerical stability
|
|
281
|
+
C_diag_clamped = torch.clamp(C_diag, min=self.cov_min, max=self.cov_max)
|
|
282
|
+
# Scale columns: P_scaled[:, i] = P[:, i] * sqrt(C_diag[i])
|
|
283
|
+
sqrt_C = torch.sqrt(C_diag_clamped)
|
|
284
|
+
return projection * sqrt_C.unsqueeze(0)
|
|
285
|
+
|
|
286
|
+
def init_cma_state(
|
|
287
|
+
self,
|
|
288
|
+
device: str | torch.device = "cpu",
|
|
289
|
+
dtype: torch.dtype = torch.float32,
|
|
290
|
+
) -> Dict[str, torch.Tensor]:
|
|
291
|
+
"""Initialize CMA-ES state tensors.
|
|
292
|
+
|
|
293
|
+
Creates the initial evolution paths and diagonal covariance for a fresh
|
|
294
|
+
CMA-ES optimization run. These should be stored in SolverState.
|
|
295
|
+
|
|
296
|
+
Initial values:
|
|
297
|
+
- p_c: zeros (no accumulated covariance direction yet)
|
|
298
|
+
- p_sigma: zeros (no accumulated step-size direction yet)
|
|
299
|
+
- C_diag: ones (isotropic initial covariance)
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
device: Target device for state tensors.
|
|
303
|
+
dtype: Target dtype for state tensors.
|
|
304
|
+
|
|
305
|
+
Returns:
|
|
306
|
+
Dict with keys 'p_c', 'p_sigma', 'C_diag', each of shape (subspace_dim,).
|
|
307
|
+
"""
|
|
308
|
+
subspace_dim = self.base.subspace_dim
|
|
309
|
+
return {
|
|
310
|
+
"p_c": torch.zeros(subspace_dim, device=device, dtype=dtype),
|
|
311
|
+
"p_sigma": torch.zeros(subspace_dim, device=device, dtype=dtype),
|
|
312
|
+
"C_diag": torch.ones(subspace_dim, device=device, dtype=dtype),
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
# ------------------------------------------------------------------
|
|
316
|
+
# Factory methods
|
|
317
|
+
# ------------------------------------------------------------------
|
|
318
|
+
|
|
319
|
+
@classmethod
|
|
320
|
+
def from_adaptive_subspace(
|
|
321
|
+
cls,
|
|
322
|
+
base: AdaptiveSubspace,
|
|
323
|
+
mu_eff: Optional[float] = None,
|
|
324
|
+
cov_min: float = 1e-6,
|
|
325
|
+
cov_max: float = 1e6,
|
|
326
|
+
) -> "CMAAdaptiveSubspace":
|
|
327
|
+
"""Create CMAAdaptiveSubspace by wrapping an existing AdaptiveSubspace.
|
|
328
|
+
|
|
329
|
+
CMA-ES hyperparameters (c_c, c_sigma, c_1, c_mu, d_sigma, expected_norm)
|
|
330
|
+
are automatically computed from the subspace dimension using the standard
|
|
331
|
+
Hansen formulas.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
base: The AdaptiveSubspace to wrap.
|
|
335
|
+
mu_eff: Effective population size. If None, defaults to
|
|
336
|
+
subspace_dim / 4 (heuristic for OT-based selection).
|
|
337
|
+
cov_min: Minimum allowed C_diag entry (numerical stability).
|
|
338
|
+
cov_max: Maximum allowed C_diag entry (numerical stability).
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
CMAAdaptiveSubspace wrapping the base instance.
|
|
342
|
+
"""
|
|
343
|
+
n = base.subspace_dim
|
|
344
|
+
|
|
345
|
+
# Default mu_eff: fraction of subspace dim, capped per Hansen CMA tutorial.
|
|
346
|
+
# Hansen recommends mu_eff ~ mu ~ lambda/2, which scales as O(sqrt(n)).
|
|
347
|
+
# Cap at 5*sqrt(n) to avoid over-aggressive step-size adaptation.
|
|
348
|
+
if mu_eff is None:
|
|
349
|
+
mu_eff = max(1.0, min(n / 4.0, 5.0 * math.sqrt(n)))
|
|
350
|
+
|
|
351
|
+
# Compute CMA hyperparameters from dimension and mu_eff
|
|
352
|
+
hyperparams = compute_cma_hyperparameters(n, mu_eff)
|
|
353
|
+
|
|
354
|
+
return cls(
|
|
355
|
+
base=base,
|
|
356
|
+
c_c=hyperparams["c_c"],
|
|
357
|
+
c_sigma=hyperparams["c_sigma"],
|
|
358
|
+
c_1=hyperparams["c_1"],
|
|
359
|
+
c_mu=hyperparams["c_mu"],
|
|
360
|
+
d_sigma=hyperparams["d_sigma"],
|
|
361
|
+
expected_norm=hyperparams["expected_norm"],
|
|
362
|
+
mu_eff=mu_eff,
|
|
363
|
+
cov_min=cov_min,
|
|
364
|
+
cov_max=cov_max,
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
@classmethod
|
|
368
|
+
def auto_from_params(
|
|
369
|
+
cls,
|
|
370
|
+
model: torch.nn.Module,
|
|
371
|
+
compression_target: float = 0.05,
|
|
372
|
+
min_rank: int = 64,
|
|
373
|
+
max_rank: int = 4096,
|
|
374
|
+
mu_eff: Optional[float] = None,
|
|
375
|
+
cov_min: float = 1e-6,
|
|
376
|
+
cov_max: float = 1e6,
|
|
377
|
+
**kwargs,
|
|
378
|
+
) -> "CMAAdaptiveSubspace":
|
|
379
|
+
"""Create CMAAdaptiveSubspace directly from an nn.Module.
|
|
380
|
+
|
|
381
|
+
Convenience factory that first creates an AdaptiveSubspace with
|
|
382
|
+
``auto_from_params``, then wraps it with CMA-ES functionality.
|
|
383
|
+
|
|
384
|
+
Args:
|
|
385
|
+
model: Any PyTorch module.
|
|
386
|
+
compression_target: Target ratio of subspace_dim / full_dim.
|
|
387
|
+
min_rank: Minimum subspace dimension.
|
|
388
|
+
max_rank: Maximum subspace dimension.
|
|
389
|
+
mu_eff: Effective population size for CMA (see from_adaptive_subspace).
|
|
390
|
+
cov_min: Minimum allowed C_diag entry.
|
|
391
|
+
cov_max: Maximum allowed C_diag entry.
|
|
392
|
+
**kwargs: Additional arguments passed to AdaptiveSubspace.auto_from_params.
|
|
393
|
+
|
|
394
|
+
Returns:
|
|
395
|
+
CMAAdaptiveSubspace configured for the model.
|
|
396
|
+
"""
|
|
397
|
+
base = AdaptiveSubspace.auto_from_params(
|
|
398
|
+
model,
|
|
399
|
+
compression_target=compression_target,
|
|
400
|
+
min_rank=min_rank,
|
|
401
|
+
max_rank=max_rank,
|
|
402
|
+
**kwargs,
|
|
403
|
+
)
|
|
404
|
+
return cls.from_adaptive_subspace(base, mu_eff=mu_eff, cov_min=cov_min, cov_max=cov_max)
|