Tim Hargreaves
PyData Manchester
23rd June 2020
Method | Flaws |
---|---|
Copy someone else | Requires trust/might not be appropriate |
Use intuition | No reproducibility; requires said intuition |
Brute force/random search | Computational complexity |
Gradient-based methods | Lack of convexity; non-differentiable hyperparameters |
Bayesian methods | Deciding priors/measuring convergence can be difficult |
gene_pool = {
'a': (-3, 3),
'b': (-3, 3),
'c': (-3, 3),
}
# Initialisation
genome = {
gene: random.uniform(alleles[0], alleles[1])
for gene, alleles in population.gene_pool.items()
}
self._fitness = -np.mean(np.square(y_hat - y))
ranked_organisms = sorted(self.organisms,
key=lambda org: org.fitness,
reverse=True)
survived = ranked_organisms[:self.retain_length]
for org in ranked_organisms[self.retain_length:]:
if len(survived) >= self.size:
break
if self.random_select > random.random():
survived.append(org)
# Determine how many children to create
shortfall = self.size - len(survived)
children = []
while len(children) < shortfall:
mother = random.choice(survived)
father = random.choice([s for s in survived
if s is not mother])
children.extend(
Organism.breed(mother, father,
min(2, shortfall - len(children)))
)
self.organisms = survived + children
for gene in mother.population.gene_pool.keys():
# Convex combination of parents' alleles
p = random.random()
genome[gene] = p * mother.genome[gene] + \
(1-p) * father.genome[gene]
for gene, alleles in self.population.gene_pool.items():
if self.population.mutation_chance > random.random():
# Convex combination of current allele and random
# choice from the gene pool
p = (1 + random.random()) / 2
self.genome[gene] = p * self.genome[gene] + \
(1-p) * random.uniform(alleles[0], alleles[1])
Key point: How easy is it to calculate gradients?
Search space size: ~10000 combinations
gene_pool = {
'num_neurons': [32, 64, 128, 256, 512, 768, 1024],
'num_layers': [1, 2, 3, 4, 5],
'use_bias': [True, False],
'dropout_rate': [0., .1, .2, .3, .4],
'activation': ['relu', 'elu', 'tanh', 'sigmoid'],
'optimiser': ['rmsprop', 'adam', 'sgd', 'adagrad',
'adadelta', 'adamax', 'nadam'],
}
# Initialisation
genome = {
gene: random.choice(alleles)
for gene, alleles in population.gene_pool.items()
}
self._fitness = self.train_and_evaluate()
def train_and_evaluate(self):
"""Train this organism's model and report the final accuarcy."""
if self.population.verbose:
print(f"Training model {self.id}")
# For prototype, only train for one epoch
self.model.fit(X_train, y_train,
batch_size=1024,
epochs=1,
verbose=False,
validation_data=(X_test, y_test))
score = self.model.evaluate(X_test, y_test, verbose=False)
return score[1] # accuracy
ranked_organisms = sorted(self.organisms,
key=lambda org: org.fitness,
reverse=True)
survived = ranked_organisms[:self.retain_length]
for org in ranked_organisms[self.retain_length:]:
if len(survived) >= self.size:
break
if self.random_select > random.random():
survived.append(org)
# Determine how many children to create
shortfall = self.size - len(survived)
children = []
while len(children) < shortfall:
mother = random.choice(survived)
father = random.choice([s for s in survived
if s is not mother])
children.extend(
Organism.breed(mother, father,
min(2, shortfall - len(children)))
)
self.organisms = survived + children
for gene in mother.population.gene_pool.keys():
genome[gene] = random.choice((
mother.genome[gene], father.genome[gene]
))
for gene, alleles in self.population.gene_pool.items():
if self.population.mutation_chance > random.random():
self.genome[gene] = random.choice(alleles)
num_neurons: 512 num_layers: 5 use_bias: False dropout_rate: 0.1 activation: relu optimiser: adam
Randomly created 25 models without improvement Randomly created 50 models without improvement Randomly created 75 models without improvement Randomly created 100 models without improvement Randomly created 125 models without improvement Randomly created 150 models without improvement Randomly created 175 models without improvement Randomly created 200 models without improvement Randomly created 225 models without improvement Randomly created 250 models without improvement Randomly created 275 models without improvement Randomly created 300 models without improvement Randomly created 325 models without improvement Randomly created 350 models without improvement Randomly created 375 models without improvement Randomly created 400 models without improvement Randomly created 425 models without improvement Randomly created 450 models without improvement Randomly created 475 models without improvement Randomly created 500 models without improvement Giving up...