DEAP / deap

Distributed Evolutionary Algorithms in Python
http://deap.readthedocs.org/
GNU Lesser General Public License v3.0
5.82k stars 1.13k forks source link

TypeError: unhashable type: 'numpy.ndarray' #354

Closed richban closed 5 years ago

richban commented 5 years ago

I always encounter this issue with the NSGA-II algorithm: TypeError: unhashable type: 'numpy.ndarray'.

    record = stats.compile(pop)
  File "/Users/richban/.local/share/virtualenvs/behavioral.neuroevolution-ViNSkuNA/lib/python3.7/site-packages/deap/tools/emo.py", line 33, in selNSGA2
    pareto_fronts = sortNondominated(individuals, k)
  File "/Users/richban/.local/share/virtualenvs/behavioral.neuroevolution-ViNSkuNA/lib/python3.7/site-packages/deap/tools/emo.py", line 74, in sortNondominated
    map_fit_ind[ind.fitness].append(ind)
  File "/Users/richban/.local/share/virtualenvs/behavioral.neuroevolution-ViNSkuNA/lib/python3.7/site-packages/deap/base.py", line 227, in __hash__
    return hash(self.wvalues)
TypeError: unhashable type: 'numpy.ndarray'

My individual is defined as below. It's a list of floating values (weights of NN) which I am trying to optimize with multiple objective functions. My entire code can be found here -> DEAP ISSUE. It's pretty interesting that I can run it with my mocked eval_fucntion however with the real function that evaluates the individual the algorithm always fails.

Not sure if this is an issue or clearly I am doing something wrong. Anyone can help out?

def init_individual(cls, model):
    ind = cls(np.concatenate(
        (
            model.get_weights()[0].flatten(),
            model.get_weights()[2].flatten()
        )
    ).tolist())

    ind.shape_1 = model.get_weights()[0].shape
    ind.shape_2 = model.get_weights()[2].shape
    ind.features = None
    ind.weights = None

    return ind

# Creating the appropriate type of the problem
creator.create("FitnessMax", base.Fitness, weights=(1.0, 1.0))
creator.create("Individual", list,
                fitness=creator.FitnessMax, model=None)

toolbox = base.Toolbox()
history = tools.History()

toolbox.register("individual", init_individual,
                    creator.Individual, model=model)
fmder commented 5 years ago

Ndarrays are not hashable, thus they can't be used as key to a dictionary. Your evaluation function probably returns a ndarray, which is multiplied by the weights and the resulting ndarray is put in wvalued. Wvalues is used as key in sort non dominated. Try to transform the fitness in a list or role before returning it.

Le ven. 17 mai 2019 13 h 12, Richard Banyi notifications@github.com a écrit :

I always encounter this issue with the NSGA-II algorithm: TypeError: unhashable type: 'numpy.ndarray'.

record = stats.compile(pop)

File "/Users/richban/.local/share/virtualenvs/behavioral.neuroevolution-ViNSkuNA/lib/python3.7/site-packages/deap/tools/emo.py", line 33, in selNSGA2 pareto_fronts = sortNondominated(individuals, k) File "/Users/richban/.local/share/virtualenvs/behavioral.neuroevolution-ViNSkuNA/lib/python3.7/site-packages/deap/tools/emo.py", line 74, in sortNondominated map_fit_ind[ind.fitness].append(ind) File "/Users/richban/.local/share/virtualenvs/behavioral.neuroevolution-ViNSkuNA/lib/python3.7/site-packages/deap/base.py", line 227, in hash return hash(self.wvalues) TypeError: unhashable type: 'numpy.ndarray'

My individual is defined as below. It's a list of floating values (weights of NN) which I am trying to optimize with multiple objective functions. My entire code can be found here -> DEAP ISSUE https://github.com/richban/behavioral.neuroevolution/blob/master/deap_issue.ipynb. It's pretty interesting that I can run it with my mocked eval_fucntion however with the real function that evaluates the individual the algorithm always fails.

Not sure if this is an issue or clearly I am doing something wrong. Anyone can help out?

def init_individual(cls, model): ind = cls(np.concatenate( ( model.get_weights()[0].flatten(), model.get_weights()[2].flatten() ) ).tolist())

ind.shape_1 = model.get_weights()[0].shape
ind.shape_2 = model.get_weights()[2].shape
ind.features = None
ind.weights = None

return ind

Creating the appropriate type of the problem

creator.create("FitnessMax", base.Fitness, weights=(1.0, 1.0)) creator.create("Individual", list, fitness=creator.FitnessMax, model=None)

toolbox = base.Toolbox() history = tools.History()

toolbox.register("individual", init_individual, creator.Individual, model=model)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/DEAP/deap/issues/354?email_source=notifications&email_token=AAHKXQX3G4OTKF2GTGKXO4TPV3RQPA5CNFSM4HNW7UCKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4GUOL5PA, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHKXQTC6RGY5OAH75URGYDPV3RQPANCNFSM4HNW7UCA .

richban commented 5 years ago

@fmder thanks for the reply. It was one-dimensional array that I was returning.