Programmation pour l’IA
On considère le fichier sonar.csv. Il contient les résultats d’une expérience menée par Gorman and Sejnowski. Dans cette expérience, un sonar est pointé vers un objet cylindrique fait en métal (M) ou en pierre (R). Chaque colonne de ce fichier contient des valeurs correspondant au niveau d’énergie de certaines fréquences relevées en réponse à un sonar.
Avec Pytorch, écrire un programme complet contenant une classe permettant de charger les données (qu’on aura pris soin de séparer en un une partie de données d’entraînement et de données test), un modèle de réseau de neurone et un algorithme permettant de l’entraîner.
Quelle est la précision de votre modèle ?
Note: Le but de cet est de vous forcer à créer une architecture sans trop de contraintes. On ne cherchera pas forcément à avoir une précision très bonne, même s’il est conseillé d’expérimenter avec quelques architectures différentes par curiosité.
MNIST est un jeu de données emblématique en apprentissage machine. Il comporte 60000 images en niveau de gris de taille \(28 \times 28\), chacune représentant un chiffre entre \(0\) et \(9\). Le chiffre représenté est donné comme un label. En d’autre mot, chaque exemple est une matrice \(28 \times 28\) de nombre entre \(0\) et \(1\) (\(0\) représentant un pixel noir et \(1\) représentant un pixel blanc) et son label est le nombre entre \(0\) et \(9\) représenté par cette image. Notre but est d’entraîner un classifieur pour ce problème.
On peut obtenir un dataset pytorch tout prêt pour MNIST grâce à
torchvision. Le programme suivant téléchargera le jeu de données dans un
dossier data (s’il n’existe pas déjà) et renvoie un
dataset. Par défaut, le jeu de données contient des images
au format PIL mais le paramètre optionnel
transform=transforms.ToTensor() convertit chaque exemple en
un tenseur [1, 28, 28].
import torchvision
d = torchvision.datasets.MNIST(root='./data', download=True, transform=transforms.ToTensor())On pourra aussi obtenir \(10000\) images tests :
test = torchvision.datasets.MNIST(root='./test', train=False, download=True, transform=transforms.ToTensor())print la valeur d[5][0] et
d[5][1]. Quelle est la forme de d[5][0] ?
Quelle est la classe de cet exemple ?plt.imshow(d[5][0].squeeze()) pour la tracer. La méthode
squeeze() enlève les dimensions égale à \(1\) d’un tenseur.nn.Flatten() qui convertit un tenseur
de forme \((s_0,\dots,s_k)\) en un
tenseur de forme \((s_0, \sum_{i=1}^k
s_i)\).
nn.Flatten() et une
couche linéaire. On attend à ce que la sortie soit un vecteur de taille
10. Nous n’avons pas besoin d’une couche softmax car nous entraînerons
avec une fonction d’erreur nn.CrossEntropy() qui applique
déjà la fonction softmax pour calculer l’erreur.predict(m,x) qui prédit la classe
de x[0],...,x[b-1] selon le modèle m où
x est un tenseur de forme [b, 28, 28]. On
appliquera une fonction softmax à la sortie de m et une
fonction argmax pour trouver la classe (on suppose qu’on a un encodage
one hot).Adam, un pas de \(0.03\)
et une erreur d’entropie croisée. Pour l’entraînement, pensez à encoder
les classes en one hot avant le calcul de l’entropie. Affichez la
précision du modèle à la fin de chaque epoch.torch.cuda.is_available()
doit retourner True), testez votre code sur GPU. Pour cela,
on enverra le modèle sur le GPU avec m.to("cuda") où
m est votre modèle. Il faudra aussi envoyer tous les
tenseurs utilisés avec m sur le GPU. Par exemple, si on
veut évaluer m sur un tenseur X en faisant
m(X), il faut que X soit sur le GPU. On peut
le faire en faisant X = X.to("cuda").Si vous n’avez pas de GPU sur votre machine ou s’il n’est pas configuré, vous pouvez tester sur Google Colab mais cela nécessite un compte google ou Kaggle Notebook (compte nécessaire aussi).