ahmedfgad / TorchGA

Train PyTorch Models using the Genetic Algorithm with PyGAD
https://pygad.readthedocs.io
96 stars 15 forks source link

pygad for mnist #1

Open yani-rl-ai opened 3 years ago

yani-rl-ai commented 3 years ago

hi @ahmedfgad assalamualaikum

thank you for sharing this work. i tried to test pygad torch_ga for MNIST datasets. but the results is not good. THe accuracy is very poor i have tried to changed the hyperparameters, but the result is not improve significant. do you have any opinion for my code?

import torch import pygad.torchga import pygad import numpy import torch.nn as nn import torchvision.datasets as dsets import torchvision.transforms as transforms from torch.autograd import Variable import os

num_epochs = 5 batch_size = 100 learning_rate = 0.001

train_dataset = dsets.MNIST(root='./data/', train=True, transform=transforms.ToTensor(), download=True)

test_dataset = dsets.MNIST(root='./data/', train=False, transform=transforms.ToTensor())

train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)

test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False) """ class CNN(nn.Module): def init(self): super(CNN, self).init()

    self.layer1 = nn.Sequential(
        nn.Conv2d(1, 16, kernel_size=5, padding=2), #1 * 28 * 28 -> 16 * 28 * 28
        nn.BatchNorm2d(16), #16 * 28 * 28
        nn.ReLU(),                 #16 * 28 * 28
        nn.MaxPool2d(2))       # 16 * 14 * 14
    self.layer2  = nn.Sequential(
        nn.Conv2d(16, 32, kernel_size=5, padding=2), # 16 * 14 * 14 -> 32 * 14 * 14
        nn.BatchNorm2d(32),
        nn.ReLU(),
        nn.MaxPool2d(2))       # 32 * 7 * 7
    self.fc = nn.Linear(32 * 7 * 7, 10)

def forward(self, x):
    out = self.layer1(x)
    out = self.layer2(out)
    out = out.view(out.size(0), -1)
    out = self.fc(out)
    return out

"""

def fitness_func(solution, sol_idx): global images_train, labels_train, loss_function prediction =pygad.torchga.predict(model=model, solution=solution, data=images_train) solution_fitness = 1.0/(loss_function(prediction,labels_train).detach().numpy()+ 0.00000001)

return solution_fitness

def callback_generation(ga_instance): print("Generation = {generation}".format(generation=ga_instance.generations_completed)) print("Fitness = {fitness}".format(fitness=ga_instance.best_solution()[1]))

input_layer = torch.nn.Conv2d(in_channels=1, out_channels = 16, kernel_size = 5, padding = 2) batch1 = torch.nn.BatchNorm2d(16) relu_layer1 = torch.nn.ReLU() max_pool1 = torch.nn.MaxPool2d(2) conv_layer2 = torch.nn.Conv2d(in_channels=16, out_channels = 32, kernel_size = 5, padding = 2) batch2 = torch.nn.BatchNorm2d(32) relu_layer2 = torch.nn.ReLU() max_pool2 = torch.nn.MaxPool2d(2) flatten_layer2 = torch.nn.Flatten() dense_layer2 = torch.nn.Linear(in_features=3277, out_features=10)

model = torch.nn.Sequential(input_layer, batch1, relu_layer1, max_pool1, conv_layer2, batch2, relu_layer2, max_pool2, flatten_layer2, dense_layer2) torch_ga = pygad.torchga.TorchGA(model=model, num_solutions=10) loss_function = torch.nn.CrossEntropyLoss()

for i, (images, labels) in enumerate(train_loader): images_train = Variable(images) labels_train = Variable(labels)

"""
for images, labels in enumerate (test_loader): images_test = Variable(images) labels_test = Variable(labels) """ num_generations = 200 num_parents_mating = 5 initial_population = torch_ga.population_weights

ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=num_parents_mating, initial_population=initial_population, fitness_func=fitness_func, on_generation=callback_generation)

ga_instance.run()

ga_instance.plot_fitness(title="PyGAD & PyTorch - Iteration vs. Fitness", linewidth=4)

Returning the details of the best solution.

solution, solution_fitness, solution_idx = ga_instance.best_solution() print("Fitness value of the best solution = {solution_fitness}".format(solution_fitness=solution_fitness)) print("Index of the best solution : {solution_idx}".format(solution_idx=solution_idx))

prediction = pygad.torchga.predict(model=model, solution=solution, data=images_train)

print("Predictions : \n", predictions)

Calculate the crossentropy for the trained model.

print("Crossentropy : ", loss_function(prediction, labels_train).detach().numpy())

Calculate the classification accuracy for the trained model.

accuracy = torch.true_divide(torch.sum(torch.max(prediction, axis=1).indices == labels_train), len(labels_train)) print("Accuracy : ", accuracy.detach().numpy())

rasmuspjohansson commented 2 years ago

Hi @ROSNovice I have done a series of experiments very similar to yours and I belive the main problem is that you simply have to train for longer. You can check out my code and results at https://github.com/rasmuspjohansson/MNIST-with-PYGAD and https://medium.com/@rasmuspjohansson/464de1d1f89f