I'm trying to use a genetic algorithm that optimizes a 28x28 matrix (its shape) to make it look like an image of the number 7 that could be found in the MNIST image dataset. My attempt is to basically use the probability the CNN digit classifier gives my matrix of being the number 7 as a score (fitness) function to "breed" matrices with until I get one that looks like a 7. I'm implementing the CNN with pytorch, and the GA with object oriented programming where I've defined a member and a population datastruct.
My algorithm doesn't converge and I'm at a bit of a loss, any help is massively appreciated.
important bits of code: score function:
def score(self):
seed_tensor = torch.FloatTensor(self.seed).unsqueeze(0).unsqueeze(0).to(
'cuda' if torch.cuda.is_available() else 'cpu')
logits = loaded_model(seed_tensor)
probabilities = torch.nn.functional.softmax(logits, dim=1)
output = probabilities[0, 6].item()
loss = 1 - output
return np.exp(-loss)
reproduction:
def reproduction(self):
crossover_num = int(self.population_size * 0.75)
crossovers = self.choose_parents(crossover_num )
self.mutate(crossovers)
reproduction_num = int(self.population_size * 0.25)
for i in range(reproduction_num):
parents = self.choose_parents_in_random()
crossovers.extend(self.create_offsprings(*parents))
self.members = crossovers
mutation
def mutate(self, mutation_rate):
mask = np.random.uniform(0, 1, size=(self.rows, self.columns)) < mutation_rate
self.seed[mask] = 1 - self.seed[mask]
crossover is at 75%, two parents create a new seed at the other 25%. here's my github with the code in it: https://github.com/Max-SF1/GA_Mnist_generator thank you for your help!
I've also recently tried a grayscale instead of binary matrix approach which similarly yielded no positive results - the algorithm does not converge.