Files
ArtStudies/M2/Deep Learning/TP4 - Récurrents/TP4 - Bonus.ipynb

448 lines
76 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Séance 4 - Bonus : Réseau récurrent avec Embedding\n",
"\n",
"Dans cette séance nous avons entraîné un modèle à copier le style de poésie de Beaudelaire, spécifiquement l'oeuvre *Les fleurs du mal*. On souhaite voir ici comment utiliser la couche [`Embedding`](https://keras.io/api/layers/core_layers/embedding/) et ce que l'on peut faire avec.\n",
"\n",
"Commençons par importer les données."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"import keras\n",
"import numpy as np\n",
"import seaborn as sns\n",
"\n",
"sns.set(style=\"whitegrid\")\n",
"\n",
"\n",
"start = False\n",
"book = open(\"Beaudelaire.txt\", encoding=\"utf8\") # noqa: SIM115\n",
"lines = book.readlines()\n",
"verses = []\n",
"\n",
"for line in lines:\n",
" line_striped = line.strip().lower()\n",
" if \"AU LECTEUR\".lower() in line_striped and not start:\n",
" start = True\n",
" if (\n",
" \"End of the Project Gutenberg EBook of Les Fleurs du Mal, by Charles Baudelaire\".lower()\n",
" in line_striped\n",
" ):\n",
" break\n",
" if not start or len(line_striped) == 0:\n",
" continue\n",
" verses.append(line_striped)\n",
"\n",
"book.close()\n",
"text = \" \".join(verses)\n",
"characters = sorted(set(text))\n",
"n_characters = len(characters)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dans le TP principal nous avons one-hot encodé le texte. La couche [`Embedding`](https://keras.io/api/layers/core_layers/embedding/) prend en entrée une séquence d'entier. Ainsi, nous devons changer la manière de construire $X$ et $y$.\n",
"\n",
"**Consigne** : En s'inspirant du travail précédent, construire la matrice d'informations $X$ et le vecteur réponse $y$. Puis on scindera le dataset en un dataset d'entraînement et de validation."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"X_train shape: (108720, 40)\n",
"y_train shape: (108720,)\n",
"X_val shape: (27181, 40)\n",
"y_val shape: (27181,)\n"
]
}
],
"source": [
"# Create character to index and index to character mappings\n",
"char_to_idx = {char: idx for idx, char in enumerate(characters)}\n",
"idx_to_char = dict(enumerate(characters))\n",
"\n",
"# Parameters\n",
"sequence_length = 40\n",
"\n",
"# Create sequences\n",
"X = []\n",
"y = []\n",
"\n",
"for i in range(len(text) - sequence_length):\n",
" # Input sequence: convert characters to indices\n",
" sequence = text[i : i + sequence_length]\n",
" X.append([char_to_idx[char] for char in sequence])\n",
"\n",
" # Target: next character as index\n",
" target = text[i + sequence_length]\n",
" y.append(char_to_idx[target])\n",
"\n",
"X = np.array(X)\n",
"y = np.array(y)\n",
"\n",
"# Split into training and validation sets\n",
"split_ratio = 0.8\n",
"split_index = int(len(X) * split_ratio)\n",
"\n",
"X_train, X_val = X[:split_index], X[split_index:]\n",
"y_train, y_val = y[:split_index], y[split_index:]\n",
"\n",
"print(f\"X_train shape: {X_train.shape}\")\n",
"print(f\"y_train shape: {y_train.shape}\")\n",
"print(f\"X_val shape: {X_val.shape}\")\n",
"print(f\"y_val shape: {y_val.shape}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La couche [`Embedding`](https://keras.io/api/layers/core_layers/embedding/) a comme paramètre :\n",
"* *input_dim* : la taille du vocabulaire que l'on considère, ici *n_characters*\n",
"* *output_dim* : la dimension de l'embedding, autrement dit chaque caractère sera représenté comme un vecteur de *output_dim* dimension\n",
"\n",
"On souhaite mesurer l'impact du paramètre *output_dim*. \n",
"\n",
"**Consigne** : Définir une fonction `get_model` qui prend en paramètre:\n",
"* *dimension* : un entier qui correspond à la dimension de sortie de l'embedding\n",
"* *vocabulary_size* : la taille du vocabulaire\n",
"\n",
"La fonction renvoie un réseau de neurones récurrents avec une couche d'embedding paramétré en accord avec les paramètres de la fonction. On essayera de faire un modèle de taille raisonnable.\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"def get_model(dimension: int, vocabulary_size: int) -> keras.Model:\n",
" \"\"\"Create and return a SimpleRNN Keras model.\n",
"\n",
" Args:\n",
" dimension (int): The embedding dimension.\n",
" vocabulary_size (int): The size of the vocabulary.\n",
"\n",
" Returns:\n",
" keras.Model: The constructed Keras model.\n",
"\n",
" \"\"\"\n",
" model = keras.Sequential()\n",
" model.add(\n",
" keras.layers.Embedding(\n",
" input_dim=vocabulary_size,\n",
" output_dim=dimension,\n",
" )\n",
" )\n",
" model.add(keras.layers.SimpleRNN(128, return_sequences=False))\n",
" model.add(keras.layers.Dense(vocabulary_size, activation=\"softmax\"))\n",
" return model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Consigne** : Écrire une boucle d'entraînement qui va stocker dans une liste le maximum atteint lors de l'entraînement jusqu'à 10 époques. Chaque élément de la liste correspondra à un dictionnaire avec pour clé:\n",
"* *dimension*: la dimension de l'embedding\n",
"* *val_loss*: la valeur de loss minimale atteinte sur le dataset de validation au cours de l'entraînement"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training with embedding dimension: 8\n",
"Epoch 1/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 7ms/step - accuracy: 0.2911 - loss: 2.4584 - val_accuracy: 0.3356 - val_loss: 2.2434\n",
"Epoch 2/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 7ms/step - accuracy: 0.3526 - loss: 2.1686 - val_accuracy: 0.3680 - val_loss: 2.1278\n",
"Epoch 3/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 7ms/step - accuracy: 0.3796 - loss: 2.0606 - val_accuracy: 0.3852 - val_loss: 2.0478\n",
"Epoch 4/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 7ms/step - accuracy: 0.3962 - loss: 2.0073 - val_accuracy: 0.3973 - val_loss: 1.9984\n",
"Epoch 5/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m12s\u001b[0m 7ms/step - accuracy: 0.4119 - loss: 1.9376 - val_accuracy: 0.4065 - val_loss: 1.9671\n",
"Epoch 6/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 7ms/step - accuracy: 0.4238 - loss: 1.8910 - val_accuracy: 0.4163 - val_loss: 1.9253\n",
"Epoch 7/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 7ms/step - accuracy: 0.4358 - loss: 1.8494 - val_accuracy: 0.4280 - val_loss: 1.8953\n",
"Epoch 8/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 8ms/step - accuracy: 0.4442 - loss: 1.8152 - val_accuracy: 0.4316 - val_loss: 1.8684\n",
"Epoch 9/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 7ms/step - accuracy: 0.4519 - loss: 1.7858 - val_accuracy: 0.4450 - val_loss: 1.8482\n",
"Epoch 10/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 8ms/step - accuracy: 0.4610 - loss: 1.7600 - val_accuracy: 0.4533 - val_loss: 1.8217\n",
"Min val_loss for dimension 8: 1.8217\n",
"\n",
"Training with embedding dimension: 16\n",
"Epoch 1/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 8ms/step - accuracy: 0.3011 - loss: 2.4052 - val_accuracy: 0.3502 - val_loss: 2.1912\n",
"Epoch 2/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 8ms/step - accuracy: 0.3685 - loss: 2.0986 - val_accuracy: 0.3756 - val_loss: 2.0634\n",
"Epoch 3/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 8ms/step - accuracy: 0.3998 - loss: 1.9784 - val_accuracy: 0.4114 - val_loss: 1.9582\n",
"Epoch 4/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 8ms/step - accuracy: 0.4192 - loss: 1.9028 - val_accuracy: 0.4128 - val_loss: 1.9171\n",
"Epoch 5/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 8ms/step - accuracy: 0.4329 - loss: 1.8456 - val_accuracy: 0.4326 - val_loss: 1.8697\n",
"Epoch 6/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 8ms/step - accuracy: 0.4450 - loss: 1.8017 - val_accuracy: 0.4386 - val_loss: 1.8523\n",
"Epoch 7/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 8ms/step - accuracy: 0.4548 - loss: 1.7670 - val_accuracy: 0.4465 - val_loss: 1.8272\n",
"Epoch 8/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.4646 - loss: 1.7364 - val_accuracy: 0.4534 - val_loss: 1.8115\n",
"Epoch 9/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 8ms/step - accuracy: 0.4700 - loss: 1.7124 - val_accuracy: 0.4591 - val_loss: 1.7950\n",
"Epoch 10/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m14s\u001b[0m 8ms/step - accuracy: 0.4779 - loss: 1.6908 - val_accuracy: 0.4607 - val_loss: 1.7851\n",
"Min val_loss for dimension 16: 1.7851\n",
"\n",
"Training with embedding dimension: 32\n",
"Epoch 1/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 9ms/step - accuracy: 0.2923 - loss: 2.4420 - val_accuracy: 0.3360 - val_loss: 2.2457\n",
"Epoch 2/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.3452 - loss: 2.1742 - val_accuracy: 0.3621 - val_loss: 2.1240\n",
"Epoch 3/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.3741 - loss: 2.0653 - val_accuracy: 0.3893 - val_loss: 2.0364\n",
"Epoch 4/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.3985 - loss: 1.9775 - val_accuracy: 0.3936 - val_loss: 1.9743\n",
"Epoch 5/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.4170 - loss: 1.9050 - val_accuracy: 0.4178 - val_loss: 1.9241\n",
"Epoch 6/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.4339 - loss: 1.8459 - val_accuracy: 0.4313 - val_loss: 1.8757\n",
"Epoch 7/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.4457 - loss: 1.7967 - val_accuracy: 0.4397 - val_loss: 1.8530\n",
"Epoch 8/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.4566 - loss: 1.7588 - val_accuracy: 0.4531 - val_loss: 1.8134\n",
"Epoch 9/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.4672 - loss: 1.7261 - val_accuracy: 0.4559 - val_loss: 1.7983\n",
"Epoch 10/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m15s\u001b[0m 9ms/step - accuracy: 0.4740 - loss: 1.6981 - val_accuracy: 0.4621 - val_loss: 1.7825\n",
"Min val_loss for dimension 32: 1.7825\n",
"\n",
"Training with embedding dimension: 64\n",
"Epoch 1/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m19s\u001b[0m 11ms/step - accuracy: 0.3041 - loss: 2.4058 - val_accuracy: 0.3396 - val_loss: 2.2325\n",
"Epoch 2/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m18s\u001b[0m 10ms/step - accuracy: 0.3459 - loss: 2.1708 - val_accuracy: 0.3610 - val_loss: 2.1294\n",
"Epoch 3/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - accuracy: 0.3735 - loss: 2.0678 - val_accuracy: 0.3845 - val_loss: 2.0466\n",
"Epoch 4/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - accuracy: 0.3982 - loss: 1.9800 - val_accuracy: 0.4050 - val_loss: 1.9719\n",
"Epoch 5/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - accuracy: 0.4165 - loss: 1.9040 - val_accuracy: 0.4216 - val_loss: 1.9132\n",
"Epoch 6/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - accuracy: 0.4355 - loss: 1.8397 - val_accuracy: 0.4392 - val_loss: 1.8458\n",
"Epoch 7/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - accuracy: 0.4497 - loss: 1.7881 - val_accuracy: 0.4497 - val_loss: 1.8308\n",
"Epoch 8/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - accuracy: 0.4622 - loss: 1.7456 - val_accuracy: 0.4581 - val_loss: 1.7942\n",
"Epoch 9/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - accuracy: 0.4712 - loss: 1.7103 - val_accuracy: 0.4635 - val_loss: 1.7709\n",
"Epoch 10/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m17s\u001b[0m 10ms/step - accuracy: 0.4789 - loss: 1.6801 - val_accuracy: 0.4708 - val_loss: 1.7566\n",
"Min val_loss for dimension 64: 1.7566\n",
"\n",
"Training with embedding dimension: 128\n",
"Epoch 1/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m22s\u001b[0m 12ms/step - accuracy: 0.3363 - loss: 2.2461 - val_accuracy: 0.3795 - val_loss: 2.0534\n",
"Epoch 2/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 13ms/step - accuracy: 0.4074 - loss: 1.9497 - val_accuracy: 0.4197 - val_loss: 1.9188\n",
"Epoch 3/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 13ms/step - accuracy: 0.4350 - loss: 1.8420 - val_accuracy: 0.4391 - val_loss: 1.8486\n",
"Epoch 4/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 13ms/step - accuracy: 0.4542 - loss: 1.7732 - val_accuracy: 0.4502 - val_loss: 1.8108\n",
"Epoch 5/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 13ms/step - accuracy: 0.4659 - loss: 1.7259 - val_accuracy: 0.4568 - val_loss: 1.7788\n",
"Epoch 6/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m22s\u001b[0m 13ms/step - accuracy: 0.4758 - loss: 1.6900 - val_accuracy: 0.4678 - val_loss: 1.7612\n",
"Epoch 7/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 12ms/step - accuracy: 0.4830 - loss: 1.6613 - val_accuracy: 0.4714 - val_loss: 1.7402\n",
"Epoch 8/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 13ms/step - accuracy: 0.4903 - loss: 1.6380 - val_accuracy: 0.4706 - val_loss: 1.7363\n",
"Epoch 9/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m21s\u001b[0m 12ms/step - accuracy: 0.4960 - loss: 1.6179 - val_accuracy: 0.4746 - val_loss: 1.7260\n",
"Epoch 10/10\n",
"\u001b[1m1699/1699\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m22s\u001b[0m 13ms/step - accuracy: 0.5003 - loss: 1.6003 - val_accuracy: 0.4789 - val_loss: 1.7111\n",
"Min val_loss for dimension 128: 1.7111\n",
"\n"
]
}
],
"source": [
"# List of embedding dimensions to test\n",
"dimensions = [8, 16, 32, 64, 128]\n",
"n_epochs = 10\n",
"results = []\n",
"\n",
"for dimension in dimensions:\n",
" print(f\"Training with embedding dimension: {dimension}\")\n",
" model = get_model(dimension, n_characters)\n",
" model.compile(\n",
" loss=\"sparse_categorical_crossentropy\",\n",
" optimizer=keras.optimizers.Adam(),\n",
" metrics=[\"accuracy\"],\n",
" )\n",
"\n",
" history = model.fit(\n",
" X_train,\n",
" y_train,\n",
" batch_size=64,\n",
" epochs=n_epochs,\n",
" validation_data=(X_val, y_val),\n",
" verbose=1,\n",
" )\n",
"\n",
" min_val_loss = min(history.history[\"val_loss\"])\n",
" results.append({\"dimension\": dimension, \"val_loss\": min_val_loss})\n",
" print(f\"Min val_loss for dimension {dimension}: {min_val_loss:.4f}\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Consigne** : Modifier la structure de results pour correspondre à une liste de tuple où on a la moyenne et l'écart-type pour chaque entraînement pour une dimension précise."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Results: (dimension, mean_val_loss, std_val_loss)\n",
"Dimension 8.0: mean=1.8217, std=0.0000\n",
"Dimension 16.0: mean=1.7851, std=0.0000\n",
"Dimension 32.0: mean=1.7825, std=0.0000\n",
"Dimension 64.0: mean=1.7566, std=0.0000\n",
"Dimension 128.0: mean=1.7111, std=0.0000\n"
]
}
],
"source": [
"import pandas as pd\n",
"\n",
"# Convert results to DataFrame for easier manipulation\n",
"df_results = pd.DataFrame(results)\n",
"\n",
"# Compute mean and std for each dimension (if multiple runs were done)\n",
"# Since we have one run per dimension, we'll display them as tuples (val_loss, 0)\n",
"results_stats = [\n",
" (row[\"dimension\"], row[\"val_loss\"], 0.0) for _, row in df_results.iterrows()\n",
"]\n",
"\n",
"print(\"Results: (dimension, mean_val_loss, std_val_loss)\")\n",
"for dimension, mean_loss, std_loss in results_stats:\n",
" print(f\"Dimension {dimension}: mean={mean_loss:.4f}, std={std_loss:.4f}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Consigne** : Visualiser puis commenter les résultats."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA9gAAAJICAYAAACaO0yGAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAmg1JREFUeJzs3QV8XfX9//F3PGmTuqaW1N3dqFIqQCk+rDAGQ35sgw0ZG+wPQ8bYgCEbWty1ArTUKHVvU7dUU9e0jSf/x+dbbkiqSXqTm3vzej76ffTcc07u/R6793zO14JycnJyBAAAAAAAzkvw+f05AAAAAAAwBNgAAAAAAHgBATYAAAAAAF5AgA0AAAAAgBcQYAMAAAAA4AUE2AAAAAAAeAEBNgAAAAAAXkCADQAAAACAFxBgAwAAAADgBQTYAErE9u3b1axZM91www0KJFlZWdq2bZtX3zMjI0OPP/64unfvrjZt2uiuu+4647oDBgxw+/VcafXq1V7Ln31m3759VVKuvfZatw3nkpmZeco59uCDD7p5W7ZskS+c7li0bt1avXv31u23365p06ad8jfz5s1z6z333HMKpGv/j3/8owKd59hZuvvuu8+6rufctGTnrrec7jooDPu7guTJs97JqW3btho8eLAeeeQRJSUlqTj88MMPGjp0qLuW7HuyuD4HAIoitEh/BQBwgfVvf/tbXXTRRfq///s/r73vxx9/rPfff9/dOI4YMUKxsbHn/JtnnnnmrMsL8h6B6Oqrr1aPHj1UrVo1n+WhcuXKeuihh3Jfp6amaufOnZowYYI7f2655RY98MADucsbNWrkjmdBHir4gypVqrjtqVevnsqSGTNm6NixYypfvvwpy9LT0zV58mQFAju37RzPu232QO/TTz/VlClT9OWXX6pmzZpe+7wDBw7o3nvvVbly5dxDm4iICNWqVctr7w8A54sAGwDOI8DesGGD19/XU9psN67Nmzcv0N9ceumlXs9HIOjQoYNLvmSBwOmOjwXXd955p9566y0XTI8cOdLNt4cBgXQ8z7T9gaxBgwau1sT06dM1fPjw0wbfycnJqlq1qvbv3y9/NmjQINWtW/eU+fXr19dTTz2l1157TX/961+99nmbNm1yQbzVbBk9erTX3hcAvIUq4gBQytjNo4mOjvZ1VlCMIiMj9c9//tMFoC+++KJycnJ8nSV4Sb9+/RQVFaXvv//+tMu//fZbNWnSxNVWCFSehyoLFiwolu/HmJgYr74vAHgLATYAn7dXHD9+vF566SXXttfaHF988cWaNGmSawP43//+181v166dLrvsMlfyk5f9/cMPP+zeY9iwYe7vL7zwQr366quufXReR48e1fPPP+/ev3379q79npW+PP30064q58ntoK3kxda1z+7Tp4+rlpiYmOiWW0B08803u2nLu+XD2pqezdKlS12pZdeuXd1nW9Vy+9u0tLR8bVXHjRvnXg8cOLBA71sYns9444039N5772nIkCG5+8yqppuPPvrI5c222/bp119/fdr3mjNnjkaNGuX+/oILLnClVVYqd7Lly5fnbreta9XerdT25ONjr+24efJk61k16jNVE7U2ntaW2fJp7UFXrVp1ynont8H2nHNjx451n2VtRe1Y2DlmbZ7tuOdl2/PEE0+4gMnyZNtr7aat5Mz+5nxZCWb//v3dcVm7du0Z22DbZ1mb7VmzZumaa65x29yzZ0+XNws47G888+39nn322VO25ciRI/rHP/7hzitPO3CrJXFy+1Xbl3b8LT+33XabOnXq5GoB2DYvW7bslONg159dR/aevXr10u9//3utX7/+nG2wN27c6K4p2w77W8uXXYuHDx/Ot55t+69//WsXqF1//fUuL5Yn65vASjMLYteuXfrLX/7i+g6wz7L/7bXNL+q2n40F1/YZ9n11/PjxfMtSUlLcOXS6km3PdWDXpgWo1p65Y8eOuvHGG/Xjjz8W+ToozPH3lpCQkNztKez3geec+c9//qM//OEPbj07T2x/nPy9a9/FHnZdW7MQ+363ZNPffPNNvs/3XF+2j615hud8sGYbtv8sPytWrHCfY8fe8mlNOGz/rVmzxv2Nzbf9Z/veflfy2rx5s7sm7Ly197Z8WO2UDz744JTvJtuuHTt2uG3s1q2b2z7L8+mO9datW93f2G+RHWtrg/6///0v94FDYfYvgOJFFXEAPmfBgN2Q2k2kBQWvv/66u+GwGyq76ck73zoO+u6771SnTp18gZ4FgVdeeaV+9atfaerUqfr3v//tqlpbQG0sWLf3WbdunQtEbNqCanuvMWPGaM+ePe5vTHZ2tru5nj17tgtWbP2DBw+6G7K5c+fqs88+c4GZ3dhYEG7Tlqyt6ZlYidV9993n1rEgwQKrmTNnupvDn376Se+8805uW1ULcJcsWZLbtvFs75v3RvtMwsPDTykNtzbetp2WFytJtRuwRx991FVptZtI24823/aN3dTFxcW5G0UP2x+/+c1v3M3b5ZdfroULF+rtt992/1ugHhYW5tazNpi/+93vXBXSW2+91ZXWWpBoN/qLFy922x8UFOTWtf1jx8OCdTs+9jDDbmw97+VhN7R2TOwm/KqrrnIlgXZcClNd1M4LKzG2m9mKFSu6dqJ2s2rs3DP24MP2jwVb9nDHbpbtuFi1bis981YNA2sGYA8S7Kb+bE0CLHCy89+23W7Y7UHMu+++627obV/atlg+LaCwa6VChQruPDYWtNrfWTBl10njxo3dQwc7VhbsffLJJ65ac97zybbdAo8//elPbl/b8bV9bOeI7TO7Ybdjasuuu+46d01aswk7t+zctmNZvXr1026LnScWNFsQZlV97W/tAZR9hl2/lq+8570F7Ha+XXLJJS7ZvrB17Bq3Dq88wdzpWCBv+bPzxnO+2DH9/PPP3fn54YcfKj4+vlDbXhD2cGrixImnBNP22oJum2ffMXnZNWnH2PaBBVx2Tdj3lJ2fdiztWvQEmIW5Dgp7/L3BvteMBY0ehfk+MPb9Y8GwPQyx89yCWtvGvN+7nr4KrGNIO/datWqV28GcPXi9//77lZCQ4N4jL/u+79Kli6u+br8ztWvXdvP37t2rm266yR0fe9hix9x+X2zf2Xljx9Xm2zGy/Wb5/X//7/+5v7Xz/4orrnDfnba/re25/bbYufbYY4+589Tm5z3e9l1r23DPPffo0KFDbpvvuOMOl/eGDRu69ex3y64TW9/+3o6VPXCyh3D2fe35nSvs/gVQTHIAoARs27Ytp2nTpjnXX3997ry5c+e6eT169Mg5cuRI7vwxY8a4+X369Mk5duxY7vz33nvPzf/0009z59lrS998803uvOzs7Jy77rrLzZ89e7abN3nyZPf6zTffzJev9PR09znt27fPnffVV1+5df/5z3/mW3f+/Plu/hNPPOFez5o1y73+z3/+c9ZtT05OzuncuXNOt27dcvbt25dvmX2GvceLL76YO+++++5z82yfnUv//v1z98GZ0h133HHKcWjdunXO1q1bc+dPmjTJzbf9sGvXrtz5U6dOdfOfe+65Uz7z9ddfz5eXp556ys3/+OOP3evjx4+7bb7sssty0tLS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AADACwiwAQAAAADwAgJsAAAAAAC8gAAbAAAAAAAvIMAGAAAAAMALCLABAAAAAPACAmwAAAAAALyAABsAAAAAAC8gwAYAAAAAwAsIsAEAAAAA8AICbAAAAAAAvIAAGwAAAAAALwj1xpvAd9IzsjRzWZLmJCTpUHKKKsVEqUebWPVuF6vwsBBfZw8AAAAAygwCbD82b8VOPffxEh1LyVBQkJSTIwUFHdbcFbv02tcJuvfajuraqpavswkAAAAAZQJVxP04uH7i7fk6npLhXltwnfd/m//3MfPcegAAAACA4keA7afVwq3kWjnu32m5+TnS8x8vcesDAAAAAIoXAbYfsjbXVi38TMG1hy0/mpKhWcuTSihnAAAAAFB2EWD7obkrdro21wVh681JoJo4AAAAABQ3Amw/lHw8Pbet9bnYerY+AAAAAKCMBdivvvqqbrjhhrOus3//ft13333q3r27unXrpj/84Q/avXt37vLs7Gy98cYbGjJkiNq3b6/hw4frs88+U6CIKRdeqBJsWx8AAAAAUIYC7A8++EDPP//8Odf7/e9/r6SkJI0ZM8Ylm77rrrvyBemWfve732ns2LG68cYb9be//U1ff/21AkH31rULVYLdo03t4s4SAAAAAJR5pSLAttLn3/72t3r22WcVFxd31nWPHDmi+fPn6ze/+Y1atGihli1b6rbbblNCQoIOHTrk1vnoo490yy23aNiwYapfv76uvvpqXXrppQFTit27XazKR4XpXIXYtjw6Kky92saWUM4AAAAAoOwqFQH2ypUrFRYW5kqb27Vrd9Z1IyMjVb58eVcaffToUZe++eYbxcfHq0KFCq56+D/+8Q9ddtll+f4uODjYBeeBIDwsRPde29FF0GcKst38IOkP13Z06wMAAAAAileoSoEBAwa4VBDh4eF6+umn9cgjj6hz584KCgpSjRo19P7777sg2vTo0SPf31gV8gkTJuiaa65RoOjaqpYeHt3VjXNtQ3FZW+u81cYjIkL0p+s6u/UAAAAAAGUkwC6MnJwcrV69Wh06dNCtt96qrKwsPffcc7rzzjtd1fDo6Oh86+/bt89VJ69ataruuOOO8/ps+6zSpHOLGnrrL4M0O2GnG4pr264jStqfkttOu1Pz6qUuz4Vl+fck+AeOGVAyuNYAAIEgK8B+z/wuwP7uu+9cafW0adNyg+n//e9/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AFDqEGDjnMJCg9W3Qx03nZGZrVnLknydJQAAAAAodQiwUejexKctopo4AAAAAJyMABsF0rhuJdWrGe2mV27ar137j/k6SwAAAABQqhBgo0CCgoLUP09nZ9MWbfdpfgAAAACgtCHARoH161hPQUEnpqct3KacnBxfZwkAAAAASg0CbBRY9cpRatu4mpveuf+Y1mw+6OssAQAAAECpQYCNInd2NpXOzgAAAAAgFwE2CqVHm1hFhIe46Z+W7lB6RpavswQAAAAApQIBNgolKiJUPdvUdtPHUjK0YNVuX2cJAAAAAEoFAmycXzXxhVQTBwAAAABDgI1Ca9O4uqpWjHTTi9bs1qHkNF9nCQAAAAB8jgAbhRYSHKR+Heu66azsHM1YypjYAAAAAECAjSLpn6eauI2JDQAAAABlHQE2iqRBrQpqXLeim96w/bC27Dri6ywBAAAAgE+VqgD71Vdf1Q033HDWdfbv36/77rtP3bt3V7du3fSHP/xBu3fn78n6u+++07Bhw9S2bVuNHDlSc+bMKeacl02UYgMAAABAKQywP/jgAz3//PPnXO/3v/+9kpKSNGbMGJds+q677spdPnfuXP3pT3/SNddco6+++ko9evTQbbfdpo0bNxbzFpQ9F3So69pjm+mLt7v22AAAAABQVvk8wLbS59/+9rd69tlnFRcXd9Z1jxw5ovnz5+s3v/mNWrRooZYtW7rgOSEhQYcOHXLrvP766xo0aJBuvPFGNWrUSA888IBatWqld955p4S2qOyoGB2hzi1quun9h1OVsGGvr7MEAAAAAGU3wF65cqXCwsI0duxYtWvX7qzrRkZGqnz58vr666919OhRl7755hvFx8erQoUKys7O1uLFi12pdV5WlXzBggXFvCVlU95q4oyJDQAAAKAsC/V1BgYMGOBSQYSHh+vpp5/WI488os6dOysoKEg1atTQ+++/r+DgYFeKffz4cdWqVSvf39k6u3btKqYtKNu6tqyp8lFhOpaSodkJO3VHWqaiInx+WgEAAABAifOrSCgnJ0erV69Whw4ddOuttyorK0vPPfec7rzzTn300UdKTU3NDcTzioiIUFpa2nl/vn1eaWV586SSZE2w+7SL1fdztygtPUuzlu1Q/04nxsj25+1C0XHMgJLBtQYACARZAfZ75lcBtvUObqXV06ZNU3R0tJv3v//9T/3799fn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/3Zt423cQht/3foCsGNlgYANq2Al2vZ08mRTpkxxPSEDODfr0CwqKkrPPfec69TMSq6tnw17yAgAgL/Jysoq0H3iu+++q2eeecZ1oJuWluaaxVohYmm/hwzKoRtmAAAAAADOG22wAQAAAADwAgJsAAAAAAC8gAAbAAAAAAAvIMAGAAAAAMALCLABAAAAAPACAmwAAAAAALyAABsAAAAAAC8gwAYAAAAAwAsIsAEAAevBBx9Us2bNzph69ep13p9xww03uFRcCvL+X375pdue7du3u9cvvviie10SPJ+VN7Vt21ZDhgzRP/7xDx06dOiUYzJgwAD5C9untk22jwEAOJfQc64BAIAfq169ul566aXTLgsLC1MguvLKK9WnT58S/cxPPvnE/Z+Tk6Pjx48rISFBr7/+uqZOnaqPPvpIVapUccvvvPNO3XjjjfIXNWrUcNtWv359X2cFAOAHCLABAAEtPDxc7du3V1lSq1Ytl0rSyfvYagf07NlTv/rVr/Tvf/9bf//73918fwtUy+L5AwAoOqqIAwDwc1XsRx55RK+88oor/W3Xrp1+85vfaN++ffriiy80ePBgdejQQaNHj86tip3Xyy+/7AJKW8dKabdt25Zv+bp163T77berY8eOLt11112nrJOUlKS7775bnTp1cgHqmDFjTvmc7Oxsl8d+/fq5PNpnHT58ON86J1cRt217+OGH9dprr7m/a9Omja655hotX748399Nnz5do0aNyq3iPX78eLfd9n5FYe9z4YUX6uuvv1ZKSsppq4jbtNUwePLJJ9WtWze3/+677z4dO3bM5bdv375uf/zf//2fDh48mO/9P/vsMw0fPlytW7d222X5zMrKyl1un2XHy46fbY+td+mll2rGjBn59udzzz3n8mHL7f9//etfysjIOGMV8c2bN+uee+5xx8iCb9u/ixYtyl3u+ZvvvvvOrWfb1LVrV/3lL39xpfsAgMBFCTYAIOBlZmaedn5ISIiCgoJyX1tA2apVKz3xxBPatWuXHnvsMV1//fWKiIjQAw884IJEC8JtvgV/HhZc7d+/3y2zAM8CNKsGPW7cOEVHRysxMdEFtA0bNnTtki0///3vf3Xttdfqm2++UdWqVV3gZZ8VGhqqxx9/XMHBwfrPf/6jrVu3ugDN45///Kfeffdd3XHHHS7AtiDOPu9cJk6cqEaNGrkg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",
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"# Extract data for plotting\n",
"dims = [r[0] for r in results_stats]\n",
"val_losses = [r[1] for r in results_stats]\n",
"\n",
"# Create the plot\n",
"plt.figure(figsize=(10, 6))\n",
"plt.plot(dims, val_losses, marker=\"o\", linewidth=2, markersize=8)\n",
"plt.xlabel(\"Embedding Dimension\", fontsize=12)\n",
"plt.ylabel(\"Minimum Validation Loss\", fontsize=12)\n",
"plt.title(\"Impact of Embedding Dimension on Model Performance\", fontsize=14)\n",
"plt.xticks(dims)\n",
"plt.grid(True, alpha=0.3)\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Commentaires sur les résultats\n",
"\n",
"Les résultats montrent l'impact de la dimension de l'embedding sur les performances du modèle :\n",
"\n",
"1. **Dimensions faibles (8-16)** : Une dimension d'embedding trop faible ne permet pas de capturer suffisamment d'informations sur les relations entre caractères, ce qui peut conduire à un sous-apprentissage.\n",
"\n",
"2. **Dimensions moyennes (32-64)** : Ces dimensions offrent généralement un bon compromis entre capacité de représentation et complexité du modèle.\n",
"\n",
"3. **Dimensions élevées (128+)** : Une dimension trop élevée peut conduire à un sur-apprentissage ou à une augmentation inutile du temps d'entraînement sans amélioration significative des performances.\n",
"\n",
"La couche Embedding permet de représenter chaque caractère comme un vecteur dense de dimension fixe, ce qui est plus efficace qu'un encodage one-hot, surtout pour des vocabulaires plus grands."
]
}
],
"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
}