mirror of
https://github.com/ArthurDanjou/ArtStudies.git
synced 2026-01-14 15:54:13 +01:00
279 lines
9.3 KiB
Plaintext
279 lines
9.3 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Séance 3 - Compléments\n",
|
|
"\n",
|
|
"Dans cette séance nous travaillerons avec le dataset d'images [CIFAR10](https://keras.io/api/datasets/cifar10/) qui correspond à des petites images en couleurs. Notre objectif est de construire un réseau de neurones convolutionnel capable d'identifier chacun des dix types en exploitant quelque-unes des nouvelles méthodes décrites en cours.\n",
|
|
"\n",
|
|
"## Exploration des données\n",
|
|
"\n",
|
|
"Commençons par importer les données."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"import pandas as pd\n",
|
|
"\n",
|
|
"%matplotlib inline\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"import seaborn as sns\n",
|
|
"\n",
|
|
"sns.set(style=\"whitegrid\")\n",
|
|
"\n",
|
|
"from tensorflow import keras\n",
|
|
"\n",
|
|
"(X_train, y_train), (X_valid, y_valid) = keras.datasets.cifar10.load_data()\n",
|
|
"\n",
|
|
"label_map = {\n",
|
|
" 0: \"airplane\",\n",
|
|
" 1: \"automobile\",\n",
|
|
" 2: \"bird\",\n",
|
|
" 3: \"cat\",\n",
|
|
" 4: \"deer\",\n",
|
|
" 5: \"dog\",\n",
|
|
" 6: \"frog\",\n",
|
|
" 7: \"horse\",\n",
|
|
" 8: \"ship\",\n",
|
|
" 9: \"truck \",\n",
|
|
"}\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Regardons la structure d'*y_train* avec son premier élément."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[6]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"print(y_train[0])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Au lieu d'avoir un entier, nous avons un array. Pour pouvoir travailler, nous allons devoir modifier la structure de *y_train* et *y_valid*. Il faudrait passer d'un vecteur de taille $n$ à une matrice de type one-hot encoding de taille $(n, 10)$.\n",
|
|
"\n",
|
|
"**Consigne** : À l'aide de la fonction [`to_categorical`](https://keras.io/2.16/api/utils/python_utils/#tocategorical-function), modifier *y_train* et *y_valid*."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Consigne** : Afficher plusieurs images du dataset d'entraînement aléatoirement. On pourra utiliser la fonction [`imshow`](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html) et le dictionnaire."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Consigne** : Standardiser les données en utilisant la classe [`StandardScaler`](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html). On commencera par applatir les images en utilisant la méthode [`reshape`](https://numpy.org/doc/stable/reference/generated/numpy.reshape.html), puis on applique le pré-processing et on termine par reformer la matrice. Attention à bien respecter les dimensions d'origines de l'image."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Modélisation\n",
|
|
"\n",
|
|
"On souhaite visualiser les différentes courbes d'apprentissages obtenues par différent optimizer. Pour pouvoir le faire, nous allons devoir choisir les optimizers à comparer et lancer l'entraîner de plusieurs modèles. Commençons par définir une architecture avec une fonction de sorte à pouvoir simplement générer des modèles lors de la comparaisons entre les optimizers.\n",
|
|
"\n",
|
|
"**Consigne** : Définir une fonction `get_model` qui ne prend pas de paramètre et qui renvoie un modèle convolutionnel de moins de 200k paramètres en utilisant des couches de régularisations au choix."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Nous avons modifié la structure de *y_train* et *y_valid*, nous devons adapter la fonction de perte à optimiser en conséquence. Cette fois on considérera la fonction de perte [`CategoricalCrossentropy`](https://keras.io/api/losses/probabilistic_losses/#categoricalcrossentropy-class) au lieu de [`SparseCategoricalCrossentropy`](https://keras.io/api/losses/probabilistic_losses/#sparsecategoricalcrossentropy-class) que l'on utilisait jusqu'à présent.\n",
|
|
"\n",
|
|
"**Consigne** : Définir une fonction `compile_train` qui prend en paramètre:\n",
|
|
"* *optimizer_function* : l'instanciation de la classe de l'optimizer\n",
|
|
"* *learning_rate* : le learning rate associé à l'optimizer\n",
|
|
"* Et des [kwargs](https://book.pythontips.com/en/latest/args_and_kwargs.html)\n",
|
|
"\n",
|
|
"La fonction renvoie l'historique d'apprentissage du modèle définit par la fonction `get_model`. La fonction doit compiler le modèle avec l'optimizer définit en paramètre et l'entraîner avec les paramètres définit dans les kwargs."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Consigne** : Valider le bon fonctionnement de la fonction `compile_train` sur quelques époques."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Pour s'affranchir un peu de l'aléatoire, nous proposons de lancer trois fois les différents schéma d'optimisation pour les comparer. La légende sera composée du nom de l'optimizer et la valeur du learning rate sélectionnée. La classe [`optimizer`](https://keras.io/api/optimizers/#optimizer-class) de Keras permet d'obtenir ces informations comme suit:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"name = optimizer.__name__\n",
|
|
"label = f\"{name} - {learning_rate:.06}\"\n",
|
|
"print(label)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Consigne** : Écrire une boucle d'entraînement qui va stocker dans une liste les courbes d'apprentissage. Chaque élément de la liste correspondra à un dictionnaire avec pour clé:\n",
|
|
"* *type*: le nom de l'optimizer\n",
|
|
"* *history*: l'historique d'apprentissage"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Il faut maintenant visualiser les résultats. Commençons par préparer les données.\n",
|
|
"\n",
|
|
"**Consigne** : Définir une fonction `agregate_result` qui prend en paramètre:\n",
|
|
"* *results*: le dictionnaire de résultat, au format décrit précédemment\n",
|
|
"* *network_type*: chaîne de caractère identifiant le type de réseau\n",
|
|
"* *metric_name*: le nom de la métrique d'intérêt\n",
|
|
"\n",
|
|
"La fonction renverra deux matrices de tailles (nombre de comparaisons, nombre d'époque) : une pour le dataset d'entraînement et une pour le dataset de validation. On concatène donc les différentes courbes d'apprentissage."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"**Consigne** : Visualiser les courbes d'apprentissage en faisant apparaître des intervals de confiance. On prendra exemple sur la fonction `show_results` du TP précédent. Commenter."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Pour continuer\n",
|
|
"\n",
|
|
"Choisir une ou plusieurs pistes de recherche parmi les suivantes. Il est possible de choisir une autre direction, mais elle doit être validé auparavant.\n",
|
|
"\n",
|
|
"1. Nous avons utilisé un learning rate fixe et dans le cours nous avons parlé d'échéancier. Comparer les deux approches, puis se poser la question de l'importance (ou non) d'un phase de warmup.\n",
|
|
"2. Le [`Dropout`](https://keras.io/api/layers/regularization_layers/dropout/) permet de régulariser un réseau de neurones. Comparer un réseau avec et sans dropout, puis se poser la question de l'importance de la magnitude et du placement d'une couche dropout."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "studies",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.13.3"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|