Evolutionary.jl
Evolutionary.jl copied to clipboard
no method matching NLSolversBase.NonDifferentiable
I've been trying to run GA on my custom structure, Organism
, but it's giving the following error:
result = Evolutionary.optimize(
fitness,
() -> init_organism("msa_data/temp.tfa"),
GA(
populationSize = 50,
))
Error
MethodError: no method matching NLSolversBase.NonDifferentiable(::typeof(Main.workspace3.fitness), ::Main.workspace3.Organism)
Closest candidates are:
NLSolversBase.NonDifferentiable(::Any, ::Any, !Matched::AbstractArray) at C:\Users\aadim\.julia\packages\NLSolversBase\QPnui\src\objective_types\nondifferentiable.jl:21
NLSolversBase.NonDifferentiable(::Any, ::TF, !Matched::TX, !Matched::Array{Int64,1}) where {TF, TX} at C:\Users\aadim\.julia\packages\NLSolversBase\QPnui\src\objective_types\nondifferentiable.jl:3
NLSolversBase.NonDifferentiable(::Any, ::Any, !Matched::AbstractArray, !Matched::Union{Real, AbstractArray}) at C:\Users\aadim\.julia\packages\NLSolversBase\QPnui\src\objective_types\nondifferentiable.jl:21
...
optimize(::Function, ::Evolutionary.NoConstraints, ::Function, ::Evolutionary.GA, ::Evolutionary.Options{Nothing})@optimize.jl:30
[email protected]:13[inlined]
top-level scope@Local: 1
The init_organism
function initializes an object of type Organism
and returns it, while the fitness
function takes an Organism
as input and returns a Number
as fitness value. I haven't defined the crossover and mutation functions for now, as I only want to see if the GA is being initialized well.
function fitness(organism::Organism)
sum = 0
if !ismissing(organism.alignment)
alignments = collect(values(organism.alignment))
for i=(1:length(alignments)-1), j=(i+1:length(alignments))
a = alignments[i]
b = alignments[j]
sum += pairwise_score(
a, b,
matrix=organism.scoring_matrix.matrix,
gop=organism.gop, gep=organism.gep)
end
end
sum
end
After a thorough search, I'm unable to figure out the way to solve this problem/error. If anyone could give me some helpful pointers to solve this error message, I'd be grateful. Thanks
You need to provide overriding for the NonDifferentiable
with the type of your individual, i.e. Organism
. Basically, it's a wrapper type that keeps fitness function with its parameter & result in one place.
Look how it is done for the BitVector
:
https://github.com/wildart/Evolutionary.jl/blob/30d677fcfc19d517f2a974a00bafda34656c468c/src/api/types.jl#L113-L120
Thank you for replying. I've thought (and searched) about it long and hard, but I'm unable to figure out how I'm supposed to approach this, because of the lack of documentation for the JuliaNSolvers and mostly because of my inexperience. I'm quite new to the Julia environment and still trying to figure things out, although I'm hopeful and excited to learn about it more.
I added an example of supervised learning problem by GA optimization of multi-layer perceptrons, see the notebook in examples/MLP.ipynb
It shows how to fill some missing functionality, when the individuals are custom types (not arrays). For starters, you need to create a NonDifferentiable
constructor, and make sure that copy
/copyto!
functions are working on your individual object. Then, write genetic operations which support your object type. In my example, I reused existing operations by writing wrappers, which accept MLP object.