mirror of
https://github.com/ArthurDanjou/ArtStudies.git
synced 2026-01-23 23:51:51 +01:00
Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Séance 2 - Bonus : ResNet à la main\n",
|
||||
"\n",
|
||||
"Pour poursuivre le travail du TP, on se propose d'explorer une autre manière de définir un réseau de neurones au travers d'une architecture classique de Deep Learning pour la vision : les ResNet. \n",
|
||||
"\n",
|
||||
"Commençons par importer et traiter les données."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"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",
|
||||
"import tensorflow as tf\n",
|
||||
"from sklearn.model_selection import train_test_split\n",
|
||||
"from sklearn.preprocessing import StandardScaler\n",
|
||||
"from tensorflow import keras\n",
|
||||
"\n",
|
||||
"(X_train_full, y_train_full), (X_test, y_test) = (keras.datasets.fashion_mnist.load_data())\n",
|
||||
"X_train, X_valid, y_train, y_valid = train_test_split(X_train_full, y_train_full, train_size=0.8)\n",
|
||||
"\n",
|
||||
"scaler = StandardScaler()\n",
|
||||
"X_train = scaler.fit_transform(X_train.astype(np.float32).reshape(-1, 28 * 28)).reshape(-1, 28, 28, 1)\n",
|
||||
"X_valid = scaler.transform(X_valid.astype(np.float32).reshape(-1, 28 * 28)).reshape(-1, 28, 28, 1)\n",
|
||||
"X_test = scaler.transform(X_test.astype(np.float32).reshape(-1, 28 * 28)).reshape(-1, 28, 28, 1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Pour rappel, une architecture ResNet correspond à la succession de ResBlock qui, dans le papier d'origine, ont l'architecture suivante :\n",
|
||||
"1. Une couche de convolution avec padding pour conserver la taille de l'image\n",
|
||||
"2. Une couche de BatchNormalization, que l'on explicitera en cours à la séance prochaine\n",
|
||||
"3. L'activation ReLU, qui ne doit donc pas être présente dans la couche de convolution\n",
|
||||
"4. Une couche de convolution avec padding pour conserver la taille de l'image\n",
|
||||
"5. Une couche de BatchNormalization\n",
|
||||
"6. Un ajout de l'input avant le point 1 et du résultat de la dernière couche de BatchNormalization (point 5)\n",
|
||||
"7. L'activation ReLU sur l'ajout\n",
|
||||
"\n",
|
||||
"On ne peut pas définir cette architecture si l'on utilise la méthode d'instanciation que l'on a utilisé jusqu'ici. Pour y arriver, nous avons besoin d'utiliser la version *fonctionnelle* de Keras. Par exemple avec un modèle dense :"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"input = keras.layers.Input(shape=X_train.shape[1:])\n",
|
||||
"flatten = keras.layers.Flatten()(input)\n",
|
||||
"dense_1 = keras.layers.Dense(units=64, activation=\"relu\")(flatten)\n",
|
||||
"dense_2 = keras.layers.Dense(units=64)(dense_1)\n",
|
||||
"activation = keras.layers.ReLU()(dense_2)\n",
|
||||
"output = keras.layers.Dense(units=10, activation=\"softmax\")(activation)\n",
|
||||
"\n",
|
||||
"model = keras.models.Model(inputs=[input], outputs=[output])\n",
|
||||
"model.summary()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Consigne** : En utilisant la version fonctionnelle de Keras, définir une fonction `ResidualBlock` qui prend en paramètre un argument *input* qui correspondra à une couche Keras et en second argument des *kwargs* à passer aux différentes couches de convolutions."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Consigne** : Définir un modèle utilisant deux ResBlock pour résoudre le problème de classification auquel on s'intéresse."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Consigne** : Après avoir compilé le modèle, lancer l'entraînement sur quelque époque pour vérifier qu'il fonctionne."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Pour aller plus loin, on pourrait se demander s'il est nécessaire de réaliser ces connexions résiduelles. Pour y répondre, on conseille de construire un réseau de neurones convolutionnel *classique* et comparer les performances pour plusieurs entraînement."
|
||||
]
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
767
M2/Deep Learning/TP2 - Convolution/TP2 - Starter.ipynb
Normal file
767
M2/Deep Learning/TP2 - Convolution/TP2 - Starter.ipynb
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user