TP-intelligence-artificiell.../IAM2022_Apprentissage_Semi_Supervise_Sujet.ipynb
2023-06-23 19:39:56 +02:00

2177 lines
343 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "XMMppWbnG3dN"
},
"source": [
"# Apprentissage Semi-Supervisé\n",
"\n",
"On se propose dans ce TP d'illustrer certains techniques d'apprentissage semi-supervisé vues en cours.\n",
"\n",
"Dans tout ce qui suit, on considère que l'on dispose d'un ensemble de données $x_{lab}$ labellisées et d'un ensemble de donnés $x_{unlab}$ non labellisées."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2onzaW7mJrgG"
},
"source": [
"## Datasets"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4BejOODdKZ70"
},
"source": [
"Commencez par exécuter ces codes qui vos permettront de charger les datasets que nous allons utiliser et de les partager en données labellisées et non labellisées, ainsi qu'en données de test."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "V2nYQ2X5JW2k"
},
"source": [
"### Dataset des deux clusters"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"id": "Pkv-k9qIJyXH"
},
"outputs": [],
"source": [
"import numpy as np\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn import datasets\n",
"import matplotlib.pyplot as plt \n",
"\n",
"def generate_2clusters_dataset(num_lab = 10, num_unlab=740, num_test=250):\n",
" num_samples = num_lab + num_unlab + num_test\n",
" # Génération de 1000 données du dataset des 2 lunes\n",
" x, y = datasets.make_blobs(n_samples=[round(num_samples/2), round(num_samples/2)], n_features=2, center_box=(- 3, 3), random_state=1)\n",
"\n",
" x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=num_test/num_samples, random_state=1)\n",
" x_train_lab, x_train_unlab, y_train_lab, y_train_unlab = train_test_split(x_train, y_train, test_size=num_unlab/(num_unlab+num_lab), random_state=6)\n",
"\n",
" return x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "OBwkuDKFLKdH"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(10, 2) (740, 2) (250, 2)\n",
"(10,) (740,) (250,)\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test = generate_2clusters_dataset(num_lab = 10, num_unlab=740, num_test=250)\n",
"\n",
"print(x_train_lab.shape, x_train_unlab.shape, x_test.shape)\n",
"print(y_train_lab.shape, y_train_unlab.shape, y_test.shape)\n",
"\n",
"# Affichage des données\n",
"plt.plot(x_train_unlab[y_train_unlab==0,0], x_train_unlab[y_train_unlab==0,1], 'b.')\n",
"plt.plot(x_train_unlab[y_train_unlab==1,0], x_train_unlab[y_train_unlab==1,1], 'r.')\n",
"\n",
"plt.plot(x_test[y_test==0,0], x_test[y_test==0,1], 'b+')\n",
"plt.plot(x_test[y_test==1,0], x_test[y_test==1,1], 'r+')\n",
"\n",
"plt.plot(x_train_lab[y_train_lab==0,0], x_train_lab[y_train_lab==0,1], 'b.', markersize=30)\n",
"plt.plot(x_train_lab[y_train_lab==1,0], x_train_lab[y_train_lab==1,1], 'r.', markersize=30)\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "sKR9vNgsLp_J"
},
"source": [
"### Dataset des 2 lunes"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_AFhsTUQwIxt"
},
"source": [
"\n",
"<img src=\"https://drive.google.com/uc?id=1xb_gasBJ6sEmbyvCWTnVEAsbspyDCyFL\">\n",
"<caption><center> Figure 1: Comparaison de différents algorithmes semi-supervisés sur le dataset des 2 lunes</center></caption>"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "tCw5v2JDLwau"
},
"outputs": [],
"source": [
"import numpy as np\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn import datasets\n",
"import matplotlib.pyplot as plt \n",
"\n",
"def generate_2moons_dataset(num_lab = 10, num_unlab=740, num_test=250):\n",
" num_samples = num_lab + num_unlab + num_test\n",
" # Génération de 1000 données du dataset des 2 lunes\n",
" x, y = datasets.make_moons(n_samples=num_samples, noise=0.1, random_state=1)\n",
"\n",
" x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=num_test/num_samples, random_state=1)\n",
" x_train_lab, x_train_unlab, y_train_lab, y_train_unlab = train_test_split(x_train, y_train, test_size=num_unlab/(num_unlab+num_lab), random_state=6)\n",
"\n",
" return x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "FkQ1L5I1MBkH"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(10, 2) (740, 2) (250, 2)\n",
"(10,) (740,) (250,)\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test = generate_2moons_dataset(num_lab = 10, num_unlab=740, num_test=250)\n",
"\n",
"print(x_train_lab.shape, x_train_unlab.shape, x_test.shape)\n",
"print(y_train_lab.shape, y_train_unlab.shape, y_test.shape)\n",
"\n",
"# Affichage des données\n",
"plt.plot(x_train_unlab[y_train_unlab==0,0], x_train_unlab[y_train_unlab==0,1], 'b.')\n",
"plt.plot(x_train_unlab[y_train_unlab==1,0], x_train_unlab[y_train_unlab==1,1], 'r.')\n",
"\n",
"plt.plot(x_test[y_test==0,0], x_test[y_test==0,1], 'b+')\n",
"plt.plot(x_test[y_test==1,0], x_test[y_test==1,1], 'r+')\n",
"\n",
"plt.plot(x_train_lab[y_train_lab==0,0], x_train_lab[y_train_lab==0,1], 'b.', markersize=30)\n",
"plt.plot(x_train_lab[y_train_lab==1,0], x_train_lab[y_train_lab==1,1], 'r.', markersize=30)\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NIGZe-yAQq-A"
},
"source": [
"## Modèles"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jaPezVmtK5tC"
},
"source": [
"Nous allons dès maintenant préparer les modèles que nous utiliserons dans la suite.\n",
"\n",
"**Travail à faire** Complétez les modèles ci-dessous : "
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mfw8EKUuUpt6"
},
"source": [
"Pour le dataset des 2 clusters, un simple perceptron monocouche suffira :"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"id": "BryV3CDKQytA"
},
"outputs": [],
"source": [
"from keras.layers import Input, Dense\n",
"from keras.models import Model\n",
"\n",
"# Ici, écrire un simple perceptron monocouche\n",
"def create_model_2clusters():\n",
"\n",
" inputs = Input(shape=(2,))\n",
"\n",
" outputs = Dense(1, activation='sigmoid')(inputs)\n",
"\n",
" model = Model(inputs=inputs, outputs=outputs) \n",
"\n",
" return model"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NrE8ZQCpUuxg"
},
"source": [
"Pour le dataset des 2 lunes, implémentez un perceptron multi-couches à une couche cachée, par exemple de 20 neurones."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"id": "o1jcG_4pyGlx"
},
"outputs": [],
"source": [
"# Ici, écrire un perceptron multi-couches à une seule couche cachée comprenant 20 neurones\n",
"def create_model_2moons():\n",
"\n",
" inputs = Input(shape=(2,))\n",
"\n",
" inter = Dense(20, activation=\"relu\")(inputs) \n",
"\n",
" outputs = Dense(1, activation=\"sigmoid\")(inter)\n",
" \n",
" model = Model(inputs=inputs, outputs=outputs) \n",
"\n",
" return model"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JMaTgZJcQbIh"
},
"source": [
"## Apprentissage supervisé"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hGTfv5YfMAXY"
},
"source": [
"Commencez par bien lire le code ci-dessous, qui vous permet de mettre en place un apprentissage supervisé en détaillant la boucle d'apprentissage. Cela nous permettra d'avoir plus de contrôle dans la suite pour implémenter les algorithmes semi-supervisés. Cela vous fournira également une base contre laquelle comparer les algorithmes semi-supervisés.\n",
"\n",
"En quelques mots, le code est organisé autour d'une double boucle : une sur les *epochs*, et la 2nde sur les *mini-batches*.\n",
"\n",
"Pour chaque nouveau batch de données, on réalise la succession d'étapes suivantes dans un bloc **GradientTape** qui permet le calcul automatique des gradients : \n",
"\n",
"\n",
"1. Prédiction de la sortie du modèle sur les données du batch\n",
"2. Calcul de la fonction de perte entre sortie du réseau et labels réels associés aux élements du batch\n",
"3. Calcul des gradients de la perte par rapport aux paramètres du réseau (par différentiation automatique)\n",
"4. Mise à jour des paramètres grâce aux gradients calculés. \n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fbmhai8PVXVd"
},
"source": [
"### Dataset des 2 clusters"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"id": "XP5XgJRQQm5_"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss : 1.5559, Acc : 0.1000, Test Acc : 0.0560\n",
"Epoch 1 : Loss : 1.5317, Acc : 0.1000, Test Acc : 0.0520\n",
"Epoch 2 : Loss : 1.5078, Acc : 0.1000, Test Acc : 0.0520\n",
"Epoch 3 : Loss : 1.4840, Acc : 0.1000, Test Acc : 0.0480\n",
"Epoch 4 : Loss : 1.4604, Acc : 0.1000, Test Acc : 0.0440\n",
"Epoch 5 : Loss : 1.4371, Acc : 0.0000, Test Acc : 0.0400\n",
"Epoch 6 : Loss : 1.4139, Acc : 0.0000, Test Acc : 0.0400\n",
"Epoch 7 : Loss : 1.3910, Acc : 0.0000, Test Acc : 0.0400\n",
"Epoch 8 : Loss : 1.3683, Acc : 0.0000, Test Acc : 0.0440\n",
"Epoch 9 : Loss : 1.3459, Acc : 0.0000, Test Acc : 0.0440\n",
"Epoch 10 : Loss : 1.3237, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 11 : Loss : 1.3018, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 12 : Loss : 1.2802, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 13 : Loss : 1.2588, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 14 : Loss : 1.2377, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 15 : Loss : 1.2169, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 16 : Loss : 1.1964, Acc : 0.0000, Test Acc : 0.0440\n",
"Epoch 17 : Loss : 1.1762, Acc : 0.0000, Test Acc : 0.0400\n",
"Epoch 18 : Loss : 1.1563, Acc : 0.0000, Test Acc : 0.0440\n",
"Epoch 19 : Loss : 1.1367, Acc : 0.0000, Test Acc : 0.0440\n",
"Epoch 20 : Loss : 1.1175, Acc : 0.0000, Test Acc : 0.0440\n",
"Epoch 21 : Loss : 1.0985, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 22 : Loss : 1.0798, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 23 : Loss : 1.0614, Acc : 0.0000, Test Acc : 0.0480\n",
"Epoch 24 : Loss : 1.0433, Acc : 0.0000, Test Acc : 0.0520\n",
"Epoch 25 : Loss : 1.0256, Acc : 0.0000, Test Acc : 0.0560\n",
"Epoch 26 : Loss : 1.0081, Acc : 0.0000, Test Acc : 0.0600\n",
"Epoch 27 : Loss : 0.9908, Acc : 0.0000, Test Acc : 0.0560\n",
"Epoch 28 : Loss : 0.9739, Acc : 0.0000, Test Acc : 0.0680\n",
"Epoch 29 : Loss : 0.9572, Acc : 0.0000, Test Acc : 0.0760\n",
"Epoch 30 : Loss : 0.9408, Acc : 0.1000, Test Acc : 0.0800\n",
"Epoch 31 : Loss : 0.9247, Acc : 0.1000, Test Acc : 0.0840\n",
"Epoch 32 : Loss : 0.9088, Acc : 0.1000, Test Acc : 0.0880\n",
"Epoch 33 : Loss : 0.8932, Acc : 0.1000, Test Acc : 0.0880\n",
"Epoch 34 : Loss : 0.8778, Acc : 0.1000, Test Acc : 0.1080\n",
"Epoch 35 : Loss : 0.8627, Acc : 0.1000, Test Acc : 0.1040\n",
"Epoch 36 : Loss : 0.8479, Acc : 0.1000, Test Acc : 0.1200\n",
"Epoch 37 : Loss : 0.8333, Acc : 0.1000, Test Acc : 0.1360\n",
"Epoch 38 : Loss : 0.8190, Acc : 0.1000, Test Acc : 0.1600\n",
"Epoch 39 : Loss : 0.8049, Acc : 0.3000, Test Acc : 0.1760\n",
"Epoch 40 : Loss : 0.7910, Acc : 0.3000, Test Acc : 0.2080\n",
"Epoch 41 : Loss : 0.7775, Acc : 0.4000, Test Acc : 0.2360\n",
"Epoch 42 : Loss : 0.7641, Acc : 0.4000, Test Acc : 0.3080\n",
"Epoch 43 : Loss : 0.7510, Acc : 0.4000, Test Acc : 0.3680\n",
"Epoch 44 : Loss : 0.7382, Acc : 0.4000, Test Acc : 0.4280\n",
"Epoch 45 : Loss : 0.7256, Acc : 0.5000, Test Acc : 0.4680\n",
"Epoch 46 : Loss : 0.7133, Acc : 0.5000, Test Acc : 0.5120\n",
"Epoch 47 : Loss : 0.7012, Acc : 0.5000, Test Acc : 0.5240\n",
"Epoch 48 : Loss : 0.6893, Acc : 0.5000, Test Acc : 0.5400\n",
"Epoch 49 : Loss : 0.6777, Acc : 0.5000, Test Acc : 0.5480\n",
"Epoch 50 : Loss : 0.6663, Acc : 0.5000, Test Acc : 0.5800\n",
"Epoch 51 : Loss : 0.6552, Acc : 0.5000, Test Acc : 0.6120\n",
"Epoch 52 : Loss : 0.6443, Acc : 0.5000, Test Acc : 0.6520\n",
"Epoch 53 : Loss : 0.6336, Acc : 0.7000, Test Acc : 0.6960\n",
"Epoch 54 : Loss : 0.6232, Acc : 0.7000, Test Acc : 0.7560\n",
"Epoch 55 : Loss : 0.6130, Acc : 0.7000, Test Acc : 0.7920\n",
"Epoch 56 : Loss : 0.6030, Acc : 0.8000, Test Acc : 0.8120\n",
"Epoch 57 : Loss : 0.5932, Acc : 1.0000, Test Acc : 0.8280\n",
"Epoch 58 : Loss : 0.5836, Acc : 1.0000, Test Acc : 0.8520\n",
"Epoch 59 : Loss : 0.5743, Acc : 1.0000, Test Acc : 0.8720\n",
"Epoch 60 : Loss : 0.5651, Acc : 1.0000, Test Acc : 0.8840\n",
"Epoch 61 : Loss : 0.5562, Acc : 1.0000, Test Acc : 0.8920\n",
"Epoch 62 : Loss : 0.5474, Acc : 1.0000, Test Acc : 0.9000\n",
"Epoch 63 : Loss : 0.5389, Acc : 1.0000, Test Acc : 0.9040\n",
"Epoch 64 : Loss : 0.5306, Acc : 1.0000, Test Acc : 0.9080\n",
"Epoch 65 : Loss : 0.5224, Acc : 1.0000, Test Acc : 0.9120\n",
"Epoch 66 : Loss : 0.5144, Acc : 1.0000, Test Acc : 0.9160\n",
"Epoch 67 : Loss : 0.5067, Acc : 1.0000, Test Acc : 0.9120\n",
"Epoch 68 : Loss : 0.4991, Acc : 1.0000, Test Acc : 0.9160\n",
"Epoch 69 : Loss : 0.4916, Acc : 1.0000, Test Acc : 0.9200\n",
"Epoch 70 : Loss : 0.4844, Acc : 1.0000, Test Acc : 0.9200\n",
"Epoch 71 : Loss : 0.4773, Acc : 1.0000, Test Acc : 0.9240\n",
"Epoch 72 : Loss : 0.4704, Acc : 1.0000, Test Acc : 0.9280\n",
"Epoch 73 : Loss : 0.4636, Acc : 1.0000, Test Acc : 0.9360\n",
"Epoch 74 : Loss : 0.4570, Acc : 1.0000, Test Acc : 0.9400\n",
"Epoch 75 : Loss : 0.4505, Acc : 1.0000, Test Acc : 0.9400\n",
"Epoch 76 : Loss : 0.4442, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 77 : Loss : 0.4380, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 78 : Loss : 0.4320, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 79 : Loss : 0.4261, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 80 : Loss : 0.4204, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 81 : Loss : 0.4147, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 82 : Loss : 0.4092, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 83 : Loss : 0.4039, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 84 : Loss : 0.3986, Acc : 1.0000, Test Acc : 0.9440\n",
"Epoch 85 : Loss : 0.3935, Acc : 1.0000, Test Acc : 0.9480\n",
"Epoch 86 : Loss : 0.3885, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 87 : Loss : 0.3836, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 88 : Loss : 0.3788, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 89 : Loss : 0.3741, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 90 : Loss : 0.3695, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 91 : Loss : 0.3650, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 92 : Loss : 0.3606, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 93 : Loss : 0.3563, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 94 : Loss : 0.3521, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 95 : Loss : 0.3480, Acc : 1.0000, Test Acc : 0.9520\n",
"Epoch 96 : Loss : 0.3440, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 97 : Loss : 0.3400, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 98 : Loss : 0.3362, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 99 : Loss : 0.3324, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 100 : Loss : 0.3287, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 101 : Loss : 0.3251, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 102 : Loss : 0.3215, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 103 : Loss : 0.3181, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 104 : Loss : 0.3147, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 105 : Loss : 0.3113, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 106 : Loss : 0.3081, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 107 : Loss : 0.3049, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 108 : Loss : 0.3017, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 109 : Loss : 0.2987, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 110 : Loss : 0.2956, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 111 : Loss : 0.2927, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 112 : Loss : 0.2898, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 113 : Loss : 0.2870, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 114 : Loss : 0.2842, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 115 : Loss : 0.2814, Acc : 1.0000, Test Acc : 0.9560\n",
"Epoch 116 : Loss : 0.2787, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 117 : Loss : 0.2761, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 118 : Loss : 0.2735, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 119 : Loss : 0.2710, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 120 : Loss : 0.2685, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 121 : Loss : 0.2661, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 122 : Loss : 0.2637, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 123 : Loss : 0.2613, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 124 : Loss : 0.2590, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 125 : Loss : 0.2567, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 126 : Loss : 0.2545, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 127 : Loss : 0.2523, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 128 : Loss : 0.2501, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 129 : Loss : 0.2480, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 130 : Loss : 0.2459, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 131 : Loss : 0.2439, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 132 : Loss : 0.2418, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 133 : Loss : 0.2399, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 134 : Loss : 0.2379, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 135 : Loss : 0.2360, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 136 : Loss : 0.2341, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 137 : Loss : 0.2323, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 138 : Loss : 0.2304, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 139 : Loss : 0.2286, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 140 : Loss : 0.2269, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 141 : Loss : 0.2251, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 142 : Loss : 0.2234, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 143 : Loss : 0.2217, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 144 : Loss : 0.2201, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 145 : Loss : 0.2184, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 146 : Loss : 0.2168, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 147 : Loss : 0.2152, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 148 : Loss : 0.2137, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 149 : Loss : 0.2121, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 150 : Loss : 0.2106, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 151 : Loss : 0.2091, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 152 : Loss : 0.2076, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 153 : Loss : 0.2062, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 154 : Loss : 0.2048, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 155 : Loss : 0.2034, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 156 : Loss : 0.2020, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 157 : Loss : 0.2006, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 158 : Loss : 0.1992, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 159 : Loss : 0.1979, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 160 : Loss : 0.1966, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 161 : Loss : 0.1953, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 162 : Loss : 0.1940, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 163 : Loss : 0.1928, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 164 : Loss : 0.1915, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 165 : Loss : 0.1903, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 166 : Loss : 0.1891, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 167 : Loss : 0.1879, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 168 : Loss : 0.1867, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 169 : Loss : 0.1855, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 170 : Loss : 0.1844, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 171 : Loss : 0.1833, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 172 : Loss : 0.1821, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 173 : Loss : 0.1810, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 174 : Loss : 0.1799, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 175 : Loss : 0.1789, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 176 : Loss : 0.1778, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 177 : Loss : 0.1767, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 178 : Loss : 0.1757, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 179 : Loss : 0.1747, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 180 : Loss : 0.1737, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 181 : Loss : 0.1727, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 182 : Loss : 0.1717, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 183 : Loss : 0.1707, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 184 : Loss : 0.1697, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 185 : Loss : 0.1688, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 186 : Loss : 0.1678, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 187 : Loss : 0.1669, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 188 : Loss : 0.1660, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 189 : Loss : 0.1651, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 190 : Loss : 0.1642, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 191 : Loss : 0.1633, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 192 : Loss : 0.1624, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 193 : Loss : 0.1615, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 194 : Loss : 0.1607, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 195 : Loss : 0.1598, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 196 : Loss : 0.1590, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 197 : Loss : 0.1581, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 198 : Loss : 0.1573, Acc : 1.0000, Test Acc : 0.9600\n",
"Epoch 199 : Loss : 0.1565, Acc : 1.0000, Test Acc : 0.9600\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"import math\n",
"\n",
"# Données et modèle du problème des 2 clusters\n",
"x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test = generate_2clusters_dataset(num_lab = 10, num_unlab=740, num_test=250)\n",
"model = create_model_2clusters()\n",
"\n",
"# Hyperparamètres de l'apprentissage\n",
"epochs = 200\n",
"batch_size = 32\n",
"if batch_size < x_train_lab.shape[0]:\n",
" steps_per_epoch = math.floor(x_train_lab.shape[0]/batch_size)\n",
"else:\n",
" steps_per_epoch = 1\n",
" batch_size = x_train_lab.shape[0]\n",
"\n",
"# Instanciation d'un optimiseur et d'une fonction de coût.\n",
"optimizer = keras.optimizers.Adam(learning_rate=1e-2)\n",
"loss_fn = keras.losses.BinaryCrossentropy()\n",
"\n",
"# Préparation des métriques pour le suivi de la performance du modèle.\n",
"train_acc_metric = keras.metrics.BinaryAccuracy()\n",
"test_acc_metric = keras.metrics.BinaryAccuracy()\n",
"\n",
"# Indices de l'ensemble labellisé\n",
"indices = np.arange(x_train_lab.shape[0])\n",
"\n",
"# Boucle sur les epochs\n",
"for epoch in range(epochs):\n",
"\n",
" # A chaque nouvelle epoch, on randomise les indices de l'ensemble labellisé\n",
" np.random.shuffle(indices) \n",
"\n",
" # Et on recommence à cumuler la loss\n",
" cum_loss_value = 0\n",
"\n",
" for step in range(steps_per_epoch):\n",
"\n",
" # Sélection des données du prochain batch\n",
" x_batch = x_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
" y_batch = y_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
"\n",
" # Etape nécessaire pour comparer y_batch à la sortie du réseau\n",
" y_batch = np.expand_dims(y_batch, 1)\n",
"\n",
" # Les opérations effectuées par le modèle dans ce bloc sont suivies et permettront\n",
" # la différentiation automatique.\n",
" with tf.GradientTape() as tape:\n",
"\n",
" # Application du réseau aux données d'entrée\n",
" y_pred = model(x_batch, training=True) # Logits for this minibatch\n",
"\n",
" # Calcul de la fonction de perte sur ce batch\n",
" loss_value = loss_fn(y_batch, y_pred)\n",
"\n",
" # Calcul des gradients par différentiation automatique\n",
" grads = tape.gradient(loss_value, model.trainable_weights)\n",
"\n",
" # Réalisation d'une itération de la descente de gradient (mise à jour des paramètres du réseau)\n",
" optimizer.apply_gradients(zip(grads, model.trainable_weights))\n",
"\n",
" # Mise à jour de la métrique\n",
" train_acc_metric.update_state(y_batch, y_pred)\n",
"\n",
" cum_loss_value = cum_loss_value + loss_value\n",
"\n",
" # Calcul de la précision à la fin de l'epoch\n",
" train_acc = train_acc_metric.result()\n",
"\n",
" # Calcul de la précision sur l'ensemble de test à la fin de l'epoch\n",
" test_logits = model(x_test, training=False)\n",
" test_acc_metric.update_state(np.expand_dims(y_test, 1), test_logits)\n",
" test_acc = test_acc_metric.result()\n",
"\n",
" print(\"Epoch %4d : Loss : %.4f, Acc : %.4f, Test Acc : %.4f\" % (epoch, float(cum_loss_value/steps_per_epoch), float(train_acc), float(test_acc)))\n",
"\n",
" # Remise à zéro des métriques pour la prochaine epoch\n",
" train_acc_metric.reset_states()\n",
" test_acc_metric.reset_states() "
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"id": "FcnTF5WWVacl"
},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAACIlUlEQVR4nO2dd5gUVdaH31td3T05JxiGHAUBUWRXRcFMUERUjBjWLCb4FrPrrlkXDCQDq4iCEgwoqGAAE0ZQQYIgcRiY0JN7Qoeq+/1R0z3dk4dpmAHqfZ59Vrq7bt2q7jn31Lnn/I6QUmJiYmJicviitPYETExMTExahmnITUxMTA5zTENuYmJicphjGnITExOTwxzTkJuYmJgc5qitctatK0OSKrNw5U/kRvek35BhoRjOxMTEpM0SF2HluI7xoq73RKukH66ZHpKTSil568s/+GynxuBL7iIsIjIUw5qYmJi0OdJiwzhvQPs6DflhHVoRQnDVGcfyzNiurJ/3EDt++7a1p2RiYmJyyAmJIRdCxAkhlgghtgghNgsh/h6KcZtKWmIMr9x2Or0Kv+WbuU9QWV52KE9vYmJi0qqEyiN/AfhUStkbGABsDtG4TUYIwTVnHcvTF3Tm93kPsfP3NYd6CiYmJiatQotj5EKIWOA3oKts6mB1xMh1BGWWBDQ1DKgzDNRkJJLvt+xjawF0Pv50VKutReOBEY+v1KDYoyBbOD8TExOT5tJQjDwUWStdgDzgdSHEAGAtcKeUMii+IYS4EbgR4OUp47lxzMlBg5RZErBGxRElNEQI7OTIQZ0YUlzO/G/eI673KaR26d2yAaUkTHqhrJIij6XlEzQxMTEJEaHwyE8AfgBOllL+KIR4ASiRUj5U70F1eORF9nRiw60hMeKBSAmf/7qLPwoEPU4+D6vN3qLB3BVOsitNQ25iYnJoOdhZK3uBvVLKH6v+vQQY1PxhRMiNOIAQcNagzkwYnMSOL94kZ9efLRpMHIxJmpiYmLSAFhtyKWU2kCmE6FX10hnAppaOG2oSYyO5fdQA0op/Z+OqJXjcrtaekomJiUlICFXWyu3AfCHEemAg8ESIxg0pQsDZg7pw9eAk/vpsHjm7a3vnv3z7Jf847xSuHfl3Fs6Z3gqzNDExMWkeITHkUsrfpJQnSCn7SykvkFIWhmLcg0VibCR3njeQtMLf2LTqXTwewzvXNI2Zj9/PY7Pm88rSr1j9yQfs3t6CUIyJiYnJIaB1tFZayIlXPoCjuKLW60mx4fz01uNNGkMIOPv4rhxXVMb8lfNI7HcqjsJS2nXsTLuMTgCcNmIM369aQaduvRoZzcTExKT1OCwNuaO4gr43PVfr9Y0v393ssZLjDO98xbrf+OLLDSSlpPnfS0ptx5/rf23RXE1MTEwONoe11kqoEALOPb4rp3aLpjhrG7l7trX2lExMTEyazGHpkR8s+nRtT6xVklywjk07NpC7by+JqWmNH2hiYmLSipiGPIDB/Xqwbc8+eqVGcGxGGP99/A1u/9czrT0tkxDx5MTLcDpLa70eFRXNfTPeboUZmZiEBtOQB6CqFmY8cBPn3PAImq5zyyVn0T+ykM1fvU+Pk0ajWq2tPUWTFuB0ltL1+toppTvm3N4KszExCR2HpSFPig2vc2MzKTa8xWOPPO0ERp52QtBrJxQ6WbDyDZIGDCMu0Qy1mJiYtC0OS0Pe1BTDUJESH8Wd5w3g419+4a8ddqw9hmG1t0CzxcTExCSEmFkrTUQIGDW4G6P7RPPTnPvI3GymJZqYmLQNTEPeTBJjInn9jtNJ3bWMNQummZotJiYmrc5hGVppbYQQ3HbeIHbsy+ffr95LpzOuJqP3wNaelkkjREVF17mxGRUV3QqzMTEJHS3WIz8g6tQj70BcRNtfV4rKvcS59vr/res6s5b9ytriaAaPu7VleucmJiYm9XCw9ciPahRFYeL5x/Pg6Qn88Mo9ZG75rbWnZGJicpRhGvIArnvgBVJOuYp+509s9rHd0pOYe8cZJG1fypq3nzNj5yYmJocM05AHcM3YM/j0lUcO+HhFUbhjzAk8MDyeH165h6yt60M3ORMTE5N6OKwNuaOwhHET/0N+UUlIxjv1hH4kxEa1eJzuHZKZe8cZxG99j+/feR6vxx2C2ZmYmJjUzWFtyOe9t4LCrL94490VrT2VWiiKwp0XDOa+YXGseWkKWVs3tPaUTExMjlAOW0PuKCxh2WermH1hKss+WxUyrzzU9OiQzBt3nkHsn0v4/p0XTO/cxMQk5By2hnzeeysY3U3QKzWM0d1Em/TKfSiKwt1jT+Te02JY8/I9ZP31R2tPycTE5AjisDTkPm98wvExAEw4PqZNe+U+emakMPf204nZvJgfFk3H6/W09pRMTEyOAA5LQ+7zxpOijAKipCg1JF75Zf/3LH+/bAp/7sqiw/Br+d+7K0Mx3SAsFoVJY09kyilRrHlpCvu2bwz5OUxMTI4uDsvKzvNvepB9+7Nrvd6+XRofvvxYy+fXADUrO1uCpuk8v/QXNrmSOWHsTaiqqXduYmJSNw1Vdh6Whrw1CaUh97F5dy5PvL+eHiNvpF3XPiEd28TE5MjALNFv4/TpZMTOIza8w4+LZ5ixcxMTk2bRhgy5pDUeDpqDMb+DM0mLReH/xp3IpJMi+O6le9i/c8tBOY+JicmRR5sx5BZvJS5pabPGXEpwSQsWb+VBPc8xnVJ54/bhhP2+gB+XzELzeg/q+UxMTA5/2kyMXEdQZklAU8OAOsNArYzE4q0kUitAOUheeU027srhyQ/+oMeom2jfpdchOaeJiUnb5LDY7DSpG69XY+oHv/CXlsbxY27Eorb9DWETE5PQc0g2O4UQFiHEr0KIZaEa0wRU1cI9Fw3hzhPtfDP7n+zb+WdrT8nExKSNEcoY+Z3A5hCOZxJAvy5pvHH7cGy/vsWP775kxs5NTEz8hMSQCyE6AKOAOaEYz6RuVNXCfZf8jTsHW/nmpX+yf5fpnZuYmITOI38emALoIRrPpAGO7ZrGGxOHY137Jj+997LpnZuYHOW0eOdMCDEayJVSrhVCDGvgczcCNwK8PGU8N445uaWnPqpRVQv3jf8763fs5+nZU+h93s2kde7Z2tM6Ynly4mU4naW1Xo+Kiua+GW+3woxMTKppcdaKEOJJ4CrAC4QBMcB7Usor6z3IzFoJKR6vxrNLfmKnpSMnnP8PFIultad0RPHkxMvI3LWdtEuDdXwsFgvlK57j8blHx/6+uZi1Lg1lrbTYI5dS3gfcB1Dlkf9fg0bcJORYVQv3X/p3ft++n2dm/ZPe599CWqcerT2tIwansxRrVAL2pI5Br7sce1ppRq2D01lK1+un13p9x5zbW2E2JoG0mcpOk5YzoFs75t4+DOXnN/j5/VfRNa21p2RiYnIICKkhl1KullKODuWYJs3Dqlp44NK/c+txgq9n/5OczB2tPSUTE5ODjOmRH6EM7N6OuROHIX/4H78s/Z/pnZuYHMGY9d5HMFbVwkOXncSv2/bx39lTOOaCiaR06NLa0zossYRFsG/uXUGveZwFZHTu1joTMjEJwDTkRwHH9WjP3ImpPLV4Dr/YuzJo9LUoivkw1lSioqLBWQphwX8uUUnd2ky2RmMZJaHIOImKiq5zYzMqKrr5EzYJKaYhP0rweefrtu5j6qx/0veCiSSb3nmTaAvGujFD3FhGSSgyTtrCfTCpG9OQH2UM6tme17uk8NTiOawN785xo642vfPDADP1z6QhTEN+FGKzqjx8+Un8snUfz82eYnjn6Z1be1qHDaEsjDGLbExCgWnIj2JOqPLOn1j0MmsjenHcqAmmd94EQukdm562SSgwDflRjs2q8sgVp/DTliyen/VP+o293fTOQ0xDXveBkJ25A60qnbTQkcsD14ym0JHLxjmT6Xv91GaNVZzv4IFrapd+mE8EhxemITcB4MTe6bzetco7j+rFcSNN7zxUhNrr1jTNLxdgjUqg6/XTyc7cQdb8+2qN6Vss6ss4kbq3SXMzQ0BtG9OQm/ix26z8+8pT+HHzXp6fNYX+F95OUvtOrT2tQ0JbN1SBhrjQkYs1KgEw8tsB0jK6Up6UUq+AV33XEOiNb5wzGa2yHDBy5H3vRUVFmyGgNo5pyE1qMaRPB+Z2S+XxRS+xLro3A0dcdcR75801VIFGz4fHWcCTEy+r02jW93kh9To/F2hIwTCmPiP9wDWj65xrS9Eqy2l/zfNUOvaie93+/rCZ7zwIGCGdtIyuLT5PW180D0dMQ25SJ3ablf9ceQrfb8pk+uwp9L/wThLbZbT2tNoEUVHRFNYja+tc8Vydx/iMZCAuxx5yFz4ctFhUOnJJu/QxLBZLkNE8lJ6v1HWsCelYbXYAv/evhUjmwfTuQ49pyE0a5O/HZHBctzQeWzSLPbF9GHDulUe8d94Y9814mweuGU1659pSwc2VKItNTAoKh9Q3buCmZKEjl6xd2wBqGXyToxPTkJs0SpjdymNXmd75gRIVFU2hY3st/XJLMxqA6FL3e7Eb50wmf9k0wAjPlCel+M/TEHWFNIrzHax78mLiktPwOAtwOfYgdS91di+og6K87CZnvfjOH7gQgbkYhQLTkJs0mSDvPK4vA8+9AiGa+id/+NDQpt+BxHBD6cHXFWtv6twaCmk8PneZf45Zu7ahVoVVfFjCIsh+50FcVYuGD6GoTQ6T+M6/fsYtQU06jrYGHQcD05CbNAufd75mUyYzZk2h/0V3k5javrWn1WICs0J8cWoI9hbbQgy3Zqzd5dhD0ecvUbhrey3PuLkLj+8eBGbFgGHE+14/1W/wA6nLGzc59JiG3OSAOOmYDAZ1S+PRhS+SmXAsA865/LD2zgMNXn3ecyDNVQJsyuefnHgZRXnZrH1qfNBnFKHUym4JRKssJ+3Sx2rNubkLj+8e1A7BuFn35MUIRa1luIvzHc06B9SWBPY4C3AlpZgqii3ANOQmB0yY3crjE4by3cZMZs66h/4X3XVEeOdNobkhlqZ83uksZdB9i4Ne2zhnMpWOvSAU1s+4BXdpARW5exCKQlhSh2bNoSVzrS/lseai0xRqVp/W5embNA/TkJu0mJP7ZjCoeyqPvvMimYn9GXDOZYe1d16c7wjajAt8/VAQGAd3lxaQcvEjVe9IHMumocal4inIwuXY06wNU5MjF9OQm4SEcLuNJ64eyjd/7Gb2rHsYcPFdJKQcWu+8JYUmgcd6NQ+5Hxleo2KLIP2KJwEjc+RA5pS1e2etY4XU6dClR615bZwzmYq8vVii4qtekeR//DyKPZKkc25BVa1YbXZ0VfWHUnKbeF2BYRtFKMQmJlGc70Dq3gOOrwup1xsyqvl9FOc7WPvUeITUiUtOC/psY5hFRA1jGnKTkDK0XydO6NGO/7z9AntSjmPAWeMPmXfekkKTwGPVvzYhFCsAOQsf9MdzG4pTNzRuyvj/YE/qSNb8+9DdhqetOQvJrNqgDDRGWmU5qeMfw5pkpHe6HXuwJnYge94koDq+7IsrgxFjrs8zb0qmSkuKc+KS0+oNizQ0dnNDKWYRUcOYhtwk5ITbbTx5zal8vWE3L82+l4EX3UV8SrvWnlaTsahWf3qcLTqB/hNnAy0QufJ68bhd6K4y0q42Kj89+XtB1+jYvU+zxu17/VS/QJYPIXWy5t/H/iov20dUVDR7d25j/Yxbao3jLT00YaLW4Gj03k1DbnLQOPVYwzv/9zvPsydlEP3PuuSwjp23BKHaQAiEqL8q1lc4JHUv0uuuPrbG5zRNwxqVQMQ5d6NpGqlVr2dXaaIEGqxbR59YSxoAYNeLV/rlbwMNvS/VsK65NSdL58mJl9Uq/AHQvV6/9G7NcUJlZI9G79005CYHlYgwG09fcyqrf9/FK7PvZeDFdxMfEB9tDery2AoduSEThQo8R6Ejl2QkuseNlBIp9XqNua9wyKKqfp0TTbHgyc9CcxaS/c6D5AoFr+bBGpvG/qVTQfcCIAEpJUXOCvL37/UbSqnXHQ6SSLpeP52sXduCinMC0wJrzq05OJ2lWKMSgsYGKM/e4ZfeDeRINrKHAtOQmxwShg3ozIm92vPI28+xJ7V1vfO6PLb1M27xi0JZLBZ/taHHWeA3Ms3Jcw6sYkRRUaw243olQS52duaOIA+10JGLsvQZhGonedSdCEAoIARkdO6G01mKs9JL+6unsmfObbS/bgZgGGxPwV5sSR3ZO/Nq//XlP3HRgdyiIJq7YWty6DENuckhIyLMxjPXnsqq33bx6ux7Oe6SScQlGYGB0qIC3nn2n1w25b9ExcY3MlLdlBbk1ZnXrCqNLxj1laBndO7WIkNlCYsgd+FDgDSMbd6uoPfdLhdSgrPSiyXMyJDRNM2Yy+cv1ppHcyopN86ZDNLwgpGyegGREiT88uR4pO7FEmncb6Ha8ZYY91ARiv9cxfkO/4ZtIPvm3oXTWVrnE07+/r2gKOyaPiHodal7iUjt3OC86xqvKC+bX5++LGgPAA68y9KRhmnITQ45wwd25sRe7Xjk7ansaT+YY8+4iJ8/WYias4GfPn6H0y+rvTnXFKITkg84NlpfCbqPmsalKC8bKRR/Gp+PmrHevtdP9YcvsubfR+6SfwNgiYpHakZYRI1vR/Il/2H/vElomobFYiG+gSYRTUWrLMcSGUfhF6+iu8oMtx6QmhehKKgJ6egVpSSfPwXHJy/gLco23pegIf2LS2Npl3U94RQ8OZ70m171h4h87Hzxikbb0TUU4/Y1uQj8bM3Mn6MR05CbtAqR4Xaeve40vvxtJzNfmMTWP37nlbHp3LbsfU4ceekBe+UHi5rGZf2MW2h/zfPsfWMyzkqv//VCh5FSWJSX7X/NF6pJOucW/4ZkynmT0bxehKL6Uw2FRcWe1BGXY0+QbG1xvsNvTHWPu8rTvQqp67gDBKfqir0r1jA8BVmkjH+0+kVdQ1isOJb9F5DG+XUvqZc9gRqbhmK14XFkEp7Ssd6YuQ/fglYzM0bK0GiX16QpG5nN3Zg9EjANuUmrcvrALvz422aKlQLW77Uwujst8soPNbqnktQJ0/z/9hRkYVFV9AX3+18L3ED1hW58KoP17EUGydYGevSegr1GKEQIvCUO0DXDhQakRcXjyPR73gDJo+4kd+kzqLGpCIu1ao57scQk+58IdI/LP0Zd2xZS09C8Xipyg1UK3c5ChFBIu/QxHCtm+3PkjYNg/7xJKNYwkkfd6X9ZUPcTUnOMbGDzaR+Fjlx/d6aj0TNvsSEXQmQA84BUjK2cV6SUL7R0XJOjA0eRk8/W/Mqiy1NZn+3mpx3l/LF5cUi8ct8ffM10t9KCvBYbE3dJHpmv34leUYKnKDvgHYk9qSPS6+GXJy5GIquMZJWF1LwI1UrJzInonkrA8MQBNGcBWfPvI+mcuhcx3V1OyvjHUGNTAUHO2/fhWDYVrazI+IAARbGgVFVb+gqFpO/8QpDzzgPoFSUIi4peUQLAvlduRHpdoGvV16JrhsYLIAVYE9KNFMoqPPl7kZoXKSDng6fRK0pIGf8YQihYYpLxFmShJqST/abx5FE1PRJS2rU8ZBTQfNqHNSqhztzxo4VQeOReYLKUcp0QIhpYK4T4TEq5KQRjmxzhzFu+htHdFZKiVE7vrnJiRhgXvLGf96c/yJUPzGhRZovvD75multIRJqEhXZXP8++uXdiCzAq7tydxn+oKu0ufwJ7Ukcqcvf4wyf737jLMIC6l7SrpiKE8DnDeAuzyF38L/YtuA80zZ+DrXm9eN0u47QIhBAI1UbSyLso+Gw2ekUptugEPM4C4pNSKM53GKEdoQR4rlVeu7uctKumoljtQWGZ3IUPgkX1e+YoFnSvG3dpAXi9ZL85uWpBMNArSlBjU0k8dyLWhHSy50/BltSxesyqOQqLii2lS/C9MQk5LTbkUsr9wP6q/y4VQmwG0gHTkJs0yup1W9mX62LBhkDFECvq3o2sfvkBBl18N7GJyU0aq2Zs1Ker7es0fzCRUvclcxshCGkYYJ9XG4hiDcNbkoe3MMsvBQCgqDaU8BhU1XjN53VW5O7BZ0Il0jCoUkci0V1lpIx/FFtcGlpJDumde/DbzInGxqXQ2FdVAeotyDKO1TxAVThF81aPquugeVHjg/VxlPBodKlz3J2vBr2+fsYtJI6+C6h61qjKkQ+4IXjyM9GcBeyfa4RWvKX5WBRR7+akb0O5ON/BL49fhPSt4ZqGYrWhVO0BBOcVNY0jvdozpDFyIURn4DjgxzreuxG4EeDlKeO5cczJoTy1yWHKh1Mn1vues9zFvxY8Q2ank+g77IJGvfOaf5Ch6jZfl0641L24c3eArhkbkD5TKwTWpAyEomBNSMdTsBcQVZ8xMkYSR9xJ/vJp/nGqxwStrAhdUbBFJwbNwTDeMuAVEfT/ge/onkpSxz+KNSEdKSF38cM4PnkBvawQqet4C/eBYmizKFY7useFUCzkLv4XlsjqhhJS92KPiqWysuGQhWqz+6tWhW9eFhVbUkcskfG0u8aItO6deTWD7lsI1B0nz9q9k5Tx/yEFYxG0JqQDkP3mZP9Csu7Ji8l+58GgxhdgpHkW5e2pt+3ckV7tGTJDLoSIAt4F7pJSltR8X0r5CvAKAGumy5rvm7RtTrxlJo5SV63Xk6Lt/DT7toNyzqgIO1OvH8aKtduZ98oDDLp4EjEJSY0fGGLq0glfP+MWLKoVxRpGzoIpRkqfRUVzFmCJSiDI0CoWFKsRXxYWtcrAGn8CPmMF4C3OQSgKUuq4nYXsfPEKkPjHBpCaB0/BXr/BlLoXNG/Qaz4CQ/O13tCNkEtYUgfKs7f71RbbXf28/2Pu3J107N6nQc1xX0aO1LzoHhdS9+AtyEKoNqTUjQVG6kZVUyPoUg96CvHF5ANDOj7VxPq00Y9kY90QITHkQggrhhGfL6V8LxRjmrQtHKUu+t5QO/9346uTD/q5zzm+Gyf1Tudfbz/Nns4n0/e0MW1GsyXtfCP32+dB7p83iZTzJpO79JkmHR+4gSilxBKZQOLIOxCK1TDSioXchQ+ihMegV5SQv/w5tLIi1BhjQdMrShCqDTU2Bb0kp/YJpES6K2l39fN48jNxfPgM1uTOSM0wuOXZ2xuYneS3mRPRNS8/B1SICgRIGdQGrygqluw3J6NXlCJ1zT8/xRZes5i1xdSXXqg0YbE4UglF1ooA/gdsllJOa+zzJiYHgsvjZcEHK9Ct31A+7THCYpNQqrzU+uKcBzOf2FcJGl+VTuiLx9ujYin6/CW0skKyXr6+Dq0TaWRylOaTs/Ah1Jjq+L/mLEBNSAcJ1qQMdI8bxWrDEpVA6uVPk/XSP+qcS/7KWaT6m080jLDayZ43Cal7jUVACKSuo8amonsqg8S6kIbHn3bZU4SnBDdLznn7fspXPOdvHh0OVFaWEp7cgYq8TLxFOf7wzd4Z1dWdv82aSPLIO2tlEjXnO6kvpn009w8NhUd+MnAVsEEI8VvVa/dLKT8OwdgmhxmOIic3PfUWr9x3FYmxkSEbd97yNbQLcyEHjiFt8Ai2ff0harte7Pvho5A0HvZRVwWnJiUFT12KLao6HdISFlGnPnlF7m4kkHap0YxC6h6sCR0QQO6Ce4IkcQsduWRcW52pu2fORFIuegRvQVZQhoe3xEHu4n8hFIW0q6bhLczyZ4J48veS88797J83CVlZiispBb28uCquUjuCmTjiTqwJHfAU7MXx4TPERYUDRqhi45zJ5C24x/9ZV0keQlgQSm1Pty4dcmNPwnhq+/WFG0i7aiqeouyqdEmD7Dcno+sEyRL4qmoDkbrXv68A+DN4AgXBAjmSi32aQiiyVr4ltE9OJocx85avoTA7kzeWfcekK84OyZiOIifLvvqZfw+P4P++/xp5/Nkcc/al5G77nR25u0keez8d+wwKOuZA46J1VXC2u/xpvEU5QV7pvrl3IYXi/6wvZz3ng6cBUOMM4+UpyjbixYGebr1II9RStVEopTRSDRUF6a4AjIIdKYMrOo3XBUidx+cuM0Su3nsUr+bx23JP3i6QMiiU4wtP+Z5cwgHCqk2Ct1SgRiccUG9QWXUuIZSgzVWtrAjH8qlYE9Jpf8WTQZWjQur+f7uK8/wLiNQ18pcZD/tCsRxQHPxIr/Y0KztNQobP4M6+MIlblv3M1aNPDolX7ss17xJvYUwPwWdrV5IxdBwpPQZgi4qj7I8vKNRKiO83rOUXUQcCw0P0KSJqXo/hrSJqaXmrqhWv1xMsQ+vIROreWkqKRXnZQYZMKyvyG9xAQy11HW9pfp2esR/F4i+88T2JPDnxMjJ3bUeERaPGt0eoVrwF+4xMGl1DKy+hsKooKPAJxvdUIoXib/YMHFDDZ2tiBzyOTNS4VMOwK0rQU0ggHbr08D8NeZwW0i59DCAoFt/QxmtDxrq5T2eHW7qiachNmkRStL3Ojc2k6GpRJJ/B7ZViZ3T3ypB45b7FYdEl0ezPreSiAdEsXfI17uPPxhYRjVAsxA8eQ5xnP/s+nUXy0MuxRsa16Jw1UW12tIAemVm7tiEAJSIWzZdRISXuvEykrmGJjMdTVcCjxiSj2uy4HHtqCWHVNBauQo3cxf9CiYwPykBR41LRSvKQUkcvyUEgsCZWG1RLZDxpVzxD1kv/qDWmkDpaaT5ZL/0DoViq5hcHCKwJ6SSdcwvpnXsEGUDfU0nWrm3kfjTVX8zkcWTWe49qpmjqmuZfjBQluA1dzZZ362fcgsdZQFRUtP/+PHDNaP/9biqhNLCHW7qiachNmkRjKYaBBhdgwqBILlnUcq88sPJzfy4kRKpBXrmPlJ4Die/Yg61fvY0t/ZgDPl+TERbaTZgWkCKn48nfa1RIUp2N0lBIpa689yJnBe2ufi4ovO0p2EvO2/ejqlbSO/dgz1+bgwWyhMBbnIOUkt07tiJEoOEUDH7ofdY9eTFxySkUOnJJvaA6Dh7Y6zOwGcZvVRICWlkhe2cam5XGxq1EIJC6l1tHn+hXfyx05GKNTvIXX5Xn7PaPK3XdCDFVzVl3l/vTHH3iXC7HHpyfvxg0B9/TjttZCLoXW0wyul5d8RroqR/tmIbcJCQEGlyApCiV0d2VFnvlgZWf+/Od6FXKD175HiVb1uBxlqBaBJv35OLVJPQ8g8LMjeTv3cl9V51LWXEh0Qm1K0Prqyz0GRB3SV5VDjSU798OAvb8tdl4QRpx22CNFfyVksIaxv437gLwC1Np5UVYhPBv1DX0iC6E4t91yn77fr8mitS9rH1qPLpmeP2iyggrtoiq1MW4oMUFjCIcqN6crM/TLc53UOjIJe3SxxAfPI3UPLS79kUjrFR1Dd6iHAo/nkb/ibP96o8uxx6/AJg9qVotUY1LI3/5NDRnIX55AF0H3YvmLCB7wb2kXvIff8jKt6AEPg0E5pQ7lk+l/TXPs2fObf7XXTX2CY5mTENuEhLqLrWH9jlbW2TIG6r8hKpCpRVPk+UowRqQVRLdrgsxXY6h6McVTX5EdjpL/Y0dcj54mrSrppK75BEcy6chFAsIgeYsROqaoSGS2KHacZbGhqLUdbRShz/DxVVehD0mGXtKJ/peP5WNcyajVZb75W59lBbk4XZVgqKy77XqazbEqB4HzYPFapTu53zwNEnn/xNrXBre4hx/miDgX1yEUMhfOQupa/7Qha9H58Y5k2tpgutS97dm8xUfCaEEl93XQ3bmDr86oru0AAAlPAZhtaOER9NuwjSklHgLs6qOEDiWTUUvycFmt/u96h0BYwZ2aZKaB81ZwJ45t6GVFVY3q9A1XKlGU+8jZdPyQDENuUlIaMzgHix8IZ+uV06j7w21i3Ayf1rBvk9nk3zq5VgjYhsdz2dU8lUrQgjSLnvS//gPRraKqyTPiDMLpbrpDjoIgT02mZQx//SLVe1bYGidaJXlfiMe6Mn6WPvUeOzx7Yg79w5/aiHA/rl3AUZ3nyDFP82LpyALpERNSDcMumLBmtgBIRTcjj3oFaWkXvIfhMVqaKwIQTISx7JpZO3ahub1AMKQ3dU13KUFZL5+J1pZUVUcvZqcRQ+jVzrRK0qNJ5aqTVCpG9otPnVES1Q8SaMmY03K8D+V+DZ+vQgKVsxE91SiV5T4M3z2C4EtMsbImqnxPYDxJGSJSqi1Sbp7xgR/+b2vwYSPtropebAwDblJmyOUcgCKaqPPsPPZ9vUCbBnHEtfnlKD3A1vMNRmvER4wwhbVwWypawjFwv6lU0kaeRdCUbBExPm72DfWpKFqlBoZK94qzfHqTwjVTs6ih420RF33/z9CQXo9xkd1zZibRa0qLnKhWO148veilRX5pWd9cxbCghIejVZWhNS8eAqzA3LZJXqlk3YTpvnTMDNfvxM1LhVPwV40jwchJdLjqlJ29OB27EErK0IJiwq+Ot1r5MIXZ/tVI6XXbeSvhzXfHB2sTcnDLV3RNOQmbY5QywHYwqPoe87lZG9Zy74VL5E89DL/ez9/shDPjjU8et0ISl169QZbaQE5ix4m7fKnag+oqqRd9iS6140an47Pyma/OZmk0ZPIfudBCt+6g0olHMViJfN1Q/1PK3Vgi2lYyVFR7XVUg0L+ipnkV3Xd8bVqM4y4BSUyzhDvqighZ/49CHsECWfd7D9W9xiLopQ6akJ7hKKQfP495H34DCBpd+2LSK/hWXuLc1BjU9n3yg3YUroYoRVf7D8g9m6MBygq6BqKajNK8RUVNT4doVoNjRXwZ/Dg02YXGNrnVVkwvtTMqKRubUZT/HDz5k1DbnLUkNb7eBI69WLb1wtwl5VQWlTAn1+/z7+GRTD5+3DCRtxORAcj46Uid09VK7S6CUvqQEXuHhSrIQ7ly8iISOuGHQ+90iLZm3YaEadc7TeAmS9cFhCS8PqzL/I+fsEf2gg04r68cYuqIr0u2l83AzAMs7c4B8eyqSSNnow1oQNS9+ItyPJrs+QufNAw9IGaNAFeveOT59ErilHCY/whGmNwDW9xNlLXyZx+BZbIeLSyQkDUiN2XkvXStVUpjbpfW0XYqySDNa+xX1BeZIxfdX4Z0NHIF67ypWbeN+Ntnpx4WS1PuCDXqA6tubl5NGur1MQ05CZHBPXludsUWefryRGCBf++gTM7aXSuKjRasP07XFWhAKl78JbmkznjSoTEnyEipI7AMD5S9yK9bqSUSAQg0MqLSbB6+PfIjtz+0Y/oFReihFc9jitG+EKNS0VQJf8K6O5KUi95lPxPXvDnbIORmqeVFxtxdkmQIRXWsCAjLRQVFAtqbGqVwJbh2UrNa8TPMTYvrYkdDANbkmecu6LE8LgVi9HdJ95oCadGJwGSdlc+y/75U6pK+9ODminvmXMbqmrFXVoQpJoovW7jc8JwvvM/ecE/F72ipGo+dQug1uUJ1ydH7Apoen20YxpykyOC5sbOHUVOxk56jvJSna92urloQAxLl6wjbvhV/k1Rb2rdbcl8KXxZu7ZhtdnxuF1V3XAsuP5YwdjeFjonhTGmZylL/vwS+4mXGAcKsEfFBumZgJGaaIQcLEHG2tfCLWPCM7hdLr/krZSS7PlTqqVsq5pFoHnxFu7zHyc1L45lU/3l8XpZoRFH17ykjje0YBzLpvqrPj35NZpgCOFfbHzn9bhd/px1vaIEN0Za4d6ZE/yeudS8RnMMTcMWn+bfI/ClEVoTO+DNzwo6VWCz6UCioqIbjFe3lVBMa2MacpODJnQVqnP4csT3O0roemW1wGZLtNDnLV/D2N4qk06N5cUvMpm7JodzOttYue5jkk65rN7jfLnmRtaHF4/bZehle91IXcP215eMPc0KUnJhvwiWvrcCZ0pvY9NPQtyZ1bFrX0HL2qfGY7FaybgmWDx039y78DgLSMvo6l80ACNNsQY+jRZrQgfU6CQSR08id+GDJI2eDFVCsjkLHwIMY2t0AhJ+I1+PgwxULShSGqGbKtSEdJTwGJLOvweQWBM7kP3G3aRd8Qyegqw6dcyFooCisv/1O9DKi/wVn4pQkLq33k3Lhtry1RWKgba7KXmwMA25yUERuoLg7JOK0mLSrKX0m/AMGe1TGjTANcMkvhzxyKT29L3h3/7XW6KFHpj3nuVwoUSEU+oswBr3ZYOG3OksJSypA/nLphkVh1Uqg1LXsWrljOwsiAu348nPJBoYne5i7qfTaHfzXIRiCeo2LzUvuaoVXdPIXfY8aZc/GXQuzd+KDf+i4UfXDNtb5YX7QiOGR16A48NnkFI3PHKMvG5fHNvfzEi1otgjyX5zstGjs6ywKgwkEFY7WonDEAfTvEZIRkp/r0/F6vPUpZEKmbcbb2k+WS/fYMTZU9vVUocMS+pAxtVTcTn24Pr8xSADfaAStIfbpuTBwjTkRzkHS+gKqrNP3GUl7FzwEE+NSub25eXkFJU3eFxNI19fjnhLCMx79y049vAoysrK2PjMxdhjk4mJjQs6xueN+9qM+Yp+LGERhOPG49jNh3ujeX+XN6BQKAxRYRSxSF1Dqygh7app+MLbVpud8uztOJZVV2Rmv30/0l2OVl6MlLqxKSql0QWoqsenkTqok7PoIYRiMVq0CZ+meQdSLvpXkOpg7sKH/LF6EaB9knbp47jzM1FjU8mZfw+JI+/0b97mLHzIX+AjqxYs3WM8DQRl1lisRKR0xB6bjCUswt+nVCgqrpI89sy5DcUaRvIoI3snUBYgVBxuIleh5qg25IcipNASDsX86hO6CuW5c9Z9xvndJe1EIed3tzH/17J6P9ta38n+vEL0Ko0SKSXl+/dQ7MjmyYmX+Q2B01lK2qWPBRfmUJUfHqZS4rFQ5gmvOTSaotHl9nnsmn4VWlkR2W9OCnpfqDa0siJ/AY3mLCBl/GMIIchb+jT2pI5GbDpAStcSEUvKmCnsm38fSngMqVcYxTXZ86eQOv4xI27uKxAyrgrp670ZZhh06XUbC44QeAuy8JY6qsIvYImMw5rYgdRL/sPe2deRM/8ef/WoXlGCJSoBodqxJXUMynvXKstJu/Qxf7GTT943+50HcX3+ov9zDYU+fIVTgL8i1XdMfUb5cBO5CjVHtSE/WCGFUHGw59eQ0NW85WvIydrNWROf47MZdx+wUXWXlVC+5WsuGCFRdRcX9LCy5Jcy8ovL6hyzJdd8oIuAo9SFJTqJztc+F/R6/k/LyPt5MeWlJURExzQ+kMXiTxH0oXvc7HvleuPtqAQSR03CltQR3eNGCMMj3zPnNoRi8VcuZr5+p6FH7nWjWMPYN/cuvF4PekUptuiqp4HIGNI79zBCM5WlhvcNRshFMyo2AXLevh/prkDqOhbVii519EonWS9dV5WZYqCVFWKNS0MrzUMRCikX3ONfsNToRNpd87zfYOcvn0a7q58Pan5RE58B9yE1jUJHrl9ky1eJWZdx9lW/AkEVsEeLUT4QjlpDfjBDCqHAUeRk6Zc/8cBJFh5f9dNBmV99Qlezlqxi1Y+/M7STjZVbCpj17ioeuq55MUxHkZMiRw5ZPy7n/O6SWFFOepyKVlTO+b0szFqyit+27Q0yui39TpqzCATG77McJWgSdr42CcUeTqcrHgcgostAwrd+wpZ3HiFqwKhmXX9j5C5+2GgWIYQRJpG6oSEiNRBVGuaah4RzbsOiqmheIwMlcfQk8j5+ASrLWT/jFiOOLiU5ix5Cej0IizVoU1KvdJJ21VSjq5A9DABN09i34D4sAfrmGqBIDQ1Dd8UXkxcYIXV/KEXXQDGya7wlDoSq1too1TweNK+HiLRu1S8qFjpNnFdLmmDHnNt5cuJlFOc7qiVwdc1Y3FQ7iedO9OfbFzpyg56QGsK3kNTVUu5IDLUctYb8YGhnh5J5y9dwWrqbTtEap7V3H5T51Sd05ZXruLCXhdVby3lhZDgTV37PreOGN9uodorysP+Pb3jb4+T9tS6i7ApOl06ZW5KWs44E1RV0XfV9J03RQm/uIpBTVA7RyfQeewd6TjkeHWxJGex/4+6gz1ksFmbfcgaLvl7Hc/t2kVReipa9I+gz7uI8opJ6kp+7v97z+TrNg1FhqbsraH/1c1CliyIQhKd0ZNeMq6uLcwT+lEOtKBthUbEndUR3V9Lh+pl43S7cBXuxJhja5FkvX29salYdA1RnpSDQNM1vRHMtVqICSuILnQJdWFDCY/A6C8ld/C9jrrqO1LxGeqHmRVjU6qpSi4XUS59AjU01en9WpUViUUH3BjWkaAins5Tj7qk2rlm7tqHEpJI9fwoRadWaK9aohCanG2qahj2pI9aohKCQy5Hq1R+VhvxgaWeHCp83/vQpGp3iVUZ28XJPE7zy5oYW6hK6chQ5uWTKCwjdw+geKkM6WDkjo7xRrzzw3FJKln31M4+fGcUtywrQdXh9XCTx4QqFFToTPqggNkxh9vnVRtd3TF3fSVNSDOtaBCaMOqne++Eud5JuKSFn7UrocEo9o1ZzyanHcKVqx/3XGsI6H0dE1xP87wmLhftmvM3NIwbVDjdII6MlvXMP8lUrimIxcqh1zW/Y0Y3NUV+RkSUiDktsCt6CrGqpXM2Lt8Th3zR1OfYYolcSw3D65qLaq3PMhZE77i3cV704VBGbmFQrD1v3VNJuwjQ8BVlYkzohFAXd4yJ7/hTSrnjGkCAYNQmE8MfSDU0XqvPpfbu4itqkhhQmoeGoNOQHSzs7VPi88c7xFsJUhc7xliZ55aGIqc9bvoZhGbBqaxmLLorAqgiuO87GFR827JUHnhtgdHeFkQPTuHpfNhtyNE7t287/2eN+yuLYVDe9UhL8Rtd3zIF8J/UtzGUud533w1HkxK6V8fiozty+/Gu0pIFgi6pn9GosQuLes4HyP78nz+NGjYo3BKd8aXZCBCkXQnVjiR1zbsfjLECgIxSjX6YvL1yvahgBkK1YUKxh5Cy4B2+Jw58yKKWRq93hyqfZ+eIV/gYTWCxBTSYSz51oFPhYrCAg+41JAV55MIEbhOtn3IIW0NNTah5kdYjbGE+xUPDFK0h3pd8r9xUcWeyRpFz8CMIW4W+uYanK7tGchQQNFkLuOH8IXl2ie9zkP3FR9RtSYo9N8Te6CORIzHA5Kg35wdLODhWf/bSZP7aVsmyTgqKArkNeuU6/4s31zi9UMf/V67byx/YSxnSH3HKN3HINIeCsTlqdRtVR5OTaR9+gqLCAORcm8Y8PfsSiCN691NgcHNUd3vq1goEvZqNaFLyaTklpBfeebBhOn9G1h0eRV9Dwd1LfE0ddC/OwDHh35fcsvDyJG5f+xJfrtvLGw9eSGBvJkBunMaqHoF20hRFddBb8+Q3WY87ClbMDb6mDHdOvAUBRBMd2qt4QbJcc70+DdDmL2fr1UiK6D8Hx1ZsASK+H3OkX4wlPCkrxQ9eqmyIvfNjYcNQ1yv0hGkl25g6/dGvyqDuxJ3Vk1/Sr/KXvvs3R+tB9nYjqMdqBreOyM3dQ6DDusy/+7PV6quesWPx54j7BLX8jZE9l9canrlUJZKlkzzMycdIue4L9bxi5577N26apPlZjsVhwF2ShOQuDjrWERVCcvy8o5u32ekm79Mla/UR3vngF/SfOrnP8IzHD5ag05K2lnd1UzjqxD2ellzPp1Gr97GlfF0N6n3qPCVXM/8OpEzl/8gy+yXHwzceB76i099Ze6OYtX4Nj327SYqz0Skkk2erg2FSL36gO6ZnGxKHFkH48k644m2nzV0LWWob0NK7N53mT3qfR+db3xFHXwlxQWsG4XoJeKXZOSy/kzXV/0W/CM1js4VBSwNgzIvAU53B+Z/jwi1+xnjQed1kJHVPi2PFWdXqgo8jJuHtf4pX7rgqaiz0qlmNHTmDfH99TXpBDRVkpcdERdInysM3pwauGoWleI//aYuGWkScYoRSLhdRL/oNj2TRDwxv8PT0bInBzFAl7thmdkqTm8WeTGB14qj1fIRSEPbzKQxYIAa4ko92bIfq1m9yPjIIhXxcin4FuKUII/zV5nAUIqbN7xgQUoQRppNRVZu+rZLVFJ9QyxmufGh9khIuevx5rUsZRH745Kg15W6epTww+D/XJWy8Macy/qQudL5b/8KkqT33rIr9Mo9Lt5fVfylm2XaAo1V6gb+4H+jRU3xOHkX3iBqrTAzVNQ5Vl3HNWBh6vzsguGp9uFuSrYXjCExiXkU9SQiwiPIZYLYtRaQW8MfcO3BoM6BIsM1szZFST9v3+juPbhaydcy9qZRGPXtqdG9/ajvWK59BVO0K1+bvIZ8+fAoBQrFjCY8ieP8WvS+JxFuBKSgmuhqzaCIXq7BMhBNkL7qvqWqSilRWghFdde1XsumZTCDUmBa00j4zO3bhvxttVIlRT+eXJ8dW9M/P3krf0KdTYNLwFe2v1GvV3CpK+4iCMsv3CLEDiLXWw96XrjH6hUiM8pZM/XOSq0XS6JnWV2RfnO5C6t9brNatF60Mgjip9FtOQt0Gaakh9RuaeGYvrTSOsmeIXSnyx/OPaqYzpJXnj5yI+ualT1dPD8XUa5gN9Gqq3cCmgenTLB9PpPfYOctau5LSi90mKUsnOL6FzvIWxfVQ+3eNk0948VhYK3tmYg4hw4y2vICw6noS0VCyu0qCN1ZqLR1x4dJ3ZM6lxEfRPtZDbDj76vYAR3S0s/+NTrAPH1Hs96VcY5fi+dLx1T14MgC4l++bf549B53/8AtLrQq8oqdrErGpgYQ0j7Ypn2D/vbtKueBZvsSH1mvXSdQCGaBWGNxwTFU5UYrcG47/WxA4oYVHkLJiCtyQPpWoDVdeMTdmsWdf4m1B48jONuLzF6m+cnJjSroaRdPsNaWO6J82JSze1lF8oSr2Lx4HKAbRlTEN+mBJoZM58eSc7YiJ44et84qIjKCotJzE2El3UTvEL9fmfOBmyS7ycmC6Y8EEh89Z7UC1KSPcbGsoy8pGz7jOSy7eTs3YlhTs3sGifh2/255BXWEJyhIJX1/FIyeX9rfzjtI7875cy3twgcUWkM2SiEV6oaaRrLh6k967zmnyZPo8Ni8LtrWTmj160XR+ip/QGxULld/OIHPF/1emHeqCGiscQ4JIS+5l3kOKtek9K8lfOxFuUQ+r4R/0t3XxkvzkZUSUTGxg7t0TG037c/dV9MBsSnRICd+4OfMVDCWfeCAhyFz0c5L1XYEOrLMftLDSuQdeQGPMMbJzcHIN8JG44tiamIT8MqGuTL9DI3H1aIt84YijO3UdsSirFufsYPnQwq378ndmjD07Bk+/8nZMiKC4pJS0xmolDo/2eeGBsub7zNjVdsqEsI6iuHp0+KpXbl39N7yseY9v8R7hyRD/IWsukU2P5euN+7v/SxXUDbchKJ2N7SD5am0OuVre32JwUVd/8TuqdCkBCeDb3f6vw5VevEdXtBLrIvezb8oW/qXEwAktMKkIoKDGpCCkNSdm83bS78ln2zroGW0oXv1BVUMjDSH/BarPjRSCEQFWtQf0uG8IWFY9QrP40QZ+OuC0mKcjI+ho1b5wz2YirL34EKbUg9cL0Tl1qn6AGgca70JFL2qWPAdUqkND8DUfFFsa+1yYGqSkCqEr9O8OHWxu3pmAa8sOAmpt8NY3MZQMimDVzOzMuTGXie9tZem0Hrlj4PeP6RRy0gqfV67ayN7uS51aXkBCuUFBRTnJ8DB2qPPGmpELOfnc1e3ZsazRHvaG4Ohje+Jgegq5JYYzpUcFna1fWOm5XdimXH2tDCNA9FSQInWuPs/HiDyWsf+kuLBZLUIFRc1JUa84vy+HEGpWAqrup/O0jxg2L49X1q5C6FSUsmpyFD2GPNWLxrpI8LBFxRiNn1Yb0uBFCIf/TGYbnq+v+DUi3Y49hrGNTa90joSh4CrJwlziC5GOF1GuVwvsMmcdZ4G+OARBo+nz64IWO3KD2d2mXP01YUodapfNN8aIDs0V+eeIi/0ar5izEp4Quve5a2iqBC0BgBaiQOnHJaWALJyotpcme/JHo8ZuGvI1T1ybfvOVrGNEViooKiQtPRHgruLyfystriri8n0q86uKMDA9UNRw4GAVPH06d6M9AmXRqbFBc3FHkZOaiz3jubDt3vL2SF5b97n/89mmIO4qcvPvZ9zw5zMZ9jVSO1hdXdxQ56X7Jf7DIVVx0saFEeNGAaD5YtIqC/EJen/kv/5jtR9/L4s1uFm/2InVJhFUSZRMkRQhuGD2gUePso66QUc35+cr/PfuzufZYHaU8nxSPm+xiC7psD7rmr6rUyqykXHCP36j5kF4X7a6dzv7Xbze0WbxukOAt3IunIAutrIjMGVeCprF7xgTA8IwVAYPuXVjrXgV6oD5D9uTEy8hc8ohfzdGXZaNYw/BqHpyVXkRYNNIaTvoVT5L5+p119hM9IITFv9HqduzxN2Le99pEv7H3zbmhdMGGNlGPJkxD3sapa5Nv9bqtbNlZyotfVRIWVk6ly018mMDldTNrZAz5JU6uG2jj9k/LuPUU7aAUPDUmuDW6h0Kfnp252FHIZ5ahZAwdB1THoWe/u5ozMjwM7xrOGTsrDkjPZd7yNcTb3IxILSCivJLKcogARqSV81GJJ+h69y17yj/vS6a8wKJLokmKUnE4vXUuci1JUfUtVCdc+QhXD+tOQqTKwJ6VXD5/H6nnXEvhd+/4DVCTN+8salXhj6Bj9z54U2tuLhoUOnLZOGeyPxzSENUZLIaRzNq1zS+UtWfObbS/5nk8bpc/26Yl+CSAfd691LVGc+NNmk5IDLkQ4lzgBcACzJFS1tF63KS51GcsX3rwBm5+7FVmj05l/AIHE46PIVLVwV1OuygLBWVedAkDUmHw9L0kRBvSqk0prmkqjQluPTLEqBC8aEA0S5d8jfv4s7FFRPvP/e5n3zP/fBthqlJn5Whj8/Pdm26Jdt7f4ubbHKOAR9cleYVeeiXbWfZVbQN9qKp65y1fw5jeFhIijfP0SA3j+iFxLNqwgorCXCrLywiLqJ6XYouoKqTRAIlWVoQndydCtQc3PS4vxpuS5jfiNT3VrF3byF8W3GmoJQiMBhg+rRipe4M2OJtKTQngXdOvQrHa0D3uRo5sGkf75mmLDbkQwgLMBM4C9gI/CyE+lFJuaunYRzv1GR1fumGvFDtnddJ4/ZcSKlxeFHSmfm8I/1ssCinx0fTrllSnd9lYDNtXsSmR/orIQBoS3JrQ30p8eHXZuCjLY92r9zLoBmN993njPZOM8umeSWotPZfG5ue7N5NODU53rBnuaUrxEIR2kfOd56eNHt74dQN2VfHn1Hulg24d0vn9jQdJOelioqKiyXznQaxRCViEALUq7c+iYrFasYWF4S5z+3O3JZJCRy75+zMRFivOKg/Xhy4sNKe3fODGX2DTDMVqKCWqNjtqlYRAvmrFoqpB6oUHjC9HXjcWLn+c/gBd9COxWrM5hMIjPxH4S0q5A0AI8Q4wBjANeQupy+jouiSvKJ9X7zY8m3vOas/awlIWP3tXk41OU8r5fRWbRZWyTmNaX+jh/MkzWLDBwbOrSrFGZeOqKCNCeki15fHr/+4n3Grh3VXrKC/x8tXuag+qpFISsX8dt1w4LKjk/5ZlPzN66EAmv7DYv6jUJ7B10oCevLzkM766pUPQ64HX15SQSeAi0pDwVkP49hCWffYVo886rdb9k1Iy9/OvOGVwf77WNcrLg7smFTolFovFaNRw1VS/BorHkWmoJE6fQMrFjwSpA2bNvw9vwV5AVG9QOgtB9yIUS51yroHe6gPXjCbinLvRNC2otZzX6yE7cweWsAijQURSStBcm5rtYbFY/NWeSlgU1rg0PAVZQLXujKXOzJ7m42tOEdiYwjfXwD2CI8WLD8VdSwcC62P3AkNqfkgIcSNwI8DLU8Zz45iTa37EpAZ1GR2fx9mS0EDNuHvNwqHAis3Hv3Hz/hc/MnroQO6b9V6jBs03565XTqPH5f/irzfvJ0l6OTYZ1u7PZZ8zko49U9kngjfNYuzQPiWhVsn/6O6V3DNjcdCiAobAFsC41zN55ZL2jO6ucMvT8xjdDfBUANYm35u6lBt9i1x9wls1CdQ3B6O6VJTmMGt0BP+tI8QjhODas/pzTl4xD5XnknrSJXQZ8Hf/+09OvIysBQ/g1Tx4CvaCovqP8wb27gxAd5eTMv4x0DUsVZ69T8c8MLcc6vdUffKvlY69eItykEj0ihIy35yCEiAQ1pixq2kkCx252DXNn2pYFBVL3oJ78DgLUIRCXtW4Quq1CokOJF3Q15wiMLsmO3MHmfPv8xt2XwpkYPpjQ/emLXPINjullK8ArwCwZnoDPbtNGqKlgl91xd3PnPM9dkXzdwMKrNi8sLfkmyzDmBbn7mvygpEUbWf9y5PoHV3KyR0UvtqtMe0sO9d+WMbrdYRqfHMbN/l57jzRwuQVTrbluRnVK4xZ325n+ogw/6ISFR1DXoGLGWuKiFPdDJ6+l5gIO/vySvi83MKiTTkkx1f4wxmN3Zu6lBt7pdgZllHuF95qLBffV2HqI/ObdzlL+4aMGGeDi0n75FjmTDyD11eu4qt5XzH44juwh0f4NyKdld6gXG/wCVkZPTSDGjJLiUCgVIU/Ns6ZjMtZjF5RSu7SZ/H9Yoweo7XxhXkkIkD21pDhFYqFsKQO9L1+KhvnTKZw1/ZaG7WBxr1mqGP9jFuwJ3X0e+S+zdimZJ6EyjvWNC1In7zmnA5nQmHIs4CMgH93qHrtqONQ9Jv8cOrEFp2nZtw9NkzhjAwPG/Ig31nAs/NX8P3aTTx9ikZihJUJA2x88GcZmVl/8fZV6dz/RbBBC9R7CfTYP37yai6Y9By6S8GuKlzQWzA43cKYXgpT56/kiVvHBs3LUeTk7Nuf5/QOlfzp0OgYqzDloxyGdo1gfF8LPRIEF/a28sXuCvYXCN55/NaqDd8IbllWzvAhA4jM31ArFbI+aurUzL7QUEnUpeT9yw1BL6F7OCPDQ7dEa5Axbuz++wqULrooBsqdjaZ/CiG47pwBnJNXxEOvP0DaKePp0v9v/ve1SicV7z9C5LmTsITHBB3rLcrx/7fUNUPPvEq5UKssp92EaUG9PqG6x2hNAhcPX6s1j9vl14sp/Hiaf9zAvpw+GvJkLWER7Jt7l19TxsfhXITTlmjOvkh9/Az0EEJ0EULYgEuBD0Mw7mFHYwJLbeE8q9dtZcEGFyfMzOWEmbn0nbaXD7d42Jzj5oWR4bzzyfcMbV9J53gLVkWQFKkwuodC70TBmp0VQRWVvrnkZO3m7DueIzdrj/+9WUtWk5VbwPDOFlbt9HL1ABuqAtcNtPLuZ2vILw5uwDz73dWIigKc5S5Wbvcwc2QYv+wpY/o3BZzdxYKuSyYMsLG3sBKtLJ9Jzy/0e86npuu8sPALRvc2NugmDIpk2Vc/1zpHXfcwcOP4tHQ3SdZKf1riqr/KuO44G44iZ9CYjd1/X4GSL2OlZiVqfaQnx/G/28+gW+4XfDPvKX/OtvbXt3Ry/YVnw6dBnxeKoXUSntKRgs9m+xUMNU0ja9c2vF5PtcBVC5G6F3dpAetn3IK7tADN6yVr1zayM3c0fjCGB95/4mziqwS0fP8LlbftC7/4/udxFhxQds3hSos9cimlVwgxEViBkX74mpRyY4tn1kZoqvd7qHqABp6nps52UwiMu/tyqoenhxEpXAzpYCVcKeO1n728/kvVhyR4NA23BlI4eevKdL936Ysnn9DeStlfJZzUMdaf8vfeqrVUenRm/FjJ5ceqZJUYRsmiwDmdZVCGii8dccbIcCYur2BcHzuD0sM4JrmSHokWusQrJEUoaFLjjC4KJS7Jl1t3MOfczgBUVFbQMVqy8LcSHjo7ucHYuKPIyTWPzqW0uIiZYxK54PXtPH298UAZqJ1eUu5iTHdDx6S0vJIeiTGM7q4wc/EqVv/0e4Pfc+HODSwscbHwj2w8zlLSk5oW4gHDO//HuQM5J7eQ9xdnI8PisW1ezgMjwrjzkwXs+XEpdm8ZurCTs+ghbFFGIZSn1FBBtCWko1ZtHNYtCVA/vlxvKY0G0Mb3LxH2SBLOuAFLVDztr3mezNfvxJqQjrUJ8ruHipoLwgPXjA5Nds1hQkhi5FLKj4GPG/3gYUhTu+4cqh6ggec5Lb2QxRt219kBJ3Dx+XN3Dufe+QIrp99Fj4yUoLF83YDeuSgcTdN49bwILlxcyXev3kuPjBSmzV/JN19/RXFZJWf3jqrlXQ7LgPd+c/LiuWE8uMrJWcckMHPxKhIiVRaO78xps/bw3haNpdvcqOg43TpRNoXovHVBqYZnddKID1M5raOCo9zLpjwP5V54d5OHJVs0I59ZSiJUIypwaV8reCpwOAXf7apk2tlhXPNhIe9u0VAtxoNmXYZz3vI1bN+xm4uPDSfJpnJ5P5Vlm5xMSrEHaaevXre1hia7EWH26muZMMDW4Pfcf8Ij/v/e+OpkfnlzEs2lQ0o8SQlxeGPSyCgrpGu3zoz/WxHvZCaTXPArZYMuJemUy/yfXz/jFnRhIXfBPf7XNGdhlcwsQQbX4ywgKimgMXIVTmcp6Vc8idvl8vcKlVKS/eZkanVYbiK+7JHAc9eUDDgY1LVB6tNh93EkhXvMys4GaKqXfah6gAaex+PVGdFF4+1fPSxa+X3QuXzhDt/m5eTnFxFvKefu5xaybFr1jzuwG1BOqUa21PnwTy9dYiVTpi/m/WduY8WPm9m2r4LpI+zc/km1umHi3s14Kp0MSXFzRheFv3VQGdldw6V5eGfFGq47PoquCVauONaKxRbOextKOauryp8OneE9olmVZSG/uIwz/28OhfszmTc2HK8uufY4K7d9XMmlLguzzoth3rYoPrMMJXXQWexc8BBvXhTDfUu28ul2nTc35KCqVi7oaSElRuXifmG0639Kg12U3vviRxLDJSO7aJSUVXJOd5Wr3q++LjAWgJoZQ4Ge/IRBkbW+56Y0iG4ucREqhZnrmHSWnf8u28KxSWDdl8nD50Yw5afP8AwaiTWiuvlI8qg7g7zQ9TNuwRLQRs6HK6l+XRJfUwdfOmB1howIKgxqLNvbZ0grA8SxoFog62BnhtR1fb5MGt+5wwHCVKKSGpb4PRwwDXkDNNXLPpTVgr7zZOeXkBwB5/dS+XK3s5ag1tBONlZuKeDR/y1j07YdLBoXziXv7mBbZq7fK/d1A/pqfx5LNpUQYxc4XRqzRkUw6bNd5BeXcc6QPpzToZxRg2L50xlceOPc8TOL1pXQPgpKXZKrB1i5cFEJNh1Gdoskv9jJdcfZuGWZkzO7CL7d7eHtcZHcsaKM4b3ieGPZd2TnFnDl4FTadYynIn8fQvNwfHsr580vxqoqWKOsiJgNAP648wsjozm2ayr/+ayQ9zaW88C5qSRFqdyTXHe5feD9S7ZWMrSzlc7xFrCG0bNjChMdjW+OBnnydXzPTWkQ3VyuGtYHssq5aEgsJ3cr5vrFeXSOU+gQa2FkWj7zX74ZNdrotuNxFtSKBzc179tn4AoduYakrtdb1YZOYlGtyMpS8pY8QlhSB9I796AoKtbv+Qd6s4Hj+gxjWwpxHO7GuiFMQ14PzfGyA1MCdV2SX1xGYmykXwkwVPjO88av+8nJL0FVIDFCIdep89/5Kznv1IF89PVvDMuA1VvLeWFkOBPe+5HzeyoMam9hfF8LE59ZwIrpd/nH/HDqRP4zZxkfrPiKc3pFUFlexnGdYrjpJPzx4Lrugc+b7xQBlV546jsXV/a3EmaRHJuiMHlZAY8MC+P4dCsjeyh8us3D6Z1VNF1nQCq8/ksJ/Qq34nVVsPAPKwv/yMbYe7cjpRWvXkBkXDv63/w8AOvnPVIr7uxr59aUBdT3fdo9Xhb84eWt9W7yykv9aYoNxa99x6bHKLz+S2m93Y9Cje/7fuv3HLLziwmzwFNn2Jj5k4uRJ3Tku2KNq556k6jYeB64ZnQt+dq+109tUnqfL1XQl47nw5eDnSsUdKmjVZb7C43AWCiiwlRTuKoNYBryemiOlx34GF5dzXdyyP+4fecZO2UmVq+TjBgL718Wzdi3S8ks0bhr2kIqykoYkuLm+DQ4NsXCeT0EMXbD6Izvq/LyGzv4adMuTjymMwB/7s7hxUVf0DUW3ltfwhtjwigodnL5wBSGv2qESOq6Bx9Oncg5d7zAtp27q8IuLj7LspJT6GZTvkb7KMG4hWW0i7Hg8ui4vJKZI63YrQrXD4nj9xK4/9pRnH3HC/Q6fxKZ3yyi99g7QEp+fe0BMmIFjnKn/9oD486fP3Ed4TKG0spy3lrv4a31fwGgCEG7xOh6Y+O+kn7/d9WENMWaxzb1mFDg+759+xRD03VO7WplaM9wPt7hJF4vZ82Hb3L2VXeEXGPb63b5M1O8mofUSx6tesfw0gGy33mQ5M61Y+1NwSeTW9d8j2TP+WBhGvJ6OJDCm4OZuRKY9/zHnzuZeqaNJ7918/HWSrKdGg+fauPOFTsZf1w8n2wq5aWRdrKKPVw/yMYdn1biKNP5YodGz0SFq//9GpsX/geASc8vomO0JDZM8PcOFvqlWthdrKO7y7Hj5tWfSli4MVjYyHcPaoZdnAnH8tPmXZQWF3H/YBe3LCvDrUSQU1bCFf2sCGGIWqmykhFdw7nl6TfpHg9/ffA8HcIryFm7Eq/HRTq5HJ+u8vmuMr594gpiEpKDwwYWNaj4xtfmjdI8fnnzn3XevwP9Pn1x8XcvNfK3D9b+R33U/yQRg1eXbFs2n97HnxQS4+fb/AOjLF+vKMUWnYAAvxRAYKVkQ7H2xtClflRro4Qa05DXw4HImNYVUz9QrY66xvblPV82IIITM+Divgqv/gYX9w3jxAwrF/SWzP25kPF9FHonK+ws1FEEHJui0Gemkyib4MURYUz8pJj84jKklGzetpPXzgvj+o8q+CtfY/k2DxKo9FbQLjmW3inVoluB2TB1hZ6GvrwGvG4uPjaCcwa0Y2JxMd84YlC0Cr7ZK/lmr7FxVlIp0RQXJWUuPr48gosW53LrGR15/JtV6K4yXh8ZwQOfl9EvNZz8Mi8X19AL73plsLqfr81bVnntsgjfnOurJm3snjcUFz8UXnljTxJSSl5a/gnf/bqaEy+6Hau9aZurNbv1ZO3aRtyZN/s3I30qiv0nzg4KpzSX+p4UGmuifCTpoBwKTEPeBJqSS+73xkdFMO71TJ4clcLNy36mrLJpWh2NnX/ZVz/zxLnxXLlgO/eMi6KgQqdXErz4QzmTh0RSUKFzaf8wlm5xsmybxndZlRSWa5R7pL/aekxvle4JChf0Upk6fyXhditj+6ic1DmM6wdpVGqCr/dIXrq4PTcvK68lxOVbTGYuXsUHX/3G2ID4NIBFqyTaBiO7aHg1nQmDInl5xi7CIyKMBPIqypyllLvc3HyClV5JCmN7W3jjm0w6CBjQycLxaWGc3lnlw62VPHVWGE+t+qleDziwzdtN83f59ydqzrmuRbWh7zVUcfH6Uj+bSmNPEkIIbhk9iJHZBfxrzr10PP0qMvoManTcvTu3+TdKpcTf2EIoKmm3zWj2POujPqPbmA770a5m2FxMQ94EmpJL7vOclm92UljmZtkmJyO6Krz26Ro+uCq5RaEW39hrdhmdgDonRZCWGMOnu/OZMFCje1oMaYkxeLw6Y/tUEhcVwUPnpOBwejl5ZiZndJKs2ePlhkE2eiZauPEEGxcs+hZdlyy7LAIhda4eYOWK9yoZ3sXGsk1ORndXg643MGx0wZtriMTF67+oLP3T6EJUUFpB5yjJ2d1UOsdbcBQ5SUuM4aaTEmrFlDtc8hSxSh43nRhJicvD+L5WPthSQawdLukbRrhNxaa6ObOrwoA0C6e1d9d774PavPW21DvnW+pYVBv6Xn059r/vVbjxpCQiuww+oIX43plLSFAr/OmczaWpT4ad0hJ4/Y4zmL18OWt+Xc3gcbc16J1LofjL8Csde/1VpNnv3MeOObfXyrk2aduEokT/iCbQGDRU9r163Vbm/VbBjO8KmXySjRnfFfLSDyXYcVeFWhov0W7o/BMGRbL6rzKWbdUYPDOHQdNzeParIv73q4cTZ+f5y+0/+tPLz5mGJnlsmMK5XSTrszX+3sHCw6tcZDt1OscpdIzSGd1doEvJ5jwvueWSfikKL/5YwbNfFbFgg4vV67b65+FrL7c7uwBXeTnTRseRkRhNWkoSCx6/lc4pMditNpZs1jl7npM+0/bT//n9tcYBqCwp4PJjVRLDJE63ZGCahQt6W9EldIoVrNnt4tO/PEzobyW/TGNUd1j21c9s3ZPLuHtfQtM0IEDTZIAR3rmwj41Zi1Zy7p0v+kvpfaGuEV1hwadrmH1hEu998SPn3vki73/xY53fqy/f/L3fCihwukHz+D/jayrdUPm/jz9357Bhy3ZevyCSDVu2sy0zt9Fj6vr+m3o+IQS3jh7Ew2cl8eOce8nc/GuTzhGW1MFf6q8oFh6fu4z4pBS/sJUvdr5v7l1kv/Ogvwz+cCycOVIxPfJGaGoueWAPy1GDYtlUUshra8v4/CajQq6hTbKGHvEDs2c+vN5IDasvc+L8yTPYl+tgnwtOmJlLSVkleHVKXDo7C3VSowSnzi0jxq6wt1hjW4HOB1uNpslG2MDOCcfEExFuDwo/XPGv/7F+ayZLLovl3585GdtHJUGtZGg7wbsbd/v1SiYMSuemxfsZmB7GxxuLSeuY5vdCA69R87h5/VfB/9ZWEmmFKJvA6ZYUVEgGzymnwqNz2bE2rFYLVlXl2IwURuwr5Jw7nqNDtEDVwtj46mQqSou5uHsltpIiKsqtJIRB52gNx/7dtVInR3aD+b+4SIpUSbZWkrm/iIz4ML9UbuD3Om/5GmJEOdkujRkjI3h4dXXeO9BkrfJ7Zy7hgl4WHviiAqvQuGvaOyx/7o5m//6aG5rr0i6R128/nVnLPmLNr6sYfNFt/gKfplJakBfUxNmHqoiQpBseiZ3sWxPTkDdAc3LJa37WZzgCO54UFRYxa8kqHvpHcHywoT/WljQB9hn24twSVIvGv4bZueOTSvY5dSYcZ+fWIZF8tNMetCj40icDww/5+/cQpWq88XMROwp15pwfRqlb5+zOsHqH5McNO9idEOWXlV2zq4I5Y8KZtHKXf1P17NufJ5Jy3lj2HfHtOtLj8n/5KzWj9GJ27SvkyvcruG7Maaxc9S3vb9H4yWFBUQByKXZWUFlRySn94vhmnyA+3o43MYFPd+7n/U3lhNntOCtc2CySF0fYueeT7/jHYKMvp8ero2qVXHGslVnf5pPvdPHwUJVnvneRX6YxYVAkFyz4kVXrtjH34WtY8eNm1u+t4OYTrERaJf1TjLz3HrlGNesT58Zz0ZufkVfsrPd7O/baaRTu3832cIiwCqSEXzZup/+1z7H+9bv9v5mmtLM7kCwoRVGYeP7x7NiXzyOv3EPnM68ho/fAJh0LEJ2Q3OQY9YFsTJoblqHFNOQN0Jxc8sDPOpxeJi8r4G/pwt8zs6C0gjjVy7tfrg0y5I39sbakCXBgHjJZaxkzOJatZcaTwgPnppEUpTLK5uKMVz7jvFMHEh8dETSX0UMHsvTLn/jXUCuPfq2zZJOHm0+wkRShABJNl1XSsoLMCgsZSdE8fipM/LCQv/Vqz01OJ7OWrGLJl2tRXcWc0juaZV/9jKbZ/LHt+HCBy1HKb9kaXWJhycrvmDM2jmsX5XPOyQN48tYLcRQ5OfPmJ3n9vCgeXlVOrM2KY99uRp55Kq4KJ7NHp3LBm3mkWVVO7wR9UyyoegWv/iRZuNFd9WTiJiZM4NU9XN7PwsA0C6d11Hnj5yImDUsk2VpJ9j5Dt+bk/t3I2beHi46xoaBz+cAI1pfaOGVANyLzN7BmVwUdojTe/uR7VtzQvs7vbf/+bI5NVNhTrPPE6Xae/M5NuUdjT1a1wnNT29m1RL+na/tE5t5xBjM/Wmp45+NuxWqzowilTsErRTQ/2nowNiZNj715mIa8AZrjDQd+1jDaOluLbfTrlsFrD13DJVNe8GtnB2ZWNOWPtalZM3V9prEnheWbnWREadw57W2yHaWM7SX8c7lnxmJOS3czuIOVC3prTPteY/k2Lyu2a7i8kqJKSUqUikeH0soyTm9nI1axcskxCq/9WMC1J8ZzxitrKCwt460LI3jk63KG97Kxe30FWd++x1vCy5trsrArOhZFcHoXC5FWSFQrueY4K//75Hv+74pz/D0+UyOsnN1NYe66Cp4bEc69K9dwWhc7Z7+0B4ui4wbu/lskTrfk1fPDufe7cN6bejfX/ud19uU68Go6JaVOTmynUFghOaOLheuXFfLary7Ky8p5/pwwnvn8B3JLKriun4qqSDrGWPir0M2ZHVXe/HQNr1+YwNVv5/LKeWHctryCuDClzsXd43axKVdy7XE2+qdZGN1D5bMdsHa/O+h7qW8Bb+xpsGZHIh9J0fZacgGKonD7mBPYnuXg31XeeXqnLjg/f7HW8emdutT5+zrUmB578zANeQM0xxsOzLUONNqvP3wtbyz7rk5j3dTQTVOzZur6TM2nChsehndW/F11SkqdTB9h54YPd9EuSoBmFL5cNiCCWTO3c/OIMGLtFs7vpbJoo4eXRofTMU5FSo35G7y4RAQr/nSi64KxvSzE2uHKY1WufL+Eq46PY1gHDxtzFQa1UxjVw0K55qFTnJXFr/4LKSVn3vwk53R0E2mFVTu9PHeuFVXo3HS8lYV/lPOf15bxxZrfSLV7yC+3cHonhXfWG5uiw9PdrNpaSVK4JKtUcsPxNtJjFHKcEtWCP9sl8MnEvfsnEiPL6BZvQSnUuPHvCfxYFM+xYTn0StL4e0oFi/Mqee1XeG2dJMYuKKqUVGiVJEdZePSzPM7pppAUDlf2t/LSt7ncdmpqre8tLDKGJLWcMb2sJEUoXNHfysd/eYm2CbZl5vLR1781uIDX9zToa8uXU1Tuly8IpC7hLh/d0pOYe8cZzPhoKaedfKLfOzc5/DENeYipqx/m52t+49lhHrxadJCxbkropilx0oY+U/dTRST9uiUxbFBPyFrLkJ6RRNt28tw5dh75uoxbT9EQ3grG97Xww14vp3VScLokLk0y5p0yQCAwtLq9upveSYJzuqmkRgkKK4yk9YGpgkHP7wZdo3uCgkURXN5P5Yr3qzcOyyrdHJfo4oMtXi7vpzK6p0q3eIWsUp2EcIUr+1t5/tMf6JcicHvhsx1exvRSufgYlbm/uhmcrvDBFjdLLo7g3PllLNnkZekWJxLILdNxa4IhRZv993L1uq38/mchc9ZoxIUZBrpSdxFhLeKeC+x0ilcZ3c3Nko1Q4dF5a2w4CREWStySy5eUUyltbNhfxj1/C0cCl/ZTufL9CiaeJmp1EBJuJ2P6Wukcr2C3QHKEYEwvKyu3e/xSCg0t4PXp9+hiHQmqC3d50/506/Pco2wCLX8PXc++lvSe/Zs0lknbxTTkIaS+fphndhHEqtKfW+37o29K6KYpoZeGPlPfU4XvyWHRJdHM+6WY83paiAuDAakwePpevF4vHo8XtwavrPPg9uqkRws0KTipf3d/y7lLprxAnqOAZVu9fLXLS2GlYcgrveDSBFf1t3Lj8Va25Rspg4GCWTv2OcjKcXPNQBtf7dZwlEveXO+h3GOMEW1X0HSNbfkK00cYG7WvrXMTF24hMULwW7aXK461ckyKwk3H2/gpS2PWmFh6ZKQw9vUssks8nD2kjz/sdP+1o7jy/ul8c10M7aIs7HdqHP9SCSO7W+gUp4DU6ZVs5aJjJL/uczOko53dRTpDuqRy57BS5v7mYkRHNwkRxkJW7ILB6RaOeWYH6UkxfpG0ecvXEBcmefN3N2/85kLKajVvXUpk7g7+OTy5wQW8Lv2e4UMHs+rH35k9OolzXsnCXV6KLSLaL1HQe2ztjJiavUR9bHx1MnPvOJ3pH77H9+u+ZPC4W1GtNv/7Zoz68MI05CGkLg/7zI4a89ZW8NlWlYKK8iC1vcZCN00JvTQ1PFMzhu6bK8CyjSXMHxdBYZmXf5xoCFoFVnXWFS7yXe+wDFhVoTBvjJ2kcMFfBTpXvV/BZf1UXvrFzZJNHlbt0iio0AmzKgjVTr9uHfhw6kT6XfovVAVWbvdSUCnRJSjCKG7QpCTSJrBZBOf3UhnRK5yL9+gs/MONo0LiUsIpL3PyynlGe7cbBll5a4OHMYs82KzZlJRWMHt0JE9/VV0IdMvTb3J5P5V2UYZuS7soIxS0cIObL3Z4UYQEBPtLNSq98LdXSyn3AOpeosLtZOYUsaxUsGSTh7gwgaNCEhlux2aBK0eeHOT5l3os6EijGYZVEmUTJEUIZp4Xy2VLSoM0bLyazv6CMo7rubnO/RHf09b4Bd8zrl8EvVLsjOlt4au1K8kYOs4vUZCzdmWzfq+KonDnBYPZtjePR1++hy7nXEeHHscCzYtRm0a/9TENeQipy8MuKYP2sVZ+m9y13vzv+jYqmxJ6aWpmTc0Yum+uM9YUMaY7OJxeLEIivJWM7h5R5zlqevw+KdvzukJhhaSgXKIqcGonCx5dEh8uGN5Z5ZpBdq5fWk65tDKgSwe/N69pHiafEs7Y3jY+3BXO/A0eFHSy84vRddhfqhFmFYw/xsruQg93DLHzfaaXv3WJ5Iu9Ni7q4SE9xoqma6RFKVxxrJVP9tm56ty/QdZazhkQy/rCQn917dkv7ebVXPjfr0Y1KhIqPTpX9Ldxw/FWuiTY2FuiM3FZGU6PZNQxMfyUWUmRHsnJx/fl01XfMa63sSF7+xAb/1xZyQfbdD6/uWNQSCtwgfalgAKUAFctk6hhUUEaNj6P++whfWr9pnz3vmuClTMyPKAZcx/Xx8Ynq77G2efvfomC25d/jaY11vKhNj06JDP3jtN5cem7fL9uFYMvvDnIO28Mc2Oy9TENeQipq6uML3wBzd/MbEropSmfqSuG7ptrYGOJhHCFgopKkuMVf5jAUeRk6Zc/1Rnj9zWmeP/PnbzzRzmRViNu7vJCjF0wsoeKLgVrsu2kRbnIdqt+b37WktXYpYvrj4vCKyUju0k+2aEyfMgA1v30PcVllRS6FIZ1EsSEC1weHacLjktTmPtzKVIIXs2VvPKLEf9VBOgSXJqDpat+4pXzIhn3eiaTTo7wFwL94+/JfLBV8tmMu0mMjWTa/JXM+2Alq3ZpzN/gJi6sApfXWIxePi+Cez4vIdoGSTEW3lnxI+d2EXz6l4d3LgrHq8OlfVU+31FJUqRaK0buW5ib+tRV1/5G4NOWr0nH7Z8YexjJUSoj0vKZ/+o/uaKfoL0sY0RaJcv2HJgwm6Io3DV2MFszc3n05Xvodu4/SO/e74DGMjn0mIb8INLSzcymZM005TO+eSRGWGoVJQVWpE46NbbWU8O85Ws4Ld1NrKrVivFPuuLsoAVhz/5cSkqdzBpl5/ZPyvlwiwevFGTsL2bu2CjGLXIy/NapLHnyZt5esYbrjrWSFKng0SXFBZWc3dnO/5Z/R/twD6+cF8kZc0tYvFGw6A83cWFQUC6xKBAdpjDwmO5s2bYLVWjYFZ1KL1zU187SrTqntXezfLM0NG82GnH0N34uQugaoqKEWe+u4pYLh7Hsq5/55PoMXvxyL99nQk45hFkVzuhsdOE5raNChRc+31WBhpWVuy2M6S4o9SiUFEGkTXB5f2PsCSfEBm1iN7Uas6H9jcDfz7bCSoSo3sNIiA7Hq9mJUEoY18dwFMb1sbF0SwmdLnuW1LiIA+pa1DMjhS1btvDxl9fh0RXssYn+VFVTebDtYhryg0hzNjO7Jlg5Pt4Z1F2+KTSWY/7n7hymLfiML29qz6zvCskpdfPmx99x60XD/SX4DcXYP/tpM39sK2XpRkGe00lyQjlWVamVS+9bELTMn+mVXMnFx1iZv8FDWqRAQeeOj53E23XKXIXcM2Mxdtws3ChZuNEIFZRUSsq9ZZS7vNw4IIJeSRbu/HsY//2ugsv62bj7b1ae/8HNL/s0thfprP1jG6nRKrmlGqN6qKzJ1NiR72Fvkcb/ftawq/D82Xbu+KScuHAL7WIkLq/OCyPDmbjye5AwurtCQYmT7/Z4efW8cC5ZXI4G3DQ4DLvNyo2D4fZPXFw7JJHILoNZvW4rX+3P4735ZdisFoTmISZM0D6mjEnDEv3pgat+/L1J1ZiN3fvavx8VUOnXLcl/v3f/+gXtOhoSt+2AiwcX8pllKI4tawAOqJdovtPNSZNfwenYx1/fryD+hPOISOtmKg+2YUxDfhBpzmZmfrGTcb3g5pXfc+u44U0uxW7M+7t35hIyojQW/lrM278W0z1BYXdxhd8rr+upYURXOOv25/hs+t2cdWIfzkov5/K+gmdX5bNDSa1Txc93LdPPglir4Ibjw/lgi5cnzgjjzk8rUBTIKxM8NyKcG5btJCUu0oiHVBFjh6KcEuLCBEPaCzbleeiVAOEqXHKMhQqv5M4hVoa94SElAjQJXh0u7K2yapfGE6fbuXNFJbcNTeZ3ZzxDk0rok+Zi7DFelv6lUFIIY7pDQrjgrE5Gha2qSJ7+oojxx6hUapJTO1n4I9dQAaysdNErxcboHhplVaJZi5+9izeWfceyz76iwGNDVYxcFJ+2DYBXruPCXhbuX57L8I5RTVLMrOuJbcKok7BaVVbM+Ge9v4XV67by8yYP7+/ODnpdxGzA14ajJb1Eo5LaM2DUBHb++Bm5f/2M9Okhm7Q5TEN+CGhsMzM2TGGHo4yB7W2ckVHRZK/c520vmZDK/V/U9v7+3J3Drxv/YubIMG5dXkS4KnlxRARXvFvBws9+5qF/jK5ng7aSikqX37ucPy6K4kIHd58UxrC524MaOPuu7+zbn2dsL4ENDwUVOvN+dXFxX5X4MAi3Ch4YauXez910ilO47vgI4noFt8JzFDkZesMTXN1XIzVapVP7ZN78LZMr+1uJtAkcZZKp37u5oJfK+lyN7YWSoiI3xyaqnN5FpW+KgkXAjG8dJEYU8+rZGSRFxfJAvJd1b5egS8kD58b6mzSvXVTKSw/ewM2PvcrDowxNlitlNpctdnL+Ig8W3UNMmBF/bx8jGd3T7hfiMrzt2nrtvj0RoXsoLKtWTazPK2/oiQ1oNDzz4dSJdL1yWr3phaFAKBa6/v1cSvOy+OW7xezfsZl2XWtvypq0LqYhPwQ0tpn50g/Ffi2QkkpJxP51TTLkPm97zc4KhmUonDXxOf9Gnu/9cX1UjusYw9jeXnYV6QxoF8bVx0le+8NDfnFZvRu0s0en+tPdhLeC2DBBWpSFy/upQdrajiInZ9/xPEplYZU+eTheTaGkVOO5s2z846MKLuhlpX20wrhjVOb96mJsv3Amf1EtUuVLh7TjZskmyWvrPLj0cspdXqwKzFnnQdcl6bEK6/ZLNAljeqks2+rh+yyND8bbWbLJS0qkQl6ZxtUnxFBUVEhceCJJUSqnpbvZkKORFJUIVHu+PtVGn0c8pGcaE4cWM+93N6oi/WmBXtXGgg0uvPpaJgywNViNOSwDVm0tY/boSG5ZXl38VJ9iZl34v4MQtAxsirxDU4hOTic5IY7w9W/z49oUThh7MxbVNB9tBVOP/CDTkJ75h1Mn8un0/6NDUjRr7ujML5O6seaOziREWBrVn/ZpXb86JpJlG0uocLkRFQXMendV0Pt3nxRGfrGTi45RKazUyS/XuXagHbs0PO7AeY679yVmv7fav/l2VieN134qZtD0bAbMKmbg7GKWbdX4ZeNO//xmLVlNSWE+z58XT+eUGFbM+CcTRp3CxKHJrC8MI0wVWC2CxAjBhX1s/LQfuqcnk2ytxFElUuW7R5/f1JFfJnXjq9s6YVUk8y+O5sI+Konh0CPRwhPD7XSMVRjTS8WlSYSAEd1VIq2wbKuXl0aFoSow49sChv+vkGOm7uWEmbnMXVfGD3sqOWFmrv9/Cza4+PXPTBZscNV6vWNaIr+8+QgTRp1C37QwJow6hU+n/x8JkSoTBhnGcMKgSJZ++ROjJ8/w34vV67Yyd20JA1JBk7q/+KmmHnvg/a7rew7eAA3WsW+OPrlvLJ8T0VKEEPzzoiFMOimCb1+awv6dW1o8pkloMJfUEFNf4Y3R3KDcH3uuKZrV3J6Q985cwuX9VPqlqAzrZOG9zaXMGGVs5N06brj//Q4xKgVllXSMFYzorvLst+VMOM7O8M5KkBLjvOVryMnazbu7Mvn8+lQA7jmrPZ/tzqFDikp5pYvR/eKYNCyRaV8X++O4Cz75jmsGqCTZXJyabuesic+REh9NtqOCouIS5p4fxgOrXAzvYiEuTGFAKhz33B6E7uHlMdE889XPlLncQfdAeI1OSL87rHy5s5TUSMHZ3VX6plo4rp3COxs8pEYrgGD5Ni9Lt3gZ28daVTZv5Y3fPQzpFEG5iOSD5yYdkCdaV3ehmt/TaeluFm/Y7f+unr3jYs649b/ccmp7eqbYeSDZy++LSv0pl4HU95RWX8tAn1de87iGNjMPVAa3sQ3SYzql8sbtyfz3/QX8uDaNEy640fTOWxnz7oeYmj0il331M/PHRfHX3jxGdFV5+bv8oPS/A+3uvmnrLv7vfCub8jzkl3s5raNCfJjgzI5ezrh1KrkFxeyOhI//KiG3VMOtSSyKgi4UPt9vZD+kJsYx7t6XePLWC1n21c+c0N6K7i4nqqoWJClK5eT2Xpb/6WLmqHBu/6SQees9qBYja8VZ4cYmK7lmYBhCSCoqyxEVlZw8fCCR9j7sX/8lKTEqJ3bQuHa5JCHaBthQLJWM6w0DO0Qyulgy78t1qEL334PcwlI0TafSW0C4xRCuunagSqRVMK6PlTWZGnllEpcGFgGqAhf2URFCcGEfKx/86aW80k1SjKVJKYB1hR9qZhMt+vwX7Cr+Oeq6JK+wlF7JNn8c3BfqWrbJyaQUe72LckMGtq6Wgb62e77fU+BxDW1mTpu/8oBkcJuyQWqxKNxz0RA27srhidn/pOfom2nfpVejx5kcHExDHkLq8+KEtwLN4wbdzfXH23jj0zX+9L8D0Ruft3wNN52UwMnHxOJwetmQl8n0EXYSY6O4drDG+5vyOK59BMtvqO65WFdVqa+i0BcrnvdTGQ6nl6XbdpMcb6TEFZTCxf3CGDUogz+d1WM4ipyc8o/HmdBXpX20hT3FGt/trOSFERHctmINMZHhvH95e5KiVL9nuvjZu3AUORl1+9NcPTCcqxfm8tyFHVj2l87iZyfX8hY7j7mXLpEuzu2hkhKh4NGha7zCOd1UNjlgaI9YNF2nsLiU7okqyVEqQrgZ18eKXRWs2evi/S9+bNQTrbn4XvPoXEqLi3j30hh/NtFnuz2smHG/f5yaufezlqxi09ZdTDvbHrTgQe1FuaHc8dXrtrJnf4VflfL2TwqJiY6iY9UGaFMNc3OaorSEvp1TeeP2JP77/lv8tK4dx48xvfPWwLzjIaTmH+i8L9eioPPc6hLi7FBQoZMapWIXWrObBAR6jTW1z8d0NyoqS8oqUXWNawdamflzOQNfzPYbE6i72vPFMYlc8Pp27rm8Pcs2KLx1YQwXvFPG20/cSnx0BJdMeYF7zqptDOYtX4Oqu1i0Uee9zV7yK3TO72kl1g6nZ3jZVVoJxDLu9UxeuaS93zP95vdtXN5P5fPtXlxeyeJ1+YzuHsXMxav4/a+9QV6xrkt+z9H4M1/nxR/cSIzqTVWBrgkKM74rpLRSx6pI3trgJUw1KkDtKvRMtDCml53Pd5fX2gQOpGbmT1mlm+07dnPxseH1ZhPVJ4525QlxjBoUH7Tg1fU9NmRga7YM9I01YdRJTaoSrvlbbG7I7kBQVQv3Xvw3/tiZzVMvTaHn6Jto19n0zg8loiW5oUKIZ4HzADewHbhWSlnU6IFrph9xCamB5fi+LkGXLCpl+JABhOX9zvmdK/nwTw8We2RVFWBprfS1hvB5z6PPOi3oDzFIyyOwE44UTLjg7Hr7SvqMxeV9BbO+K2CDw8LQDjDppDAe/rKMDd5ODB3QAy3zZ8Z299K5XSKqRfF79p/9tJn1f+4kIRxAUOaWvD4mjHZxYRRW6ly22IkuVBJsHnYXSTJSYmiXnMgff2USb9dxunSmjwjj1o8riI2JQbGoJFjdQdf36P+WUbL1O548P90It1Q6mb/BjcUexT9PT2ba19UZJgCZuSWEWTTeuCCchHCFUg9ctLCc9BgLl19wTp0GbOyUmWTv3s7Fx8WjofDa2jLSIzT+zHMTZrf5i35KKiURMXH89tbDQd44gMerc+/SPcRFRfDQOSn+776m8NhNT73FwB4diMzf4D8Wgp+WGvodNXRcTQJ/F4G0D9B4ORh4vRrPvvcz22U6J4y53vTOQ0habBjnDWhfp5hOS+/yZ8B9UkqvEOJp4D7gnhaOeVhSX2HNa5+uYcklkcRaBdcOtHPJkhKuHhzXLO/I58X5ekWed+pAfx53zYYWwQagWvmvLlmARZdEU1hYwNndVOb9VsYNAyPYlOfhnO4qCz/cRaXLy/bMUl78qpLw8ApiIg2lwfY5WzmpfzeOsWXx+Bnh/HtVOUmRFnql2MAaRs+OMVxzYiHvbSznxZExXLM4n3FnnEhkmI2z0stB94K7nFG9w7h6n84vFUlUljmZPTomKGb87qp15OdXsHTbXsoqXGiaji4llZqb+X9oqBaFjmlJtVraDetvGDuH00tq9G6ePy+eh+vI5/Zl9nxwaSR3fFLCo2fFMP8XFwsndGbmmhLe21jO59enBxnU/OKyWvsaxgLqpXdKpf+7r0vcrDA7k3czc1AVWe+eSH2e9LyqAqam7qUcTGPdEKpq4b5L/saGHdk89dI/6TX6ZtM7PwS0yJBLKQN1M38ALmrZdNoWzcnBra+wJsLixYaNggqjYjBQK6OhDc1AfH/ca3ZVkBGlMWX6Yl69/+o6s2PqWkg+uCrZ34PzvlnvMbBnB/9nk6JSiM4vYcJAL1tKIhg5yMi1vslRTFliN1wVTp44PYmL3sxh+Qu3+heQgVf+h/ISL1/tdrK70ItFwLQ1LixqGSnxlRSUVnBhT0GyzeXfF+jULpVshxH/fXNsmH/ReG3xLu48LTko9jth1EkkRFhYeEkn/vGBE2IjeODESu78pIJom+CCM0+slWtf8zswwk4KqeFeRne311o4AzN/RvWwsGxjSZAuyxkZHuLCFf/99Bnn+ppc7ynXSX1kO+0SIv0bwoGdoOorJGrsdwQELViHA8d2TeONick8++6b/LQugxPGXI9isTR+oMkB0aLQStBAQnwELJRSvlXP+zcCNwK8PGX88TeOOTkk5z2Y1BfOaCqheLz1F4eMiuCWJft4cUQYF7xTxsXnnsKPP631z62uc/kWEp+E7jeOGIpz95HnslJS6iQxNhJFEf4sER2F9KRof0eamJgorh1oB93L4l8LSevUjfefua2W9//oilw+2FDCBSNP98eQL5nyAtPPgkSrC1UIznzTybgRw4kMswWFJRxOL2e+tJv54xPomxFfZyhh7OtZdI/TuWaAhSuWlPHM2WFMWa3wxcv312sQ6wtR+Iyoo8jJydf8m9fOtxIfruBwakx439Bl6RhvpO1syXWDavM/iTT23dX3e2lIlOxo4Pft+3nmo030Pu8W0jr1aO3pHLY0FFpp1JALIT4H0up46wEp5dKqzzwAnABcKJuyMhwGMfKazRSaE88OJT4j4AtHTDopjAe/KOOtP2RVB/e651bTkP2Z42LU/zJZem0HLlrgIC0Czjt7WJ0GZdr8lbz36SqcHoWFlyUFLSCfzLyXj77+DeeOn/l9r5MnR6Vy8+Is/jPcxsSV8MXL9/PGsu/QMn/m/M6VdE2wYFUEz35XwWt/KHRql4qjsNB/LsNr1rl1SKTf2392dSGvrS3jm5uMn90Fr+3hieEqX+7SKXPpXDfIxpxfvcT1ObXeCtiacWwIjinXfH9bZi6zfixj6V8KCdHh/mOauujW93tpbEE5WvB4NZ5Z8hO7LB054fx/mN75AdCiGLmU8syG3hdCXAOMBs5okhE/TGhKi7VDQWA6mi8ccXZXCx9sqailg13X/H3G47K3sri0rwreCuzSxaNn1B039oUBhnay4XZV8OHGEkb3UOmVZOG87gp3T1uIogj+2F5CnOrmtNl7uLSvxS9G5Wtht2VnKa+uMTZefdgRnD2kT63N2m9yHHzzIUB1zDnC4iUpSmXa6nxO76wQHy74YLObl0aFYVVgfF8LN35av8BYzRBFzS48DfUyPdCU0Lp+L4cye6QtY1UtPHDp3/l9+36env1Pjjn/VlI7dm/taR0xtDRr5VxgGnCalDKvyQe2cY+8rXlRgd6jx6uzY29OoxkwgaGWvOJyLJqLuRdE8OkOnTi7YGR3hWV7IrB1OrHOMMDqrcVszHahScn8cRHE2KCkUueqD9x8Outebn7sVZ443c6VC/bx7cROpMVYg+7Ttf95/YDDSoFzz3KUIjUvbk1yZX8r/xluZ0+x0RZu/kZJTM9T+G3b3kb3MVoaJmuIhn4vLbkPB4tQ6a8cKB6vxtNLfmSPpTPHn3+d6Z03kRaFVhpCCPEXYAfyq176QUp5c6MHtnFD3thjeUs4kD+i+lIM28dY+fD6jg3OzVHk5KTrHuf8rl7G9bVx/5duFoy1Gx5qpZV7v7Gx+Nm7kFJy7aNvUFRYwPuXx/pj30XOch4/rwO79+XRKU7hgS8q+NObwentnKB7KSop5daTE0hLjGnRfWrsvhibq0X+VEBf7NorFRJUV4MG+kDDZE39rg7m7+VgcDAXtebw21/7eXbZJvqMmUhqRtdWm8fhwkFLP5RSHpHPRgdSNt9UmtM9xkd9PSADdbDrm9u85WvwuCtZuFHnzfVuLu1nJa9Mw6IIwvAwoqvdL6jk2LebtBirXyXw58xKtuR6WbJ5N3ZFVhlRnSLXDuaO6sJ17+xjV4GX6T/uJyPZaLbQ0FwO9L44ipwkRFj4/JrOQR6vT4Z29uiGtUR8qoRN0Qhv6pwCOZi/l1BzoPorB4OB3dsxd2IKTy3+H7+s68qg0deY3vkBErKslWbRxj3yg8Wh3kB1FDm5YNJzWFzFvHJeBGfMLUHHaFEWG6b4PdtuGe1wVTi55/hKbllWRkx0lL8i1KvpVJRX8N3EDJKiVDZmFnLFwgK+uKUziZEWpq3OD8poOdB5NnRf6vN4v3HEMDSppMFsEN/Yw9M9rNpWyvAe0azKsjZ67xubU2uHJw6UtppB8+u2ffx3+RaOuWAiKR26tPZ02iQNeeSmjO0hpCF50lDw5+4culxwP9syc/3nS7ZWMqaXlV5JFu4+KYxjkhQmHB/rl8ztkBTNSQO6Mbq7wjkD2jFxaDITRp3CL28+4pdyveL4OG5avJ/8Mg0bHoZ3Vhg8fS8DX8xmxneFPHianU1bdwVJqzZHbrWx+7J63dZacrNv/V7JLxt3BsnKBsoE+2V5311taIT/ZWiEr/qrjOEdafTeNzanUMrDHip83nh996w1Oa5He16/7VS071/llw9fQ9f11p7SYYVpyA8Rzf0jaq7uNBgFLglqBVOmLwZgxY+b+X1fBUM6GK3TBrcT/FWg8d3OCsDIoBiWAe+u/L7eefk0tnfmVzJ4+l4u+xC+yYmkX7cMLjz9ROLCLPytV3tuOikhyKg1Zuh817d1T26j9+XDqRP9C4vvf1eOPJm7T0usMxsk8Pzvfrm2yRrhgXNraE4Nacw3Rl3f64F81wdCQxk0bQGbVeXhy07mxn5evpr1T/L27mztKR02mIb8ENHcP6Lmeny+cvPXL4hkwxajHds5Q/owcWgyJx/TgWO6tKddnJ2xx9jYWgQDX8wm9ZHt/O/nYs7qpNU7r9ceuobOKTG8PaGjv3HEL28+wmsPXcPbK9YQa9ONLvIBxq4phs53fTW79DTVuNTlpS/Y4GL1uq1B548Ns5CeEMUD52ZwTJf2PHBuBp1TYurUCA+cW0NzasmTle+6Zy5e5Tfeh8q7b+ietSWO75nO3NtOxfPdq6z96HXTO28CZoz8ENGcKs8DiaWPnTKTY9Xd/Of0SL/olabJes85bFDPWk2E65pXfTHV/8xZxnufrmLhRZHc+FE50WEqQ7pEE9llsDFAA3HYwOsbPnsvmsRf1t7QfWkqgXN++ONsNuRoLLqqHbuz8+ncLpEXvyttMDbc0Hf12kPXHHBqauB1X/BmHmkRcPqpJ7Hqx99bvfCsrfLzn1k898mf9Bt7O8npnVt7Oq3KwRTNMmkizTFKdRWX1KdiCNXe+KzrogC45cQwhr62nU9m3hvUJNlHcE/I+o1HQ5Kr761ay/DOCi6Pl4Gp8OGfFWzKl/TK24yrwtmg3Grg9Q3pGEZ2iYeLR50Skk0335x9zTxGdpO88UsZvZ7dg8ft9ot/NZRR0tB35WvWcCAFPr7rToyw+IuyJn5s9EVt7cKztsrgXunM7ZrKE4teZm1EL44bNQFFMQMJNTHvSBujvvjs7PdW1/v47RN/ahdlpG61C2iSXBdNDQ3UF2KYuXgVCZEq1w+Jw6YKLu5rJT3WSnpCFCf179ZgWCLw+hxOLwVOFw+fqrJ01U8hiRH75uxr5pEUqXLRMVZ0XfL5LZ3okBTNihn/PGBv/0DDE4HXPe+XYq441kqSzcUZGR7QPEDb2nxsS9isKo9ccQrX9XHz1ax/4ti3u7Wn1OYwPfI2Rl3G07chufDyunN/f/0zk5/cHv73a1HQWFZbZq3xm9M5pr4y9+S4n7l6oA1VqyTSJoi0Csb2Vvk2q5J3G5FbDby+aavzGdPLynHtVE5r7w6JN7p63Vb2Zlfy3OoSEsIFuU4nEVZBuAW6JVpbXB5/oAuA77oBlm0sYdFFEbi8GuP7Wrj3izJuPUU7asv3m8qJvdN5vWsKTyx6ibVRvThupOmd+zBj5G2MuuKzBaUVjOsleHZsw1WcTaElVYi+isACj43yigqkx0WlVychXKAIhbQYKy5rTINxXt/1eTXdrx8TH65Q6lG471t7SGLE/5mzjA9WfMVbl8SzYF0R7272sOSSSBJjo1DtEa0it+C7bp9I2A3H2/F6dSQw93dPkFhXa5bvHy78uHkvz6/YRv9xd5DUrmNrT+eQcNBK9A8Y05A3mVDrvhyotG7gRt2NS8vQpeTsThqRwsXtf7OzNsvDM9/rHNcxisgug5u0KDS0oAQW3Egpm1x84yhyMvSGJ0i1ufh7B4UrjrVy5XsVfDohmuJKSbeMVP9mZ0P7DgeL1urccyTicnt4bNGPOKJ7M3DEVUe8d25udh5mBBqxUKvntTQ00CvFzmnphWzI0fg5U2NfiYcFf7jZX6KREin4LVenX2H9G4m+ayuvcJFXUH9Ze82UvKbKGsxashq7dDFjRBi3Li9nbG8rw7tYOGlOCaqigLrXv9nZnHFDhWmsQ4fdZuXRK0/hh817eXH2FPpfeCeJ7TJae1qtgmnI2yCBRqwt6HjUjKuP6g5v/VphlPLbw/BqOnark6fOjuTptWGN5mgXZmc2KnLlywO/celP6FIypx5tkJql8r5sGl1KBqZZGLWgDJuqoGMhPT7a7/kGZ+60ruaIScv4W58ODOyaymOLZrE7tg/HjbgKIep0XI9YTEPexqgpatSSWG6o9EBqPhUM6ZnGxKG1mzScMyCWjcXF9Xq4TRVsqsv775WSWGd6XuCiN2HUSSREqjxwrqEL83A7L3+U1R2Gait68yahIcxu5bGrTmHNpkxmzPonA8bdRUJah9ae1iHjyA4qHYaEUo8lVBWDTamibIr0QFOuLXA8j1dnZBeNAqeL/DKt0VL52e+tblKVaFvWHDFpGScdk8FrN59CyZcz+PWTtziCet00iGnI2xChNDAt0QOpSV1aJ7+8+QgfTp3YZOmBpl5b4Hj5xU46x1sY08toiAxQVFjErCWrgj7rWxje/XJdk3K827rmiEnLCLNbeXzCUK7o6mT1rCnkZ2e19pQOOmZopQ0Ryo3NQxU6aGoMv6nXFjieryk0gI6bGT84iVO9vPvlWm4ZN6xWPvyyv0pZ/OzkRsNIbWHfweTgc3LfDAZ1T+WxhdPZE38sA8+9/IiNnZvph22IUKWmtbVWddDya6upPzN8yAAi8zccNl15TFqXb//Yw6wvdjLg4rtISGnf2tM5IMw88qOMw631WFOoKd4173d3g2JfJiY1qXC5efSdHylO7M+Acy477LxzM4/8KONICx3UJSuw7C/dVAo0aRbhdhtPXD2Ub/7YzUuz76X/RXcett55TUyP3OSg09I0yCPxCcOkdSmvdPPoOz9QkjyQAWdfelh452arN5MDIlSda1qaBtmaDREOVfcek0NLRJiNJ685lUsyClg96x4Kc/e39pRahBlaMamXpnaRb4hQdG1vzZh3KO6BSdvltP6dGdyzPf9+53l2pxzHgLPGHxbeeU1Mj9ykTkKVh36wG063hMa87VDm4pu0XSLCbDx9zalcnJ7Pqln3UJiX3dpTajamITepk1AY4LZeQdlYyKctL0ImoWfYgM7MufFvOD59jvWfLTqsqkJNQ25Si1AZ4LZcQdmYt93WFyGTg0NkuJ1nrj2VC9vlsXr2vRQ5clp7Sk3CNOQmtWjIADdn868td21vzNtuziJkbogeeQwf2JlXbxhC7sdTWf/54jbvnZubnSa1aCgPHZqu4d1WC3Oa0u6uObn45obokUlkuJ1nrzuNL3/byZyX7uO4SyYRl1i7mXlbwMwjN2kyNcvkD9eCnFDmpR8p98SkYZzlLv79zg+40ofQ7/QLWyWzxcwjNwkJR8rmXyhDPkfKPTFpmKgIwzs/P3kfq1+6j+L8vNaeUhAh8ciFEJOB/wLJUsraykg1MT3yw462KMTV2pj35OjEWe7ikbd/wJPxN/oOH3vIvPOD6pELITKAs4E9LR3LpO3SljNQWgvznhydREXY+e8/TmNU4l5Wv/xAm/DOQ7HZ+RwwBVgagrFM2ihHmhBXKDDvydHN2cd34++903nk7WfI7HQSfYdd0GpVoS0KrQghxgCnSynvFELsAk6oL7QihLgRuBHg5Snjj79xzMkHfF4TExOTtsSKtduZ90M2gy6eRExC0kE5R4v0yIUQnwNpdbz1AHA/cLaUsrgxQx6EGSM3aWOEqlG1ydFLaVkl/3r7B/TOJ9N32AUhH79FMXIp5ZlSyn41/wfsALoAv1cZ8Q7AOiFEXUbfxKRNE6pG1SZHL9GRYUy7fhjnxO5m9csPUFLYuE8bKg54s1NKuUFKmSKl7Cyl7AzsBQZJKQ8/xRmToxpTHMsklIwY3J3Z1xzH3g+e4o+vDs3WoZlHbnLUY+aCm4SamMhwnrthOOdE72L1yw9SWpR/UM8XMkNe5ZkfumcJE5MQYIpjmRxMRp7YnVlXD2T3e0+y8asPD9p5TI/c5KjGzAU3OdjERoXzwo3DOTNqx0Hzzk3RLJOjGjMX3ORQMXpID4b27cBD85/E0nMYxwwdHbKxTdEsExMTk0PMRz9s5Z21+Rw/fhLRcQlNOsYUzTIxMTFpQ5z3t57MnDCAXe89waZvl7d4PNOQm5iYmLQCcdERvHjjcIbbt7L6lQdxFhce8FimITcxMTFpRc7/e09mXjWAHUseY/OaTw5oDNOQm5iYmLQycdERTL/pdE5Tt/DVKw832zs3DbmJiYlJG2HMST2ZfuWxbF/8GFvWfNrk40xDbmJiYtKGiI+JYMbNp3OKZSNfvfovykqKGj3GNOQmJiYmbZCxJ/fmxSv6sn3xo/z5/YoGP2sachMTE5M2SkJMJNNvOp2TxB98+9bUej9nVnaamJiYtHEuPKU3Y6Pb1fu+6ZGbmJiYHAY01EbONOQmJiYmhzmmITcxMTE5zDENuYmJiclhTutsdkamtMppTUxMTA5bwuPrfat1ZGwPIUKIG6WUr7T2PNoS5j2pG/O+1Ma8J7Vpi/fkaAit3NjaE2iDmPekbsz7UhvzntSmzd2To8GQm5iYmBzRmIbcxMTE5DDnaDDkbSqW1UYw70ndmPelNuY9qU2buydH/GaniYmJyZHO0eCRm5iYmBzRmIbcxMTE5DDnqDHkQojbhRBbhBAbhRDPtPZ82gpCiMlCCCmESGrtubQ2Qohnq34j64UQ7wsh4lp7Tq2FEOJcIcSfQoi/hBD3tvZ8WhshRIYQYpUQYlOVDbmztecUyFFhyIUQw4ExwAApZV/gv608pTaBECIDOBvY09pzaSN8BvSTUvYHtgL3tfJ8WgUhhAWYCYwAjgEuE0Ic07qzanW8wGQp5THA34Db2tI9OSoMOXAL8JSU0gUgpcxt5fm0FZ4DpgDmjjcgpVwppfRW/fMHoENrzqcVORH4S0q5Q0rpBt7BcISOWqSU+6WU66r+uxTYDKS37qyqOVoMeU9gqBDiRyHEV0KIwa09odZGCDEGyJJS/t7ac2mjXAd80tqTaCXSgcyAf++lDRmt1kYI0Rk4Dvixlafi54jpECSE+BxIq+OtBzCuMwHjkWgwsEgI0VUe4bmXjdyT+zHCKkcVDd0TKeXSqs88gPEoPf9Qzs2k7SOEiALeBe6SUpa09nx8HDGGXEp5Zn3vCSFuAd6rMtw/CSF0IAnIO1Tzaw3quydCiGOBLsDvVV1HOgDrhBAnSimzD+EUDzkN/U4AhBDXAKOBM470hb4BsoCMgH93qHrtqEYIYcUw4vOllO+19nwCOVpCKx8AwwGEED0BG+BozQm1JlLKDVLKFCllZyllZ4xH50FHuhFvDCHEuRh7BudLKctbez6tyM9ADyFEFyGEDbgU+LCV59SqCMPj+R+wWUo5rbXnU5OjxZC/BnQVQvyBsXFz9VHsbZnUzwwgGvhMCPGbEOKl1p5Qa1C14TsRWIGxqbdISrmxdWfV6pwMXAWcXvXb+E0IMbK1J+XDLNE3MTExOcw5WjxyExMTkyMW05CbmJiYHOaYhtzExMTkMMc05CYmJiaHOaYhNzExMTnMMQ25iYmJyWGOachNTExMDnP+H3ncUOttxUDhAAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from mlxtend.plotting import plot_decision_regions\n",
"\n",
"# Affichage des données\n",
"plt.plot(x_train_unlab[y_train_unlab==0,0], x_train_unlab[y_train_unlab==0,1], 'b.')\n",
"plt.plot(x_train_unlab[y_train_unlab==1,0], x_train_unlab[y_train_unlab==1,1], 'r.')\n",
"\n",
"plt.plot(x_test[y_test==0,0], x_test[y_test==0,1], 'b+')\n",
"plt.plot(x_test[y_test==1,0], x_test[y_test==1,1], 'r+')\n",
"\n",
"plt.plot(x_train_lab[y_train_lab==0,0], x_train_lab[y_train_lab==0,1], 'b.', markersize=30)\n",
"plt.plot(x_train_lab[y_train_lab==1,0], x_train_lab[y_train_lab==1,1], 'r.', markersize=30)\n",
"\n",
"plt.show()\n",
"\n",
"#Affichage de la frontière de décision\n",
"plot_decision_regions(x_train_unlab, y_train_unlab, clf=model, legend=2)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "caF0geTEx5Zv"
},
"source": [
"### Dataset des 2 lunes"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GdFbVzKbMcYE"
},
"source": [
"**Travail à faire** : Mettez en place le même apprentissage pour le dataset des 2 lunes. "
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss : 0.6756, Acc : 0.7000, Test Acc : 0.7200\n",
"Epoch 1 : Loss : 0.6550, Acc : 0.9000, Test Acc : 0.7560\n",
"Epoch 2 : Loss : 0.6354, Acc : 0.9000, Test Acc : 0.7600\n",
"Epoch 3 : Loss : 0.6172, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 4 : Loss : 0.6000, Acc : 0.8000, Test Acc : 0.8120\n",
"Epoch 5 : Loss : 0.5837, Acc : 0.8000, Test Acc : 0.8200\n",
"Epoch 6 : Loss : 0.5677, Acc : 0.8000, Test Acc : 0.8280\n",
"Epoch 7 : Loss : 0.5520, Acc : 0.8000, Test Acc : 0.8360\n",
"Epoch 8 : Loss : 0.5363, Acc : 0.8000, Test Acc : 0.8360\n",
"Epoch 9 : Loss : 0.5205, Acc : 0.8000, Test Acc : 0.8360\n",
"Epoch 10 : Loss : 0.5050, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 11 : Loss : 0.4898, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 12 : Loss : 0.4749, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 13 : Loss : 0.4607, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 14 : Loss : 0.4475, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 15 : Loss : 0.4347, Acc : 0.8000, Test Acc : 0.8360\n",
"Epoch 16 : Loss : 0.4223, Acc : 0.8000, Test Acc : 0.8360\n",
"Epoch 17 : Loss : 0.4104, Acc : 0.8000, Test Acc : 0.8360\n",
"Epoch 18 : Loss : 0.3991, Acc : 0.8000, Test Acc : 0.8360\n",
"Epoch 19 : Loss : 0.3886, Acc : 0.8000, Test Acc : 0.8360\n",
"Epoch 20 : Loss : 0.3787, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 21 : Loss : 0.3694, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 22 : Loss : 0.3606, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 23 : Loss : 0.3523, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 24 : Loss : 0.3446, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 25 : Loss : 0.3374, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 26 : Loss : 0.3306, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 27 : Loss : 0.3242, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 28 : Loss : 0.3181, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 29 : Loss : 0.3125, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 30 : Loss : 0.3072, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 31 : Loss : 0.3021, Acc : 0.8000, Test Acc : 0.8440\n",
"Epoch 32 : Loss : 0.2972, Acc : 0.8000, Test Acc : 0.8520\n",
"Epoch 33 : Loss : 0.2924, Acc : 0.8000, Test Acc : 0.8520\n",
"Epoch 34 : Loss : 0.2878, Acc : 0.8000, Test Acc : 0.8560\n",
"Epoch 35 : Loss : 0.2834, Acc : 0.8000, Test Acc : 0.8560\n",
"Epoch 36 : Loss : 0.2790, Acc : 0.8000, Test Acc : 0.8560\n",
"Epoch 37 : Loss : 0.2747, Acc : 0.8000, Test Acc : 0.8560\n",
"Epoch 38 : Loss : 0.2705, Acc : 0.8000, Test Acc : 0.8560\n",
"Epoch 39 : Loss : 0.2664, Acc : 0.8000, Test Acc : 0.8560\n",
"Epoch 40 : Loss : 0.2623, Acc : 0.8000, Test Acc : 0.8600\n",
"Epoch 41 : Loss : 0.2583, Acc : 0.8000, Test Acc : 0.8640\n",
"Epoch 42 : Loss : 0.2544, Acc : 0.8000, Test Acc : 0.8680\n",
"Epoch 43 : Loss : 0.2506, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 44 : Loss : 0.2468, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 45 : Loss : 0.2431, Acc : 0.8000, Test Acc : 0.8880\n",
"Epoch 46 : Loss : 0.2394, Acc : 0.8000, Test Acc : 0.8880\n",
"Epoch 47 : Loss : 0.2362, Acc : 0.8000, Test Acc : 0.8880\n",
"Epoch 48 : Loss : 0.2334, Acc : 0.8000, Test Acc : 0.8880\n",
"Epoch 49 : Loss : 0.2306, Acc : 0.8000, Test Acc : 0.8880\n",
"Epoch 50 : Loss : 0.2281, Acc : 0.8000, Test Acc : 0.8920\n",
"Epoch 51 : Loss : 0.2258, Acc : 0.8000, Test Acc : 0.8960\n",
"Epoch 52 : Loss : 0.2237, Acc : 0.8000, Test Acc : 0.9080\n",
"Epoch 53 : Loss : 0.2215, Acc : 0.8000, Test Acc : 0.9040\n",
"Epoch 54 : Loss : 0.2194, Acc : 0.8000, Test Acc : 0.9040\n",
"Epoch 55 : Loss : 0.2174, Acc : 0.8000, Test Acc : 0.9080\n",
"Epoch 56 : Loss : 0.2154, Acc : 0.8000, Test Acc : 0.9080\n",
"Epoch 57 : Loss : 0.2134, Acc : 0.8000, Test Acc : 0.9080\n",
"Epoch 58 : Loss : 0.2115, Acc : 0.8000, Test Acc : 0.9120\n",
"Epoch 59 : Loss : 0.2096, Acc : 0.8000, Test Acc : 0.9120\n",
"Epoch 60 : Loss : 0.2078, Acc : 0.8000, Test Acc : 0.9120\n",
"Epoch 61 : Loss : 0.2061, Acc : 0.8000, Test Acc : 0.9120\n",
"Epoch 62 : Loss : 0.2044, Acc : 0.8000, Test Acc : 0.9120\n",
"Epoch 63 : Loss : 0.2028, Acc : 0.8000, Test Acc : 0.9120\n",
"Epoch 64 : Loss : 0.2012, Acc : 0.8000, Test Acc : 0.9120\n",
"Epoch 65 : Loss : 0.1997, Acc : 0.9000, Test Acc : 0.9120\n",
"Epoch 66 : Loss : 0.1982, Acc : 0.9000, Test Acc : 0.9120\n",
"Epoch 67 : Loss : 0.1968, Acc : 0.9000, Test Acc : 0.9120\n",
"Epoch 68 : Loss : 0.1954, Acc : 0.9000, Test Acc : 0.9120\n",
"Epoch 69 : Loss : 0.1941, Acc : 0.9000, Test Acc : 0.9120\n",
"Epoch 70 : Loss : 0.1928, Acc : 0.9000, Test Acc : 0.9120\n",
"Epoch 71 : Loss : 0.1916, Acc : 0.9000, Test Acc : 0.9080\n",
"Epoch 72 : Loss : 0.1904, Acc : 0.9000, Test Acc : 0.9080\n",
"Epoch 73 : Loss : 0.1893, Acc : 0.9000, Test Acc : 0.9080\n",
"Epoch 74 : Loss : 0.1882, Acc : 0.9000, Test Acc : 0.9080\n",
"Epoch 75 : Loss : 0.1872, Acc : 0.9000, Test Acc : 0.9000\n",
"Epoch 76 : Loss : 0.1862, Acc : 0.9000, Test Acc : 0.9000\n",
"Epoch 77 : Loss : 0.1854, Acc : 0.9000, Test Acc : 0.8960\n",
"Epoch 78 : Loss : 0.1844, Acc : 0.9000, Test Acc : 0.8960\n",
"Epoch 79 : Loss : 0.1835, Acc : 0.9000, Test Acc : 0.8960\n",
"Epoch 80 : Loss : 0.1826, Acc : 0.9000, Test Acc : 0.8960\n",
"Epoch 81 : Loss : 0.1818, Acc : 0.9000, Test Acc : 0.8960\n",
"Epoch 82 : Loss : 0.1812, Acc : 0.9000, Test Acc : 0.8960\n",
"Epoch 83 : Loss : 0.1805, Acc : 0.9000, Test Acc : 0.9000\n",
"Epoch 84 : Loss : 0.1797, Acc : 0.9000, Test Acc : 0.9000\n",
"Epoch 85 : Loss : 0.1789, Acc : 0.9000, Test Acc : 0.9000\n",
"Epoch 86 : Loss : 0.1782, Acc : 0.9000, Test Acc : 0.8960\n",
"Epoch 87 : Loss : 0.1776, Acc : 0.9000, Test Acc : 0.8960\n",
"Epoch 88 : Loss : 0.1769, Acc : 0.9000, Test Acc : 0.8920\n",
"Epoch 89 : Loss : 0.1763, Acc : 0.9000, Test Acc : 0.8920\n",
"Epoch 90 : Loss : 0.1757, Acc : 0.9000, Test Acc : 0.8800\n",
"Epoch 91 : Loss : 0.1750, Acc : 0.9000, Test Acc : 0.8800\n",
"Epoch 92 : Loss : 0.1744, Acc : 0.9000, Test Acc : 0.8800\n",
"Epoch 93 : Loss : 0.1739, Acc : 0.9000, Test Acc : 0.8800\n",
"Epoch 94 : Loss : 0.1733, Acc : 0.9000, Test Acc : 0.8800\n",
"Epoch 95 : Loss : 0.1727, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 96 : Loss : 0.1722, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 97 : Loss : 0.1716, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 98 : Loss : 0.1711, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 99 : Loss : 0.1706, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 100 : Loss : 0.1701, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 101 : Loss : 0.1696, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 102 : Loss : 0.1691, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 103 : Loss : 0.1687, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 104 : Loss : 0.1682, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 105 : Loss : 0.1677, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 106 : Loss : 0.1673, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 107 : Loss : 0.1669, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 108 : Loss : 0.1664, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 109 : Loss : 0.1660, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 110 : Loss : 0.1656, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 111 : Loss : 0.1652, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 112 : Loss : 0.1648, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 113 : Loss : 0.1644, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 114 : Loss : 0.1640, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 115 : Loss : 0.1636, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 116 : Loss : 0.1632, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 117 : Loss : 0.1628, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 118 : Loss : 0.1624, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 119 : Loss : 0.1620, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 120 : Loss : 0.1617, Acc : 0.9000, Test Acc : 0.8760\n",
"Epoch 121 : Loss : 0.1613, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 122 : Loss : 0.1610, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 123 : Loss : 0.1606, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 124 : Loss : 0.1602, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 125 : Loss : 0.1599, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 126 : Loss : 0.1595, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 127 : Loss : 0.1591, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 128 : Loss : 0.1588, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 129 : Loss : 0.1585, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 130 : Loss : 0.1581, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 131 : Loss : 0.1578, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 132 : Loss : 0.1574, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 133 : Loss : 0.1571, Acc : 0.9000, Test Acc : 0.8720\n",
"Epoch 134 : Loss : 0.1567, Acc : 0.9000, Test Acc : 0.8680\n",
"Epoch 135 : Loss : 0.1564, Acc : 0.9000, Test Acc : 0.8680\n",
"Epoch 136 : Loss : 0.1561, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 137 : Loss : 0.1558, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 138 : Loss : 0.1554, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 139 : Loss : 0.1551, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 140 : Loss : 0.1548, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 141 : Loss : 0.1544, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 142 : Loss : 0.1541, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 143 : Loss : 0.1538, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 144 : Loss : 0.1535, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 145 : Loss : 0.1531, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 146 : Loss : 0.1528, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 147 : Loss : 0.1525, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 148 : Loss : 0.1522, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 149 : Loss : 0.1519, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 150 : Loss : 0.1515, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 151 : Loss : 0.1512, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 152 : Loss : 0.1509, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 153 : Loss : 0.1506, Acc : 0.9000, Test Acc : 0.8640\n",
"Epoch 154 : Loss : 0.1503, Acc : 0.9000, Test Acc : 0.8600\n",
"Epoch 155 : Loss : 0.1499, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 156 : Loss : 0.1496, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 157 : Loss : 0.1493, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 158 : Loss : 0.1490, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 159 : Loss : 0.1487, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 160 : Loss : 0.1484, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 161 : Loss : 0.1481, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 162 : Loss : 0.1477, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 163 : Loss : 0.1474, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 164 : Loss : 0.1471, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 165 : Loss : 0.1468, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 166 : Loss : 0.1465, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 167 : Loss : 0.1462, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 168 : Loss : 0.1458, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 169 : Loss : 0.1455, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 170 : Loss : 0.1452, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 171 : Loss : 0.1449, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 172 : Loss : 0.1446, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 173 : Loss : 0.1443, Acc : 0.9000, Test Acc : 0.8560\n",
"Epoch 174 : Loss : 0.1440, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 175 : Loss : 0.1437, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 176 : Loss : 0.1433, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 177 : Loss : 0.1430, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 178 : Loss : 0.1427, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 179 : Loss : 0.1424, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 180 : Loss : 0.1421, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 181 : Loss : 0.1417, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 182 : Loss : 0.1414, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 183 : Loss : 0.1411, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 184 : Loss : 0.1408, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 185 : Loss : 0.1405, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 186 : Loss : 0.1402, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 187 : Loss : 0.1398, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 188 : Loss : 0.1395, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 189 : Loss : 0.1392, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 190 : Loss : 0.1389, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 191 : Loss : 0.1386, Acc : 0.9000, Test Acc : 0.8520\n",
"Epoch 192 : Loss : 0.1382, Acc : 0.9000, Test Acc : 0.8480\n",
"Epoch 193 : Loss : 0.1379, Acc : 0.9000, Test Acc : 0.8480\n",
"Epoch 194 : Loss : 0.1376, Acc : 0.9000, Test Acc : 0.8480\n",
"Epoch 195 : Loss : 0.1373, Acc : 0.9000, Test Acc : 0.8480\n",
"Epoch 196 : Loss : 0.1369, Acc : 0.9000, Test Acc : 0.8480\n",
"Epoch 197 : Loss : 0.1366, Acc : 0.9000, Test Acc : 0.8480\n",
"Epoch 198 : Loss : 0.1363, Acc : 0.9000, Test Acc : 0.8480\n",
"Epoch 199 : Loss : 0.1360, Acc : 0.9000, Test Acc : 0.8480\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"import math\n",
"\n",
"# Données et modèle du problème des 2 clusters\n",
"x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test = generate_2moons_dataset(num_lab = 10, num_unlab=740, num_test=250)\n",
"model = create_model_2moons()\n",
"\n",
"# Hyperparamètres de l'apprentissage\n",
"epochs = 200\n",
"batch_size = 32\n",
"if batch_size < x_train_lab.shape[0]:\n",
" steps_per_epoch = math.floor(x_train_lab.shape[0]/batch_size)\n",
"else:\n",
" steps_per_epoch = 1\n",
" batch_size = x_train_lab.shape[0]\n",
"\n",
"# Instanciation d'un optimiseur et d'une fonction de coût.\n",
"optimizer = keras.optimizers.Adam(learning_rate=1e-2)\n",
"loss_fn = keras.losses.BinaryCrossentropy()\n",
"\n",
"# Préparation des métriques pour le suivi de la performance du modèle.\n",
"train_acc_metric = keras.metrics.BinaryAccuracy()\n",
"test_acc_metric = keras.metrics.BinaryAccuracy()\n",
"\n",
"# Indices de l'ensemble labellisé\n",
"indices = np.arange(x_train_lab.shape[0])\n",
"\n",
"# Boucle sur les epochs\n",
"for epoch in range(epochs):\n",
"\n",
" # A chaque nouvelle epoch, on randomise les indices de l'ensemble labellisé\n",
" np.random.shuffle(indices) \n",
"\n",
" # Et on recommence à cumuler la loss\n",
" cum_loss_value = 0\n",
"\n",
" for step in range(steps_per_epoch):\n",
"\n",
" # Sélection des données du prochain batch\n",
" x_batch = x_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
" y_batch = y_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
"\n",
" # Etape nécessaire pour comparer y_batch à la sortie du réseau\n",
" y_batch = np.expand_dims(y_batch, 1)\n",
"\n",
" # Les opérations effectuées par le modèle dans ce bloc sont suivies et permettront\n",
" # la différentiation automatique.\n",
" with tf.GradientTape() as tape:\n",
"\n",
" # Application du réseau aux données d'entrée\n",
" y_pred = model(x_batch, training=True) # Logits for this minibatch\n",
"\n",
" # Calcul de la fonction de perte sur ce batch\n",
" loss_value = loss_fn(y_batch, y_pred)\n",
"\n",
" # Calcul des gradients par différentiation automatique\n",
" grads = tape.gradient(loss_value, model.trainable_weights)\n",
"\n",
" # Réalisation d'une itération de la descente de gradient (mise à jour des paramètres du réseau)\n",
" optimizer.apply_gradients(zip(grads, model.trainable_weights))\n",
"\n",
" # Mise à jour de la métrique\n",
" train_acc_metric.update_state(y_batch, y_pred)\n",
"\n",
" cum_loss_value = cum_loss_value + loss_value\n",
"\n",
" # Calcul de la précision à la fin de l'epoch\n",
" train_acc = train_acc_metric.result()\n",
"\n",
" # Calcul de la précision sur l'ensemble de test à la fin de l'epoch\n",
" test_logits = model(x_test, training=False)\n",
" test_acc_metric.update_state(np.expand_dims(y_test, 1), test_logits)\n",
" test_acc = test_acc_metric.result()\n",
"\n",
" print(\"Epoch %4d : Loss : %.4f, Acc : %.4f, Test Acc : %.4f\" % (epoch, float(cum_loss_value/steps_per_epoch), float(train_acc), float(test_acc)))\n",
"\n",
" # Remise à zéro des métriques pour la prochaine epoch\n",
" train_acc_metric.reset_states()\n",
" test_acc_metric.reset_states() "
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAD4CAYAAADvsV2wAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABuOUlEQVR4nO2dd5wU5f3H38/MbLveC0cvIoJdMZZYYokgir1gN2qCwVhITKwxiYn+TCBRsASNBUWK2BDEDjZUQEQUEaTDcb3u3taZeX5/zO7eHRyK3nGH3PN+ve51u7OzM8/M7n6e5/k+3yKklCgUCoVi70fr6gYoFAqFonNQgq9QKBTdBCX4CoVC0U1Qgq9QKBTdBCX4CoVC0U0wuroB38WCbyqVC5FCoVD8AE7Yt0Ds7LU9WvDXVga6ugkKhULxk+KEfQt2+poy6SgUCkU3QQm+QqFQdBOU4CsUCkU3YY+24beFQJLpsvHqIMRO1ya6DCklYQsaYhqSPa99CoWi+/KTE/xMl01WqhdbGLAHCj5S4pUmNIWpj+ld3RqFQqFI8pMz6Xh19lyxBxACWxh4ldYrFIo9jHYLvhCilxBigRDiayHESiHEDW3sI4QQDwoh1gohVgghDmnH+fZcsU8gxB5pblIoFN2bjjDpmMB4KeUyIUQ68JkQ4i0p5dct9hkBDIr/HQE8Ev+vUCgUik6i3SN8KWWZlHJZ/LEfWAWUbLfbaGCqdPgEyBJCFLf33F3F0g/f5VenH8OVI49k5uOTuro5CoVCsUt0qA1fCNEXOBj4dLuXSoAtLZ5vZcdOIXGMa4UQS4UQS9+fM70jm9chWJbFQ3+/jXsensaUV95j4fyX2bRudVc3S6FQKL6XDvPSEUKkAS8AN0opG3/scaSUU4ApAI+9v75duXRuuOwsGhp3bEpmRgYPTH3pRx1z9ZefU9y7L8W9+gBw3IjRfLzgDfoMGNyepioUCsVup0MEXwjhwhH7aVLKF9vYpRTo1eJ5z/i23UpDYyODrp28w/Zvp4z70cesqSwnv6h5cpJXWMzqFZ//6OMpFApFZ9ERXjoC+B+wSko5cSe7zQEui3vr/AxokFKWtffcCoVCodh1OmKEfzRwKfClEGJ5fNttQG8AKeWjwGvASGAtEASu7IDzdgm5BUVUlTdPTqorysgtLOrCFikUCsWu0W7Bl1J+CN+dQ0BKKYHftvdcewKDhx3Etk0bKN+6mdzCIt6b/wp//L+Hu7pZCoVC8b385FIrdDW6YXDdbf/g9t9chG1ZnHLWhfQdqBZsFQrFns9eLfiZGRltLtBmZmS067jDjz2R4cee2K5jKBQKRWezVwv+j3W9VCgUir2Rn1zyNIVCoVD8OJTgKxQKRTdBCb5CoVB0E5TgKxQKRTdBCb5CoVB0E5Tg/wgm3nkTFxw3jF+fdXxXN0WhUCh2GSX4P4KTR5/PPY8819XNUCgUih9EtxD8hroa/v67S2isr+2Q4+1/2JGkZ2Z3yLEUCoWis+gWgv/uy9Owt33BOy8929VNUSgUii5jrxf8hroaPn9rNv85uyefvzW7w0b5CoVC8VNjrxf8d1+exukDYVChj9MHokb5CoWi27JXC35idD/m0EwAxhyaqUb5CoWi27JXC35idJ+b5gKc/x0xyr/3lrHcdMkotm5cxyUnHsLrLyqPHYVCseezV2fL/HLxB3xQFmb6iq2ttmdVfcBZV/7uRx/31vsfaW/TFAqFotPZqwX/rkee7+omKBQKxR7DXm3SUSgUCkUzHSL4QognhBCVQoivdvL68UKIBiHE8vjfXT/2XFJKkPLHN7YzkNJpp0KhUOxBdJRJ5ylgMjD1O/b5QEo5qr0nClvglSY2BojvrJ3eNUiJJk3CVlc3RKFQKFrTIYIvpXxfCNG3I471fTTENGgK49VB7IGCL6UkbMXbqVAoFHsQnbloe6QQ4gtgG/B7KeXKtnYSQlwLXAtwyfh7OPaMi1q9LhHUx3SI7e7mKhQKxd5FZwn+MqCPlDIghBgJvAwMamtHKeUUYArAY++vV4ZwhUKh6CA6xe4gpWyUUgbij18DXEKIvM44t0KhUCgcOkXwhRBFIm5wF0IMj5+3pjPOrVAoFAqHDjHpCCGmA8cDeUKIrcCfAReAlPJR4FxgrBDCBELAhVL5LSoUCkWn0lFeOhd9z+uTcdw2FQqFQtFFKN9BhUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpuwl5d4lChuHfcRQQC/h22p6Wlc+vk6V3QIoWi61CCr9hj2RWx3n6f+qpypNDQhEZmbh511ZW40nLQvSkAWOEgADVlq7hu1HCA5L7bH1uh2NtQgq/YYwkE/PS/etIO29c/fv1O91kxeSw9rvgPkerNlPQdROnGb/Hk9WbbUzcC0OOK/wCw+fHf0vvqhwCS+25/bIVib0MJvuInz8rHxydH7lF/LaHKzUjbpHzL+i5umUKxZ6EEX/GTxwoHkyP3LU/egCuvF9KMYjVWtNovGqgjVLk5+TwWjTjvN81Oa6tC0ZUowVd0CR29mGpGI9hSIqVE2jZSSiwzlnwNAClx5fUCQGg6wnAnt5du/BaAuupKbr9iVLvaolDsqSjBV3QJgYCflF/ehGVZrbZvmXEH945zsm3XVVeyYvLYVq/r3hR88cf3jruIuupKhDcdu2V5hURte81ACEG0tpRYoBbbjFD21A0AWE11lD19Y3x/nV5XTATAlZaTXBNQ9nzF3oYSfMVuo61RfH1VOUIzsKVN/Qv/QOjOV1Bzp1By8b240nKS7ym5+N4dOoTyGXeQ33cA4HQa3ryehKq2YjY45huhG5Q9+TtAYIca0HwZyLCfXn0HsGndanJH3ugcqEUHUTHrruSibsKbR6HYG1GCr9httOVl8/kD15B72s2O4OrNX7/KmXew5YnfYfqriQWc7Z642Ou6TlGv/gBE8gpamVmGXj2BFZPH4soqQkoovnQC0erNuPN6U/b0jRScPp7I2w9y6+Tp/GbkobgL+rXRUknUH6+46a9h6b3nA2DHIow7/WdJl01QZh7FTxsl+IpORUqJ0AykbeLK6YnQnGBvPTWHossnUvrwFbjScpxtGYVIIFpb2srGfu+4i1qJru5NoWzqzYAzwjcbqxGahrRtKl7+P2TY79jlW4zqYzVbkdKOPxPoqTkgQLhTKLroH0jbZutDl5F7zp3ohiv5vi0z7uD2K0aRlpYOoIK6FD8plOArughHfBOljaVtOSJs20T9tQCUTb8VGYsCMmn6kRK2bnDEv76qnKX3XRgXctnq2IUX/gNXbk+kGcVurKCk7yBq/n4udiwSP46NK6cnAHpqFkWX/xshRLNdvwWV8x5AxsIA2JZFbXWVs3YgbQ659fkd9le2f8WeSkcVMX8CGAVUSimHtfG6AB4ARgJB4Aop5bKOOLfip0PCL17aJkiQVqzFqxIjsxA9NZv8M26het4EsCyKLv1X/HVnJdas20rFzLv47WmHYUmJ7ktzXnV5yB3hLMhWTL8N24wQrdwAgNvjSR5CCJH0zknMLpzTxz18pMSOdzIARnYJWCbFVzqmqfJnf4+MdxpWsD65qKx7Uxh69YQOu1cKxe6go0b4T+EUKZ+6k9dHAIPif0cAj8T/K7oRlmUhNL2VaaUlZkMlIJ0OQTOwGisxa0tb2frBEWrLdswxVlO90xdYJjVzHU8bbBMhNHoPHLJ9AyibejNCN7ACtehx05EwPMnjCiHQXG7sWLS5Q4h3FAAyFqHo0gkIIYjVlpJS5KwtJBZ9FYo9mQ4RfCnl+0KIvt+xy2hgqnTm758IIbKEEMVSyrKOOL+i89je86ahphpb2ghpk5VflNyelpZOWlo66x+/PpnfxrYtsEwqZt2F0DS01GxHSCVo3jRammUKL/wH5dP+AEIkbf12LILZUIGWmk1e3NvGyO4BQPkz4ylOBF9NuqTNthtuL6a/BmG4kbadnBG03QHJVg/lTjopheKnRGfZ8EuALS2eb41v20HwhRDXAtcCXDL+Ho4946JOaWB35YcGQG3vedMyV03L7esfv56/PzWXe8ddRG1FGQUX3I0jooLquRPQvGnY4QBozlfQDgeonHmHI+CajjAMRMKhXtAKgQBNdx4b7qRgJ+zzOyORTK3PuKlsefKGpMdOtHIDsaqNIMBsrE52GNKKsW3KNUjbJla5IT7TiI/0pQQpCVZuQiCI+mtZ+fh4ZdZR7NHscYu2UsopwBSAx95fr4ZVu5mdJShbdu95yYjTltRXlbd5nGhjVasgqVigltuvGOXsr+m4C/pRPv1W7EgQq6keO9SY3FfaFnpqNtK2KTjvL1gNlQjR0r5O3KMmvsCLBNtx2ZRmFOLmFs3lSb6hYtadmAXFNNRUY1mm8x7LAk0nGgkjXF4nCCv+XtNfTW5BMbomOOTW5ynd+C2WLTGyiih/9g+gGxiZhaBpSdNT4r0SZ9E4WLae9Y9fn/TgUSj2NDpL8EuBXi2e94xvU+yhSKG12RF8dt8Fbb9B6Ml8NtCcgfKz+y5IWkdkJETxZf8mVr0JV35fZ2QuBOVP30ThxfdR+ujVlD8zHjvkR0/LxvRXUzHzToz0XBACaZnYoUaMnJ6tRvjSjAIQrU7kyREYuou/PzWX268Yheek3+HJ6w3AxsmXYzZUkHPitfHBuiPalTPvdN6pNf8khBCY9eUI3aBi+m1JV0+sGEZOCQiB0A2E0NDTcrCb6vj7U3MBlYdfsWfSWYI/BxgnhJiBs1jboOz3ezbStp1RrmnGhdnZblsmS++9AITAl1dC1km/2eG94eqt2LEYm9euwo4HT9mxSHwkvDMEQtMoPPOP1MydmOw8tj49HjsWdhZam+oRmkbOyb9BCK2FH72DkVnorAkIKOnTVoCV44IphIYEat54KOlxI4Ha6iqkbbLy8fFknfQbXJlOHEDRRfc6i70uL7GarVTMugs9PbdFy0HzpGI31SW3fV9qZ9UhKLqCjnLLnA4cD+QJIbYCfwZcAFLKR4HXcFwy1+K4ZV7ZEedVdAwrHx9PtKmx1cKklBLLBiO7GBAI3Qk+EppOz98+Tax6C3WvTdzhWKXTbsUKNTp2eCGaA6Cm3wa2lXTFTIzKwXHTNGtLkbaNZZrYmp70erECtWhCw46bdPT0fKrnOnZyu6kex6vHRlom26ZcAwiwTLZsXMd1o4ZjRcMYL/+f4x2Ek0On6pX7nEViy6LHVZMBZ3YgEEjbpHL2X4i8/H9J338AO9SIbKqn+JJ/UjHzdnpc8UD8PtlgmQhgy6NXJc1giTxAO3PX3JVc/wpFR9NRXjrfubIa9875bUecS9FxtEw+VnTpBFqujpY/czPYZtxe3Yy0bbZMvgw9JQMrWE/Zc7chkUjTZPPjv8UONaKlZoNtI+MCnfvL31Ix6y4Ax81SJM4j0Vxex4wSF9f61x/ECtSSkVcAQFregOSId+zIQ8n95Y5fo4pZd6K5vRhZRchYGGmZSbG2rWryRv8Rd24vpLQxa7chrRiVz/8ZaDYDCaEhLacTkpZJ3hm3JI8vhMA2o1TO+rPjMhq/D63uS/x/IOy8LrzpWLZNtGoLyx8aR/5pjkdQIlJ4ZzTUVLe5dqJG/oqOYI9btFV0Hm0lHwOSC6JAMhpVaBpSSvTULOxQI8WXTUxGsAIsvfcCii+biFlfgZFbgjRjaC4P2566ASOnBCM9no8mLsQtbe8JhKZzwLhHkh4+2yMBd2F/pLSbTToSQICU2OEAxZdNREqZXMDd9sS4Vm6XrtyeRCt2LIySOJaRU4LQNFxZzS6msdrS5GzFlVMCCGK1W3e8X1Jixc/lzCgEmi+DWH15cg2hZXK4liSKuJhWLNlpQHNAlxr5KzoCJfjdnJbJxxwXR5tozVaEy0PFzDuTtuqEi6RweSDUxoHigUgAMp6HfvtRsPD4qJx5B85MQja/bptUzroLZOvMmNvbuaVlUvbUDY5zp2jhq2lbuDPzMc0YLrcnWdik+XWzWeS3c/HEtpILwABmQwXStjEbKhyvnOTJ4/+kxMguTpqVsC3sYIMTpGXbFF/+n/h+jpkJKSl99CrWT7wgOeuINDhvrfn7uSAEh9/2fLKIS7B8fTKYC1RAl6JjUYKvaEViLJw74gYqZ95B0cX3AyRt+LHqTVTMvJNYfTnYVjKpmRM4tR1CNPvSA4UX/J3yqTdTePH/obk8bH3oMkp+/Tgud3w0vp24bW/nrr33AoqveAA7FmnhgglbH7r8O69JaE7bjaxCXG4P0UjYSZYWx5XrOJBJM4rQXcnZTNKGr+nJUbww3BRedG/cwUcQrd5M1aw7yc4roLaq2fwliCeK012AwMjIS6ZnSMw4YrVbqZh+GysmjyXqryVc3WLWoFDsBpTg/wTpDA8PIZzFVrNum7NBNvvAC01Ljn41ITDcnrYPIuVOPXPaG7naatFXWsQCtWi+jB9yBITb12oWg20hdCM589ixiY4LaYunWIFapBmlprIsec92iRYzlKxTf0f13AnYZmSnaScUio5ACf5PkI728NC9KZQ/Mz4pwlZTPUDcJGGD0ByBkjI5Yk+MsKUZdcoLhuIdkJTOwiyAbmA31VH+zHiE4SFWtRHTX03po7+KHz/G1kevQkv41Et7lwKXhBDJWQGApun06juALRvXEanenCxtCE6enPLptzrNSc3CMFyYZgzdl0HJxfeycdJlFF/yT4ThJlq5AXdBP8qe+X3S7x5amKaEoOiyiXGxlgihse2JcVjBety5vYlWb04uCNtRx+6VuF92qBGzttTx39+OlKL+jj+/5kJasVZ1d6P+WlZMHovpr/7Oe6JQ7ApK8LsxiVw3PsCX6k167Lhye2JHQ2ieFGrmT4p7pjhpEaymerAttjxwYTItgpPnJhq3aztiaIcDIO3mkbhtJT11jAxnAddsrE6K9a7NTCRbH7ocKa1kJwFgaIJbJ093Zj5vP0hddWVzTn3AXdgHKxwkd9TNlPQdlEwH0dbxY9VbyD3lOqrnTUx66jh++5KK526lbKozwrf8NfEOwckFZEeDzjXVlmKHA3GvJ5Lbquc/sEPcQJsIx/SUQPOlkzvqZipn3rUL90eh+G6U4CvaRAhB0UX3AnHXRdvCld+Xsievp8eVkyh7+iaKLptIrHYrRmYh5c+Mp8eVk4jWOCmTat96FBkJYjXVtjquK683RRf9wzlu5QZ0wyDw9oO71KbDbp0FsFMvnkSncfsVo3aYAbVM+6DrOpG4O6aUluOFoxlohgdvXk+C5etB01t5KCXy9BRdfD8VM25PJn8D4vEFJghB5ey7AZpNYS06pp0Ri0YQLi8VM29H2laraF+kRc3ciUl3UIWiPSjB78YEAn5cx1+XtLLnS4mRU0L5M+MBKH/uT45pIrFgqRnYoUbKZ9y+3ZESOWWakdEgRZf/m1jNlqS936wtpXrexOYUCFKi6zsXxMQMpK3tPxTdm0L5jDuIxP37E7gNg6rZdydnBACRhiqneEoiSCzpPCQp/e+vQELhBX9LZuoEgTBclD15vRNwBvGFXrPVvauYflvyOElPJcuifFqzz7+0Lfrd8NwO7d80+bIffM0KxfYowe/mSIgnNrsNO9SI0I1kYjMrWI+RWUjuqPEQH8EiZTK9cdnUmxCaQe6p4+IHi0t+PO+NNKNgmZh125xRazz3TEpBH8DJt1PUqz87esU7dGSgUcKXva2ZwfaL4JFGKDz/r8k1jZZRxoUX/J2Kmdt3eDJpunJMPfFOTDOSHkCFY+6lfOrN5J12c9K0VXjBPa1r+9omFTPvYsuTN7Q6uuZWhdUVHYMS/J8g7Rn5JsStoaYa04pRIG2iFeuxQ41Ju3PSHAHUzH8AV05PYrVbHfGKB1/lnXELrpyelD31u7gJQjgj4u1NEkKgGwaevN6tFiP3JLbvWH7zy4OcUbeU8bF4fAZjRmlZJKulCyc4o3gnlYSTQkIgdgguSyCtuIlGiBaBW87CcsKXP0FbZRcVih+DEvyfIO0Z+SY8fEo3fkvlqxMQugt3Xu94Dvp4bnlNbxYsKZtLEbZIotYSoWkIl4fyZ8ZjBevRNB3btjDrtiXLC0aqNyNtE2mZSfv5d5lz2kN7TUFC15uLoyTNL1Ax805K+g6ibLub0CoIDCc3UNXzdycjkxN2fM2bhpFTgp6a5Sx+J7yThOZEAFfGS0Bu10lIy0RrmS5aofiRKMFXYCcEpoUPuGglanKHh9KKEavaiNVUT3ncNi2lhdsweHDOp9x+xagdSgyWb1mPDPuJtFikXc+Ps8lvj7++lhn//AMX3fKvdpuCcgqKk20v37IeK57xU9N11j9+PVJaIGXr9AqA1VSLtC2M9DwOufFxlv3namcmlNsrKeLCcDudq+aIPNIJwLJj0eS9tRqr8Ob1JFztFHW3Q36EIJljp7vn1Wn5WadlZnd1c35SKMHvxmjuFCpn3oHmy8AONSYFTAgNqRtOFkghaGtYL4QGmoGemkXhmX8EnBF78I1/AzsfZe+6C+YPY8n8mRgVX7L4tRn84qKx3/+G9hAv09hy9A5OuUU7HNhhdyFEsstsORtIpKDAtjAbmgvL2LGI4ykUX0TXfOnkjboZcMxjpd3cRbOtz1p1AruGEvxuTMnF97L5id+RN2o81XMn4Mrt5aQplrbjaojEbKxOlvlLJEATLg9Gdg8n34zhSiZQA5ILsJ05AvXX17L6/Zd46KwSfjv3JYaPvLDDfvSWZbVKfNb/6kn0xykEkzdqfDyZWjNlU29OirowPFTOvAM9NQfTX9W8mItA2nbyvgpNQ0/NwWqqRc/IByFIKepPsHw9msuD0A3cBf2RZhSX2xNPFd092dln3akd/k8YJfh7CT8m3ULptFuxm+qonnM/VlM9pQ9fjrRt9NRsQMajZyWaLwOzsbpVtGeiMpUvv+duuqJdZ8n8mZw+CAYW+Dh9UFOn/OiFtKl54a87iK8di5JS7CQ/yz11HNWv/Yeiy/9N2ZPXU3TphOQ6SWIRvDweyFV8+X8oe2Y8VmMVFbPuxJORT6ShCiMjD+FOcYLYpCQWjWDbVrc177T1WR8+4oLd1uHvbSjB30vY1XQLCVNLwkun8Ly/Oi/EXQOr59xP3qibEbqLqlfua/bcaahIpgwum3ozeaPGU//6g8niHglbd111Zat87rtbkBIjvj9fkAnARYdkMmZm+370Lc1RraJ2vc3ukVn5RW26eI47/WdknfSb5qRybh/lT9+E1VTveD+1GOUjpePhY1tEqzeTN/Imql65Dxn2c8C4R5yU0y2ybzr+/m6E0JOfdXdKm7yzzzoSDnV6h/9TRQn+T5zEyL6uujIpMuDY04t69W+1T0syc/NoqKmm96D92Lx2Fa7cngihORkipdwxDYBtYTZUOvvpO35tEqaPhNkjwe4WpMSILzfV8ZXPTXVx+iDa9aNv2UG1FbX7XUjbpGauUwksGqhzirEkfTnjxddbZMu0m+ocM04LbMti89pVtEohrWjzsz6xt8Wr78zgH1c7sR0d0eHvzSjB/4mTGNmvmDy2VX6YSPXmHfbZns/uu4DyLc7iYKxyI9DsH25kFjreJPGgIzQ92QmYjdVUz52AFaxPFjW3bQsB+OJBVZ3FqiULeX9dKY+/V0pqZjZaXFzTyj/qklFeVn5Rq3udKGwSaaxCN5x7aZmmk7ohtydaajaFFzqpJsy6bcnEde6CfkjbpvyZm5szi8azeW5fN6C78O3nH/F5ZZiZK5q9owJ+P+ftKzu0w9+bUYK/F1O+ZT111U6O9sTo3zKdRGi64cK2LaKRiJNGIF4lSuhGMnVv0qMk4VhiW8SqnVw5eaPG4/Z4krOI0o3fUjN3Ypv1W3cnQw4/Hsq/ZmtdmCNOOJtjzroi6a3REbTXpz9xPz6774Lk4nbpxm+xbIjVbE1mEwWSienQdLY+dJlTYrKxed1EaDqaLx2jRTWu7sSv7392h23/veUS5pduZv5DrV1ku6rD39PpqCLmpwIP4CQnfFxKed92r18B/BOI581lspTy8Y44d3cmUZM2UUAjEclaPf8BZCwMNOedr5zzL4TbB4AdDsRHiiQzXAqX2wk20nQnR3y8lGErV00NfAW9EZqObhhJse8q/PW1rFo4m+FFFrot+Gy+k4NmZ94aP8Z1r6PWH+xYtNVsSE/JAkBPz6dg1I0AlE79A0ZWoRMD4aTaAQFmfblTeOWCe/AV9G41e+vutNUJKHZOuwVfCKEDDwEnA1uBJUKIOVLKr7fbdaaUclx7z6doJhDwU3ThPXjyelM67Vaq58UXWBurKbzgb4AT/i+ljTuvN2VPOdGjRZdORHO545GdzvC98vk/UzNvYvw9OkWXTqBixm1Uz7k/abO3ArW403NbFe/oTLYX7CXzZ3JMvp8VmyweONXL5S83svKt53jq4l5temt0peue5nJz6J9mAk7mzpxRv0fathOVO+8B7FjYuc+23RyB60mh6KJ/sGXSJUjbpmLmHbjTc4gFapNJ4DoiaG1vQfnifz8dMcIfDqyVUq4HEELMAEYD2wu+YjdScvG9yccbJ12azGdjZBYQqy93xCX+euXzdyGjIWSLYuXStjEbqxyXTCkpn3YLQjPIO+1mEE6ZwPIZt5LmNagL7JjlUtd1YoHaNr2COoqWgn34iAtYtXA2x2U2cca+BsN7GvTLgv0KgvTPde/grbE7ffVbsjMTkNhuEVzaNq48JwJXWjGKr3yQWNUmjOweTidtm5RPvTleVMWMV+KyiDRUAVBTWeYktCvuxe1XjNpr3TNbiri/oY6Hb76Acf+eRWGvfjvsN/mm88mlXgVkfQcdIfglwJYWz7cCR7Sx3zlCiGOBNcBNUsotbeyDEOJa4FqAS8bfw7FnXNQBTdx7aZnbPUEimEfatpP+RmhJjxAAu6megvgMIIltUfn83fS4ajKxmq1IaVMx/Taq503EDvlxp+egC8Hfn5rL7VeM2sGcU9SrP8G8gjZdFduLv76WZ/9xI8GqDeRbfla8NZ1PXn+ekSV+Pt9icvuxPurDNiETzh2i46+r5qJDclp5a3SWr/7ORLelq6ruTaFi5h3oadlIy3RMZzUtbNDxrKSJ2ZfQDQrjNQScl520DFsfuvwn7Z65K2LcspNf/dkHFGn1vPjAHYz917RW+33w0pNkhbZy1L65fPC+CsjaGZ21aPsqMF1KGRFC/Bp4GvhFWztKKacAUwAee3+9KvD5PbRlR98mwJvXM2nTd+U6wVF6vGCH1VSHK6dnPNOjDZJ4gjTHDTCR511oGnmjbqZq9l9I8xqk5TmLjh2Zp35XWDJ/JnrZcvRIDM1rUSir+bIqxswKGLO/QZnf5tkVMUbtY9A3S6PB30BRXmHSWyMRmNORvvrtYejVE1gxeSw9rvgPkerNVLz8f7jzejfXCUgiceX2cvLu5DQHuDm5dyJI22Lz2q8B0enxDx3B94lxy1nZ1S9Mp7FqG1NG+Rj72lIqtmxIjvL99bWsemcmU0amcOeCBk4c7FUBWTuhIwS/FOjV4nlPmhdnAZBS1rR4+jhwfwect9vS0ve+VSUnb0orLxmhaZh1pUmbsBUf4Sdoq+SeaJn/F0Hvgfthbjdy7+y0CasWzuYPwwV3vRNj8tkpXDMnTJ8sF1sDgtcrsnnzDY3a6moMYTFpiYXQYqRnOyNm79aFLH7zBS7er2N99dvDysfHE/XXsuXJG5Ij/LKnbgRdp/DCf7TOltmixkBLEjWFhebCyCrs9PiH9tJSzMfOmc3qzz/m0tsfSApywkRzzmDJwAIfhbKaE/c1OKaPzpmDteQo319fy6QbzuHMXkEO75nGaYNs6qwoq99XAVlt0RGCvwQYJITohyP0FwJjWu4ghCiWUpbFn54BrOqA83ZbEn71LTM5ApTPuIP1j1+PsKxkhaTtPUKEEI5N34ptd1RHUKKVG5JbWtr4u4ol82dySkkTa6pijNnfRa5PcPYQg4+2WBRkZ5B5zMXf+SN+d/ojvD/9AaYuTmHWytZphzvTda/lrChcXUnBuX9uUfjEwsjuQfkz450C8HGTjtVUT9lTv4OWefXjwp/wvpK2idlQ0SnX0JG0NLGdUlLGy18uayXICRONYeVTURckGIlx/n5eBHD1IS5enu6M8pe99SKyfitXjkjF0ASXHujhwtl1HNVX520VkLUD7RZ8KaUphBgHvIHjlvmElHKlEOKvwFIp5Rzgd0KIMwATqAWuaO95FTuacyJt2NBvv2IUIdxEmxqRZoTWNrLWdmLnvwsjp4cTdbsL9Vg7mpZ2XSklq99/iYsPM7l3gcm0s7xUByVH9dR5dGmUgqwwn814mL4HHsnrT01AIHYYJa5+/yUev3QQlz+zgYyeJVx598Nd8oPfPnoXIZKpKmL1FZgNFdihRiqevwshNDRfBgDFV06i/OmbEIbbEf1kCmvnf/Vr/wHbwgrWs2Ly2B1meXsiLVMkWJbF6H4xPlgrWfnubPY75lRemvRn/Fu+5n8jU7hzQR1Bfz1n7utiYK5GY0QyINsZ5c+a8Ef85Rs4Z4gLKSXfVEYRwMGF8NySSi4+0L3HzOr2FDrEhi+lfA14bbttd7V4fCtwa0ecS9HM9iP8hB23pf02LS2duo3ryD/37qRpp2L6rU5Fp3iQT6LikjSjVMy4LSk20oyy/vHrO9X1r6VdF+D0QfBxKYwebNAjQ8fVZFOQqvGbw9y8s9mmb5rJlD9eTJYHcnx6qx90YhS5dGMj/dJjbF27bI/5weuGgcvtwYxGMDIdF0vNl4HVVI+UNnmn3Uz1/AdASoTHR+kjVyCt1jMuaZnYTfXo6XkUnPcXhO6icuYdrJg8lligdo/13mmZIsFfW0XfbI2z9nWxsLSRVx++G71sOb28JjleHwcVSqYuC+F1CSYtjqILyPIKAjGoj3xBSZaLBZvhlTURTF3H7UuhqTGM5vIwvzRdBWRth4q0/QnR0na//KFx2PHgKhAI3akyVVtZtsMCniY0dMNAyyhEGG5ceb2xQ37sUGNS3IVu4Croh4yGKDh9PCV9B+20BuzuYnvXSenL4fPaMFXlDbg0ycSPHbOGBCcdhA3/OsXHnQtCxCJw5gEpPPjcg+jYxEIB3p79JGkHZPDmqnp+2V9jTXWMhTMfITWwEY/XCwgsKbDRsBHxP+exaUs+ee9djh91LqlZuWieVHRPCoY7BZfHg9vjxe314XJ7cXu9uD0+dOOH/5xiDRVJ84wdakyuodS88RCaJ5WyeDbNRGnJoksnOLWBNQNpxTAbKpxYCaFR+9ajAFhSIrzpBMImddXruHfcRXuU6CdSJExfvpmm+mryUjR0DdJ9kqpti5k80su9H1q4Cvpz6RE1zFm1hVS3hi5shNAJxMAyvLjtGP89I50B/XpTF7YZM7OBvsNPpfyjGfQ58cpuLew7Qwn+Hk7LxGeJzI1SQqy+nJ7jpiKEhh2LJgOpqudOJG/U+FbiYz13W6tjFl74d2JVm6ieO4G8UeNbFdKunNV1xTWWzJ/JqIGSDJ/BYfkRVqf04IhfnEqorhKXjOIWJi5p4hIWy1Z8jS+wmc2NUQ4r1tlUL+mbKTm5j03lkpcwdI1LhglyUqJcd5iL3w13kZ8qeG2dyX4ZYW6++NidtkNKyf1TX2cLlZTUfcalRx5JMFxDKBqjKRwl0GARjFg0RUyawib+iEkwEiNqSWw0JAJbaNhSINvoTEJ1FUQ+exUjJZNo0I8rswAMN2gG6YeejjBcNC5+idwRv0MYHoTLQ/Wr/0LaFnYsgjBczaYd28IONVI9dwJ2yE/BBffgyipCAIbbQ6R6M4EWFcb2BBLRse9Of4R9yl5i3M+dOguPLiylobaKAwoEowbCzMUVnDsoxhlD3Dy3IkpBmkGN30RzufCkZHLZARGyjQhbyqr4y9sN/KJnBi+8MZ3nLu2pvHJ2ghL8PZyWic9KN36LJ6834eqtlE37Y7PvdqJwuIyP1HNKkuYCiSNglXP/gzQj8aM6cft2qJHat/9LwXl/QTPc8ZFza8+dH5Nnf2eEgwHqqipoqC4jUltGsGYbRJtwYRILBVj01pv0HOrh3RVBjioWLFv8AePG7MeQPkPQ9Wbvoer6AOd//B7/d7KPdGHzsx6Cq+aEyfbAjUe4OWXaRjyGziYfBCIBnh7tY32dzSn9DWatDPPSO59y+aijyc1MbbOdNQ1NvPHRMh4/L5+xc7/ixotOYp/eBT/oWr+LL5Z8zBfffoIrLZtQY63jLmvb6GnZGNnF8QVaZ6HWDgWctZdIEGlbBD6f51TKEhoIZ1YgpcQ3YDj+z+ZQMfNOsM1W55OxMNedMoxLrvwVhicFw+tDd/vQPSnOzMXtw+Px4fZ6cXmc2YrL48xcjHjCt91By2RopmVh+Wt44nQ3tU0mPyvRuPyVcp75Mp9Y2ENRpuD8Q3KZu7ycrY0WtrR45tMa5q80KPf76ZmhsWRziPw0TXnlfAdK8H+CePN6IjQ9uehX/tytSTG3muop/e/VIDSMrCKKxsTTGtkmPa6c5HQAcY8Ps6EinktHJuvaStumcuZdRHLzSEtL36U8+7FoBH99DfVVFQRrSgnVlBFprMYtLFwyhktYGDJKVoqLvnmp9M5LoWRYJiX5vUnxugGYOO1Nhh2Vxs3HZiaPu7m+jsv+/D/emnxTK3F+5IWFHJrtR8R0dA98WmrRJ8ux8Z7Qz6B/liDbpzFiaCbbqhsYkKvRK0OnPGBz0f5uvqwJ8/Tcj7j54lPavL9T5y1i1ECNwQUeRg387n1/DIsf+S3Dxz5EtT/C5kZJ/um/b35RCBACGQtT+3rzfXcK02SRMfwsWpacNOu2Efr2EyKlX6N5UtB86fS4quX7JGbtVqpm3s4j5/cjGIkSDEcJRQIEw3XO80iMgN+iqcokGDFpipgEwiahqEnEtFvNWiQCW7aetcj4bCaxTWoGhtuL4UlB96Sge33o7hQ0d0oLM5iP835/f/Lxhy8+yeDylxkyNJvares5rEDj7P3g2z4j2fbFezw0KpU/zv6WR0Z6OO/5EMFALRfu7+LiI4q4amYZ/zcqn9+8WMWUS51YEeWV0zZK8H/iSAnSjNDjqslI205WUorVbKFmruOtIa0Ypr+GbU+29s0Whhu7qY6K5/6EtEwMw4WuCUr69CMQ8BMI+KmtqqDxgauRZgxNExQeeDxC2oTrKlj5zO3o0iLFBcXZKeyXk0LvXhmUHJJJbmZxq/qt38fCZWvYVhnhuS8rk9tq/SFyXOYOgvvCgmVUVoV4cSWEohJDF0wa4eX6+WFWVkaYfJqPf3wQZd7XflZXxnh9rYmugS2hOiixMVlWvqDNUX51fYC57y1h1vnOQvVlh6Ry/qwl3zkj+DEsfuS3AHhOvZuMwuagqlAk5lTFAgouuAd3Xi+khLKnb4wXlhdOyurEvdV0tNRs7HAgmTu/Ldd9IQRejwuvx0VORsddR1tYlu10KtEYwXCUYLiJUCRGMBxjW42fidPf5rIzfo7QXAQjJjWRGJ/Ne5f3Ak1Mensz2CYuDWI2WJ8/y2G9fdzxcgVuYry4SiPbC9sqI9QGXdz04lZ6p+t89G0Nw/IkD7y9lTMPysfr0jgkL8ybz07imDMvx+314fb4cHs86IbrB3039yaU4P+EcQwzCX/suCnGtojVbIG4yG996DKE7qLw/L+CbiCEloykLXvqd+hpOZSMuZemjcvJ8hmUzX+Yqi1ryT/klwhsotkBvEX9cGUVUvPWYww74QyEprNywyL+c+VRHXYtcya0zqtXXR/g/Fse4JFRKYyd6wiulJIr//Y0Hl1i6BohUyI0OGtfFwcV6Zw9xGBFhcXwEufx2+tj3HSUj4sPcIMrhdzMNG57tZRVsR4Ea8vbHLknRvd5ac5PIy/NYNRArcNH+Qk0TRCqavYkicbi5hqIV8JyMpAI3YVZX07po7/aITjOyOmBHfK3SNOwXdaS7Uw8uxtd10hP9ZKe6t3htYnT3iTVrCPib2h1P/885ujkZz7pZNDNIDUhuPKVCBVNkmBTiCfP8JCfqvHRZpMDCjXSXRLLltx3kptQTDI4R3DL2w18VhpFSkl1Y5g+xW9QuI9GMGrRFI5RnZi1SIEUGhYazuJ9y1mLaJ7VxNddpNAxPI4pzPD40L0p6C4fmicFlzclaQpzOhZP0iymtfqsuh4l+D8hWuXNsS1Kp1yDHXepTKQxRkqMzELMhgr09FyKLr6fsmf/AIYbu6mW8NavwbaRto3VVIcQGoHlryE1g8Ie+xBJ96FpGkNPOheALzdUJOvW1hmuTvPNb8usAlC9bRNRUzIwR8OyJZsabM4a4qIuLDlviIu31lmsrrYZnKNx74cWy8uDTPw4gq434XXXEwyFiVrrOLjE26Ytv62ZBkCPijW7RfD375NH9dvNgeeVlfXJYvFGdg80lxspJbkjfoeRWci2KddQcO7dGDklVD7/Z+xoCBkJOR4+uo7my3CK17TArNvW4e3+MSRmT4+cnZfsxFve+6nzFjGiPxhWmFS3wLYtzhvm5bmVFufsn8rgAg0NKPVL/nWKl3GvhRkx0MCyJCluncN7e7j5hCwoOZSmcJQ5byzgjBMO4OoRB7e77ZZlO7OUSDQ+W6mN/48SCMcIBmzHFBYxaQrHqI065jHLptkUhub8tfAMkwiseOdixc1lusuN4fE6XmGeVHS3F82Tgu5JbdGxeB1PsfjjXZ21KMHfw9lZ3preA/bh1snTuf2KUQTCJq6sIqSUhLd8RayhgsjmL7ECtTR8PAvZVE940xe4cktwFw/G22sYQtMJrf0Eq6me2sWvgG2zdV0WBZk+qv2RNlrSebRlVjnzuU9BSu461uD6eUEeGZnGJS8E8Ohw/yc2tx+jc0CxxqmDDBZu8xIONbFvns6WJp0vpv2F6voAJ173L849IJ2vSpuIxmJ4RQMPv7CAO69qdmHdfqaxu0mYdhJ4Tr2bfldNZNO02yl/ZryTJVNKpxRiak5y9G81VGCHA801h+u2UT13IsRHlEJ3ITQnYrcrAuja4vvWRhYuW8M3G/xM+ShC2LTJ8gpqghJbwjPLBNOXCyIxizH7u+iTqTF6sMGra0ze2WARQyc/Ox2IkLt1FRWVldx7vJtb3/yY6845od3mOF3XSEvxkJbiaedd+G6klMRMK24KixGMNBGK1MefR/EHLII1zR5iTVGTmqhJOGYlPcI4duZOj68Efw9nZ54wsUiEjd+sIOKvIxaOUP/RdGeqLzR8Aw7HGPYLIlu/JuuYiwmv/4y0/U8CHGEw650sF1ZTPQhBwXl/oXLWnax/9mYA+l8yMXkeQ282OcQCdax8zKnOlJe++774bZlV8l1heqRaPPBxlDP3NVi0OYYpJWmGYFVFmHNnQkGqwB+R1IVryfQIHhrp4/r5YR6evYBlqzfRM81i3io/BSmCf5zo4cLZQVY9/zYXnjycQb06zgunPSRMPAWnjCUaMzFySgAon3YLhRf/nxMwpxvoLUbxmuFyylFqGsLtS1bQSmAH6/EZXWuz3pW1kSfuvILzb3mAE0q8pIoI1w1388c3m/D6UvmozMDtTWPtxk2cv58LIeDi/V18Wmrh0aEsKHhj8h/IzUzlb/+bS/03pZzQ38eJG0I7dOp7MkII3C4Dt8sgazfEOyrB/4nQWFvNuiVvEy5bQ6qIkOm2OaRPNn3zUli9JUjTl2+BcFIiB9cuxm6qw2iRYRGcIhxoOu48J9ed0DSMtBwyi/tQsxNb45AW7ohaXkayU9idJMwqz35RQU1DE5lpPgJNIUoGaARjEp8BM76KkOcT3HWch3vej2DoOo+fk0uj38+ZM4KcMdjFiQO9XHuY5J/T3ybLp/HkaA+XvRhk9GAXH28x6ZslqA9Jbpo4k7n/3jOSjRXnpDO0nyPmn63Z6iS/kziL69P+iOWvoXLmnWipWVhN9U7unTjStsj95W/BigECt+GM7Mtm3MGQPvltna7T2JW1kanzFnF8L1iwpolZ56ZQH7K5+hAXv30tQKbPw6rNNVww1MXAPBeBiCP0x/YxmLvGZP9iD0/P/YjLTjuKF976mGlnuPEaGlcd7ObiOR0zyt8bUIK/B1NXVc7aj+YiazbQP1vjpiP7M3DkIa1sdeccO5ThYx/iiw1VuNKyCdY2J9KSkSDlU2/G9Fezbcq1aL50rKb65KJfwkc/FIlh2Tb9L5lIXrqHvHRPciTfkt05qm9JwqwycdqbzH3rPTILijg4vZ63V9Xy8Glefjc/Qn6qzn75GgcX65y7n4uPt9o8s7SOXx/mJjdFcO4Qg631MU7fx+DRJWFO7ivw6JDmFgzO0bj/4ygPjfBx1qwgi75aS01DE1JKfn3fs0y59dI9QhwO3cfpsD/7thQ9LYfiyyZimzEqZ/8FGQkCJGcAgJMmQ0qM7BI0IfB5nJ+3Ky27y810u7I28sanq1iysoqLDzCoCFjYtkW/bI1TB2pMXR6iKFXw7IooU7+IogFZPqfD7pst+GJbiNCnq2gKRzmxV4x98lIA2CfP4MRewZ/UKH93ogS/i9k+sMmKRYkFG/Eagj9eegp3HTuIngU794ZJiD2+DGKmhdAN8kbeiJQ2QjSP2itm3onb0IllFtLjMicxGUJQFk/MhdAYes0EVj42vlNG8d9HywW+k/67geW6xukDBJaEYQUaM7+KcstRKWR5BBcOM3hxVZilpTGe+SLK2UMMCtIEwagNwvHiiVmS51fGuGiYiw+3Wpy5r8FBxRqXHejisc9iPDx7AaleN3XlW3abR873MXzsQ5TV+im995pW22PRKO7C5kR5MhIk7/TfUzHjNsdFM47m9lE58w40X0ZydA/g9vqAwG5v/3exK2sjRx8wgE++Wsfsr2O8skaiSZNgTJLu0Uj3CF68KJ2Hl8GX4UJ+ntcItkl9o5/rjs7huZUSSoYwdf4nBBtN3tvU/JtqDEtSypYpwUcJfpfj9zdSPPoP+FcvglAjqdk59BgynLUz/sbMt5bw0Isf7vCevHRPcrGv2h+h+MJ7qHzzEexIyBm9azrCkiAlEhn333aQZoSy6bdTdOE9nXaNP4aWC3zX/CybF1cGueu0QvLSDH7trWPhpmry0w3SfS5SfZIz9zX5ZKvG5+UW89eavLfJoi7kOK36DEGfLIEtoSIgCUQlU8/08U21zakDDKatiPHkqx/SKy+NKTvxIOkMqv0RTvrjlB22v3bPVRB1Zmt23PVSWjGkbVP+TLxzlk6qZID8UTdzyKCSVsdoa8bWmVTXB75z9lRdH+DZ1z5iYI7GYT0M3lxv0xCW9EgXbGm0mTQyldqQzdEl8Ny8ddxzVU+uf6GWaef4aPA3MeagPMbMXkJRTibVonW0eIYHehTkdNal7tEowe8CTDPGhhWfUvnVB0TqK9DKVrDPYT/HndJ6labaH2HoNTumum354y2r9ZNtWljhIMWX/5uyp2/GldsrGU1rNVTgzuuFnppFryv/TVM4Rvkz44nWbEXgFCYve/qmHVIqdCXbL/AJO8aJvWJk+ZwZi5sYx/fROe5/fpyBrEAgsQFdwJJrU1lTZXP+7BB9swQhS+ebKpMMr6AiYDNmfzcZXieIKdsnGL2vi+lfhTiuh5vBBTm7Jbq2PQgh6HeVs5DeULHVKTav6ejpueSN+n1zIRvbonruBCSCVZsrW62/dDVT5y1qc/aU6AhK8rOIhoM8cHYKt70T5ue9NBZuFBzfx2DRVov5a2L88+xiXt/UwJhhUWYvq2HUIIPiNB2BBbEQowZqUDJkj/nc9kSU4HcSgYY61i5+m+CWr8jRQ5xyYAknXLof77/7Nr0O2jGRV1mtH9uW2BuabfIx0wIkFRX1eE69m1g0gtBd8cRZjZQ9fTNWUy0VM253CmxsR6hqK5ZpYQfrqZxxm+PiJ20MIUkp6LnD/l3F9gt8S7aE+abS5NUJW8lIBvOkUVKk4bGDfFMeold+OnX+EOfuK6hugr++H6FPluDkAQYxqZPnczPmABcnPR3ghVUWL3wTTzUswbJtTBtOG+hs2l3Rte1h/aQrADAtp15xMqW1tJPRuNKMIjQdoemY1p5THfS7/O+nzltEbdlm3l+2mjFDXRxarHH6YIO5q2OMGGiwvMJmwileLn85xEv3bcSSAg2bsBnBa2hM+NjJGKvrTRRkp++2eIm9BSX4uwkpJeWb17N5yRvo/lJ6pcN1w/ux36mH71KAhG1LXGnZyaAnACIxYvUVoGn0v/4pvn3wCgouuCcZaOXK6Umsdis1c5vdKhM/ewHsH/f+WFmQBdDm7GFPYMcFPi8ZmV56FOQlbcGJqEwjajMgW5BXkMe2mk3MWimZudLEpUkmx9MtWHaUWRekURuy+d9Zadz6oYfn/3kjuZmpTJz2Js/PfZuiDBdH7FNEdcDk18+XcULvtC4d5a/aXNks2q2026k7XD13AlawkcqZdzj++TgmHaupjspZd6Ih0fIyku+qqm1o5W6boKV5sKNJjN4PGtSzTf/7REdw05Eerp/TxNWHeBECzt/P4NGlUQ4shDMGGxzWQ+ecIS6mfxXjg//dvse40P4UUYLfgbQ01aRZDRzUM42xvxxIfnaf3XtiIcAynWhb24p75TgLf9KMOulyXa09bLraE+e72JUFvqnzFnF4oc0Ly6PMOtfHac9tYP8eKYz+5QnODqWfMXp4Jp9Vl/NlhcXR+zXbtEeVNyRd+Oa+t4S7j/cwdm4Tw/69jbKaAH2yBJ9X2Ayr67rRomnJZGcvBeSd76y5SNtMdgAVs+4CoZE7yrHj65qGjs3+/Qp3WHzvf8nE7zUPdjSJ0ftz6zbzwa+dRH8tZ09OErwAH603uXh/F1LCqirHPHX6PgZvr7d47WI3hgZXHezi1TUxbpw4g3n//t1ua/PejhL8dtLSVJNrhDlp/2J+cel+uF27dmt3JryabF3dKFC1Dcu2wbaQts2GJ2528ufYZtIX2xX3u0+kVADYNuUackY4P5Bl327DZehU1Pr3CE+cH0tiZJhiBhgzzEXPTEFeimD84ZL73/4EIQQvjXGybp42EJ79PMRBD5ZjtEix3KNiDQCjBmr88sBixjU0MH+zl7IaP385OZvfvx5gwo3nd+p1tfwulFU34kqLZ3m0zGTshDSj+DwuQhHTyZEjDGrmNKdmQEBjahpZndryHUl8Rn87MYVxc+oQQrSaPT30/AJefPtjHjkFbnkrxppqyROfR9E1gWWDaUsuGuaiLgT+iI0t4YzBLmasXM+3WyrVKP9HogT/ByKlZNuGNWz57C2MQBm90wXXDe+7y6aa7dnZdLr/JROpx8eWJ52KR2F/HXpqNtK2MLIKKb70X2x56HLQDNy5vYhWbWwuTG5byfwp0raone8UwJCWicvQwWpOppVI07s9u3Oq316aR/cRHhuVwrNfxLhkfxd9swRH5DWxvtEgLy0XgCP2KWLczxug5NCkGeGKvz2FPxRlwrQ3WfAbZ+R/0YEpPLBwA/2yBB+uCzBqANwy6Xleur/z7kHL++2MyB0hn/+Pa3bY1+cxELpBzzH/aG32A9Y//juaQo2tTDil1Y1onbiQm1iHKfRFOKGvxiEPbMEfitIzHT6vsEn1LeWUXjF6Zbo5oa+BLiw21ttMGuHlvo+ieF06L6+OMX+tSZZX0Bj/iuZ4O/9z2ZvoEMEXQpwKPIBTxPxxKeV9273uAaYChwI1wAVSyo0dce7OIBoJs275R9Su+pg06Wd430yuHzmQ3Mx+u/W8R1/zl+TjBZNuIW/M/Y4NfzsSJfJ2QNOBZg+PDU/9AaSJLfSkGJRWN5Ka16PVuaDr3fi+i4XL1rDk6zquPMDAtOHV1SbTzvFi2YKRAwVXvxpsc0R/88WnMHXeItat30RjMEavLMHcrwPcXODBijRx5mADjwGLtpj8/UQvV81Zt8ePJlumvkhgNdWTUdCToS0+08pJt3TaQm5LL6u8tEx+447wzBeb6ZUuGLlfBp9Wuqn0x5zP7YswLk3w4AgvdyyIkO0TnL6PQXlQsLle8L/TvWR6BXVhyeUvh/BHBYHVW76/EYo2abfgCyF04CHgZGArsEQIMUdK+XWL3X4F1EkpBwohLgT+D7igvefendRVlrF+yZvEKtZS4DEZfWAPjr7iAAyjcxJRbW/qiQUaidVuI2HAjVRuREpJxfTb0ONh9oksi5ovAyO7R6ugHAAZi9DrmgcJVW1Nhu/bGxJFUH46zJkwjr6j/8TTKyI8tqyJi4a5qGoCISR5PsG5+3koPvCYHdz/Th//EJXV1WS4baIxyW3HeLjxjVqeWh6lsq6RNBcMydcZPdhg/poYFw41umw0WVbrb+Whlax7u51mtzViL9O0HTrwzqSll1XMtHn0wzJ6Z0iO6Gnw6aYgRw/Q+e+iBj4c15s/zq2kf0aM/tkaF+/v4pXVJmfu6+biF4Oc0t8gyyfQdYPjDyjmhnpnpnbZaUdxzp8e3WMion9KdMQIfziwVkq5HkAIMQMYDbQU/NHA3fHHs4HJQgghdzo07Xxsy2LjquWUr1iAN1LL4Dw3f/pZf/oW/6xL2rO9OaX/JRMZOqhH651uf5w3772GU26awPx/XEPx5c6oXUqn6Im0Yi2LI+1VbHzFmUSOuOEBZn+9gblrYsQsyPQKakIS16p3dnD/q9q2kU21UX5WYnDOvm4O7eHikkM8fObPJ+D38/SZPrK8UB+WXPxiCE0IYmygpqGp84XFMpMdsTSjbHuyeaEyGUX7A349bq+Pshl3tPLcgd2zSN/Sy6rOHyIWifD0mT5uezdCU1RSVe8n3W0z+cNavtwW4l+/8BE24cqDXFwwO8SVw9M4d6jN1OUhPt0mqQ2Fyc+uQNNEcu2lKyOif8p0hOCXAC3nWFuBI3a2j5TSFEI0ALlA9fYHE0JcC1wLcMn4ezj2jIs6oIltE/Q3snbpu/g3LCdLC3LckAJOOa8/qb4hu+2cP4SW9vXS6sbkiM/QxY4jO2lTPtVZiJVSIu1mP/O9kYTL34H79GL9ho2MGGBQnC747XA3t78T4dVvo63c/155dzG3HWVw3bwI5fHgq0yPZEQ/i2de2MAvBxpYEsbND4OUnDrQ4JNSuOyI3C4RluL87KQN/6PH/kw0HAKcjKUFcdEuC+76bPPoa/7SaWkzWrrOHnXV3zl9iIsjeuqc3F9n1soY766Lcv5QF/9d2sCvD3VTnK5RHZRUBSWHFOsc/1gFmaleemS6WD6+PxPfb70Gc/4tD+w0p77iu9njFm2llFOAKQCPvb++Q+Uq4Ru/ZekbiMZtlKTYXHV4Hw466bA9suRZy0jb+sf+nBzxxQJ12PEfvVuTSdNPzogb4u+UyTp3FbP+nAzasWybUNVWDH3Pu9YfSiJy87mV6zm1j8bnFRY3H+XFo8OVB7t4a72ZLHAydd4ifl4cpk8mDM3XGZKvMe61CA+N9NI7Q+PMfQ1eWSt46ZsQxanOCP+rKhPDMHjuy0iXB/O0NM+0FO3hYx/aYa2lrNaPGYvy5YbWaz276zP/rpQJD89eiDDDXHmwF8uGEQMN3llvUR2yeXZFDE3Aq2tM3lhnErOd8pM5PkGuT6OqKcq8cb2B5noIC5Z9y/ChfXZrveG9nY4Q/FKgV4vnPePb2tpnqxDCADJxFm93O7FohA1ffkrVyg9Jsxo5uFc6Y08ZsPt94zuYnf3oE3hOvZvM4h2vqUbXiLx+NxA3C/VrXQ3J0EWrPPcJ9gR//J3RMnLz5w9tZt5ayfn7GTSEoS5kowsYOcjgi4oG/jntDRYvX8XNB1r8/s0wgajk2S9i9MzUOOCRAG5D4HIZDB3Qm2DAz58OC3L3ghB6SjavPjC+zZq3nZFRs6yqjspJt+yw3fLXJR+35UXleHcV77AuEwvUcWC/jk+RnPC1P/n6f/PWpOZi89X1Aaa/sYjT99FxaYL1dTYlGRqjBhu8tc5kfb3k2kPd/OYwF/kpgqqgZMKiCDNXmpi2pHdm84J6oh7Cli0beaF0G29f7XyH98SI6D2djhD8JcAgIUQ/HGG/EBiz3T5zgMuBj4FzgXd3p/2+oaaK9UveJrJtFbmuCKcc0IPjLh26y77xP0U0aSVdOLffnmBnPv8H9svfY10w2yKxKJibotMjXSPHK3hng8mCjSYVAUleqkATkOUVzJj/Mb85MpP3NzmjyBEDDZpiJn85wcMdC2IIbxYLHhnP03M/on71hxxQoHHWvgbvbQnstOZtZ9iPbaHT98p/s2na7diRUHK7KUUyjfXOPrO2FmxXPja+wz/jlr72Vzxfw8OzF3Dnr0ZRXR/glOv/g2FHWbhZ8sb6MNUBi8I0gZRQnK7h0iRPLo/w6uoYQkjK/BIhQBOCdI/g7uN93PhmHVNXOK7Gjf4Qp/TXSXU351Ta3fWG90barYBxm/w44A0ct8wnpJQrhRB/BZZKKecA/wOeEUKsBWpxOoUOw7Zttn67kq3L3sYTrmJAtsFNR/Rj0KjtlxL2XlrafFvSUuB/SqK+M1q6/E1d2sDF+7v4ZX+NHJ+bglTBXxZGWFllM2mkFyE0Tp4a4MEPanFh8fBpXq6eE+KCYS76Zmqc0l/jha9r+Nv/5vL5ym+57xiLTI8T1fnK6hCz3/qk1ejx+2qydiSJyldW0E/xZc2j9VjtNoYO6rFHuM0matDmuyNcfaibp19fxHXnnsDUeYvQwnU0WQa6x8Pm6nquOsjFzUd5kBIaIvDYZ1FWVJhMHulj1soYb64zqQlJQjHJmP3dDM43GHt0Onqvw5yTlX7GwjUNfLMhul1Opd1Xb3hvpEOGvFLK14DXttt2V4vHYeC8jjhXgnCwiXXLPqBh7WLSZYCjBubyh7MHkJG6T0eeRrGH0dLlb+HaJrbWx/j3IpMcnzOqtyWUBWwOnxLAbWh4DY1w1OKKw1zsX6hRkOZUQcr0CM7Yx+CDTSYz3/iYXx2eRu+MRJEUZ5S/YHNgh4pMnWU/TlS+KtvO9C5xCstX1PrbfF9nkej8Jp0MmS7B1Qd7mfFVgH8++waLv1jFtEt7MnZukAP2HUj56x8xZ43J7FUmOSkGtUGbmGUTtSQnT23CpQsmj/Ty1/cihGPSGcm7YEQ/ydnT3yIvK505l2Rx87GZVAdMzp/lT+ZCUvwwflI2juqyLWxY/CayZgOFPosLDunFEccejLaT8nw/dfbkfDddRevEal7qTcl5QzWuPcRgn1ydNTUW584KcvI+KTx4bi8+2RDkvKlbGLmPm0mLo5y/nxObUBOS9MvWOG+oiwc+ifLE0iYeX2yTiNWSEiIWsHhVq0RfO6vJutts+xKnQE0coen48ntib++Q/yP5se1OjO4NK0xupmOnv3h/Fw/MX8TVh2dx27xKhmV7mfraIp4e7ePfn8Q4oZ+b1LRU6oMxZn/ZhLAtjuql4XMJhpfojBhksKTUoihNUN1kAk2M6C9ZUxcgL82JMVFmnPaxRwu+ZZpsWLmUyhXv4YvVs1+xlz8fO5CS/CO7ummdwg8xwXSXzmH7xGojbniAF1dt5N0NMdy6oCZok+UVvLkmSHljjIumlXLuEBdFmR5W19lsa4zxxPIQTVFJfqrAowsG5+lsbdK55NAs7jwpm/KaRhoa/UxbpZM12HHR/b6arJ1l2/8+fuj34Lva/V2dwcJla/hmg5/HFkXjtQWchG9uaRMKB6lrivJtVYRB2YIVFTanDNApC5g8+UUdEQuawibn7WfwVaXN/Sd7SXEJThto8OyKGMc+2QRCYGjNHe8hkxw//ATKjPPj2KMFf81zt/OL/Qo5acxgvB7X97+hG7M32Od/DCcPH8LhmTVcdwgYQnDm9EbuOcHD5S+HOGjiJrAtXl5tM2NlLS6XQXqKl6ZogPxUwaxzfQzMd4Tw968H+N/iBp7/KsyWqkZ6ZOg0RiTDGlZx2WlH8cCsBWSnunjuy9Z5h3pUrElm3exI235CuK1gPdHq5jCX75vN/pDvwfetSXxXZ/DEnVdw6OV/JzstjcS0qNEf4pSBFh9tDHPvST4ufSHA/53m5Z4PojxxZipj50W48ohcmrKHMPuND0lxaZw0QGNgjoahweElOuMOd/PWepMVFRZPjk7lvkUmw/tl8OYGwRuTb1JmnHYi9qBg1x1ZNGkPbpxiT+CM8ZNZvnoDlmUTNW0uGubi7CEG174aIhiDR89I4TdzQgwp8hGIWJSHNLx2GI8BwZhTADLTpzt1TzOy6JGfyedfr+eKwzJ5Y02Is049jlSvm7lvvceok49rc1Q5cdqbUPoZNx+b2SpICNrvxun75Z3o8ZQZLbH81YTe+NsPv2E/oN3n3/IAj4xKYezc4A4280SB+cQ9Wb2pgp/96j5SvQbn7QsuIbEl/OpgF8+siGHagpiEF9cI/MEYZ+2r8fZ6E9uGmFN6OBkjGLUkhWkaL13g49VvJe9tkpQ1xjhz5C9UXdpd4ajrdxp0sXcavxXdhjkTxrF57gS+mP439u9XwF2n9WZZbSo5KRqDcjVWVlr0yhSsKg9y5YEadjTEvDE+njnLxxNn+IhakqiWQkZmBukpPj5buZ5BORrTlzeSoltMe+0jXnrnUx45O4+57y2hpqGp1fkTo+TLDnHE8LJDUlvt13KU/GMozs/mhOvv3+GvOD+7XfdtV9rdvECttWp/dX2AF9/5FJeweOmdT6lpaOJPD82mfxaA5Dc/78EHmy3O3teJfv7lAIPpX0Z5Y5Ob7PRU+mTCS6ti5PoEUcupWxuzJJaUvHBhKkPydd651EemV3BkieCbqgj/HuHlhTc/3uH+K34YSvAVewUJgQJ45csG/nysh1BM8vLXUR49zYtbh2eWh7lkfxe9MnXyUzUG5rm4/CAPA3oXsfSZu6kPNJGfInjoNC9pLjish45mhdhUXkteqrGD8LU8b8K2D1BfV8/Dsxe0Mpm01VnsCgnTzvZ/7V2badnu1RURDv/3Bo4osnl49gJGjZ/MKwsWf2dnkO8KE4vFyHOFuf+ZN/jym3U8doYPtzR5emk9Jw9w0T9HI8Ul6J+jcfYQg2p/mEyfzgOn55Dl1fj7ST7SPYKnz/JRmK7h9Xi4dI7FocU6VSGobJK8sjrG+fsZZHvg5D7Wj+44FQ57tA1fodhVEt47kxfVc3p/GFqg8Yt+Bl9VWgzK1Rizv4uHl0TxR01eXRNA4oTyCyGIWmv55KuNVFXXcdPP3AyIZ258cnmUghSBV5c8/GENi7eEqf/GSddQXR/glN/9h6hpU5jpSdr2a/0hsgyTF979jFSvu91unLsjWOrX9z1LUzBCdZ3j7VRa3UhxiuSpJXXkfbuUiup6rj0ijby0HGKmTX19HSP6u5JVwl5851P0SIQpp6dy7atBpr22iCsPMtgvT+PCYQaPLqrHY8CLX0fRNbBsqA1JLEtyTFGYXLfgwmEGEz8Kc95QF0g4qb/BK+t0hg3oyaLKaha96dTvbfRHeOYsL16Pmz+enKMia9uJEnzFXsGcCeOSducxB0Xwx2xOHWDw7gaLz8osThlg8NyXMd65IpOYLcGVwnMrJR9UZ9BQuY1r/vEUBamCqw5xYWhw+UEuZqyMURawmTzSx5/eaSTDA3kZOk/P/YgPvviWPCNMRRQuO+1ELjvtKK7421OkeuqZckYq177SxEvvfJqsvPVj0gDsDlfPhImppe39tOv/j6fOSuPsWUGC4TBuXfLE0gCvbaggEIoQCoXx+bzsW+Vkqsx3hfl5XxeD83R+VqKzqS7MtYek4XW7uP5IjRkr/YzY18edxxggJbZtM2FRhFdWxzii0OTm16PceZyXWSubeOJMH8EY/OEYH/PWNjHhxvOT9QcSawxH75eZbL9yyWwfyqSj2GtImCmO2KeI3Mw09ilwc+YQg3lrLDK9GqP2cbHvpHoO/a+f4Y9U8ewXYZau3MA/Ts2mtKKWE/sZVDVJvq2xqQ5Kju9jYNmCIfk6x/XR2DdP47PNTcx8ZxlffrOO/47y4tUls978mEdeWMi69Zs4rkeUwQUefl4cZmtlbTIpX0s3zpZU1wc450+Ptmnuaa/9f3tampheeXcxo8ZPZvwDsxgzzGBYkcH5QzQCTSHeuSKTgjSdU446kJ556bw9tg8989J58q4refWjr3hvXYB98+CjzRGmrQhx0TAnHw5AcZrOhUMNZixv4tBH/Rz8aCPHPBHg+a9jpLkFS7eZhE3Jvz4Kc9H+LlwaZHoEhoAxw5z6AwkWLlvDc19GOOyhyuTfc19GWLhsTYfcj+6IGuEr9hpaBmVV1vmxLKcgto3G22VuwM2RB+QlffkTI8hFG0P0SNdYuMnm3Y1hQOKPSEIxGJSr0RiRXHWwi9+9HmXUPgbzN9UzZqjOgUU6Y/Z38epaP1PnfUShTzKyn4Vp2ZzaT/Lc5zaHPLCF/MyUZBu39x/fmevj7kjj0HIh9riSOp5bvgHbtnns6nRM0+baQ1w892UMTchkENUNx+S0MkllpXkYnKvz4Rab7PQUQrEATy2P8eTyGGELfIZA0wTpqT5+d/4vCKxfwsI19Xg0izK/zTMrYvznl17GzQ+zaIvJlM9iyZINuq7hcje7oO5KMXvFD0MJvmKv4YcIRMvI2atmbMNt6FQFbXIy06n3B9F0jQuHwB+O8uCPWPTOEIwcqLGlUWJHQ1xzcAq6DmMPdzHtyyYiVozRB/rom61TWesnP1Xj2sO9PPWlRlFBHk/fdWWbmTcTov6rl530v0/ddQW5mak/KI1DwvRz73Vnc+vDL7ZpAmp5veGIycm9Ykz/3OKMfXQKUzUiUSeD6Jj9Xdw0v4kJv0zlkcVhRvR3nCUvOySVc6YvprSqnokne7huXhOGHmHq2alcNy9Eanomhd4YtaaH3kV5PHXXFVz51yf5al0jowfCNYemMPXzCFleOKSHwZWHZ5I1+BhlmulklElH0S1p6aUy5+reLPv9AG46voD+vQoZkOchLTWF2V/HOO7JAKc/F+TI/zUx46sY89bEuHh/Fz3SNSwbmqJwwVAXwahkytIII59t4rCHKhj5bIB/Lwpjx8Is+uJbjv31Pxk1fjJrNlcmTTgtRT3fFaZ62yaenvtRUpxPG+zlnCe3MGpf73d6+SRmCX+c/PxOTUAtr3drVR19swQj4pGtJf+qo/+DAfr8O8CTy2MsKTV58vMwFw4zEGYYcExSx5VEGVbkJj9NQyAYPdjFwX0yOG2QgRUN8rcTU2isr6Nsy0aenvsRcyaMY9iAXnxQkcqYVzVmrbL4eV8X/qjgxF4xXlmwWLlZdjIq8ErRLTlj/GS2VbYuuGZaNqFgiDlX9eCC56o5Z1gKSzb62VQboSZok+MTbG20cceLiUjAEGBKEEiK0l28PbYPJz26iV8O8rBkSwSkzcZ6mwyPICIN9h3Uj4bKbZzw8yNZ8OkXydw85zy5mT8d4+bvi700RuC8/XSkZTLl41p+fVQOqV53q8CoBImF6n/8wsMlz23jlSt7cv380A6BUonrjZkWlbWN5PoE1UGJrgnchuCp0V7yU3XqwjaXvuTUDdCkjdtlUJCTjm1Lquoa2SdXZ/98mLsmxuOn+8hN05m9Mkp9WPLrw7z8b1mYQBS+CWbx4oTmyNi/Pj6Xl954jylnpFCS7cXvD8RTV6hRfofzHYFXSvAVijgtI0//8NJmXlgtSfO62VTZwIVDXfx2uBuvx0NOTg4nPLyZQNTm4VEpjJ3j596Tfdz+bhRLGIzoZ/NVpc2Dp3o4Z2YT+akadxzr4a/vx6gJSeb+qhcXz6zhnGEp3HlSNhMX1kA0yJgDXEz4OMbzX4ZoiDrVzAblaKyrkxTmZtC7uGAHs1Wizdgm9Y1+rjs6h+dWyp12Dodf8XcuHmLxeVmMcr+kLGCzf6HOhFN85GVnUJSbwcT3G5LeSyf8/EiWf7uVg/bpiat8OUflN3H1nCBXHezm9H2cRe6/vB/lwVM9SEAXMHZemOF9U+kx7NhkGw66+C+IcD2ljTaGLshP1akN2Qwb1Jf5D9yAogP5DsFXNnyFgtY27uqAyTc1UJKTRmZmFkbMz1sbLBZsioAhMe1SZCzGqH0MBuW5uOwgD2WRVMb9PJOpX0R5c1OQ0/uDJmBQrs5hPXQOLtI5vo/FV1U2ue4oJ/exeHJpIy98HaHRH+CZs7zUBG1OHwizv4I8nw1oPH5mGhfMasLG4Mm7rmyzzY+clsLY2duYdo6PBn8TYw7KY8zsHRd6H3lhIeFQkKnLQQiYfZ6PC2eHWFFuccozTeh6iPxsp9hKVX0Nb/+6hAue+xivZvPB8rW4NZuJMZMcn8b0r2JM+SxKQ1hyyYFuhHASnQ3K1Rk5yKAsEOGVBYu5fNTRSCnJ9Or86Rgff10Yxh+Dd6/ry9OfBaBkz6gf3V1QNnyFgtY27qlLG2gKx9Ai9Xy1Zj1Tz0mnb7aLuVf3oiArlfwMHwUpGhcNdRMKhxk73MvclY2M2tdLmkejR3Yq5w5xUR9yPH1O38cgy+vk32+KSjZW+hl/YjF9CzI456ThjD06l8IMD9kZqRSna5w52EAgOH0fgz4ZgtMH6wQaavnFdf9qZfNOtHneqgCjBhkUp+lkegV2JMih2QEefmEB4HQMo8ZPZvabi3j+gjSiFly8v4uDinTGHOAiN0Xw+xPyuOn4Ai4ZeTSXjDyaa36WzZ/mVnJUUZQMt0WvNJtgxCLFJXj9Yh8f/yqVdy9LQQh44esYZ80McfbMIMMfCzD9qxhfV5kc18MpJD913iKOK4lycJHO6ME6A7METy+p3yGCV7H7UYKvUNDs833Qg+VM/qiOG49ws6HW5OR+Gl7dZsRAnblfB8h3hfGafqKWRNckWV5BnhdGDTJ45atGfLEGjiwIku2D19eZnD7YoG+2RkWTzYAcjdP3MXhjbQxiIUYN1Hjh3WU8ttjP8f+r47DJFRz3ZID5a2NETLj8QBframOMHKBTkCqoq63l4dkLdmjz/QvruP/DICX/qufQR/0cMqmc574IMuvtpYAzsl+1ei0n9IxRH7LxGXDtIS50DcYe6iJswsxldeyfHWT2W5/wyoLF2FaM2kAYQ0jW10SZcIqHDA+cu5+LkgwdgaAwXefaQ92ETCeSNhCFioDEtOGrSpunPmvijU9X8cq7ixnZz6kmdvmBLurCNi+taEAI0WZsgmL3oWz4CkULJk57E2vLEk7vG+a/S0LELMnYw9zUhOCKV8JETZuoKemZqbG1wU7maNc1jagNtm1haAINsKWTusGWkogJHsOp2RqzIdVrUJCdTn5ONpFQgCMKony4tpHhJTp5qYJgzPGFj1pObd5pX8Z4Z71JacTHh4/fvtPMlZX1AWbMe4+HT/Nx2wc6s+6/gbPH/5tUwkw41cs/PjQ5uEDy5+M8GLqTo/LuhRFeXW1y6kAXy6sEQwvdLN4c4sFT3VzxcoiT+hv87gg3//wowoyvYrgNgWU714wAl9vDxlfuazP7JkD96g+57hDIcttI4IFPIry53mRjwE1Ouo8eBXnK574j2V02fCFEDjAT6AtsBM6XUta1sZ8FfBl/ullKeUZ7zqtQ7A5alu0zbJurD3bxm3lh7PhodszBqbzwZRMx0+bfv/Ry98IIg3M1Xl9nIg0PvbJ8BPyNmKbJaYNd3PQzNzO/tnn2SwuvIThv1Ek7pE0+aFBPUmu+ZN5XITY1OLV4b383TGmj5PHPYmgaZHudYiBZXoEWC/KvaW9w73VnJ4/zyruLuf0onTvfWMTq0jou3M/gqF46J/aKMe6f0yjyRBgx0KBPpmBFWZRlpfC/z2Otrj1sSp5cHiVmw2elUS4caqALOK6PTmPY5tpXQ9x5rIcFm2z65XoY3jed1H6Ht7qetiqCeXxprFzXxP+W2K3OZ6Nx+H69lNB3Mu1dtP0T8I6U8j4hxJ/iz//Yxn4hKeVB7TyXQrFbSIrvPj2TZfuc0TkcWqxz4lMBDEMAGuGYxU0/c5PtExxYpDHzqxiaJihwhQk1mRjCotGE6w5zURuSDMqGuqYoj47O4P73mhdSp85bRG3ZZp5bt5kPfl3E+9/Wc/YQJ9XAfSd6sST88a0wh/bQ+c1hbsIxiQ1M/SLGc/M/5vcX/5LczFQeeWEhh2Q30ifdhSfmx61JXDq4dbh0f53RMzbRJ1Mw/SuTqSscU1GvLI16082wAY7gJmY1Zw6I8Z+Pw7y13uT8oU7BoSsPdnPJiyHS3fDSNyZ5PthaF+HLShu5ZEGr62mrIhglQ5QXzh5EewV/NHB8/PHTwELaFnyFYo8lEbj0wtZKgsEgjy2Kku4RmJZjnkl1axSmCzb5NXplCa482I2hCa4+xM2SbTbb/DY3/8zNnxdGOG0fF7qAglSNQEzy7Jcmlx7k4aCeqYxqkMmMk3PfW8LfTkxh3Jw6aoMWS7eE2ZgiWLjRpCEsiViOSejraptX15hUByW5PkFDWJLiFjz8wgLGnn08s17/iIdO1vDoUOq32SdX5411Jn88WjIgW+OX/TU+KbVZcGUmUVtywhMNZHp1Ut1pPHnXla1mNZFIFEOajOgHh/V0s6XeJGra/KKfTjAGM76KYmgaD47wceeHggw3yQjg1rWGm1GlCPcs2iv4hVLKsvjjcqBwJ/t5hRBLARO4T0r5cjvPq1B0CK1z1gQpyimmuq6OxqYwmJIUFwghuflnHm6YH+KCoW4KUx3bdX3Y8cBZuNFk9tcxLhjqYnGpxeZGm7lrYvhc0BiGZ85OwR8Mc9khTnrfpnCUUQM1Cn0RTuircezDWzh/iItfH+qiqkly7dwQvzrEzflDDQpTBRvrJTO+imFJiFkw62uTF95dBhJO6BkjN8XF459FSHEJHhrpZcyLIY78X4D8VI0yv01hmsah/23AH7Y5oFDHti3yXOHkYumI/qBbYdBgVbXF+jqb+esayfBqNIZtbFvSJ0twaA+DvplOYZlf9Izi9aUwNz5rUaaZnwbfu2grhHgbKGrjpduBp6WUWS32rZNS7lCKRwhRIqUsFUL0B94FTpRSrtvJ+a4FrgX47y0XHHrt6KN39VoUih/Mzsr8JSJTa/0hRg+08Wjw6uoYukbS5zwQlQRjxP3MBc+fl0KmV1AesPnDWxF+0VfHRnDBMDf79i3G0DX+ubCOJz5r4oNfF5GXZlAdMDl04gb8EYuiNEFdyDlWzIaI6Zhmwibk+AS9MwWPjvJyycsxpCeTKn+UhoZGBI655/rhHv54jJv/+zDKpMVO3pqwKfjPqV5ueD2CZdn0zNSZcrqX61+PYXsySU3LYP3WMiLhMB7dseXHbDClRmF2Kttq/Dw92kfvLMH188P84wQPeakaVU02ty80OXlIditbvmIPoD2LtlLKk3b2mhCiQghRLKUsE0IUA5Vt7SelLI3/Xy+EWAgcDLQp+FLKKcAUQHnpKHYrO1toTIxYE2kLbj/VSbDmcdlUBW3yszOobggQMy2yfTB6sJssL3gNaAhLMtyCQ4p0Hl4axa0Lnvg8SmrKVjJSvTQ2hUnRzaStO9OrMShHEIjpHNtbZ0mpybIymzQ3PHyaj2tfDXH+UBe/PsxN/2wNIWDUII33toRY2xikIE1wXB8n7/+VBxtoAq44yGDGyhgl6fDz3i72zXdz5r4272+Mcea+BvsXezixn+SJz+u46NChBAKN6BGTF85PJdMn+Kw0xh8/8pGekYnXauLWd8KcO9TN6H0MBuRoVDRJclMEP+8pwIolR/mqKMmeT3tNOnOAy4H74v9f2X4HIUQ2EJRSRoQQecDRwP3tPK9C0W52ttCYsEtvn2ANaHMW8PSXfjRsJi02sW2bbJ+gLizRdYPi/AyApOth4j2HPeSMjer8IayoxaOjfPzjgwgn9zfwR02yvIJDeujkpGi8sMrk+a9N4qn1kRJMGcWrS37R18Vr38b45UCDuhDUhRxvmBP66kz/MsaTo12Y0ubsfXVe+SbK0HyNr8pj1ARNsr02017/lEN7GPy8r4u8VCcsp2+2zuF5YV78qpZf9NX5bJvJpE/CeA3BhI+jSOnMOOrCkgN6aIwa4lFFSX4itMsPXwiRC8wCegObcNwya4UQhwG/kVJeLYQ4Cvgv4MSKw3+klP/bpROoEb5iN9JWAjXYUZx39vr27Mw89F3sf9HdnFAU4FcHu/jf51FmfhXjsTMc8b/vJC9ZXsFvXwszNF9nzuoYLl2QnWJQG9Ex7DBTz/Txm3lhYrbEZzTP5ANRSdSSzBvjjLoNDWasNLFsOH1fN7e9G+VvJ7i57MUQTTGJhtNRaMJZnzBtyblDPXxRFuOe491c/koYQxP4IzYXDjO47jA3jyyNMusbSUlehvKl35PYXX74Usoa4MQ2ti8Fro4/XgTs357zKBS7g+8TqB+bXx92raRhdX0AXca4cJiLVI/GtYd6eHeDxcAcnbOHuJi/1uKek1I5ez/JlnqLLK9Glg8aQibBcIzLDnST5RP0zRJUBKAxKvFHoEd+FmYsgCXgvJclmFHCpo1pSSKW5H+fR7lwmJtsr2DUPjrrZW9qyrdQH5Zcc+7JXHbaUZx/ywMUZcYYkKVxdD8PZ+5r8tK3ghR3jF8d7KZPts5VB7t59dsIb0z+gzLn/ERQqRUUig7gu8xDO+ORFxZyYq8YQwt0glEbW0ouGubiyc+jDO+hM/OrKIf/t5GnPo8wa2UEly654+duclMEhiaZtdLk7JkhKpvARpDm1inKdHHJyKPZPHcCX07/CxFLkJKWRk5WBl63zqSRKfgMuOhAH7mZaYwZZrByzXpuPEIn1yd56Z1PeeTFhRzfCxasbeKyA924NMG1hznlHEcOcrFfkQef2/l/1hAjmbNHseejsmUqFB3Aj/FDf2HBMoKNJu9tsqj0W7h0SZZXI9sruGa4l7P2s3hlrUZTKIJPFxzXR+eAQp1R+xi8uR6+KLcpSjNAA2ETX1BOZeGyNck1iAHZGqNOPsY5YelnlEdNLjvIpneOk1lzaKHB6ME6n28zOXtfFx+Uhnnh3WU0BpoYPRAqgxaVQQsh4NR+8MKqGIu3+ZPX0BiWpJQt486rRu22e6voOJTgKxQdwA+1X1fXB8hJ0Xn7ir7kpRnsf/86glELITQ2N0pGzQiTkZrKoN7ZNAUakaEGzh9qUJDu4upDXbz6rZ/iDJ23xvYlN1UHWi8otyqf+NInrCtv5L2xJfx+TgVb6y0eX1ZBqluQYkiCMUmqS/D25Sm8srqJdI+X4j49+KCijg9ea25zZZ3EFjp40pPbMjzQoyCnQ+6hYvejBF+h6GSq6wOccv1/OGuwSPri56dqTDrXMbMYnhTOn+Xn+X/eyNNzP+KD99/jyN4aA3I06kM2RekGp++j8+Y6k8MnbSUn3Zc8dmJG0bJ84pEFlVRUm8z9OsCcq3tTHTA56dFNTBmdRkmKhYbNxS+GEQJGD3ZG+T8ffoTyutkLUYKvUHQyU+ctQgvX8eRSg1dWx+LBXU5Alz8YZlBuBqMGajz0/AIWLv4CT8xk2ooYz3wRpTook540O0tA1nIBOWbanDEQ3lsveOCDWqauiNEYjDB6oIZXmNQEJRLJsAKNfSfV4zY0bDSsZSolwt6IEnyFohNJiPG0S3sydm6Q5/95I1f+9Uk+qKhuYT5x1gFM+zMuO9DNzcf2Sb5/V9w9Wy4gl9c0MijfxYX7wwelGj8/9hgWLlvjnO+Nlu/ycOQByrVyb0flw1coOpEf4qv/Q+MAtn9fovB4foqGpkF+qkHElbFDgXPFXoYqYq5QdD2JVA2zzk9P2u4TtvrdIcAtO5fktl0MCFP8hFFFzBWKruf7Ujl0NCplsWJ7lOArFJ1EZwuwsscrtkcJvkLRSSgBVnQ1KrWCQqFQdBOU4CsUCkU3QQm+QqFQdBOU4CsUCkU3QQm+QqFQdBOU4CsUCkU3QQm+QqFQdBOU4CsUCkU3oV2CL4Q4TwixUghhxwuX72y/U4UQq4UQa4UQf2rPORUKhULx42jvCP8r4Gzg/Z3tIITQgYeAEcB+wEVCiP3aeV6FQqFQ/EDalVpBSrkKQIidJmcDGA6slVKuj+87AxgNfN2ecysUCoXih9EZNvwSYEuL51vj29pECHGtEGKpEGLplFc+2u2NUygUiu7C947whRBvA0VtvHS7lPKVjm6QlHIKMAVQ+fAVCoWiA/lewZdSntTOc5QCvVo87xnfplAoFIpOpDNMOkuAQUKIfkIIN3AhMKcTzqtQKBSKFrTXLfMsIcRW4EhgnhDijfj2HkKI1wCklCYwDngDWAXMklKubF+zFQqFQvFDUTVtFQqFYm/iO2raqkhbhUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6CYowVcoFIpughJ8hUKh6Ca0t4j5eUKIlUIIWwhx2Hfst1EI8aUQYrkQYml7zqlQKBSKH4fRzvd/BZwN/HcX9j1BSlndzvMpFAqF4kfSLsGXUq4CEGKnRdIVCoVCsYfQWTZ8CbwphPhMCHHtd+0ohLhWCLFUCLF0yisfdVLzFAqFYu/ne0f4Qoi3gaI2XrpdSvnKLp7nGCllqRCiAHhLCPGNlPL9tnaUUk4BpgCwaJLcxeMrFAqF4nv4XsGXUp7U3pNIKUvj/yuFEC8Bw4E2BV+hUCgUu4fdbtIRQqQKIdITj4FTcBZ7FQqFQtGJtNct8ywhxFbgSGCeEOKN+PYeQojX4rsVAh8KIb4AFgPzpJSvt+e8CoVCofjhCCn3YDO5suErFArFD+Oo63fqNqkibRUKhaKboARfoVAouglK8BUKhaKboARfoVAouglK8BUKhaKb0N7kabuX1IKuboFCoVDsNezZbpkdhBDi2njKhm5Dd7vm7na9oK65u9CR19xdTDrfmbBtL6W7XXN3u15Q19xd6LBr7i6Cr1AoFN0eJfgKhULRTegugt+tbH5xuts1d7frBXXN3YUOu+ZusWirUCgUiu4zwlcoFIpujxJ8hUKh6CZ0G8EXQvxTCPGNEGKFEOIlIURWV7dpdyKEOE8IsVIIYQshDuvq9uxOhBCnCiFWCyHWCiH+1NXt2d0IIZ4QQlQKIbpNISEhRC8hxAIhxNfx7/UNXd2m3YkQwiuEWCyE+CJ+vX/piON2G8EH3gKGSSkPANYAt3Zxe3Y3XwFns5eXkhRC6MBDwAhgP+AiIcR+Xduq3c5TwKld3YhOxgTGSyn3A34G/HYv/5wjwC+klAcCBwGnCiF+1t6DdhvBl1K+KaU0408/AXp2ZXt2N1LKVVLK1V3djk5gOLBWSrleShkFZgCju7hNuxUp5ftAbVe3ozORUpZJKZfFH/uBVUBJ17Zq9yEdAvGnrvhfuz1suo3gb8dVwPyuboSiQygBtrR4vpW9WAgUIIToCxwMfNrFTdmtCCF0IcRyoBJ4S0rZ7uvds5On/UCEEG8DRW28dLuU8pX4PrfjTA+ndWbbdge7cr0Kxd6EECINeAG4UUrZ2NXt2Z1IKS3goPh640tCiGFSynat2+xVgi+lPOm7XhdCXAGMAk6Ue0EAwvddbzehFOjV4nnP+DbFXoYQwoUj9tOklC92dXs6CyllvRBiAc66TbsEv9uYdIQQpwK3AGdIKYNd3R5Fh7EEGCSE6CeEcAMXAnO6uE2KDkYIIYD/AauklBO7uj27GyFEfsKTUAjhA04GvmnvcbuN4AOTgXTgLSHEciHEo13doN2JEOIsIcRW4EhgnhDija5u0+4gvhA/DngDZyFvlpRyZde2avcihJgOfAwMFkJsFUL8qqvb1AkcDVwK/CL++10uhBjZ1Y3ajRQDC4QQK3AGNW9JKee296AqtYJCoVB0E7rTCF+hUCi6NUrwFQqFopugBF+hUCi6CUrwFQqFopugBF+hUCi6CUrwFQqFopugBF+hUCi6Cf8PbtFSj4W6OM0AAAAASUVORK5CYII=",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from mlxtend.plotting import plot_decision_regions\n",
"\n",
"# Affichage des données\n",
"plt.plot(x_train_unlab[y_train_unlab==0,0], x_train_unlab[y_train_unlab==0,1], 'b.')\n",
"plt.plot(x_train_unlab[y_train_unlab==1,0], x_train_unlab[y_train_unlab==1,1], 'r.')\n",
"\n",
"plt.plot(x_test[y_test==0,0], x_test[y_test==0,1], 'b+')\n",
"plt.plot(x_test[y_test==1,0], x_test[y_test==1,1], 'r+')\n",
"\n",
"plt.plot(x_train_lab[y_train_lab==0,0], x_train_lab[y_train_lab==0,1], 'b.', markersize=30)\n",
"plt.plot(x_train_lab[y_train_lab==1,0], x_train_lab[y_train_lab==1,1], 'r.', markersize=30)\n",
"\n",
"plt.show()\n",
"\n",
"#Affichage de la frontière de décision\n",
"plot_decision_regions(x_train_unlab, y_train_unlab, clf=model, legend=2)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YPiuBS36V8EG"
},
"source": [
"# Minimisation de l'entropie"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "UlBFMsFLMtEp"
},
"source": [
"Nous allons dans cette partie mettre en place le mécanisme de minimisation d'entropie, conjointement à la minimisation de l'entropie croisée.\n",
"\n",
"Pour commencer, implémentez la fonction de coût qui calcule l'entropie $H$ des prédictions du réseau $\\hat{y}$ :\n",
"$$ H(\\hat{y}) = - ∑_{i=1}^N \\hat{y}_i log(\\hat{y}_i) $$\n",
"\n",
"Pour les exemples simples des datasets des 2 clusters et des 2 lunes, il faut implémenter une entropie binaire ! (plus tard, sur MNIST, il faudra implémenter une version multi-classe de l'entropie)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"id": "1gEt2x_sXFin"
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"\n",
"# Calcul de l'entropie de y_pred\n",
"def binary_entropy_loss(y_pred):\n",
" return -tf.reduce_sum(y_pred * tf.math.log(y_pred))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "-L1Li1YtNN87"
},
"source": [
"**Travail à faire** : Reprenez maintenant la boucle d'apprentissage supervisé et introduisez la minimisation d'entropie pour régulariser l'apprentissage.\n",
"\n",
"La difficulté principale va être l'introduction des données non labellisées dans la boucle. Ainsi, un batch devra maintenant être composé de données labellisées et non labellisées. Je vous suggère de conserver le même nombre de données labellisées par batch que précédemment (i.e. 16) et de prendre un plus grand nombre de données non labellisées, par exemple 90.\n",
"\n",
"N'oubliez pas également d'introduire un hyperparamètre λ pour contrôler l'équilibre entre perte supervisée et non supervisée. Utilisez un λ constant dans un premier temps, et testez ensuite des variantes qui consisteraient à augmenter progressivement sa valeur au fil des epochs. \n",
"\n",
"La fonction objectif à minimiser aura donc la forme : \n",
"$$ J = \\sum_{(x,y) \\in \\mathcal{L}} CE(y, \\hat{y}) + \\lambda \\sum_{x \\in \\mathcal{U}} H(\\hat{y})\t$$"
]
},
{
"cell_type": "code",
"execution_count": 188,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss : 1.5490, Acc : 0.7000, Test Acc : 0.7800\n",
"Epoch 1 : Loss : 1.5385, Acc : 0.7000, Test Acc : 0.8000\n",
"Epoch 2 : Loss : 1.5271, Acc : 0.7000, Test Acc : 0.8600\n",
"Epoch 3 : Loss : 1.5151, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 4 : Loss : 1.5028, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 5 : Loss : 1.4902, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 6 : Loss : 1.4767, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 7 : Loss : 1.4626, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 8 : Loss : 1.4474, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 9 : Loss : 1.4315, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 10 : Loss : 1.4145, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 11 : Loss : 1.3964, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 12 : Loss : 1.3772, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 13 : Loss : 1.3567, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 14 : Loss : 1.3348, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 15 : Loss : 1.3121, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 16 : Loss : 1.2887, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 17 : Loss : 1.2647, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 18 : Loss : 1.2405, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 19 : Loss : 1.2163, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 20 : Loss : 1.1924, Acc : 0.7000, Test Acc : 0.8600\n",
"Epoch 21 : Loss : 1.1691, Acc : 0.7000, Test Acc : 0.8600\n",
"Epoch 22 : Loss : 1.1466, Acc : 0.7000, Test Acc : 0.8600\n",
"Epoch 23 : Loss : 1.1253, Acc : 0.7000, Test Acc : 0.8600\n",
"Epoch 24 : Loss : 1.1053, Acc : 0.7000, Test Acc : 0.8600\n",
"Epoch 25 : Loss : 1.0868, Acc : 0.7000, Test Acc : 0.8600\n",
"Epoch 26 : Loss : 1.0698, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 27 : Loss : 1.0543, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 28 : Loss : 1.0402, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 29 : Loss : 1.0273, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 30 : Loss : 1.0154, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 31 : Loss : 1.0045, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 32 : Loss : 0.9943, Acc : 0.7000, Test Acc : 0.8800\n",
"Epoch 33 : Loss : 0.9845, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 34 : Loss : 0.9751, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 35 : Loss : 0.9660, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 36 : Loss : 0.9570, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 37 : Loss : 0.9477, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 38 : Loss : 0.9383, Acc : 0.8000, Test Acc : 0.9000\n",
"Epoch 39 : Loss : 0.9286, Acc : 0.8000, Test Acc : 0.9200\n",
"Epoch 40 : Loss : 0.9187, Acc : 0.8000, Test Acc : 0.9200\n",
"Epoch 41 : Loss : 0.9087, Acc : 0.8000, Test Acc : 0.9200\n",
"Epoch 42 : Loss : 0.8986, Acc : 0.8000, Test Acc : 0.9000\n",
"Epoch 43 : Loss : 0.8883, Acc : 0.8000, Test Acc : 0.9200\n",
"Epoch 44 : Loss : 0.8776, Acc : 0.8000, Test Acc : 0.9000\n",
"Epoch 45 : Loss : 0.8667, Acc : 0.8000, Test Acc : 0.9000\n",
"Epoch 46 : Loss : 0.8560, Acc : 0.8000, Test Acc : 0.9000\n",
"Epoch 47 : Loss : 0.8452, Acc : 0.8000, Test Acc : 0.9000\n",
"Epoch 48 : Loss : 0.8344, Acc : 0.8000, Test Acc : 0.9000\n",
"Epoch 49 : Loss : 0.8235, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 50 : Loss : 0.8123, Acc : 0.8000, Test Acc : 0.8800\n",
"Epoch 51 : Loss : 0.8011, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 52 : Loss : 0.7900, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 53 : Loss : 0.7789, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 54 : Loss : 0.7677, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 55 : Loss : 0.7566, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 56 : Loss : 0.7455, Acc : 0.8000, Test Acc : 0.8400\n",
"Epoch 57 : Loss : 0.7345, Acc : 0.8000, Test Acc : 0.8200\n",
"Epoch 58 : Loss : 0.7237, Acc : 0.8000, Test Acc : 0.8200\n",
"Epoch 59 : Loss : 0.7133, Acc : 0.8000, Test Acc : 0.8200\n",
"Epoch 60 : Loss : 0.7028, Acc : 0.8000, Test Acc : 0.8200\n",
"Epoch 61 : Loss : 0.6923, Acc : 0.8000, Test Acc : 0.8200\n",
"Epoch 62 : Loss : 0.6819, Acc : 0.8000, Test Acc : 0.8200\n",
"Epoch 63 : Loss : 0.6715, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 64 : Loss : 0.6611, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 65 : Loss : 0.6509, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 66 : Loss : 0.6408, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 67 : Loss : 0.6307, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 68 : Loss : 0.6207, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 69 : Loss : 0.6108, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 70 : Loss : 0.6011, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 71 : Loss : 0.5914, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 72 : Loss : 0.5816, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 73 : Loss : 0.5716, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 74 : Loss : 0.5616, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 75 : Loss : 0.5515, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 76 : Loss : 0.5415, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 77 : Loss : 0.5313, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 78 : Loss : 0.5210, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 79 : Loss : 0.5108, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 80 : Loss : 0.5006, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 81 : Loss : 0.4904, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 82 : Loss : 0.4802, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 83 : Loss : 0.4701, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 84 : Loss : 0.4600, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 85 : Loss : 0.4501, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 86 : Loss : 0.4402, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 87 : Loss : 0.4305, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 88 : Loss : 0.4210, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 89 : Loss : 0.4115, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 90 : Loss : 0.4020, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 91 : Loss : 0.3926, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 92 : Loss : 0.3833, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 93 : Loss : 0.3741, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 94 : Loss : 0.3650, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 95 : Loss : 0.3560, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 96 : Loss : 0.3471, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 97 : Loss : 0.3381, Acc : 0.9000, Test Acc : 0.8000\n",
"Epoch 98 : Loss : 0.3292, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 99 : Loss : 0.3204, Acc : 0.9000, Test Acc : 0.7800\n",
"Epoch 100 : Loss : 0.3116, Acc : 0.9000, Test Acc : 0.7600\n",
"Epoch 101 : Loss : 0.3028, Acc : 0.9000, Test Acc : 0.7600\n",
"Epoch 102 : Loss : 0.2940, Acc : 0.9000, Test Acc : 0.7600\n",
"Epoch 103 : Loss : 0.2853, Acc : 0.9000, Test Acc : 0.7600\n",
"Epoch 104 : Loss : 0.2766, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 105 : Loss : 0.2681, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 106 : Loss : 0.2597, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 107 : Loss : 0.2513, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 108 : Loss : 0.2429, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 109 : Loss : 0.2348, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 110 : Loss : 0.2279, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 111 : Loss : 0.2209, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 112 : Loss : 0.2134, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 113 : Loss : 0.2061, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 114 : Loss : 0.1991, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 115 : Loss : 0.1921, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 116 : Loss : 0.1852, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 117 : Loss : 0.1783, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 118 : Loss : 0.1716, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 119 : Loss : 0.1650, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 120 : Loss : 0.1587, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 121 : Loss : 0.1527, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 122 : Loss : 0.1468, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 123 : Loss : 0.1412, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 124 : Loss : 0.1360, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 125 : Loss : 0.1309, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 126 : Loss : 0.1258, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 127 : Loss : 0.1212, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 128 : Loss : 0.1171, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 129 : Loss : 0.1130, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 130 : Loss : 0.1089, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 131 : Loss : 0.1050, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 132 : Loss : 0.1012, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 133 : Loss : 0.0976, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 134 : Loss : 0.0942, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 135 : Loss : 0.0910, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 136 : Loss : 0.0878, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 137 : Loss : 0.0850, Acc : 1.0000, Test Acc : 0.7400\n",
"Epoch 138 : Loss : 0.0823, Acc : 1.0000, Test Acc : 0.7400\n",
"Epoch 139 : Loss : 0.0796, Acc : 1.0000, Test Acc : 0.7400\n",
"Epoch 140 : Loss : 0.0768, Acc : 1.0000, Test Acc : 0.7400\n",
"Epoch 141 : Loss : 0.0743, Acc : 1.0000, Test Acc : 0.7400\n",
"Epoch 142 : Loss : 0.0719, Acc : 1.0000, Test Acc : 0.7400\n",
"Epoch 143 : Loss : 0.0696, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 144 : Loss : 0.0675, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 145 : Loss : 0.0655, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 146 : Loss : 0.0635, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 147 : Loss : 0.0615, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 148 : Loss : 0.0597, Acc : 1.0000, Test Acc : 0.7600\n",
"Epoch 149 : Loss : 0.0580, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 150 : Loss : 0.0563, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 151 : Loss : 0.0547, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 152 : Loss : 0.0532, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 153 : Loss : 0.0518, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 154 : Loss : 0.0504, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 155 : Loss : 0.0491, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 156 : Loss : 0.0478, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 157 : Loss : 0.0465, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 158 : Loss : 0.0454, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 159 : Loss : 0.0443, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 160 : Loss : 0.0433, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 161 : Loss : 0.0423, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 162 : Loss : 0.0412, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 163 : Loss : 0.0402, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 164 : Loss : 0.0394, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 165 : Loss : 0.0385, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 166 : Loss : 0.0377, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 167 : Loss : 0.0368, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 168 : Loss : 0.0360, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 169 : Loss : 0.0353, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 170 : Loss : 0.0345, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 171 : Loss : 0.0338, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 172 : Loss : 0.0332, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 173 : Loss : 0.0325, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 174 : Loss : 0.0318, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 175 : Loss : 0.0312, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 176 : Loss : 0.0306, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 177 : Loss : 0.0301, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 178 : Loss : 0.0295, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 179 : Loss : 0.0290, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 180 : Loss : 0.0285, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 181 : Loss : 0.0280, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 182 : Loss : 0.0275, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 183 : Loss : 0.0270, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 184 : Loss : 0.0265, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 185 : Loss : 0.0261, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 186 : Loss : 0.0256, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 187 : Loss : 0.0252, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 188 : Loss : 0.0248, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 189 : Loss : 0.0244, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 190 : Loss : 0.0240, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 191 : Loss : 0.0236, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 192 : Loss : 0.0232, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 193 : Loss : 0.0229, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 194 : Loss : 0.0225, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 195 : Loss : 0.0222, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 196 : Loss : 0.0218, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 197 : Loss : 0.0215, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 198 : Loss : 0.0212, Acc : 1.0000, Test Acc : 0.7800\n",
"Epoch 199 : Loss : 0.0209, Acc : 1.0000, Test Acc : 0.7800\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"import math\n",
"\n",
"# Données et modèle du problème des 2 clusters\n",
"x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test = generate_2moons_dataset(num_lab=10, num_unlab=90, num_test=50)\n",
"model = create_model_2moons()\n",
"\n",
"# Hyperparamètres de l'apprentissage\n",
"lambdaa = 0.25\n",
"epochs = 200\n",
"batch_size = 16\n",
"if batch_size < x_train_lab.shape[0]:\n",
" steps_per_epoch = math.floor(x_train_lab.shape[0]/batch_size)\n",
"else:\n",
" steps_per_epoch = 1\n",
" batch_size = x_train_lab.shape[0]\n",
"\n",
"# Instanciation d'un optimiseur et d'une fonction de coût.\n",
"optimizer = keras.optimizers.Adam(learning_rate=1e-2)\n",
"loss_fn = keras.losses.BinaryCrossentropy()\n",
"\n",
"# Préparation des métriques pour le suivi de la performance du modèle.\n",
"train_acc_metric = keras.metrics.BinaryAccuracy()\n",
"test_acc_metric = keras.metrics.BinaryAccuracy()\n",
"\n",
"# Indices de l'ensemble labellisé\n",
"indices = np.arange(x_train_lab.shape[0])\n",
"indices_unlab = np.arange(x_train_unlab.shape[0])\n",
"\n",
"# Boucle sur les epochs\n",
"for epoch in range(epochs):\n",
"\n",
" # A chaque nouvelle epoch, on randomise les indices de l'ensemble labellisé\n",
" np.random.shuffle(indices)\n",
" np.random.shuffle(indices_unlab)\n",
"\n",
" # Et on recommence à cumuler la loss\n",
" cum_loss_value = 0\n",
"\n",
" for step in range(steps_per_epoch):\n",
"\n",
" # Sélection des données du prochain batch\n",
" x_batch = x_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
" x_batch_unlab = x_train_unlab[indices_unlab[step*batch_size: (step+1)*batch_size]]\n",
" y_batch = y_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
"\n",
" # Etape nécessaire pour comparer y_batch à la sortie du réseau\n",
" y_batch = np.expand_dims(y_batch, 1)\n",
"\n",
" # Les opérations effectuées par le modèle dans ce bloc sont suivies et permettront\n",
" # la différentiation automatique.\n",
" with tf.GradientTape() as tape:\n",
"\n",
" # Application du réseau aux données d'entrée\n",
" y_pred = model(x_batch, training=True) # Logits for this minibatch\n",
" y_pred_unlab = model(x_batch_unlab, training=True)\n",
"\n",
" # Calcul de la fonction de perte sur ce batch\n",
" loss_value = loss_fn(y_batch, y_pred) + lambdaa * binary_entropy_loss(y_pred)\n",
"\n",
" # Calcul des gradients par différentiation automatique\n",
" grads = tape.gradient(loss_value, model.trainable_weights)\n",
"\n",
" # Réalisation d'une itération de la descente de gradient (mise à jour des paramètres du réseau)\n",
" optimizer.apply_gradients(zip(grads, model.trainable_weights))\n",
"\n",
" # Mise à jour de la métrique\n",
" train_acc_metric.update_state(y_batch, y_pred)\n",
"\n",
" cum_loss_value = cum_loss_value + loss_value\n",
"\n",
" # Calcul de la précision à la fin de l'epoch\n",
" train_acc = train_acc_metric.result()\n",
"\n",
" # Calcul de la précision sur l'ensemble de test à la fin de l'epoch\n",
" test_logits = model(x_test, training=False)\n",
" test_acc_metric.update_state(np.expand_dims(y_test, 1), test_logits)\n",
" test_acc = test_acc_metric.result()\n",
"\n",
" print(\"Epoch %4d : Loss : %.4f, Acc : %.4f, Test Acc : %.4f\" % (epoch, float(cum_loss_value/steps_per_epoch), float(train_acc), float(test_acc)))\n",
"\n",
" # Remise à zéro des métriques pour la prochaine epoch\n",
" train_acc_metric.reset_states()\n",
" test_acc_metric.reset_states()"
]
},
{
"cell_type": "code",
"execution_count": 189,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from mlxtend.plotting import plot_decision_regions\n",
"\n",
"# Affichage des données\n",
"plt.plot(x_train_unlab[y_train_unlab==0,0], x_train_unlab[y_train_unlab==0,1], 'b.')\n",
"plt.plot(x_train_unlab[y_train_unlab==1,0], x_train_unlab[y_train_unlab==1,1], 'r.')\n",
"\n",
"plt.plot(x_test[y_test==0,0], x_test[y_test==0,1], 'b+')\n",
"plt.plot(x_test[y_test==1,0], x_test[y_test==1,1], 'r+')\n",
"\n",
"plt.plot(x_train_lab[y_train_lab==0,0], x_train_lab[y_train_lab==0,1], 'b.', markersize=30)\n",
"plt.plot(x_train_lab[y_train_lab==1,0], x_train_lab[y_train_lab==1,1], 'r.', markersize=30)\n",
"\n",
"plt.show()\n",
"\n",
"#Affichage de la frontière de décision\n",
"plot_decision_regions(x_train_unlab, y_train_unlab, clf=model, legend=2)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 113,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss : 0.4852, Acc : 0.7000, Test Acc : 0.6111\n",
"Epoch 1 : Loss : 0.4787, Acc : 0.7000, Test Acc : 0.6444\n",
"Epoch 2 : Loss : 0.4723, Acc : 0.7000, Test Acc : 0.6444\n",
"Epoch 3 : Loss : 0.4660, Acc : 0.7000, Test Acc : 0.6444\n",
"Epoch 4 : Loss : 0.4598, Acc : 0.7000, Test Acc : 0.6556\n",
"Epoch 5 : Loss : 0.4537, Acc : 0.7000, Test Acc : 0.6667\n",
"Epoch 6 : Loss : 0.4478, Acc : 0.7000, Test Acc : 0.6667\n",
"Epoch 7 : Loss : 0.4420, Acc : 0.7000, Test Acc : 0.6667\n",
"Epoch 8 : Loss : 0.4363, Acc : 0.7000, Test Acc : 0.6667\n",
"Epoch 9 : Loss : 0.4307, Acc : 0.7000, Test Acc : 0.6667\n",
"Epoch 10 : Loss : 0.4252, Acc : 0.7000, Test Acc : 0.6667\n",
"Epoch 11 : Loss : 0.4199, Acc : 0.7000, Test Acc : 0.6778\n",
"Epoch 12 : Loss : 0.4147, Acc : 0.7000, Test Acc : 0.6889\n",
"Epoch 13 : Loss : 0.4095, Acc : 0.7000, Test Acc : 0.6889\n",
"Epoch 14 : Loss : 0.4045, Acc : 0.7000, Test Acc : 0.6889\n",
"Epoch 15 : Loss : 0.3996, Acc : 0.7000, Test Acc : 0.6889\n",
"Epoch 16 : Loss : 0.3948, Acc : 0.7000, Test Acc : 0.7111\n",
"Epoch 17 : Loss : 0.3900, Acc : 0.7000, Test Acc : 0.7222\n",
"Epoch 18 : Loss : 0.3854, Acc : 0.7000, Test Acc : 0.7222\n",
"Epoch 19 : Loss : 0.3808, Acc : 0.7000, Test Acc : 0.7333\n",
"Epoch 20 : Loss : 0.3764, Acc : 0.7000, Test Acc : 0.7333\n",
"Epoch 21 : Loss : 0.3720, Acc : 0.7000, Test Acc : 0.7333\n",
"Epoch 22 : Loss : 0.3677, Acc : 0.7000, Test Acc : 0.7444\n",
"Epoch 23 : Loss : 0.3635, Acc : 0.7000, Test Acc : 0.7444\n",
"Epoch 24 : Loss : 0.3593, Acc : 0.7000, Test Acc : 0.7444\n",
"Epoch 25 : Loss : 0.3552, Acc : 0.7000, Test Acc : 0.7444\n",
"Epoch 26 : Loss : 0.3512, Acc : 0.7000, Test Acc : 0.7556\n",
"Epoch 27 : Loss : 0.3473, Acc : 0.7000, Test Acc : 0.7556\n",
"Epoch 28 : Loss : 0.3434, Acc : 0.7000, Test Acc : 0.7556\n",
"Epoch 29 : Loss : 0.3396, Acc : 0.7000, Test Acc : 0.7667\n",
"Epoch 30 : Loss : 0.3358, Acc : 0.7000, Test Acc : 0.7667\n",
"Epoch 31 : Loss : 0.3321, Acc : 0.7000, Test Acc : 0.7667\n",
"Epoch 32 : Loss : 0.3285, Acc : 0.7000, Test Acc : 0.7667\n",
"Epoch 33 : Loss : 0.3249, Acc : 0.7000, Test Acc : 0.7667\n",
"Epoch 34 : Loss : 0.3214, Acc : 0.7000, Test Acc : 0.7667\n",
"Epoch 35 : Loss : 0.3179, Acc : 0.7000, Test Acc : 0.7778\n",
"Epoch 36 : Loss : 0.3144, Acc : 0.7000, Test Acc : 0.7778\n",
"Epoch 37 : Loss : 0.3110, Acc : 0.7000, Test Acc : 0.7778\n",
"Epoch 38 : Loss : 0.3077, Acc : 0.7000, Test Acc : 0.7778\n",
"Epoch 39 : Loss : 0.3044, Acc : 0.7000, Test Acc : 0.7778\n",
"Epoch 40 : Loss : 0.3012, Acc : 0.7000, Test Acc : 0.7778\n",
"Epoch 41 : Loss : 0.2980, Acc : 0.8000, Test Acc : 0.7778\n",
"Epoch 42 : Loss : 0.2948, Acc : 0.8000, Test Acc : 0.7778\n",
"Epoch 43 : Loss : 0.2917, Acc : 0.8000, Test Acc : 0.7889\n",
"Epoch 44 : Loss : 0.2886, Acc : 0.8000, Test Acc : 0.7889\n",
"Epoch 45 : Loss : 0.2856, Acc : 0.8000, Test Acc : 0.7889\n",
"Epoch 46 : Loss : 0.2826, Acc : 0.8000, Test Acc : 0.7889\n",
"Epoch 47 : Loss : 0.2796, Acc : 0.8000, Test Acc : 0.7889\n",
"Epoch 48 : Loss : 0.2767, Acc : 0.8000, Test Acc : 0.7889\n",
"Epoch 49 : Loss : 0.2738, Acc : 0.8000, Test Acc : 0.7889\n",
"Epoch 50 : Loss : 0.2710, Acc : 0.8000, Test Acc : 0.8000\n",
"Epoch 51 : Loss : 0.6722, Acc : 0.8000, Test Acc : 0.8111\n",
"Epoch 52 : Loss : 0.6680, Acc : 0.8000, Test Acc : 0.8111\n",
"Epoch 53 : Loss : 0.6631, Acc : 0.8000, Test Acc : 0.8111\n",
"Epoch 54 : Loss : 0.6577, Acc : 0.8000, Test Acc : 0.8111\n",
"Epoch 55 : Loss : 0.6520, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 56 : Loss : 0.6462, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 57 : Loss : 0.6403, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 58 : Loss : 0.6344, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 59 : Loss : 0.6285, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 60 : Loss : 0.6227, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 61 : Loss : 0.6171, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 62 : Loss : 0.6116, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 63 : Loss : 0.6062, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 64 : Loss : 0.6011, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 65 : Loss : 0.5961, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 66 : Loss : 0.5913, Acc : 0.8000, Test Acc : 0.8222\n",
"Epoch 67 : Loss : 0.5866, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 68 : Loss : 0.5822, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 69 : Loss : 0.5779, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 70 : Loss : 0.5738, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 71 : Loss : 0.5698, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 72 : Loss : 0.5660, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 73 : Loss : 0.5624, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 74 : Loss : 0.5589, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 75 : Loss : 0.5555, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 76 : Loss : 0.5523, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 77 : Loss : 0.5491, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 78 : Loss : 0.5461, Acc : 0.8000, Test Acc : 0.8333\n",
"Epoch 79 : Loss : 0.5432, Acc : 0.8000, Test Acc : 0.8444\n",
"Epoch 80 : Loss : 0.5404, Acc : 0.8000, Test Acc : 0.8444\n",
"Epoch 81 : Loss : 0.5377, Acc : 0.8000, Test Acc : 0.8444\n",
"Epoch 82 : Loss : 0.5350, Acc : 0.8000, Test Acc : 0.8556\n",
"Epoch 83 : Loss : 0.5324, Acc : 0.8000, Test Acc : 0.8556\n",
"Epoch 84 : Loss : 0.5299, Acc : 0.9000, Test Acc : 0.8444\n",
"Epoch 85 : Loss : 0.5275, Acc : 0.9000, Test Acc : 0.8444\n",
"Epoch 86 : Loss : 0.5252, Acc : 0.9000, Test Acc : 0.8444\n",
"Epoch 87 : Loss : 0.5228, Acc : 0.9000, Test Acc : 0.8444\n",
"Epoch 88 : Loss : 0.5206, Acc : 0.9000, Test Acc : 0.8556\n",
"Epoch 89 : Loss : 0.5184, Acc : 0.9000, Test Acc : 0.8556\n",
"Epoch 90 : Loss : 0.5162, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 91 : Loss : 0.5141, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 92 : Loss : 0.5120, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 93 : Loss : 0.5100, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 94 : Loss : 0.5080, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 95 : Loss : 0.5060, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 96 : Loss : 0.5041, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 97 : Loss : 0.5022, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 98 : Loss : 0.5003, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 99 : Loss : 0.4984, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 100 : Loss : 0.4965, Acc : 0.9000, Test Acc : 0.8667\n",
"Epoch 101 : Loss : 0.4947, Acc : 0.9000, Test Acc : 0.8778\n",
"Epoch 102 : Loss : 0.4929, Acc : 0.9000, Test Acc : 0.8778\n",
"Epoch 103 : Loss : 0.4911, Acc : 1.0000, Test Acc : 0.8778\n",
"Epoch 104 : Loss : 0.4893, Acc : 1.0000, Test Acc : 0.8778\n",
"Epoch 105 : Loss : 0.4875, Acc : 1.0000, Test Acc : 0.8778\n",
"Epoch 106 : Loss : 0.4858, Acc : 1.0000, Test Acc : 0.8778\n",
"Epoch 107 : Loss : 0.4840, Acc : 1.0000, Test Acc : 0.8778\n",
"Epoch 108 : Loss : 0.4822, Acc : 1.0000, Test Acc : 0.8778\n",
"Epoch 109 : Loss : 0.4805, Acc : 1.0000, Test Acc : 0.8778\n",
"Epoch 110 : Loss : 0.4788, Acc : 1.0000, Test Acc : 0.8778\n",
"Epoch 111 : Loss : 0.4770, Acc : 1.0000, Test Acc : 0.8889\n",
"Epoch 112 : Loss : 0.4753, Acc : 1.0000, Test Acc : 0.8889\n",
"Epoch 113 : Loss : 0.4736, Acc : 1.0000, Test Acc : 0.8889\n",
"Epoch 114 : Loss : 0.4719, Acc : 1.0000, Test Acc : 0.8889\n",
"Epoch 115 : Loss : 0.4702, Acc : 1.0000, Test Acc : 0.8889\n",
"Epoch 116 : Loss : 0.4685, Acc : 1.0000, Test Acc : 0.9000\n",
"Epoch 117 : Loss : 0.4668, Acc : 1.0000, Test Acc : 0.9000\n",
"Epoch 118 : Loss : 0.4650, Acc : 1.0000, Test Acc : 0.9000\n",
"Epoch 119 : Loss : 0.4633, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 120 : Loss : 0.4616, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 121 : Loss : 0.4599, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 122 : Loss : 0.4582, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 123 : Loss : 0.4565, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 124 : Loss : 0.4548, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 125 : Loss : 0.4531, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 126 : Loss : 0.4513, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 127 : Loss : 0.4496, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 128 : Loss : 0.4479, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 129 : Loss : 0.4461, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 130 : Loss : 0.4444, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 131 : Loss : 0.4427, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 132 : Loss : 0.4409, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 133 : Loss : 0.4392, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 134 : Loss : 0.4374, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 135 : Loss : 0.4356, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 136 : Loss : 0.4339, Acc : 1.0000, Test Acc : 0.9111\n",
"Epoch 137 : Loss : 0.4321, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 138 : Loss : 0.4303, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 139 : Loss : 0.4285, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 140 : Loss : 0.4267, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 141 : Loss : 0.4249, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 142 : Loss : 0.4231, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 143 : Loss : 0.4213, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 144 : Loss : 0.4194, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 145 : Loss : 0.4176, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 146 : Loss : 0.4158, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 147 : Loss : 0.4139, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 148 : Loss : 0.4120, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 149 : Loss : 0.4102, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 150 : Loss : 0.4083, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 151 : Loss : 0.4064, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 152 : Loss : 0.4045, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 153 : Loss : 0.4027, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 154 : Loss : 0.4008, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 155 : Loss : 0.3988, Acc : 1.0000, Test Acc : 0.9222\n",
"Epoch 156 : Loss : 0.3969, Acc : 1.0000, Test Acc : 0.9333\n",
"Epoch 157 : Loss : 0.3950, Acc : 1.0000, Test Acc : 0.9333\n",
"Epoch 158 : Loss : 0.3931, Acc : 1.0000, Test Acc : 0.9444\n",
"Epoch 159 : Loss : 0.3912, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 160 : Loss : 0.3892, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 161 : Loss : 0.3873, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 162 : Loss : 0.3853, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 163 : Loss : 0.3834, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 164 : Loss : 0.3814, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 165 : Loss : 0.3794, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 166 : Loss : 0.3775, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 167 : Loss : 0.3755, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 168 : Loss : 0.3735, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 169 : Loss : 0.3715, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 170 : Loss : 0.3695, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 171 : Loss : 0.3675, Acc : 1.0000, Test Acc : 0.9556\n",
"Epoch 172 : Loss : 0.3656, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 173 : Loss : 0.3636, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 174 : Loss : 0.3616, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 175 : Loss : 0.3596, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 176 : Loss : 0.3576, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 177 : Loss : 0.3556, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 178 : Loss : 0.3536, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 179 : Loss : 0.3516, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 180 : Loss : 0.3496, Acc : 1.0000, Test Acc : 0.9667\n",
"Epoch 181 : Loss : 0.3476, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 182 : Loss : 0.3456, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 183 : Loss : 0.3436, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 184 : Loss : 0.3416, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 185 : Loss : 0.3396, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 186 : Loss : 0.3376, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 187 : Loss : 0.3356, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 188 : Loss : 0.3336, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 189 : Loss : 0.3316, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 190 : Loss : 0.3296, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 191 : Loss : 0.3277, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 192 : Loss : 0.3257, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 193 : Loss : 0.3237, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 194 : Loss : 0.3218, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 195 : Loss : 0.3198, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 196 : Loss : 0.3179, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 197 : Loss : 0.3159, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 198 : Loss : 0.3140, Acc : 1.0000, Test Acc : 0.9778\n",
"Epoch 199 : Loss : 0.3121, Acc : 1.0000, Test Acc : 0.9778\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"import math\n",
"\n",
"# Données et modèle du problème des 2 clusters\n",
"x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test = generate_2clusters_dataset(num_lab=10, num_unlab=90, num_test=90)\n",
"model = create_model_2clusters()\n",
"\n",
"# Hyperparamètres de l'apprentissage\n",
"epochs = 200\n",
"batch_size = 16\n",
"if batch_size < x_train_lab.shape[0]:\n",
" steps_per_epoch = math.floor(x_train_lab.shape[0]/batch_size)\n",
"else:\n",
" steps_per_epoch = 1\n",
" batch_size = x_train_lab.shape[0]\n",
"\n",
"# Instanciation d'un optimiseur et d'une fonction de coût.\n",
"optimizer = keras.optimizers.Adam(learning_rate=1e-2)\n",
"loss_fn = keras.losses.BinaryCrossentropy()\n",
"\n",
"# Préparation des métriques pour le suivi de la performance du modèle.\n",
"train_acc_metric = keras.metrics.BinaryAccuracy()\n",
"test_acc_metric = keras.metrics.BinaryAccuracy()\n",
"\n",
"# Indices de l'ensemble labellisé\n",
"indices = np.arange(x_train_lab.shape[0])\n",
"indices_unlab = np.arange(x_train_unlab.shape[0])\n",
"\n",
"# Boucle sur les epochs\n",
"for epoch in range(epochs):\n",
"\n",
" if epoch > 50:\n",
" lambdaa = 0.25\n",
" else:\n",
" lambdaa = 0\n",
"\n",
" # A chaque nouvelle epoch, on randomise les indices de l'ensemble labellisé\n",
" np.random.shuffle(indices)\n",
" np.random.shuffle(indices_unlab)\n",
"\n",
" # Et on recommence à cumuler la loss\n",
" cum_loss_value = 0\n",
"\n",
" for step in range(steps_per_epoch):\n",
"\n",
" # Sélection des données du prochain batch\n",
" x_batch = x_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
" x_batch_unlab = x_train_unlab[indices_unlab[step*batch_size: (step+1)*batch_size]]\n",
" y_batch = y_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
"\n",
" # Etape nécessaire pour comparer y_batch à la sortie du réseau\n",
" y_batch = np.expand_dims(y_batch, 1)\n",
"\n",
" # Les opérations effectuées par le modèle dans ce bloc sont suivies et permettront\n",
" # la différentiation automatique.\n",
" with tf.GradientTape() as tape:\n",
"\n",
" # Application du réseau aux données d'entrée\n",
" y_pred = model(x_batch, training=True) # Logits for this minibatch\n",
" y_pred_unlab = model(x_batch_unlab, training=True)\n",
"\n",
" # Calcul de la fonction de perte sur ce batch\n",
" loss_value = loss_fn(y_batch, y_pred) + lambdaa * binary_entropy_loss(y_pred)\n",
"\n",
" # Calcul des gradients par différentiation automatique\n",
" grads = tape.gradient(loss_value, model.trainable_weights)\n",
"\n",
" # Réalisation d'une itération de la descente de gradient (mise à jour des paramètres du réseau)\n",
" optimizer.apply_gradients(zip(grads, model.trainable_weights))\n",
"\n",
" # Mise à jour de la métrique\n",
" train_acc_metric.update_state(y_batch, y_pred)\n",
"\n",
" cum_loss_value = cum_loss_value + loss_value\n",
"\n",
" # Calcul de la précision à la fin de l'epoch\n",
" train_acc = train_acc_metric.result()\n",
"\n",
" # Calcul de la précision sur l'ensemble de test à la fin de l'epoch\n",
" test_logits = model(x_test, training=False)\n",
" test_acc_metric.update_state(np.expand_dims(y_test, 1), test_logits)\n",
" test_acc = test_acc_metric.result()\n",
"\n",
" print(\"Epoch %4d : Loss : %.4f, Acc : %.4f, Test Acc : %.4f\" % (epoch, float(cum_loss_value/steps_per_epoch), float(train_acc), float(test_acc)))\n",
"\n",
" # Remise à zéro des métriques pour la prochaine epoch\n",
" train_acc_metric.reset_states()\n",
" test_acc_metric.reset_states()"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from mlxtend.plotting import plot_decision_regions\n",
"\n",
"# Affichage des données\n",
"plt.plot(x_train_unlab[y_train_unlab==0,0], x_train_unlab[y_train_unlab==0,1], 'b.')\n",
"plt.plot(x_train_unlab[y_train_unlab==1,0], x_train_unlab[y_train_unlab==1,1], 'r.')\n",
"\n",
"plt.plot(x_test[y_test==0,0], x_test[y_test==0,1], 'b+')\n",
"plt.plot(x_test[y_test==1,0], x_test[y_test==1,1], 'r+')\n",
"\n",
"plt.plot(x_train_lab[y_train_lab==0,0], x_train_lab[y_train_lab==0,1], 'b.', markersize=30)\n",
"plt.plot(x_train_lab[y_train_lab==1,0], x_train_lab[y_train_lab==1,1], 'r.', markersize=30)\n",
"\n",
"plt.show()\n",
"\n",
"#Affichage de la frontière de décision\n",
"plot_decision_regions(x_train_unlab, y_train_unlab, clf=model, legend=2)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "y25fa_IIZeuH"
},
"source": [
"Une fois cette étape réalisée, vous pouvez tester l'algorithme sur le dataset des 2 lunes ; comme annoncé en cours, vous devriez avoir beaucoup de mal à faire fonctionner l'algorithme sur ces données.\n",
"\n",
"S'il vous reste du temps, vous pouvez également tester votre algorithme sur les données MNIST, cela vous avancera pour la prochaine séance."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "T3qJ5s-NUPnT"
},
"source": [
"# MNIST"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kH_eMruIMMVF"
},
"source": [
"## Chargement des données\n"
]
},
{
"cell_type": "code",
"execution_count": 166,
"metadata": {
"id": "ebv6WLB1MOkU"
},
"outputs": [],
"source": [
"from keras.datasets import mnist\n",
"import numpy as np\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"def generate_mnist_dataset(num_lab = 10, seed=10):\n",
"\n",
" # Chargement et normalisation (entre 0 et 1) des données de la base de données MNIST\n",
" (x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
"\n",
" x_train = np.expand_dims(x_train.astype('float32') / 255., 3)\n",
" x_test = np.expand_dims(x_test.astype('float32') / 255., 3)\n",
"\n",
" x_train_lab, x_train_unlab, y_train_lab, y_train_unlab = train_test_split(x_train, y_train, test_size=(x_train.shape[0]-num_lab)/x_train.shape[0], random_state=seed)\n",
"\n",
" return x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test\n"
]
},
{
"cell_type": "code",
"execution_count": 184,
"metadata": {
"id": "ZTsEZ2pzMpiU"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[7 5 9 4 4 1 8 1 0 7]\n",
"[7 2 8 3 1 4 6 9 5 0]\n",
"[0 5 6 4 5 5 8 2 1 4]\n"
]
}
],
"source": [
"# for i in range(1000, 10000):\n",
"# x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test = generate_mnist_dataset(num_lab = 10, seed=i)\n",
"# if len(set(y_train_lab)) >= 10:\n",
"# print(i)\n",
"# break\n",
"\n",
"# print(y_train_lab)\n",
"# print(len(y_train_lab))\n",
"# print(set(y_train_lab))\n",
"# test = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
"# print(set(test))\n",
"# print(len(set(y_train_lab)))\n",
"\n",
"# print(x_train_lab.shape, x_train_unlab.shape, x_test.shape)\n",
"# print(y_train_lab.shape, y_train_unlab.shape, y_test.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cl7GCcHvUa-l"
},
"source": [
"## Définition du modèle"
]
},
{
"cell_type": "code",
"execution_count": 142,
"metadata": {
"id": "RiYrQU0NUcKs"
},
"outputs": [],
"source": [
"from keras.layers import Conv2D, MaxPooling2D, Flatten\n",
"\n",
"# Ici, on implémentera le modèle LeNet-5 :\n",
"def create_model_mnist():\n",
"\n",
" inputs = keras.Input(shape=(28, 28, 1,))\n",
"\n",
" # 1 couche de convolution 5x5 à 6 filtres suivie d'un max pooling\n",
" x = Conv2D(6, 5, activation = 'relu')(inputs)\n",
" x = MaxPooling2D(pool_size=(2, 2))(x)\n",
"\n",
" # puis 1 couche de convolution 5x5 à 16 filtres suivie d'un max pooling\n",
" x = Conv2D(16, 5, activation = 'relu')(x)\n",
" x = MaxPooling2D(pool_size=(2, 2))(x)\n",
"\n",
" # et d'un Flatten\n",
" x = Flatten()(x)\n",
"\n",
" # Enfin 2 couches denses de 120 et 84 neurones\n",
" x = Dense(120, activation='relu')(x)\n",
" x = Dense(84, activation='relu')(x)\n",
"\n",
" # avant la couche de sortie à 10 neurones.\n",
" outputs = Dense(10, activation='softmax')(x)\n",
"\n",
" model = keras.Model(inputs=inputs, outputs=outputs) \n",
"\n",
" return model"
]
},
{
"cell_type": "code",
"execution_count": 190,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss : 2.3014, Acc : 0.1000, Test Acc : 0.1074\n",
"Epoch 1 : Loss : 2.2547, Acc : 0.3000, Test Acc : 0.1335\n",
"Epoch 2 : Loss : 2.2146, Acc : 0.4000, Test Acc : 0.1968\n",
"Epoch 3 : Loss : 2.1732, Acc : 0.6000, Test Acc : 0.2695\n",
"Epoch 4 : Loss : 2.1275, Acc : 0.7000, Test Acc : 0.3152\n",
"Epoch 5 : Loss : 2.0814, Acc : 0.8000, Test Acc : 0.3496\n",
"Epoch 6 : Loss : 2.0271, Acc : 0.8000, Test Acc : 0.3671\n",
"Epoch 7 : Loss : 1.9674, Acc : 0.8000, Test Acc : 0.3805\n",
"Epoch 8 : Loss : 1.9000, Acc : 0.8000, Test Acc : 0.3940\n",
"Epoch 9 : Loss : 1.8275, Acc : 0.8000, Test Acc : 0.4053\n",
"Epoch 10 : Loss : 1.7498, Acc : 0.9000, Test Acc : 0.4102\n",
"Epoch 11 : Loss : 1.6640, Acc : 0.9000, Test Acc : 0.4171\n",
"Epoch 12 : Loss : 1.5701, Acc : 0.9000, Test Acc : 0.4208\n",
"Epoch 13 : Loss : 1.4696, Acc : 0.9000, Test Acc : 0.4260\n",
"Epoch 14 : Loss : 1.3669, Acc : 0.9000, Test Acc : 0.4301\n",
"Epoch 15 : Loss : 1.2611, Acc : 0.9000, Test Acc : 0.4359\n",
"Epoch 16 : Loss : 1.1529, Acc : 0.9000, Test Acc : 0.4425\n",
"Epoch 17 : Loss : 1.0442, Acc : 0.9000, Test Acc : 0.4470\n",
"Epoch 18 : Loss : 0.9338, Acc : 1.0000, Test Acc : 0.4501\n",
"Epoch 19 : Loss : 0.8274, Acc : 1.0000, Test Acc : 0.4498\n",
"Epoch 20 : Loss : 0.7254, Acc : 1.0000, Test Acc : 0.4487\n",
"Epoch 21 : Loss : 0.6296, Acc : 1.0000, Test Acc : 0.4457\n",
"Epoch 22 : Loss : 0.5413, Acc : 1.0000, Test Acc : 0.4438\n",
"Epoch 23 : Loss : 0.4580, Acc : 1.0000, Test Acc : 0.4425\n",
"Epoch 24 : Loss : 0.3813, Acc : 1.0000, Test Acc : 0.4404\n",
"Epoch 25 : Loss : 0.3130, Acc : 1.0000, Test Acc : 0.4395\n",
"Epoch 26 : Loss : 1.8660, Acc : 1.0000, Test Acc : 0.4432\n",
"Epoch 27 : Loss : 1.5501, Acc : 1.0000, Test Acc : 0.4450\n",
"Epoch 28 : Loss : 1.2730, Acc : 1.0000, Test Acc : 0.4461\n",
"Epoch 29 : Loss : 1.0235, Acc : 1.0000, Test Acc : 0.4431\n",
"Epoch 30 : Loss : 0.7895, Acc : 1.0000, Test Acc : 0.4384\n",
"Epoch 31 : Loss : 0.5879, Acc : 1.0000, Test Acc : 0.4381\n",
"Epoch 32 : Loss : 0.4273, Acc : 1.0000, Test Acc : 0.4399\n",
"Epoch 33 : Loss : 0.3016, Acc : 1.0000, Test Acc : 0.4425\n",
"Epoch 34 : Loss : 0.2109, Acc : 1.0000, Test Acc : 0.4444\n",
"Epoch 35 : Loss : 0.1455, Acc : 1.0000, Test Acc : 0.4435\n",
"Epoch 36 : Loss : 0.0974, Acc : 1.0000, Test Acc : 0.4459\n",
"Epoch 37 : Loss : 0.0641, Acc : 1.0000, Test Acc : 0.4455\n",
"Epoch 38 : Loss : 0.0427, Acc : 1.0000, Test Acc : 0.4473\n",
"Epoch 39 : Loss : 0.0290, Acc : 1.0000, Test Acc : 0.4475\n",
"Epoch 40 : Loss : 0.0200, Acc : 1.0000, Test Acc : 0.4470\n",
"Epoch 41 : Loss : 0.0138, Acc : 1.0000, Test Acc : 0.4471\n",
"Epoch 42 : Loss : 0.0097, Acc : 1.0000, Test Acc : 0.4473\n",
"Epoch 43 : Loss : 0.0069, Acc : 1.0000, Test Acc : 0.4474\n",
"Epoch 44 : Loss : 0.0050, Acc : 1.0000, Test Acc : 0.4475\n",
"Epoch 45 : Loss : 0.0037, Acc : 1.0000, Test Acc : 0.4478\n",
"Epoch 46 : Loss : 0.0029, Acc : 1.0000, Test Acc : 0.4492\n",
"Epoch 47 : Loss : 0.0022, Acc : 1.0000, Test Acc : 0.4495\n",
"Epoch 48 : Loss : 0.0018, Acc : 1.0000, Test Acc : 0.4498\n",
"Epoch 49 : Loss : 0.0014, Acc : 1.0000, Test Acc : 0.4497\n",
"Epoch 50 : Loss : 0.0011, Acc : 1.0000, Test Acc : 0.4508\n",
"Epoch 51 : Loss : 0.0009, Acc : 1.0000, Test Acc : 0.4520\n",
"Epoch 52 : Loss : 0.0008, Acc : 1.0000, Test Acc : 0.4524\n",
"Epoch 53 : Loss : 0.0007, Acc : 1.0000, Test Acc : 0.4528\n",
"Epoch 54 : Loss : 0.0006, Acc : 1.0000, Test Acc : 0.4534\n",
"Epoch 55 : Loss : 0.0005, Acc : 1.0000, Test Acc : 0.4537\n",
"Epoch 56 : Loss : 0.0004, Acc : 1.0000, Test Acc : 0.4540\n",
"Epoch 57 : Loss : 0.0004, Acc : 1.0000, Test Acc : 0.4550\n",
"Epoch 58 : Loss : 0.0003, Acc : 1.0000, Test Acc : 0.4559\n",
"Epoch 59 : Loss : 0.0003, Acc : 1.0000, Test Acc : 0.4560\n",
"Epoch 60 : Loss : 0.0003, Acc : 1.0000, Test Acc : 0.4559\n",
"Epoch 61 : Loss : 0.0002, Acc : 1.0000, Test Acc : 0.4559\n",
"Epoch 62 : Loss : 0.0002, Acc : 1.0000, Test Acc : 0.4560\n",
"Epoch 63 : Loss : 0.0002, Acc : 1.0000, Test Acc : 0.4563\n",
"Epoch 64 : Loss : 0.0002, Acc : 1.0000, Test Acc : 0.4562\n",
"Epoch 65 : Loss : 0.0002, Acc : 1.0000, Test Acc : 0.4566\n",
"Epoch 66 : Loss : 0.0002, Acc : 1.0000, Test Acc : 0.4572\n",
"Epoch 67 : Loss : 0.0002, Acc : 1.0000, Test Acc : 0.4579\n",
"Epoch 68 : Loss : 0.0002, Acc : 1.0000, Test Acc : 0.4580\n",
"Epoch 69 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4582\n",
"Epoch 70 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4582\n",
"Epoch 71 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4585\n",
"Epoch 72 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4585\n",
"Epoch 73 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4585\n",
"Epoch 74 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4586\n",
"Epoch 75 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4583\n",
"Epoch 76 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4583\n",
"Epoch 77 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4580\n",
"Epoch 78 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4577\n",
"Epoch 79 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4573\n",
"Epoch 80 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4577\n",
"Epoch 81 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4576\n",
"Epoch 82 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4576\n",
"Epoch 83 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4574\n",
"Epoch 84 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4573\n",
"Epoch 85 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4572\n",
"Epoch 86 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4574\n",
"Epoch 87 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4573\n",
"Epoch 88 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4571\n",
"Epoch 89 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4570\n",
"Epoch 90 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4569\n",
"Epoch 91 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4567\n",
"Epoch 92 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4567\n",
"Epoch 93 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4567\n",
"Epoch 94 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4567\n",
"Epoch 95 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4569\n",
"Epoch 96 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4567\n",
"Epoch 97 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4568\n",
"Epoch 98 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4568\n",
"Epoch 99 : Loss : 0.0001, Acc : 1.0000, Test Acc : 0.4571\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"import math\n",
"\n",
"# Données et modèle du problème des 2 clusters\n",
"x_train_lab, y_train_lab, x_train_unlab, y_train_unlab, x_test, y_test = generate_mnist_dataset(num_lab=10, seed=1164)\n",
"model = create_model_mnist()\n",
"\n",
"# Hyperparamètres de l'apprentissage\n",
"epochs = 100\n",
"batch_size = 64\n",
"if batch_size < x_train_lab.shape[0]:\n",
" steps_per_epoch = math.floor(x_train_lab.shape[0]/batch_size)\n",
"else:\n",
" steps_per_epoch = 1\n",
" batch_size = x_train_lab.shape[0]\n",
"\n",
"# Instanciation d'un optimiseur et d'une fonction de coût.\n",
"optimizer = keras.optimizers.Adam(learning_rate=1e-3)\n",
"loss_fn = keras.losses.SparseCategoricalCrossentropy()\n",
"\n",
"# Préparation des métriques pour le suivi de la performance du modèle.\n",
"train_acc_metric = keras.metrics.SparseCategoricalAccuracy()\n",
"test_acc_metric = keras.metrics.SparseCategoricalAccuracy()\n",
"\n",
"# Indices de l'ensemble labellisé\n",
"indices = np.arange(x_train_lab.shape[0])\n",
"indices_unlab = np.arange(x_train_unlab.shape[0])\n",
"\n",
"# Boucle sur les epochs\n",
"for epoch in range(epochs):\n",
"\n",
" if epoch > 25:\n",
" lambdaa = 0.2\n",
" else:\n",
" lambdaa = 0\n",
"\n",
" # A chaque nouvelle epoch, on randomise les indices de l'ensemble labellisé\n",
" np.random.shuffle(indices)\n",
" np.random.shuffle(indices_unlab)\n",
"\n",
" # Et on recommence à cumuler la loss\n",
" cum_loss_value = 0\n",
"\n",
" for step in range(steps_per_epoch):\n",
"\n",
" # Sélection des données du prochain batch\n",
" x_batch = x_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
" x_batch_unlab = x_train_unlab[indices_unlab[step*batch_size: (step+1)*batch_size]]\n",
" y_batch = y_train_lab[indices[step*batch_size: (step+1)*batch_size]]\n",
"\n",
" # Etape nécessaire pour comparer y_batch à la sortie du réseau\n",
" y_batch = np.expand_dims(y_batch, 1)\n",
"\n",
" # Les opérations effectuées par le modèle dans ce bloc sont suivies et permettront\n",
" # la différentiation automatique.\n",
" with tf.GradientTape() as tape:\n",
"\n",
" # Application du réseau aux données d'entrée\n",
" y_pred = model(x_batch, training=True) # Logits for this minibatch\n",
" y_pred_unlab = model(x_batch_unlab, training=True)\n",
"\n",
" # Calcul de la fonction de perte sur ce batch\n",
" # print(y_batch)\n",
" # print(y_pred)\n",
" loss_value = loss_fn(y_batch, y_pred) + lambdaa * binary_entropy_loss(y_pred)\n",
"\n",
" # Calcul des gradients par différentiation automatique\n",
" grads = tape.gradient(loss_value, model.trainable_weights)\n",
"\n",
" # Réalisation d'une itération de la descente de gradient (mise à jour des paramètres du réseau)\n",
" optimizer.apply_gradients(zip(grads, model.trainable_weights))\n",
"\n",
" # Mise à jour de la métrique\n",
" train_acc_metric.update_state(y_batch, y_pred)\n",
"\n",
" cum_loss_value = cum_loss_value + loss_value\n",
"\n",
" # Calcul de la précision à la fin de l'epoch\n",
" train_acc = train_acc_metric.result()\n",
"\n",
" # Calcul de la précision sur l'ensemble de test à la fin de l'epoch\n",
" test_logits = model(x_test, training=False)\n",
" test_acc_metric.update_state(np.expand_dims(y_test, 1), test_logits)\n",
" test_acc = test_acc_metric.result()\n",
"\n",
" print(\"Epoch %4d : Loss : %.4f, Acc : %.4f, Test Acc : %.4f\" % (epoch, float(cum_loss_value/steps_per_epoch), float(train_acc), float(test_acc)))\n",
"\n",
" # Remise à zéro des métriques pour la prochaine epoch\n",
" train_acc_metric.reset_states()\n",
" test_acc_metric.reset_states()"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [
"fbmhai8PVXVd",
"kH_eMruIMMVF"
],
"machine_shape": "hm",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3.10.7 64-bit",
"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.10.7"
},
"vscode": {
"interpreter": {
"hash": "767d51c1340bd893661ea55ea3124f6de3c7a262a8b4abca0554b478b1e2ff90"
}
}
},
"nbformat": 4,
"nbformat_minor": 0
}