Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Representation doesn't allow the passing of parameters to individual_cls #278

Open
lukepmccombs opened this issue May 31, 2023 · 10 comments
Labels
enhancement New feature or request

Comments

@lukepmccombs
Copy link
Collaborator

If using a subclass of Individual that has parameters, they cannot be overridden when created using a Representation.

@SigmaX
Copy link
Collaborator

SigmaX commented Jun 1, 2023

Is there a particular scenario/usage where this has posed a problem recently?

@lukepmccombs
Copy link
Collaborator Author

Since pytorch is primarily used for deep learning, I gave a hand at memetic algorithms with my extra library using deep learning as the local search. In memetic algorithms there are Baldwinian and Lamarckian variants, where in Lamarckian the genome is replaced with the one found after local search while the Baldwinian is not. Since the two both have benefits, and I was using a real valued genome, I parameterized this with an alpha value that controlled how much of the change due to the local search was applied back to the base genome.

In any case, since the genome has to be updated after every fitness evaluation, I subclassed Individual to do the necessary operations in .evaluate(). But I can't change the alpha parameter on the fly with the base Representation, only change it manually in code. I could use an operator, but the expectation is it must occur every fitness evaluation.

@lukepmccombs
Copy link
Collaborator Author

Looking through the code, I'm reconsidering my approach. While I think the ability to pass parameters through a Representation to a subsequent Individual would be useful, the modification would require propagating changes through much of the core code of both Representation and Individual. I am hesitant to make changes where it can affect so much of LEAP's functionality.

@SigmaX
Copy link
Collaborator

SigmaX commented Jun 1, 2023

That sounds like a really cool project! I've done quite a bit of lit review & hacking around Baldwinian vs. Lamarckian methods, but never thought of having a parameter that tunes a balance between the two!

You're right that it seems that Individual would be the place to handle that—since that's where fitness evaluations & the genome you aim to modify come together. The individual_cls mechanism always struck me as a bit smelly anyway.

Is there a way we could make Individual an object you initialize and pass in to an algorithm, rather than a class that the algorithm instantiates instances of? Or perhaps have a new type of object called IndividualFactory?

@markcoletti
Copy link
Collaborator

Or perhaps have a new type of object called IndividualFactory?

Oddly enough, when I discussed this with Luke earlier I observed that initializers are a kind of factory function, and that we could explore maybe parameterizing that in some way.

@lukepmccombs
Copy link
Collaborator Author

lukepmccombs commented Jun 1, 2023

I think that the intent of the Representation class is to be an Individual factory, although it currently functions as a wrapper to calling Individual.create_population(). I'm not a big fan of how those classes / functions interact frankly, passing in a class with the parameters and calling create_population is equivalent to constructing a Representation. I suppose it serves to reduce the number of parameters by letting you prepare the arguments elsewhere.

I think this ties in well with #155, where changing how we construct the initial population would come in handy. I think rather than passing around Representation objects we would be better served by having an initial_pop parameter and moving Individual/Representation.create_population into its own helper function. This would give the user finer control over that step of the algorithm, and require roughly the same amount of boilerplate for clearer functionality. If we or the user want to forward parameters to the Individual being constructed, then it won't require any hacky solutions.

@lukepmccombs
Copy link
Collaborator Author

Actually, I think it would reduce boilerplate since we could then drop init_pop_size too.

@SigmaX
Copy link
Collaborator

SigmaX commented Jun 2, 2023

@lukepmccombs: I think this is a good proposal.

(Thinking through the cons.) Having the initializer be part of the Representation and arguments of the metaheuristic functions (ex. generational_ea) allows us to think of the latter as a whole, self-contained "algorithm"—but you're right that splitting it into two steps (initialize your population, then pass it to a metaheuristic function) does not increase the amount of boilerplate code involved. Having it part of Representation also would make it possible to have an algorithm object that can be called multiple times to produce end-to-end independent runs—but we are not using them that way.

Especially now that we've changed generational_ea & friends to return the final population as its output, making the initial population an input makes a great deal of sense, IMO.

@lukepmccombs
Copy link
Collaborator Author

I've found another problem point with subclassing Individual to be parameterized. The clone method creates the copy by re-initializing the class using the parameters of the base Individual. If I'm understanding the intentions of what should and should not be copied, I think a copy of self with the genome deepcopyed separately would achieve the same effect with more reusability.

@markcoletti
Copy link
Collaborator

Just a quick note, @SigmaX and I are going to continue this discussion when the three of us can be in a meeting.

@SigmaX SigmaX added the enhancement New feature or request label Jul 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants