Skip to content

Commit 741b2ef

Browse files
committed
Fix bug in IndividualMultiGenome and add test
Add test for local search with MultiGenome Fix bug in IndividualMultiGenome.update_parameters function
1 parent 60fd4f2 commit 741b2ef

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

cgp/individual.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,10 @@ def to_sympy(self, simplify: bool = True) -> List["sympy_expr.Expr"]:
211211

212212
def update_parameters_from_torch_class(self, torch_cls: List["torch.nn.Module"]) -> None:
213213
any_parameter_updated = any(
214-
self._update_parameters_from_torch_class(g, tcls)
215-
for g, tcls in zip(self.genome, torch_cls)
214+
[
215+
self._update_parameters_from_torch_class(g, tcls)
216+
for g, tcls in zip(self.genome, torch_cls)
217+
]
216218
)
217-
218219
if any_parameter_updated:
219220
self.fitness = None

test/test_local_search.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,43 @@ def objective(f):
3232
ind.genome.parameter_names_to_values["<p1>"] = 1.0
3333
cgp.local_search.gradient_based(ind, objective, 0.05, 1)
3434
assert ind.genome.parameter_names_to_values["<p1>"] == pytest.approx(1.0)
35+
36+
37+
def test_gradient_based_step_towards_maximum_multi_genome():
38+
torch = pytest.importorskip("torch")
39+
40+
primitives = (cgp.Parameter,)
41+
genome = cgp.Genome(1, 1, 1, 1, 1, primitives)
42+
# f(x) = c
43+
genome.dna = [ID_INPUT_NODE, ID_NON_CODING_GENE, 0, 0, ID_OUTPUT_NODE, 1]
44+
genome2 = genome.clone()
45+
ind = cgp.individual.IndividualMultiGenome(None, [genome, genome2])
46+
47+
def objective(f):
48+
x_dummy = torch.zeros((1, 1), dtype=torch.double) # not used
49+
target_value = torch.ones((1, 1), dtype=torch.double)
50+
loss = torch.nn.MSELoss()(f[0](x_dummy), target_value) + 2 * torch.nn.MSELoss()(
51+
f[1](x_dummy), target_value
52+
)
53+
return loss
54+
55+
# test increase parameter value if too small
56+
ind.genome[0].parameter_names_to_values["<p1>"] = 0.9
57+
ind.genome[1].parameter_names_to_values["<p1>"] = 0.9
58+
cgp.local_search.gradient_based(ind, objective, 0.05, 1)
59+
assert ind.genome[0].parameter_names_to_values["<p1>"] == pytest.approx(0.91)
60+
assert ind.genome[1].parameter_names_to_values["<p1>"] == pytest.approx(0.92)
61+
62+
# test decrease parameter value if too large
63+
ind.genome[0].parameter_names_to_values["<p1>"] = 1.1
64+
ind.genome[1].parameter_names_to_values["<p1>"] = 1.1
65+
cgp.local_search.gradient_based(ind, objective, 0.05, 1)
66+
assert ind.genome[0].parameter_names_to_values["<p1>"] == pytest.approx(1.09)
67+
assert ind.genome[1].parameter_names_to_values["<p1>"] == pytest.approx(1.08)
68+
69+
# test no change of parameter value if at optimum
70+
ind.genome[0].parameter_names_to_values["<p1>"] = 1.0
71+
ind.genome[1].parameter_names_to_values["<p1>"] = 1.0
72+
cgp.local_search.gradient_based(ind, objective, 0.05, 1)
73+
assert ind.genome[0].parameter_names_to_values["<p1>"] == pytest.approx(1.0)
74+
assert ind.genome[1].parameter_names_to_values["<p1>"] == pytest.approx(1.0)

0 commit comments

Comments
 (0)