Ressources

Nous utilisons pas encore le GPU, il ne faut pas changer le runtime

Merci de commenter un maximum votre code.

Notation :

Exercice 1 (sur 4):

  • Layer ok et bons paramètres
  • Bonne forward pass / calcul de loss / retropropagation du gradient
  • Bonne accuracy sur le test (100% escompté)
  • Divers (bonne gestion de type, bonne création de batch, bon arrêt d'entrainement, tracking de la training loss)

Exercice 2 (sur 2) :

  • Bonne modification du réseau
  • Bonne accuracy sur le test (100% escompté)

Exercice 3 (sur 2):

  • Bonne déclaration de la classe Network
  • Bonne modification de optimizer et de la forward pass

Exercice 4 (sur 2):

  • Bonne déclaration de la classe Dataset
  • Bon calcul de l'accuracy

Bonus (2 points):

  • Exercice 4: plot de l'évolution de la training loss par epoch
  • Un truc cool qui va au dela des énnoncés (merci de le dire explicitement dans cette cellule pour que je le trouve facilement)

Exercice 1 : Classification linéaire

In [ ]:
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles, make_blobs
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
In [ ]:
X, y = make_blobs(n_samples=200, centers=2, n_features=2, center_box=(0, 10))
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=ListedColormap(['#FF0000', '#0000FF']),
               edgecolors='k')
Out[ ]:
<matplotlib.collections.PathCollection at 0x7fb4ffc581d0>
In [ ]:
import torch
import torch.nn as nn
import numpy as np
from random import randrange
import torch.optim as optim

## Créez les layers ici 


# Déclarez les parametres de l'expérience (batch_size, learning rate, ...)

# Déclarez la loss et l'optimisation (SGD)
loss_func = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(list(layer1.parameters())+list(layer2.parameters()), lr=learning_rate)

# Split test/train selon https://playground.tensorflow.org/


# Procédure de training cad 
# 1) boucle d'entrainement avec création de batch aléatoirement 
# 2) prediction du reseau (forward pass) 
# 3) calcul de la loss 
# 4) rétropropagation du gradient 
# 5) tracking de la training loss
# 6) Si vous avez une bonne training loss, vous utilisez break


# Quand le modèle a convergé, on calcule l'accuracy sur le test. 
# Ici, il n'est pas nécéssaire de créer des batch, on peut tout envoyer dans le réseau en une fois
# ne pas utiliser de fonction sklearn, calculez l'accuracy vous même avec np.argmax

Exercice 2 : Classification non-linéaire

In [ ]:
X, y = make_circles(n_samples=200, noise=0.05, factor=0.5, random_state=1)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=ListedColormap(['#FF0000', '#0000FF']),
               edgecolors='k')
plt.show()
In [ ]:
# Modifiez votre reseau (la couche intermédiaire) pour obtenir 100% sur ce dataset


## Créez les layers ici 

# Déclarez les parametres de l'expérience (batch_size, learning rate, ...)

# Déclarez la loss et l'optimisation (SGD)
loss_func = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(list(layer1.parameters())+list(layer2.parameters()), lr=learning_rate)

# Split test/train

# Training

# Eval sur test

Exercice 3 : Network class

Vous allez recoder l'exercice 2 en ajoutant deux modifications:
1) Pour l'instant, on traite nos couches séparément, et non comme un "block" unifié. Par exemple, il faut donner les parametres de chaque couche a l'optimizer (par exemple : optim.SGD(list(layer1.parameters())+list(layer2.parameters()), lr=learning_rate)

Allez sur ce lien et regardez comment définir une classe pour votre réseau (https://pytorch.org/tutorials/beginner/examples_nn/two_layer_net_module.html). Utilisez la et modifiez votre ligne de l'optimiseur ainsi que la gestion de votre forward pass.

2) Imaginez qu'on ait 1000 couches, ce n'est pas pratique des les appeler une par une lors de la forward pass. Utilisez la fonction suivante pour palier au problème : https://pytorch.org/docs/stable/generated/torch.nn.ModuleList.html

In [ ]:
X, y = make_circles(n_samples=200, noise=0.05, factor=0.5, random_state=1)

# Classe Network

# Copiez collez votre solution en modifiant l'otim.SGD et la forward pass

Exercice 4 : Dataloader

En général, il est compliqué de créer soi même ses batchs, surtout si le dataset devient complexe. Nous allons utiliser un dataloader de pytorch, qui lui même crée les batch. Lisez seulement la section "dataset" de cette ressource :https://stanford.edu/~shervine/blog/pytorch-how-to-generate-data-parallel#dataset et créer votre classe dataset. Voici une esquisse de code pour vous aider :

In [ ]:
import torch

X, y = make_circles(n_samples=200, noise=0.05, factor=0.5, random_state=1)

class Dataset(torch.utils.data.Dataset):
  'Characterizes a dataset for PyTorch'
  def __init__(self, X, y):
        # a completer

  def __len__(self):
        'Denotes the total number of samples'
        return # a completer

  def __getitem__(self, index):
        'Generates one sample of data'
        # Select one sample at position index
        # Return in type : np.array

        # a compléter
        return x, y


X_train, X_test, y_train, y_test = # splitting a faire
train_dataset = Dataset(X_train, y_train)
test_dataset = Dataset(X_test, y_test)

training_generator = torch.utils.data.DataLoader(train_dataset, batch_size=10, shuffle=True)
test_generator = torch.utils.data.DataLoader(test_dataset, batch_size=10, shuffle=False)

print('Train set length', len(train_dataset))
print('Test set length', len(test_dataset))

net = Network()

# Déclarez les parametres de l'expérience (batch_size, learning rate, ...)
# Déclarez la loss et l'optimisation (SGD)



for i in range(num_epochs):
  for j, sample in enumerate(training_generator):
    x, y = sample # Generator automatically transform it to tensor
    # A compléter


accuracy = []
for j, sample in enumerate(test_generator):
  x, y = sample # Generator automatically transform it to tensor
  # A compléter

print('\n Accuracy is ' , # A compléter)