├── 01_Premier_neurone.ipynb ├── 02_Application_catdog.ipynb ├── 03_ANN_2couches.ipynb ├── 04_ANN_profond.ipynb ├── README.md ├── Tensorflow_MNIST_pour_débutants.ipynb ├── datasets ├── testset.hdf5 └── trainset.hdf5 └── utilities.py /03_ANN_2couches.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "from sklearn.datasets import make_blobs, make_circles\n", 12 | "from sklearn.metrics import accuracy_score, log_loss\n", 13 | "from tqdm import tqdm" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "# Fonctions" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "def initialisation(n0, n1, n2):\n", 30 | "\n", 31 | " W1 = np.random.randn(n1, n0)\n", 32 | " b1 = np.zeros((n1, 1))\n", 33 | " W2 = np.random.randn(n2, n1)\n", 34 | " b2 = np.zeros((n2, 1))\n", 35 | "\n", 36 | " parametres = {\n", 37 | " 'W1': W1,\n", 38 | " 'b1': b1,\n", 39 | " 'W2': W2,\n", 40 | " 'b2': b2\n", 41 | " }\n", 42 | "\n", 43 | " return parametres" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 3, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "def forward_propagation(X, parametres):\n", 53 | "\n", 54 | " W1 = parametres['W1']\n", 55 | " b1 = parametres['b1']\n", 56 | " W2 = parametres['W2']\n", 57 | " b2 = parametres['b2']\n", 58 | "\n", 59 | " Z1 = W1.dot(X) + b1\n", 60 | " A1 = 1 / (1 + np.exp(-Z1))\n", 61 | "\n", 62 | " Z2 = W2.dot(A1) + b2\n", 63 | " A2 = 1 / (1 + np.exp(-Z2))\n", 64 | "\n", 65 | " activations = {\n", 66 | " 'A1': A1,\n", 67 | " 'A2': A2\n", 68 | " }\n", 69 | "\n", 70 | " return activations" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 4, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "def back_propagation(X, y, parametres, activations):\n", 80 | "\n", 81 | " A1 = activations['A1']\n", 82 | " A2 = activations['A2']\n", 83 | " W2 = parametres['W2']\n", 84 | "\n", 85 | " m = y.shape[1]\n", 86 | "\n", 87 | " dZ2 = A2 - y\n", 88 | " dW2 = 1 / m * dZ2.dot(A1.T)\n", 89 | " db2 = 1 / m * np.sum(dZ2, axis=1, keepdims = True)\n", 90 | "\n", 91 | " dZ1 = np.dot(W2.T, dZ2) * A1 * (1 - A1)\n", 92 | " dW1 = 1 / m * dZ1.dot(X.T)\n", 93 | " db1 = 1 / m * np.sum(dZ1, axis=1, keepdims = True)\n", 94 | "\n", 95 | " gradients = {\n", 96 | " 'dW1' : dW1,\n", 97 | " 'db1' : db1,\n", 98 | " 'dW2' : dW2,\n", 99 | " 'db2' : db2\n", 100 | " }\n", 101 | " \n", 102 | " return gradients" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 5, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "def update(gradients, parametres, learning_rate):\n", 112 | "\n", 113 | " W1 = parametres['W1']\n", 114 | " b1 = parametres['b1']\n", 115 | " W2 = parametres['W2']\n", 116 | " b2 = parametres['b2']\n", 117 | "\n", 118 | " dW1 = gradients['dW1']\n", 119 | " db1 = gradients['db1']\n", 120 | " dW2 = gradients['dW2']\n", 121 | " db2 = gradients['db2']\n", 122 | "\n", 123 | " W1 = W1 - learning_rate * dW1\n", 124 | " b1 = b1 - learning_rate * db1\n", 125 | " W2 = W2 - learning_rate * dW2\n", 126 | " b2 = b2 - learning_rate * db2\n", 127 | "\n", 128 | " parametres = {\n", 129 | " 'W1': W1,\n", 130 | " 'b1': b1,\n", 131 | " 'W2': W2,\n", 132 | " 'b2': b2\n", 133 | " }\n", 134 | "\n", 135 | " return parametres" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 6, 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [ 144 | "def predict(X, parametres):\n", 145 | " activations = forward_propagation(X, parametres)\n", 146 | " A2 = activations['A2']\n", 147 | " return A2 >= 0.5" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 9, 153 | "metadata": {}, 154 | "outputs": [], 155 | "source": [ 156 | "def neural_network(X, y, n1=32, learning_rate = 0.1, n_iter = 1000):\n", 157 | "\n", 158 | " # initialisation parametres\n", 159 | " n0 = X.shape[0]\n", 160 | " n2 = y.shape[0]\n", 161 | " np.random.seed(0)\n", 162 | " parametres = initialisation(n0, n1, n2)\n", 163 | "\n", 164 | " train_loss = []\n", 165 | " train_acc = []\n", 166 | " history = []\n", 167 | "\n", 168 | " # gradient descent\n", 169 | " for i in tqdm(range(n_iter)):\n", 170 | " activations = forward_propagation(X, parametres)\n", 171 | " A2 = activations['A2']\n", 172 | "\n", 173 | " # Plot courbe d'apprentissage\n", 174 | " train_loss.append(log_loss(y.flatten(), A2.flatten()))\n", 175 | " y_pred = predict(X, parametres)\n", 176 | " train_acc.append(accuracy_score(y.flatten(), y_pred.flatten()))\n", 177 | " \n", 178 | " history.append([parametres.copy(), train_loss, train_acc, i])\n", 179 | "\n", 180 | " # mise a jour\n", 181 | " gradients = back_propagation(X, y, parametres, activations)\n", 182 | " parametres = update(gradients, parametres, learning_rate)\n", 183 | "\n", 184 | "\n", 185 | " plt.figure(figsize=(12, 4))\n", 186 | " plt.subplot(1, 2, 1)\n", 187 | " plt.plot(train_loss, label='train loss')\n", 188 | " plt.legend()\n", 189 | " plt.subplot(1, 2, 2)\n", 190 | " plt.plot(train_acc, label='train acc')\n", 191 | " plt.legend()\n", 192 | " plt.show()\n", 193 | "\n", 194 | " return parametres" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "metadata": {}, 200 | "source": [ 201 | "# Dataset" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": 8, 207 | "metadata": {}, 208 | "outputs": [ 209 | { 210 | "name": "stdout", 211 | "output_type": "stream", 212 | "text": [ 213 | "dimensions de X: (2, 100)\n", 214 | "dimensions de y: (1, 100)\n" 215 | ] 216 | }, 217 | { 218 | "data": { 219 | "image/png": "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", 220 | "text/plain": [ 221 | "
" 222 | ] 223 | }, 224 | "metadata": { 225 | "needs_background": "light" 226 | }, 227 | "output_type": "display_data" 228 | } 229 | ], 230 | "source": [ 231 | "X, y = make_circles(n_samples=100, noise=0.1, factor=0.3, random_state=0)\n", 232 | "X = X.T\n", 233 | "y = y.reshape((1, y.shape[0]))\n", 234 | "\n", 235 | "print('dimensions de X:', X.shape)\n", 236 | "print('dimensions de y:', y.shape)\n", 237 | "\n", 238 | "plt.scatter(X[0, :], X[1, :], c=y, cmap='summer')\n", 239 | "plt.show()" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 10, 245 | "metadata": {}, 246 | "outputs": [ 247 | { 248 | "name": "stderr", 249 | "output_type": "stream", 250 | "text": [ 251 | "100%|██████████| 1000/1000 [00:00<00:00, 1652.52it/s]\n" 252 | ] 253 | }, 254 | { 255 | "data": { 256 | "image/png": "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", 257 | "text/plain": [ 258 | "
" 259 | ] 260 | }, 261 | "metadata": { 262 | "needs_background": "light" 263 | }, 264 | "output_type": "display_data" 265 | }, 266 | { 267 | "data": { 268 | "text/plain": [ 269 | "{'W1': array([[ 1.80212588, 0.37821374],\n", 270 | " [ 1.01147118, 2.72196966],\n", 271 | " [ 2.58920092, -1.12112355],\n", 272 | " [ 1.0508304 , -0.23999551],\n", 273 | " [-0.32911352, 0.61126472],\n", 274 | " [ 0.10449739, 1.5211303 ],\n", 275 | " [ 0.90568599, 0.00334079],\n", 276 | " [ 0.44974817, 0.32479341],\n", 277 | " [ 2.19228574, -0.55199865],\n", 278 | " [ 0.07362119, -0.72521454],\n", 279 | " [-2.55294805, 0.64962759],\n", 280 | " [ 0.79621311, -0.67148306],\n", 281 | " [ 2.47060832, -1.49806086],\n", 282 | " [-0.08319614, -0.07417017],\n", 283 | " [ 1.61979578, 1.66597748],\n", 284 | " [ 0.1398299 , 0.38577941],\n", 285 | " [-1.5500226 , -2.61344251],\n", 286 | " [-0.19459163, 0.0227914 ],\n", 287 | " [ 1.3320316 , 1.1949539 ],\n", 288 | " [-0.71462983, -0.02385873],\n", 289 | " [-1.23999647, -2.47955126],\n", 290 | " [-2.07311228, 2.57822617],\n", 291 | " [-0.31829059, -0.65082684],\n", 292 | " [-1.46140776, 0.96926358],\n", 293 | " [-2.59100928, -0.09863181],\n", 294 | " [-0.78361708, 0.24660244],\n", 295 | " [-0.63362911, -1.18964448],\n", 296 | " [ 0.17256072, 0.22460295],\n", 297 | " [ 0.08147971, 0.28453067],\n", 298 | " [-0.49084692, -0.52323217],\n", 299 | " [-0.63238933, -0.40196504],\n", 300 | " [-0.79406174, -2.12548332]]),\n", 301 | " 'b1': array([[ 0.23078455],\n", 302 | " [-1.32264413],\n", 303 | " [-1.47764201],\n", 304 | " [ 0.16617422],\n", 305 | " [-0.09384934],\n", 306 | " [-0.28249715],\n", 307 | " [ 0.1434703 ],\n", 308 | " [-0.00400412],\n", 309 | " [ 1.07366016],\n", 310 | " [-0.17318453],\n", 311 | " [-0.23088063],\n", 312 | " [-0.23375636],\n", 313 | " [-1.19500203],\n", 314 | " [ 0.09860723],\n", 315 | " [-0.82273456],\n", 316 | " [ 0.00199761],\n", 317 | " [-1.53871161],\n", 318 | " [-0.08439808],\n", 319 | " [ 0.37972245],\n", 320 | " [-0.10838977],\n", 321 | " [ 1.4616674 ],\n", 322 | " [ 1.7604331 ],\n", 323 | " [ 0.13016958],\n", 324 | " [-0.5653716 ],\n", 325 | " [-1.3137538 ],\n", 326 | " [ 0.13198297],\n", 327 | " [-0.33018176],\n", 328 | " [-0.10135498],\n", 329 | " [-0.00515508],\n", 330 | " [ 0.10008457],\n", 331 | " [ 0.01747326],\n", 332 | " [ 0.95369839]]),\n", 333 | " 'W2': array([[ 0.22266084, -1.80462233, -2.42962594, 0.4136683 , -1.32685359,\n", 334 | " -0.54372178, 0.59478101, -0.13161512, 1.69377949, -1.37413274,\n", 335 | " -0.41048486, -0.74712648, -1.47717838, -0.85803551, -1.07435841,\n", 336 | " -0.2700743 , -2.48820231, 0.54650674, 0.41287645, -1.90551401,\n", 337 | " 2.22419434, 2.47254256, 0.90462615, -1.05235962, -2.3293656 ,\n", 338 | " 0.56939008, -0.71529265, 0.89493879, -0.11718641, 0.65795803,\n", 339 | " 0.00674728, 1.13550524]]),\n", 340 | " 'b2': array([[-0.58428489]])}" 341 | ] 342 | }, 343 | "execution_count": 10, 344 | "metadata": {}, 345 | "output_type": "execute_result" 346 | } 347 | ], 348 | "source": [ 349 | "neural_network(X, y, n1=32)" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "metadata": {}, 356 | "outputs": [], 357 | "source": [] 358 | } 359 | ], 360 | "metadata": { 361 | "interpreter": { 362 | "hash": "038c04557dfd72b4d6039cb7951b93ffe7520921b6515cb88d8784deedfaf89f" 363 | }, 364 | "kernelspec": { 365 | "display_name": "Python 3.7.9 ('base')", 366 | "language": "python", 367 | "name": "python3" 368 | }, 369 | "language_info": { 370 | "codemirror_mode": { 371 | "name": "ipython", 372 | "version": 3 373 | }, 374 | "file_extension": ".py", 375 | "mimetype": "text/x-python", 376 | "name": "python", 377 | "nbconvert_exporter": "python", 378 | "pygments_lexer": "ipython3", 379 | "version": "3.7.9" 380 | }, 381 | "orig_nbformat": 4 382 | }, 383 | "nbformat": 4, 384 | "nbformat_minor": 2 385 | } 386 | -------------------------------------------------------------------------------- /04_ANN_profond.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np\n", 10 | "import matplotlib.pyplot as plt\n", 11 | "from sklearn.datasets import make_blobs, make_circles\n", 12 | "from sklearn.metrics import accuracy_score, log_loss\n", 13 | "from tqdm import tqdm" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "# Fonctions" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 3, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "def initialisation(dimensions):\n", 30 | " \n", 31 | " parametres = {}\n", 32 | " C = len(dimensions)\n", 33 | "\n", 34 | " np.random.seed(1)\n", 35 | "\n", 36 | " for c in range(1, C):\n", 37 | " parametres['W' + str(c)] = np.random.randn(dimensions[c], dimensions[c - 1])\n", 38 | " parametres['b' + str(c)] = np.random.randn(dimensions[c], 1)\n", 39 | "\n", 40 | " return parametres" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 4, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "def forward_propagation(X, parametres):\n", 50 | " \n", 51 | " activations = {'A0': X}\n", 52 | "\n", 53 | " C = len(parametres) // 2\n", 54 | "\n", 55 | " for c in range(1, C + 1):\n", 56 | "\n", 57 | " Z = parametres['W' + str(c)].dot(activations['A' + str(c - 1)]) + parametres['b' + str(c)]\n", 58 | " activations['A' + str(c)] = 1 / (1 + np.exp(-Z))\n", 59 | "\n", 60 | " return activations" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 5, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "def back_propagation(y, parametres, activations):\n", 70 | "\n", 71 | " m = y.shape[1]\n", 72 | " C = len(parametres) // 2\n", 73 | "\n", 74 | " dZ = activations['A' + str(C)] - y\n", 75 | " gradients = {}\n", 76 | "\n", 77 | " for c in reversed(range(1, C + 1)):\n", 78 | " gradients['dW' + str(c)] = 1/m * np.dot(dZ, activations['A' + str(c - 1)].T)\n", 79 | " gradients['db' + str(c)] = 1/m * np.sum(dZ, axis=1, keepdims=True)\n", 80 | " if c > 1:\n", 81 | " dZ = np.dot(parametres['W' + str(c)].T, dZ) * activations['A' + str(c - 1)] * (1 - activations['A' + str(c - 1)])\n", 82 | "\n", 83 | " return gradients" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 6, 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "def update(gradients, parametres, learning_rate):\n", 93 | "\n", 94 | " C = len(parametres) // 2\n", 95 | "\n", 96 | " for c in range(1, C + 1):\n", 97 | " parametres['W' + str(c)] = parametres['W' + str(c)] - learning_rate * gradients['dW' + str(c)]\n", 98 | " parametres['b' + str(c)] = parametres['b' + str(c)] - learning_rate * gradients['db' + str(c)]\n", 99 | "\n", 100 | " return parametres" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 7, 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "def predict(X, parametres):\n", 110 | " activations = forward_propagation(X, parametres)\n", 111 | " C = len(parametres) // 2\n", 112 | " Af = activations['A' + str(C)]\n", 113 | " return Af >= 0.5" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 10, 119 | "metadata": {}, 120 | "outputs": [], 121 | "source": [ 122 | "def deep_neural_network(X, y, hidden_layers = (16, 16, 16), learning_rate = 0.001, n_iter = 3000):\n", 123 | " \n", 124 | " # initialisation parametres\n", 125 | " dimensions = list(hidden_layers)\n", 126 | " dimensions.insert(0, X.shape[0])\n", 127 | " dimensions.append(y.shape[0])\n", 128 | " np.random.seed(1)\n", 129 | " parametres = initialisation(dimensions)\n", 130 | "\n", 131 | " # tableau numpy contenant les futures accuracy et log_loss\n", 132 | " training_history = np.zeros((int(n_iter), 2))\n", 133 | "\n", 134 | " C = len(parametres) // 2\n", 135 | "\n", 136 | " # gradient descent\n", 137 | " for i in tqdm(range(n_iter)):\n", 138 | "\n", 139 | " activations = forward_propagation(X, parametres)\n", 140 | " gradients = back_propagation(y, parametres, activations)\n", 141 | " parametres = update(gradients, parametres, learning_rate)\n", 142 | " Af = activations['A' + str(C)]\n", 143 | "\n", 144 | " # calcul du log_loss et de l'accuracy\n", 145 | " training_history[i, 0] = (log_loss(y.flatten(), Af.flatten()))\n", 146 | " y_pred = predict(X, parametres)\n", 147 | " training_history[i, 1] = (accuracy_score(y.flatten(), y_pred.flatten()))\n", 148 | "\n", 149 | " # Plot courbe d'apprentissage\n", 150 | " plt.figure(figsize=(12, 4))\n", 151 | " plt.subplot(1, 2, 1)\n", 152 | " plt.plot(training_history[:, 0], label='train loss')\n", 153 | " plt.legend()\n", 154 | " plt.subplot(1, 2, 2)\n", 155 | " plt.plot(training_history[:, 1], label='train acc')\n", 156 | " plt.legend()\n", 157 | " plt.show()\n", 158 | "\n", 159 | " return training_history" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "# Dataset" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 9, 172 | "metadata": {}, 173 | "outputs": [ 174 | { 175 | "name": "stdout", 176 | "output_type": "stream", 177 | "text": [ 178 | "dimensions de X: (2, 100)\n", 179 | "dimensions de y: (1, 100)\n" 180 | ] 181 | }, 182 | { 183 | "data": { 184 | "image/png": "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", 185 | "text/plain": [ 186 | "
" 187 | ] 188 | }, 189 | "metadata": { 190 | "needs_background": "light" 191 | }, 192 | "output_type": "display_data" 193 | } 194 | ], 195 | "source": [ 196 | "X, y = make_circles(n_samples=100, noise=0.1, factor=0.3, random_state=0)\n", 197 | "X = X.T\n", 198 | "y = y.reshape((1, y.shape[0]))\n", 199 | "\n", 200 | "print('dimensions de X:', X.shape)\n", 201 | "print('dimensions de y:', y.shape)\n", 202 | "\n", 203 | "plt.scatter(X[0, :], X[1, :], c=y, cmap='summer')\n", 204 | "plt.show()" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 15, 210 | "metadata": {}, 211 | "outputs": [ 212 | { 213 | "name": "stderr", 214 | "output_type": "stream", 215 | "text": [ 216 | "100%|██████████| 3000/3000 [00:02<00:00, 1412.11it/s]\n" 217 | ] 218 | }, 219 | { 220 | "data": { 221 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsIAAAD8CAYAAAB9/cItAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAA5SklEQVR4nO3deXxU9b3/8dcnk40sQEjCvoVdZLOkCApSq1XEtbbWrbWbUm7V2ttbr9ZqbX9dbW9bF2wptd6qrdLe1rWitlrcKiqgILsEEBNAlrATQrbP748ZaAjBDGGScyZ5Px+PeTBzzsmZdw4zJ5/5zvd8v+buiIiIiIi0NylBBxARERERCYIKYRERERFpl1QIi4iIiEi7pEJYRERERNolFcIiIiIi0i6pEBYRERGRdimuQtjMppjZKjMrMbObG1nfycyeMrPFZrbMzL6Y+KgiIiIiIoljTY0jbGYR4F3gE0AZMB+43N2X19vmFqCTu99kZoXAKqC7u1e1WHIRERERkeMQT4vwOKDE3dfGCtvZwIUNtnEg18wMyAG2AzUJTSoiIiIikkCpcWzTCyit97gMOLnBNjOAJ4GNQC5wqbvXfdhOCwoKvH///vEnFREJkYULF25z98Kgc7QWnbNFJJkd7ZwdTyFsjSxr2J/ibGAR8HFgIPAPM3vF3XcftiOzacA0gL59+7JgwYI4nl5EJHzMbH3QGVpT//79dc4WkaR1tHN2PF0jyoA+9R73JtryW98XgUc9qgRYBwxruCN3n+Xuxe5eXFjYbhpSRERERCSE4imE5wODzazIzNKBy4h2g6jvfeAMADPrBgwF1iYyqIiIiIhIIjXZNcLda8zsOuA5IALc7+7LzGx6bP1M4PvA781sCdGuFDe5+7YWzC0iIiIiclzi6SOMu88B5jRYNrPe/Y3AWYmNJiLHq7q6mrKyMiorK4OOkrQyMzPp3bs3aWlpQUcJHb2+mk+vK5FwiKsQFpHkVFZWRm5uLv379yc6uqEcC3envLycsrIyioqKgo4TNzO7HzgP2OLuIxpZb8BdwFSgAviCu791rM+j11fzJOvrSqQt0hTLIm1YZWUl+fn5KlKayczIz89PxhbP3wNTPmT9OcDg2G0a8OvmPIleX82TxK8rkTZHhbBIG6ci5fgk4/Fz95eJTmx0NBcCD8ZG+nkd6GxmPZrzXMl4fMJAx00kHJKqa8Sjb5Wxv7qWK0/uF3QUEYnDzp07efjhh/nqV796zD87depUHn74YTp37hzX9t/97nfJycnhm9/85jE/VzvU2ERJvYBNwcRpntZ8fbUluyureWjeeg5U1wYdReSY9S/I5uKP9E7Y/pKqEH5y8UZ27KtSISySJHbu3MmvfvWrRguV2tpaIpHIUX92zpw5R10nxy2eiZKOmAQpbPT6ap65K7fws+dWAaCGaUk2k4cUtt9CODXFqKk74lwtIiF18803s2bNGsaMGcMnPvEJzj33XL73ve/Ro0cPFi1axPLly7nooosoLS2lsrKSG264gWnTpgH/nsls7969nHPOOUycOJHXXnuNXr168cQTT9ChQ4ejPu+iRYuYPn06FRUVDBw4kPvvv5+8vDzuvvtuZs6cSWpqKsOHD2f27Nm89NJL3HDDDUD06+qXX36Z3NzcVjk+AYpnoiTcfRYwC6C4uDh0J9/WfH099dRT/OAHP6Cqqor8/Hz++Mc/0q1bN/bu3cv111/PggULMDNuv/12PvWpT/Hss89yyy23UFtbS0FBAS+88EIQh6hRFVXRluB53/o4PTod/X0k0i64eyC3sWPH+rGa9uB8P/uXLx3zz4m0V8uXLw/0+detW+cnnnjiocdz5871rKwsX7t27aFl5eXl7u5eUVHhJ554om/bts3d3fv16+dbt271devWeSQS8bffftvd3S+55BJ/6KGHjniu22+/3X/2s5+5u/vIkSP9xRdfdHf32267zW+44QZ3d+/Ro4dXVla6u/uOHTvc3f28887zV1991d3d9+zZ49XV1Ufsu7HjCCzwgM6f8dyA/sDSo6w7F3iGaMvweODNpvbX2Dm7Pb2+tm/f7nV1de7u/tvf/ta/8Y1vuLv7f//3fx96fR3cbsuWLd67d+9DOQ5maCio43f/q2u9301/8/K9BwJ5fpEgHO2cnWQtwilqERZppu89tYzlG3cndJ/De3bk9vNPPKafGTdu3GFDRt1999089thjAJSWlrJ69Wry8/MP+5mioiLGjBkDwNixY3nvvfeOuv9du3axc+dOJk+eDMDnP/95LrnkEgBGjRrFlVdeyUUXXcRFF10EwKmnnso3vvENrrzySi6++GJ6907cV25BMbNHgI8BBWZWBtwOpMGhMeDnEB06rYTo8GlfPN7nbOuvr7KyMi699FI2bdpEVVXVoed4/vnnmT179qHt8vLyeOqppzjttNMObdOlS5dj+h1aWmV1HQCZabpeXiSp3gWRFKOmti7oGCJyHLKzsw/df/HFF3n++eeZN28eixcv5qSTTmp0SKmMjIxD9yORCDU1Nc167qeffpprr72WhQsXMnbsWGpqarj55pu577772L9/P+PHj2flypXN2neYuPvl7t7D3dPcvbe7/87dZ8aKYGINJNe6+0B3H+nuC4LOnCgt9fq6/vrrue6661iyZAm/+c1vDu3H3Y8YAaKxZWFSGbtILjP16H2oRdqLJGsRVh9hkeY61pa1RMjNzWXPnj1HXb9r1y7y8vLIyspi5cqVvP7668f9nJ06dSIvL49XXnmFSZMm8dBDDzF58mTq6uooLS3l9NNPZ+LEiTz88MPs3buX8vJyRo4cyciRI5k3bx4rV65k2LBhx52jvWnrr69du3bRq1cvAB544IFDy8866yxmzJjBnXfeCcCOHTuYMGEC1157LevWraOoqIjt27eHqlW4sqaW9EgKKSnhLdZFWktStQinRoxaFcIiSSM/P59TTz2VESNGcOONNx6xfsqUKdTU1DBq1Chuu+02xo8fn5DnfeCBB7jxxhsZNWoUixYt4jvf+Q61tbV89rOfZeTIkZx00kn853/+J507d+bOO+9kxIgRjB49mg4dOnDOOeckJIO0vNZ8fX33u9/lkksuYdKkSRQUFBxafuutt7Jjx45Dr6G5c+dSWFjIrFmzuPjiixk9ejSXXnpps5+3JRyoriND3SJEALBo/+HWV1xc7AsWHNu3cd96dAnPr9jM/G+f2UKpRNqWFStWcMIJJwQdI+k1dhzNbKG7FwcUqdU1ds7W6+v4BHH8Xly1hR88vYJd+6v1t1TalaOds5PqI2FqilqERUREmmvmS2tYX76PSYMKmt5YpB1IqkJYF8uJiIg0X0VVLRMHFfCLS8cEHUUkFJKqENbFciIiIs2370ANWRlJdZ28SItKqndDJKJCWORYhX0op7AL6jqKZKHXV/O05uuqts754dMrKN93gI07KxnbL6/Vnlsk7JKqRTgtJUV9hEWOQWZmJuXl5SrmmsndKS8vJzMzM+gooaTXV/O09utqffk+7v/XOv5VUk73Tpmcqv7BIockV4tw7GI5tUCIxKd3796UlZWxdevWoKMkrczMzDYx21xL0Our+VrzdVVRFZ1A40efHMFZJ3ZvlecUSRZxFcJmNgW4C4gA97n7TxqsvxG4st4+TwAK3X17ArOSGhv8u7bOSY2oEBZpSlpa2mHTzYokkl5fyWHfgehMednqGyxyhCa7RphZBLgXOAcYDlxuZsPrb+PuP3P3Me4+BvgW8FKii2CI9hEG1E9YREQkTs8u+wCArHRNqSzSUDx9hMcBJe6+1t2rgNnAhR+y/eXAI4kI19DBFmEVwiIiIvFZX14BwMCuOQEnEQmfeArhXkBpvcdlsWVHMLMsYArw16Osn2ZmC8xsQXP6lGWkRj/NVlbXHvPPioiItEf7DtRwclEXOmamBR1FJHTiKYQb64x7tCbZ84F/Ha1bhLvPcvdidy8uLCyMN+MhnbOib+KdFdXH/LMiIiLtUUVVrfoHixxFPO+MMqBPvce9gY1H2fYyWqhbBEDnrHQAdu2vaqmnEBERSUruzi2PLTnUFeKgki176ZefFVAqkXCLp0V4PjDYzIrMLJ1osftkw43MrBMwGXgisRH/rXOHaIvwjn1qERYREalvz4EaHnmzlNIdFVTX1h26jejVkakjewQdTySUmmwRdvcaM7sOeI7o8Gn3u/syM5seWz8ztukngb+7+76WCts/P5vUFGPG3BI27drPyN6dGdY9l8w0XQkrIiLtW8WB6PUz/zF5EFec3DfgNCLJIa5OQ+4+B5jTYNnMBo9/D/w+UcEa0ykrjZumDOPXL63htieWAdGRJIZ0y2VU706M6NWJUb07MbR77qEL60RERNqDfVUHxwvW3z+ReCVd7/lrThvA1ZOKKNuxn6UbdrEkdntm6QfMnh8d3CItYgztnsvIXp0p7pfHR/t3oU+XDpqNTkREkt6uimquffgt9sQmyjioMjaDXFZ60v1pFwlMUr5bzIw+XbLo0yWLc2L9ntydsh37eafsYHG8k7+9s5FH3nwfgG4dM/ho/y6MK+rCR/t3YWi3XFJSVBiLiEhyWfnBbl4t2cboPp0PXTsDQIc0BhRmc1LfzoFlE0k2SVkIN6Z+cXzuqGhxXFfnrNq8h/nvbWf+ezuYv247f3tnEwAFORlMHlLI5KGFTBpUQF52epDxRURE4lIRa/n97vnDOalvXsBpRJJbmymEG5OSYpzQoyMn9OjIVRP6H2o1fn1tOS+v3sYLKzfz17fKMIPRvTtz9ondOXdkD/pqmBkREQmpf/cFbtN/wkVaRbt6F9VvNb6kuA+1dc47ZTt56d2tzF25hTueXckdz648NNTM+aN60qeLimIREQne429v4N65JeyujA4h2kEjJokct3ZVCDcUSTFO6pvHSX3z+PqZQyjdXsEzSzfx9JIP+Omzq/jps6uYMCCfy8b14ewTu2uYNhERCczcVVvYuHM/k4cW0jU3k16dOwQdSSTptetCuKE+XbKYdtpApp02kNLtFTz+9gb+vLCUG2YvomNmKhed1IurJvRnUNecoKOKiEg7s+9ALX3zs/nVlWODjiLSZqgQPoo+XbK4/ozBXHv6IOatLedP80uZPb+UB+et5+PDunL1xCImDMzXkGwiItIq9lfXkJ2ubyZFEkmFcBNSUoxTBxVw6qACtu09wB9eX89D89ZzxX1vMKx7Ll89fRDnjuxBREOxiYhIglzz4AKWb9x92LKtew4wfmB+QIlE2iYVwsegICeDr585hOmTB/LEog389pV1fO2Rt7nnhdV87YzBnDuyh8YmFhGR41JX5zy/YjMndO/I8J4dD1t3/uieAaUSaZtUCDdDZlqESz/al0+P7cOcJZu464XVXP/I29zzz9X811lDOWt4N3WZEBGRZqmsqcUdLhjTk+mTBwYdR6RNSwk6QDKLpBjnj+7Jc18/jbsvP4naOucrDy3kslmvs3TDrqDjiYhIEtp3IDphhvoDi7Q8tQgnQCTFuGB0T6aO6M4j80v55T/e5fwZr/Kpj/TmxrOH0q1jZtARRUQkQWb8czX3vbquxfZfW+cAZKXrT7RIS9O7LIFSIyl8bnw/LhzTk3vnlvC/r77Hs0s/4L+nDOXKk/vpgjoRaRVmNgW4C4gA97n7TxqszwPuBwYClcCX3H1pqwdNUm+s205aJIWpI7q32HNkpEU4fVjXFtu/iESpEG4BHTPT+NY5J3DFuL7c+vhSvvPEMh59awM/vngkJ/To2PQORESaycwiwL3AJ4AyYL6ZPenuy+ttdguwyN0/aWbDYtuf0fppk1NFVS1Du+XyvQtHBB1FRI6T+gi3oH752Tz4pXHceekY3t9ewfn3vMov/r6K6tq6oKOJSNs1Dihx97XuXgXMBi5ssM1w4AUAd18J9Dezbq0bM3ntO1BDlvrvirQJahFuYWbGRSf1YvKQQr7/t+Xc/c8SXnp3K7+8dAwDCjVDnYgkXC+gtN7jMuDkBtssBi4GXjWzcUA/oDewOdFhlm7YxXn3vMqL3/wY/QuyE737FnPBjFdZuWlPo+uqausYrm/3RNqEuArhpvqbxbb5GHAnkAZsc/fJCUvZBuRlp/OLS8dw5vBufOvRJZx796vcel60+4SGWhORBGrshOINHv8EuMvMFgFLgLeBmiN2ZDYNmAbQt2/fZoV57O0NAPxj+WauOW1As/bR2qpr63inbBfjirowtl9eo9ucP0rj+Yq0BU0WwvH0NzOzzsCvgCnu/r6ZqYf/UUwd2YOP9M3jxr8s5tuPLeW1NeXc8alR5GSocV5EEqIM6FPvcW9gY/0N3H038EUAi34SXxe70WC7WcAsgOLi4obFdFzSItEeeNV1ydMlrKIqOnzZWcO7cfWk5CjeRaR54ukjHE9/syuAR939fQB335LYmG1L906ZPPDFcdw0ZRjPLNnEhTNepWRL41/BiYgco/nAYDMrMrN04DLgyfobmFnn2DqAq4GXY8VxwqVFog3U1TXNqqNbnLtTXVt32G33/moAstVAIdLmxfMuj6e/2RAgzcxeBHKBu9z9wYQkbKNSUoz/+NhARvfpxNceeZsLZvyLn356FOfp6zYROQ7uXmNm1wHPEe3Odr+7LzOz6bH1M4ETgAfNrBZYDny5pfKkpkTbW2pC2iJ8w+xFPLl4Y6Pr9E2dSNsXz7s8nv5mqcBYosPvdADmmdnr7v7uYTtKQH+ztuaUgQX87fpJXPvwW1z38NuUbNnLDWcMVr9hEWk2d58DzGmwbGa9+/OAwa2R5eDw6R7OBmFWfrCbId1yuGD04Y0QGakax1ekPYinEG6yv1lsm23uvg/YZ2YvA6OBwwrhRPQ3a4u6d8rkkWvG861Hl3Dn86t5b9s+7vj0KDJSNTyPiEhL2neglvED8rnu463yuUBEQiaeQvhQfzNgA9H+Zlc02OYJYIaZpQLpRLtO/DKRQdu69NQU/ueSUQwozOZnz61iw879/OZzxXTJTm/6h0VEQs6P+CKx5VVW13Kg+sO7ZOyrqiE7Q40OIu1Vk4VwPP3N3H2FmT0LvAPUER1iTdN1HiMz49rTB9EvP4tv/Hkxl8x8jYe+fDI9O3cIOpqISFLZU1nNKT/+J3sOHDEq3BFyM9UXWKS9iuvd31R/s9jjnwE/S1y09uu8UT3pmpvJl38/n0tmzuMPV59MURINRC8iclBQlzvsrKhmz4EaLhrTk1G9Ox91uxSLDmspIu2TPgaH1LiiLjwybTxX3f8ml8x8jQe/dDLDe2omIxGReFTFprL/+AndjrgQTkTkoHjGEZaAjOjViT9/ZQJpkRQunTWPxaU7g44kIpIUqmOFcHpEI/CIyNGpEA65QV1z+L/pE+iclcbnfvcGSzfsCjqSiEjoHZzA4+A4xiIijdEZIgn0zsvi4avHk5uZxmd/9wbLN7bIBFAiIi2mtccRPtg1Ii1Vf+ZE5Oh0hkgSfbpk8cg14+mQFuGzv3uDVR9oSmYRCb+gJgc62DUiTV0jRORDqBBOIn3zo8VwWsT47O/eoHR7RdCRREQCUbq9gpIteynZspetew4ctq62znk/dn5Mj+jPnIgcnUaNSDL9C7L5w5dP5tMz53HV/W/yl+kTyM/JCDqWiEireWX1Vj73uzcPPU6LGG/eciZ5sQmIfvGPVdw7dw0A2Rn6MyciR6ePyklocLdc7v9CMZt27eeLv5/PvjgGjBcRaSs27awE4HsXnMgXTulPda1Tvu/AYevzs9P53y9+lGHdc4OKKSJJQIVwkhrbrwszLv8IyzbuZvofFlJV8+HTiIqItBX7qqIf/i8Y3ZNJgwsAqKiqPbS+oqqWgpwMTh/aNbA+yiKSHPSdURI7c3g3fnzxSP77L+9w6+NLuONTo3TSF5FQas6gEZXVtby7+cgLg9du3QdAVkaErPTon7El9YaW3LynkqyMSLNyikj7okI4yX2muA+l2yu4558lDOmWy9WTBgQdSUQkIX767Cru/9e6Rtdlp0dIj6TQJdYv+NuPLT1s/RnDurZ4PhFJfiqE24D/PHMIJVv28sM5KygqyOaME7oFHUlE5Lht2VNJj06Z/OCiEUes652XhZkxpFsOf/7KBPZUVh+2fmSvTq0VU0SSmArhNiAlxfj5Z0ZT+psKvvbI2zz61VMZqgtERCTJHezr+2Ef7s2McUVdWjGViLQluliujchKT+W3VxWTnZHKlx+Yz459VUFHEhE5ZPf+6qY3AtydRaU7mbemnA92VZKVrr6+ItJyVAi3IT06dWDWVcVs2X2Ar/9pEbV1rTynqYhIAx6bW/mPb7wf1/ZvrNvORff+i8t/+zrLN+2mIFfjpItIy1HXiDZmTJ/O3H7BcL792FLu+edqvn7mkKAjiUg7Vl17bB/It+2Njgf8P5eMplfnDgzv0bElYomIACqE26QrxvVl4fod3PXCasb06czHhurqaREJRk3dsY1xXnEgOh7whIH59OrcoSUiiYgcElfXCDObYmarzKzEzG5uZP3HzGyXmS2K3b6T+KgSLzPjhxeNZGi3XL7+p0WUbq8IOpKItFMNW4Rr65x/lWzjtZJtlGzZw9yVW6iITZCxvnwfi8p2AtHh0UREWlqTLcJmFgHuBT4BlAHzzexJd1/eYNNX3P28FsgozdAhPcKvPzuWC+55leseeZu/TJ9AWkRdwkWkdeVlpR/2+JXVW/nC/84/bNmNZw/l2tMHMe3BhazavIcOaRGyM/SFpYi0vHgqo3FAibuvdfcqYDZwYcvGkkQoKsjmjk+PYnHpTn75j3eDjiMi7VBBTrQQ7t4xE4DtjYxoU743uqx8XxVnn9iNf35zsj64i0iriOdM0wsorfe4LLasoQlmttjMnjGzExOSTo7b1JE9uLS4D79+aQ2vrdkWdBwRaWcOdoyoi40esa+q9ohtDnaNqKiqoU9eFj06qW+wiLSOeApha2RZw8uA3wL6ufto4B7g8UZ3ZDbNzBaY2YKtW7ceU1BpvtsvGE5Rfjbf+NNijS8sIoGoc+fNddtZ+N72I9at3rKXJxZtoKKqlix1iRCRVhRPIVwG9Kn3uDewsf4G7r7b3ffG7s8B0sysoOGO3H2Wuxe7e3FhYeFxxJZjkZWeyt2Xn0T5vgPc9Nd3Do3rKSLSWnZWVHPZrHk8vmgjORmppNfr+rBw/Q5umL0IgB6dMgNKKCLtUTwfvecDg82sCNgAXAZcUX8DM+sObHZ3N7NxRAvs8kSHleYb0asTN00Zxg+eXsEjb5Zyxcl9g44kIu1B7HN3TWyCn2+eNYTPju+HO+yprKEgN52NOysBSE0x+uVnBZVURNqhJgthd68xs+uA54AIcL+7LzOz6bH1M4FPA/9hZjXAfuAyV7Nj6Hzp1CJeXLWVHz69nEmDC+jTRX9wRKR19S/IpnNsJIm87Oi/g7rmBBlJRNqxuC7Ldfc57j7E3Qe6+w9jy2bGimDcfYa7n+juo919vLu/1pKhpXlSUoyffGokZsZNf32HOk3BLCItzBtcUpKdrj7AIhIeGp+mnemdl8Wt557Aa2vK+eMb64OOIyItII5JkDqZ2VOxkX6WmdkXWytbQU5Gaz2ViEiTVAi3Q5d+tA+nDSnkR3NW8n65Zp0TaUvqTYJ0DjAcuNzMhjfY7FpgeWykn48BPzezdFrBCT1yW+NpRETiokK4HTIz7vjUSFJTjBv/slhdJETalngmQXIg18wMyAG2AzUtEab+1SIZqSmkaqIMEQkRnZHaqR6dOnDb+cN5Y912/vjm+0HHEZHEiWcSpBnACUSHwlwC3ODudS0dLDMt0tJPISJyTFQIt2OXjO3NxEEF/PSZlWzZXRl0HBFJjHgmQTobWAT0BMYAM8ys4xE7SsAkSPWfuDBX/YNFJFxUCLdjZsYPLhrBgdo6vve35UHHEZHEaHISJOCLwKMeVQKsA4Y13FGiJ0H649UnH/c+REQSSYVwO9e/IJuvfXwQT7+zibkrtwQdR0SO36FJkGIXwF0GPNlgm/eBMwDMrBswFFjb0sE6Zqa19FOIiBwTFcLCtNMGMqhrDrc+vpSKqha5XkZEWom71wAHJ0FaAfz54CRIBydCAr4PnGJmS4AXgJvcfVvL5Pn3/cw0/ckRkXDRyOZCemoKP/rkSD7zm3nc9fxqvjX1hKAjichxcPc5wJwGy2bWu78ROKu1c0UHqRARCQ99PBcAxhV14bKP9uG+V9ex6oM9QccRkTbi4Mxyb9xyRsBJRESOpEJYDrlpyjByMlL53lPLcNfYwiKSOGoLFpEwUiEsh+Rlp/NfZw3htTXlPLv0g6DjiEgboM/UIhJmKoTlMFeM68uw7rn84OkVVFbXBh1HRNoKNQmLSAipEJbDpEZSuP38E9mwcz+/eanFR1MSERERCYwKYTnChIH5nDuqB79+qYQNO/cHHUdEkph6RohImKkQlkbdEhtC7UdzVgScRETaAlPfCBEJIRXC0qhenTvwldMG8vQ7m3jr/R1BxxGRZKWr5UQkxOIqhM1sipmtMrMSM7v5Q7b7qJnVmtmnExdRgjLttAEU5mbwo6dXaDg1ETkumktDRMKoyULYzCLAvcA5wHDgcjMbfpTt7iA6rae0AdkZqfznmUNYsH4Hf1++Oeg4IiIiIgkVT4vwOKDE3de6exUwG7iwke2uB/4KbElgPgnYZ4p7M7AwmzueWUl1bV3QcUQkyei7JBEJs3gK4V5Aab3HZbFlh5hZL+CTwEykTUmNpHDzOSewdts+Zs8vbfoHREQaoZ4RIhJG8RTCjZ2/Gn7IvxO4yd0/dAYGM5tmZgvMbMHWrVvjjChBO/OErowr6sJdz7/L3gM1QccRkSSiywtEJMziKYTLgD71HvcGNjbYphiYbWbvAZ8GfmVmFzXckbvPcvdidy8uLCxsXmJpdWbGLVNPYNveKma9tCboOCKShExXy4lICMVTCM8HBptZkZmlA5cBT9bfwN2L3L2/u/cH/gJ81d0fT3RYCc6YPp05d1QP7nt1Hdv2Hgg6joiIiMhxa7IQdvca4Dqio0GsAP7s7svMbLqZTW/pgBIe3/jEECqra5n5olqFRSQ+GnpRRMIsNZ6N3H0OMKfBskYvjHP3Lxx/LAmjgYU5XPyR3jz4+nqunjSA7p0yg44kIklCHSNEJIw0s5wckxvOGIy7M2Pu6qCjiEgSUHuwiISZCmE5Jn26ZHHpR/vwp/mllG6vCDqOiCQJXSsnImGkQliO2XWnDybFjLteUKuwiIiIJC8VwnLMunfK5HPj+/HoW2Ws2bo36DgiEmK6Vk5EwkyFsDTL9I8NJDMtwp3Pq1VYRJpmulxOREJIhbA0S0FOBl86tYinFm9kxabdQccRkZBSg7CIhJkKYWm2ayYNIDcjlXv+qVZhEWmCGoRFJIRUCEuzdcpK4wun9mfOkg9Y9cGeoOOISAhpQg0RCTMVwnJcvjyxiJyMVO5Wq7CIfAgNnyYiYaRCWI5L56x0Pn9KP+Ys2cS7m9UqLCIiIslDhbAct6snDiArLcLdGldYREREkogKYTluednpXHVKf55esonVahUWkUaoZ4SIhJEKYUmIayYNoENahHv+WRJ0FBEJEV0rJyJhpkJYEqJLdjpXTejPU+9spGSLZpsTkcOZrpYTkRBSISwJc82kIjJTI8zQCBIigTKzKWa2ysxKzOzmRtbfaGaLYrelZlZrZl2CyCoiEiQVwpIw+TkZXDWhH08u3siarWoVFgmCmUWAe4FzgOHA5WY2vP427v4zdx/j7mOAbwEvufv2lsjjmltOREJMhbAk1DWnDSAjNcIM9RUWCco4oMTd17p7FTAbuPBDtr8ceKSlQ6ljhIiEkQphSaiCnAw+O74vTyzawFq1CosEoRdQWu9xWWzZEcwsC5gC/LWlwuhiOREJs7gK4Tj6m11oZu/E+pstMLOJiY8qyWLaaQNJT01hxly1CosEoLHG16OVo+cD/zpatwgzmxY7py/YunXr8YVSk7CIhFCThXA8/c2AF4DRsf5mXwLuS3BOSSKFuRlceXI/nli0kfe27Qs6jkh7Uwb0qfe4N7DxKNtexod0i3D3We5e7O7FhYWFCYwoIhIO8bQIN9nfzN33uh/6Aiybo7c+SDvxlckDSE0xjSss0vrmA4PNrMjM0okWu0823MjMOgGTgSdaMoz+GIhImMVTCMfV38zMPmlmK4GnibYKSzvWNTeTz47vx2Nvl7FOrcIircbda4DrgOeAFcCf3X2ZmU03s+n1Nv0k8Hd3b5U3qOlyOREJoXgK4bj6m7n7Y+4+DLgI+H6jO0pgfzMJv+mTo32F735B4wqLtCZ3n+PuQ9x9oLv/MLZsprvPrLfN7939spbP0tLPICLSfPEUwsfS3wx3fxkYaGYFjaxTf7N2pDA3g89P6M8TizZQsmVP0HFEJEC6WE5EwiieQrjJ/mZmNshi82ea2UeAdKA80WEl+Uw7bQCZaRHuekF9hUXaI02oISJh1mQhHGd/s08BS81sEdERJi6td/GctGP5ORl8/pT+/O2djby7Wa3CIiIiEh5xjSPcVH8zd7/D3U+MTdk5wd1fbcnQklymTRpAVlqEu55XX2EREREJD80sJy0uLzudL00s4uklm1ixaXfQcUSkFem7QREJMxXC0iqunjiA3IxU7nz+3aCjiEgAdLGciISRCmFpFZ2y0vjypCKeW7aZpRt2BR1HRERERIWwtJ4vTSyiY2Yqd6qvsEi7owk1RCSMVAhLq+mYmca00wbw/IrNvP3+jqDjiIiISDunQlha1RdOLaIgJ52fPLMSjbAn0vbpfS4iYaZCWFpVTkYqXztjMG+s286L72qabZH2QhfLiUgYqRCWVnfZR/vSLz+LO55ZSW2dWotE2jI1CItImKkQllaXnprCjWcPZeUHe3j87Q1BxxGRVqAGYREJIxXCEoipI3owqncnfvGPd6msrg06joiIiLRDKoQlECkpxs1ThrFh534emrc+6Dgi0kLUM0JEwkyFsATmlEEFTB5SyIy5JeysqAo6joi0INPVciISQiqEJVDfmjqMPZXV/PIfmnpZpC3SxXIiEmYqhCVQw7p35MqT+/GHN95n1Qd7go4jIi1E7cEiEkYqhCVw3/jEEHIyUvneU8s0+L6IiIi0GhXCEri87HT+66whvLamnOeWfRB0HBFJINflciISYiqEJRSuGNeXYd1z+cHTKzScmkgbpGvlRCSM4iqEzWyKma0ysxIzu7mR9Vea2Tux22tmNjrxUaUtS42k8J3zh1O2Yz+/fnFN0HFEJEHU20lEwqzJQtjMIsC9wDnAcOByMxveYLN1wGR3HwV8H5iV6KDS9p0ysIALRvfk1y+uoWTL3qDjiEgCafg0EQmjeFqExwEl7r7W3auA2cCF9Tdw99fcfUfs4etA78TGlPbitvOG0yE9wi2PLqGuTk1JIslO72IRCbN4CuFeQGm9x2WxZUfzZeCZ4wkl7VdhbgbfnnoCb763nT8vKG36B0RERESaKZ5CuLHvsxr9kG9mpxMthG86yvppZrbAzBZs3bo1/pTSrlxS3JuTi7rwozkr2LKnMug4IiIi0kbFUwiXAX3qPe4NbGy4kZmNAu4DLnT38sZ25O6z3L3Y3YsLCwubk1faATPjRxePpLK6jtuf0NjCIklN718RCbF4CuH5wGAzKzKzdOAy4Mn6G5hZX+BR4HPurrly5bgNLMzh658YzDNLP+CJRUd87hKRJKLr5EQkrJoshN29BrgOeA5YAfzZ3ZeZ2XQzmx7b7DtAPvArM1tkZgtaLLG0G185bSBj++Vx2xNL2bhzf9BxRKQZ1B4sImEW1zjC7j7H3Ye4+0B3/2Fs2Ux3nxm7f7W757n7mNituCVDS/sQSTF+8ZnR1NY5N/5lsUaREElSahAWkbDSzHISav3ys7n13OH8q6ScB+a9F3QckaTQ1CRIsW0+FvsGb5mZvdTaGUVEwkCFsITe5eP6cMawrvx4zkqWlO0KOo5IqMUzCZKZdQZ+BVzg7icCl7RUHl0rJyJhpkJYQs/M+J9LRlOQk85XH17Irv3VQUcSCbMmJ0ECrgAedff3Adx9S0sG0qxyIhJWKoQlKeRlp3PPFR9h085Kbvy/xRpSTeTo4pkEaQiQZ2YvmtlCM7uqpcK4LpcTkRBTISxJY2y/PG4+Zxh/X76Z+15ZF3QckbCKZxKkVGAscC5wNnCbmQ05YkcJmgRJ7cEiElYqhCWpfHliEVNO7M6Pn1nBi6ta9NtckWQVzyRIZcCz7r7P3bcBLwOjG+5IkyCJSFunQliSipnx88+MZmj3jlz/8NuUbNkTdCSRsGlyEiTgCWCSmaWaWRZwMtFx4hNOvZhEJMxUCEvSyc5I5b7PF5ORFuFLv1/Ajn1VQUcSCY14JkFy9xXAs8A7wJvAfe6+tKUy6Vo5EQkrFcKSlHp17sCsq8bywe5KrnlwAfuraoOOJBIaTU2CFHv8M3cf7u4j3P3OFsvSUjsWEUkAFcKStD7SN487Lx3Dwvd38NU/LqS6ti7oSCLSCNPlciISUiqEJalNHdmDH1w0grmrtnLj/2kaZhEREYlfatABRI7XlSf3Y2dFNT97bhXZGal8/8IRpKSoBUokDHSxnIiEmQphaRO++rGB7K6s5jcvraW2zvnRJ0eqGBYJC70VRSSkVAhLm2Bm3DxlGGkpKcyYW0JNnXPHp0YRUTEsEijNLCciYaZCWNoMM+ObZw8lLZLCL59/l/3Vtfz8ktFkpkWCjibSrunjqIiElQphaXNuOHMwWekRfjhnBVt3H2DWVWPpnJUedCyR9kkNwiISYho1Qtqka04bwD2Xn8Si0p1c/OvXKN1eEXQkkXZLE2qISFjFVQib2RQzW2VmJWZ2cyPrh5nZPDM7YGbfTHxMkWN3/uie/OHqkynfW8UFM17l1dXbgo4kIiIiIdJkIWxmEeBe4BxgOHC5mQ1vsNl24GvA/yQ8ochxGFfUhce+egqFuRlcdf8b/OrFElzjOYm0Gr3bRCTM4mkRHgeUuPtad68CZgMX1t/A3be4+3ygugUyihyXAYU5PPbVU5k6sgc/fXYV0x5ayPZ9VUHHEmk3NLOciIRVPIVwL6C03uOy2DKRpJGdkco9l5/Ed84bzourtnD2nS/z4qotQccSafP0DYyIhFk8hXBjH+WbdWYzs2lmtsDMFmzdurU5uxBpNjPjSxOLeOLaieRlpfGF/53PbY8vZd+BmqCjibRpulhORMIqnkK4DOhT73FvYGNznszdZ7l7sbsXFxYWNmcXIsdteM+OPHndRK6eWMRDr6/nE794ib8v+yDoWCIiItLK4imE5wODzazIzNKBy4AnWzaWSMvKTItw63nD+et/TKBjhzSmPbSQqx+Yr2HWRBJMPSNEJMyaLITdvQa4DngOWAH82d2Xmdl0M5sOYGbdzawM+AZwq5mVmVnHlgwukghj+3XhqesncsvUYfyrpJwzfvESP56zgl0Vuu5TJFHUM0JEwiqumeXcfQ4wp8GymfXuf0C0y4RI0kmLpDDttIGcN6onP//7u8x6ZS2z55dy3emD+NyEfpqiWeQ4qEFYRMJMM8uJxPTs3IGff2Y0T18/iTF9OvPDOSuY9NO5zHp5jS6oEzkOpqvlRCSkVAiLNDC8Z0ce+NI4HrlmPEO65fCjOSs55Sf/5M7n36V874Gg44mIiEiCxNU1QqQ9mjAwnwkD83n7/R3cO3cNdz6/ml/NXcO5o3rwuQn9OKlPZ7V0iTRBF8uJSJipEBZpwkl987jv88Ws3ryHh15fz6NvbeCxtzcwoldHLvtoX84b1YPOWelBxxQJpTp3jSMsIqGlrhEicRrcLZf/d+EIXr/lDL5/0Qiqa5xbH1/KuB++wFceWsCzSz/gQE1t0DFFQidFlbCIhJRahEWOUU5GKp8b34/PntyXZRt38+hbG3hy8UaeW7aZjpmpfHxYV846sTuThxSSnaG3mLRvahEWkTDTX2mRZjIzRvTqxIhenbhl6jBeKdnG0+9s4oUVm3l80UbSU1OYNKiAj5/QlUmDCumbnxV0ZJFW564WYREJLxXCIgmQGknh9KFdOX1oV2pq61iwfgd/X7aZvy//gBdWbgGgb5csJg4uYNKgAiYMzFe/YmkX6tw1oYaIhJYKYZEES42kMH5APuMH5HPbeSewZus+Xl29lVdLtvHkoo08/Mb7AAzplsPYfl0Y2y+P4n559MvP0igU0uY4GkdYRMJLhbBICzIzBnXNYVDXHL5wahHVtXUsLt3JvDXlLFi/g7+9s5FH3owWxgU56Yzp05nhPTtxYs+OjOjViZ6dMlVESFJz9REWkRBTISzSitIiKRT370Jx/y4A1NU5q7fsZeH6HSxYv513ynbxwsoth8Ze7ZyVxok9O3Jiz04MjhXUg7rmkJuZFuBvIRK/aB/hoFOIiDROhbBIgFJSjKHdcxnaPZcrTu4LQEVVDSs27WH5xl0s27ibZRt38/t/vUdVbd2hn+vWMSNaFBdGC+P+Bdn07ZJFz84dSItoVEQJjzp3XSwnIqGlQlgkZLLSUxnbL4+x/fIOLaupreP97RWUbNlLyda9lGzZy5ote/nLwjL2Vf177OIUg56dO9AnL4u+XbLom59Fny5Z9OqcSfdOHeiam6FCWVpVnaOL5UQktFQIiySB1EgKAwpzGFCYw1n1lrs7H+yuZH15BaXbo7f3Y7cXVm5h294Dh+3HDApyMujeMZPunTIP+7dbx0wKctPJz84gLyuNVBXMkgDuulhORMJLhbBIEjMzenTqQI9OHRg/IP+I9RVVNZRu38/GXfvZvKuSTbsq2bw7+m/p9greXLedXfurG9kv5GWlk5+dTn5OOvk5GRRkR//Nz0knLyudzh3S6NghjU4d0uiclUZORqoKnpAwsynAXUAEuM/df9Jg/ceAJ4B1sUWPuvv/a4ksulhORMJMhbBIG5aVnnqoD/LR7K+q5YPd0QJ5+74qyvceYNveKsr3HaB8bxXle6tYsWk35XurGi2aD4qkGJ1ihXHHDml0jt0/eMvNTCU7IzX6b3q9+xmp5MRumWkpKqaPk5lFgHuBTwBlwHwze9LdlzfY9BV3P6+l8ziaUENEwkuFsEg71yE9QlFBNkUF2U1uW1VTx/Z9VeyoiBbFu/ZXs6si+u/O/QeX1bCzooqdFVWsL9/Hzv3V7N5fTZ03nSWSYmSnR8jNTCM7I0JORrRQ7pAWISs9Qof0CJlpETocvNV7nJUeITP98HUd0mLrY/cj7WP4gnFAibuvBTCz2cCFQMNCuFVoimURCTMVwiISt/TUlGif4k6Zx/Rz7s7+6lr2Vtaw90C9W2UN+6pq2Hsgum5fI+v2VNawdc8BKqtrqaiqZX91LZXVtVTXxlFZN5AWMTJSI2SmpZCRGiEjLYUvTyziypP7HfO+QqwXUFrvcRlwciPbTTCzxcBG4JvuvizRQf74xnqeWLSRfppeXERCKq5COI7+ZhZbPxWoAL7g7m8lOKuIJCkzIys9laz0VLomaJ/VtXVUVteyP1Yc7693/1DRXBW9vz/2+EBNHQeq66isqT30b352m5vqurH214afGt4C+rn7XjObCjwODD5iR2bTgGkAffv2PeYgXbLSmTqyO6cMLDjmnxURaQ1NFsJx9jc7h+hJdDDRlodf03gLhIhIQqRFUkiLpGhykSOVAX3qPe5NtNX3EHffXe/+HDP7lZkVuPu2BtvNAmYBFBcXH3MT/Dkje3DOyB7H+mMiIq0mnvGRDvU3c/cq4GB/s/ouBB70qNeBzmams5+ISOubDww2syIzSwcuA56sv4GZdY99k4eZjSP6t6C81ZOKiAQsnq4R8fQ3a2ybXsCm40onIiLHxN1rzOw64Dmi3dnud/dlZjY9tn4m8GngP8ysBtgPXObux97pWkQkycVTCMfT3yyebY67v5mIiDTN3ecAcxosm1nv/gxgRmvnEhEJm3i6RjTZ3yzObXD3We5e7O7FhYWFx5pVRERERCRh4imEm+xvFnt8lUWNB3a5u7pFiIiIiEhoNdk1Is7+ZnOIDp1WQnT4tC+2XGQRERERkeMX1zjCcfQ3c+DaxEYTEREREWk58XSNEBERERFpcyyoEXPMbCuwvhk/WgBsa3Kr8FHu1pWsuSF5s7e33P3cvd1c9atzdlJJ1uzK3braW+5Gz9mBFcLNZWYL3L046BzHSrlbV7LmhuTNrtzSmGQ9vsmaG5I3u3K3LuWOUtcIEREREWmXVAiLiIiISLuUjIXwrKADNJNyt65kzQ3Jm125pTHJenyTNTckb3blbl3KTRL2ERYRERERSYRkbBEWERERETluSVMIm9kUM1tlZiVmdnPQeRoys/fMbImZLTKzBbFlXczsH2a2OvZvXr3tvxX7XVaZ2dmtnPV+M9tiZkvrLTvmrGY2NvY7l5jZ3WZmAeT+rpltiB33RWY2NYS5+5jZXDNbYWbLzOyG2PJQH/MPyR3qY25mmWb2ppktjuX+Xmx5qI93W6TzdsJy6pytc/bx5A71MQ/8nO3uob8Rndp5DTAASAcWA8ODztUg43tAQYNlPwVujt2/Gbgjdn947HfIAIpiv1ukFbOeBnwEWHo8WYE3gQmAAc8A5wSQ+7vANxvZNky5ewAfid3PBd6N5Qv1Mf+Q3KE+5rHnyIndTwPeAMaH/Xi3tRs6bycyp87ZOmcfT+5QH3MCPmcnS4vwOKDE3de6exUwG7gw4EzxuBB4IHb/AeCiestnu/sBd18HlBD9HVuFu78MbG+w+JiymlkPoKO7z/Poq+/Bej/TmrmPJky5N7n7W7H7e4AVQC9Cfsw/JPfRhCW3u/ve2MO02M0J+fFug3TeThCds3XOPs7cRxOW3IGes5OlEO4FlNZ7XMaH/+cGwYG/m9lCM5sWW9bN3TdB9AUKdI0tD+Pvc6xZe8XuN1wehOvM7J3Y13AHvzoJZW4z6w+cRPQTb9Ic8wa5IeTH3MwiZrYI2AL8w92T6ni3EWE8zzWUzOftZH49h/r8UZ/O2Yctb8m8gZ2zk6UQbqyPR9iGuzjV3T8CnANca2anfci2yfD7HHS0rGH5HX4NDATGAJuAn8eWhy63meUAfwW+7u67P2zTRpYFlr2R3KE/5u5e6+5jgN5EWwpGfMjmocndxiTD8WuL5+2wv55Df/44SOfsI5a3mCDP2clSCJcBfeo97g1sDChLo9x9Y+zfLcBjRL8y2xxrqif275bY5mH8fY41a1nsfsPlrcrdN8feQHXAb/n3V5Whym1maURPTH9090dji0N/zBvLnSzHPJZ1J/AiMIUkON5tTBjPc4dJ8vN2Ur6ek+X8oXN2+zlnJ0shPB8YbGZFZpYOXAY8GXCmQ8ws28xyD94HzgKWEs34+dhmnweeiN1/ErjMzDLMrAgYTLSDd5COKWvsa4o9ZjY+dlXmVfV+ptUcfJPEfJLocYcQ5Y49z++AFe7+i3qrQn3Mj5Y77MfczArNrHPsfgfgTGAlIT/ebZDO2y0rKV/PYT9/xDLqnN2eztnegldeJvIGTCV6BeQa4NtB52mQbQDRKxgXA8sO5gPygReA1bF/u9T7mW/HfpdVtPKV6MAjRL8eqSb6CerLzckKFBN9Q60BZhCboKWVcz8ELAHeib05eoQw90SiX8+8AyyK3aaG/Zh/SO5QH3NgFPB2LN9S4Dux5aE+3m3xhs7bicqqc7bO2ceTO9THnIDP2ZpZTkRERETapWTpGiEiIiIiklAqhEVERESkXVIhLCIiIiLtkgphEREREWmXVAiLiIiISLukQlhERERE2iUVwiIiIiLSLqkQFhEREZF26f8Dj90xMMSYiWsAAAAASUVORK5CYII=", 222 | "text/plain": [ 223 | "
" 224 | ] 225 | }, 226 | "metadata": { 227 | "needs_background": "light" 228 | }, 229 | "output_type": "display_data" 230 | }, 231 | { 232 | "data": { 233 | "text/plain": [ 234 | "array([[0.76537816, 0.5 ],\n", 235 | " [0.73318091, 0.5 ],\n", 236 | " [0.71304419, 0.5 ],\n", 237 | " ...,\n", 238 | " [0.01403589, 1. ],\n", 239 | " [0.01402475, 1. ],\n", 240 | " [0.01401363, 1. ]])" 241 | ] 242 | }, 243 | "execution_count": 15, 244 | "metadata": {}, 245 | "output_type": "execute_result" 246 | } 247 | ], 248 | "source": [ 249 | "deep_neural_network(X, y, hidden_layers = (16, 16, 16), learning_rate = 0.1, n_iter = 3000)" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": null, 255 | "metadata": {}, 256 | "outputs": [], 257 | "source": [] 258 | } 259 | ], 260 | "metadata": { 261 | "interpreter": { 262 | "hash": "038c04557dfd72b4d6039cb7951b93ffe7520921b6515cb88d8784deedfaf89f" 263 | }, 264 | "kernelspec": { 265 | "display_name": "Python 3.7.9 ('base')", 266 | "language": "python", 267 | "name": "python3" 268 | }, 269 | "language_info": { 270 | "codemirror_mode": { 271 | "name": "ipython", 272 | "version": 3 273 | }, 274 | "file_extension": ".py", 275 | "mimetype": "text/x-python", 276 | "name": "python", 277 | "nbconvert_exporter": "python", 278 | "pygments_lexer": "ipython3", 279 | "version": "3.7.9" 280 | }, 281 | "orig_nbformat": 4 282 | }, 283 | "nbformat": 4, 284 | "nbformat_minor": 2 285 | } 286 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deep-Learning-Youtube 2 | Codes développés dans les vidéos Tutoriels de la série Deep Learning sur la chaine YouTube Machine Learnia 3 | -------------------------------------------------------------------------------- /Tensorflow_MNIST_pour_débutants.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Tensorflow MNIST pour débutants.ipynb", 7 | "provenance": [], 8 | "authorship_tag": "ABX9TyOs8BB3zR8xdfuugq88TB1k", 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "name": "python3", 13 | "display_name": "Python 3" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "view-in-github", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "\"Open" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "id": "kLrzSZ1Cfv6L" 31 | }, 32 | "source": [ 33 | "# Tensorflow MNIST pour débutants\r\n", 34 | "Ce Notebook permet aux débutants d'apprendre à développer un premier modèle de classification sur le dataset MNIST, en utilisant l'API Keras." 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "metadata": { 40 | "id": "AIUwgqwP5hkp", 41 | "outputId": "9d5e60c6-a4bd-4a30-c09b-7994496b39ca", 42 | "colab": { 43 | "base_uri": "https://localhost:8080/" 44 | } 45 | }, 46 | "source": [ 47 | "!pip install tensorflow" 48 | ], 49 | "execution_count": 7, 50 | "outputs": [ 51 | { 52 | "output_type": "stream", 53 | "text": [ 54 | "Requirement already satisfied: tensorflow in /usr/local/lib/python3.6/dist-packages (2.4.0)\n", 55 | "Requirement already satisfied: keras-preprocessing~=1.1.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (1.1.2)\n", 56 | "Requirement already satisfied: protobuf>=3.9.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (3.12.4)\n", 57 | "Requirement already satisfied: absl-py~=0.10 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (0.10.0)\n", 58 | "Requirement already satisfied: flatbuffers~=1.12.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (1.12)\n", 59 | "Requirement already satisfied: termcolor~=1.1.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (1.1.0)\n", 60 | "Requirement already satisfied: tensorboard~=2.4 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (2.4.0)\n", 61 | "Requirement already satisfied: opt-einsum~=3.3.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (3.3.0)\n", 62 | "Requirement already satisfied: six~=1.15.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (1.15.0)\n", 63 | "Requirement already satisfied: typing-extensions~=3.7.4 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (3.7.4.3)\n", 64 | "Requirement already satisfied: google-pasta~=0.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (0.2.0)\n", 65 | "Requirement already satisfied: astunparse~=1.6.3 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (1.6.3)\n", 66 | "Requirement already satisfied: gast==0.3.3 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (0.3.3)\n", 67 | "Requirement already satisfied: h5py~=2.10.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (2.10.0)\n", 68 | "Requirement already satisfied: tensorflow-estimator<2.5.0,>=2.4.0rc0 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (2.4.0)\n", 69 | "Requirement already satisfied: grpcio~=1.32.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (1.32.0)\n", 70 | "Requirement already satisfied: wheel~=0.35 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (0.36.2)\n", 71 | "Requirement already satisfied: wrapt~=1.12.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (1.12.1)\n", 72 | "Requirement already satisfied: numpy~=1.19.2 in /usr/local/lib/python3.6/dist-packages (from tensorflow) (1.19.4)\n", 73 | "Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from protobuf>=3.9.2->tensorflow) (51.0.0)\n", 74 | "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.6/dist-packages (from tensorboard~=2.4->tensorflow) (0.4.2)\n", 75 | "Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.6/dist-packages (from tensorboard~=2.4->tensorflow) (2.23.0)\n", 76 | "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.6/dist-packages (from tensorboard~=2.4->tensorflow) (1.0.1)\n", 77 | "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.6/dist-packages (from tensorboard~=2.4->tensorflow) (1.7.0)\n", 78 | "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.6/dist-packages (from tensorboard~=2.4->tensorflow) (3.3.3)\n", 79 | "Requirement already satisfied: google-auth<2,>=1.6.3 in /usr/local/lib/python3.6/dist-packages (from tensorboard~=2.4->tensorflow) (1.17.2)\n", 80 | "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.6/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard~=2.4->tensorflow) (1.3.0)\n", 81 | "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard~=2.4->tensorflow) (1.24.3)\n", 82 | "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard~=2.4->tensorflow) (2020.12.5)\n", 83 | "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard~=2.4->tensorflow) (2.10)\n", 84 | "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.21.0->tensorboard~=2.4->tensorflow) (3.0.4)\n", 85 | "Requirement already satisfied: importlib-metadata; python_version < \"3.8\" in /usr/local/lib/python3.6/dist-packages (from markdown>=2.6.8->tensorboard~=2.4->tensorflow) (3.3.0)\n", 86 | "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard~=2.4->tensorflow) (4.2.0)\n", 87 | "Requirement already satisfied: rsa<5,>=3.1.4; python_version >= \"3\" in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard~=2.4->tensorflow) (4.6)\n", 88 | "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.6/dist-packages (from google-auth<2,>=1.6.3->tensorboard~=2.4->tensorflow) (0.2.8)\n", 89 | "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.6/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard~=2.4->tensorflow) (3.1.0)\n", 90 | "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.6/dist-packages (from importlib-metadata; python_version < \"3.8\"->markdown>=2.6.8->tensorboard~=2.4->tensorflow) (3.4.0)\n", 91 | "Requirement already satisfied: pyasn1>=0.1.3 in /usr/local/lib/python3.6/dist-packages (from rsa<5,>=3.1.4; python_version >= \"3\"->google-auth<2,>=1.6.3->tensorboard~=2.4->tensorflow) (0.4.8)\n" 92 | ], 93 | "name": "stdout" 94 | } 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "metadata": { 100 | "id": "oa63KejBfog8" 101 | }, 102 | "source": [ 103 | "import numpy as np\r\n", 104 | "import matplotlib.pyplot as plt\r\n", 105 | "from tensorflow import keras" 106 | ], 107 | "execution_count": 8, 108 | "outputs": [] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": { 113 | "id": "UvrLumwPhZrN" 114 | }, 115 | "source": [ 116 | "## 1. Chargement des données et Normalisation" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "metadata": { 122 | "colab": { 123 | "base_uri": "https://localhost:8080/" 124 | }, 125 | "id": "oPZCV7XTfucK", 126 | "outputId": "aea04f64-37bd-4a81-bd9a-d36b79e4f13b" 127 | }, 128 | "source": [ 129 | "# Chargement des données MNIST\r\n", 130 | "(X_train, y_train) , (X_test, y_test) = keras.datasets.mnist.load_data()\r\n", 131 | "\r\n", 132 | "print('trainset:', X_train.shape) # 60,000 images\r\n", 133 | "print('testset:', X_test.shape) # 10,000 images\r\n", 134 | "\r\n", 135 | "# Normalisation des données\r\n", 136 | "X_train = X_train / 255\r\n", 137 | "X_test = X_test / 255" 138 | ], 139 | "execution_count": null, 140 | "outputs": [ 141 | { 142 | "output_type": "stream", 143 | "text": [ 144 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n", 145 | "11493376/11490434 [==============================] - 0s 0us/step\n", 146 | "trainset: (60000, 28, 28)\n", 147 | "testset: (10000, 28, 28)\n" 148 | ], 149 | "name": "stdout" 150 | } 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": { 156 | "id": "JKEjEqbOhdh0" 157 | }, 158 | "source": [ 159 | "## 2. Visualisation des données" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "metadata": { 165 | "colab": { 166 | "base_uri": "https://localhost:8080/", 167 | "height": 162 168 | }, 169 | "id": "BmTNBz7bgeZG", 170 | "outputId": "95ff4814-9e82-488a-c1b2-a8febd82f019" 171 | }, 172 | "source": [ 173 | "# visualisation de quelques images\r\n", 174 | "fig, ax = plt.subplots(nrows=1, ncols=10, figsize=(20, 4))\r\n", 175 | "for i in range(10):\r\n", 176 | " ax[i].imshow(X_train[i], cmap='gray')\r\n", 177 | "\r\n", 178 | "plt.tight_layout()\r\n", 179 | "plt.show()" 180 | ], 181 | "execution_count": null, 182 | "outputs": [ 183 | { 184 | "output_type": "display_data", 185 | "data": { 186 | "image/png": "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\n", 187 | "text/plain": [ 188 | "
" 189 | ] 190 | }, 191 | "metadata": { 192 | "tags": [], 193 | "needs_background": "light" 194 | } 195 | } 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": { 201 | "id": "FInfYGsMhflz" 202 | }, 203 | "source": [ 204 | "## 3. Configuration des Couches du Réseau de Neurones" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "metadata": { 210 | "id": "RFfzviJKg5WE" 211 | }, 212 | "source": [ 213 | "# Configuration des couches du réseau\r\n", 214 | "model = keras.Sequential([\r\n", 215 | " keras.layers.Flatten(input_shape=(28, 28)),\r\n", 216 | " keras.layers.Dense(128, activation='relu'),\r\n", 217 | " keras.layers.Dense(128, activation='relu'),\r\n", 218 | " keras.layers.Dense(10)\r\n", 219 | "])" 220 | ], 221 | "execution_count": null, 222 | "outputs": [] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": { 227 | "id": "YfdDh4_zhkL7" 228 | }, 229 | "source": [ 230 | "## 4. Entrainement du Réseau de Neurones" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "metadata": { 236 | "colab": { 237 | "base_uri": "https://localhost:8080/" 238 | }, 239 | "id": "TvrDQgcTfeDx", 240 | "outputId": "dd45c00a-d4da-4215-aba2-2fc89012449d" 241 | }, 242 | "source": [ 243 | "# Compilation du modele\r\n", 244 | "model.compile(optimizer='adam',\r\n", 245 | " loss= keras.losses.SparseCategoricalCrossentropy(from_logits=True),\r\n", 246 | " metrics=['accuracy'])\r\n", 247 | "\r\n", 248 | "# Entrainement du modele\r\n", 249 | "model.fit(X_train, y_train, epochs=10)" 250 | ], 251 | "execution_count": null, 252 | "outputs": [ 253 | { 254 | "output_type": "stream", 255 | "text": [ 256 | "Epoch 1/10\n", 257 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.4070 - accuracy: 0.8833\n", 258 | "Epoch 2/10\n", 259 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.1002 - accuracy: 0.9692\n", 260 | "Epoch 3/10\n", 261 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0653 - accuracy: 0.9781\n", 262 | "Epoch 4/10\n", 263 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0468 - accuracy: 0.9845\n", 264 | "Epoch 5/10\n", 265 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0373 - accuracy: 0.9872\n", 266 | "Epoch 6/10\n", 267 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0310 - accuracy: 0.9898\n", 268 | "Epoch 7/10\n", 269 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0251 - accuracy: 0.9916\n", 270 | "Epoch 8/10\n", 271 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0245 - accuracy: 0.9919\n", 272 | "Epoch 9/10\n", 273 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0180 - accuracy: 0.9940\n", 274 | "Epoch 10/10\n", 275 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0155 - accuracy: 0.9950\n" 276 | ], 277 | "name": "stdout" 278 | }, 279 | { 280 | "output_type": "execute_result", 281 | "data": { 282 | "text/plain": [ 283 | "" 284 | ] 285 | }, 286 | "metadata": { 287 | "tags": [] 288 | }, 289 | "execution_count": 6 290 | } 291 | ] 292 | }, 293 | { 294 | "cell_type": "markdown", 295 | "metadata": { 296 | "id": "EnifmnaOhodj" 297 | }, 298 | "source": [ 299 | "## 5. Évaluation du réseau de neurone sur les données de Test" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "metadata": { 305 | "colab": { 306 | "base_uri": "https://localhost:8080/" 307 | }, 308 | "id": "3LdmrOwKg8nK", 309 | "outputId": "ab21b696-7ffa-4ad0-cafa-ac258a770f7b" 310 | }, 311 | "source": [ 312 | "# Evaluation du modele\r\n", 313 | "test_loss, test_acc = model.evaluate(X_test, y_test)\r\n", 314 | "print('Test accuracy:', test_acc)" 315 | ], 316 | "execution_count": null, 317 | "outputs": [ 318 | { 319 | "output_type": "stream", 320 | "text": [ 321 | "313/313 [==============================] - 0s 1ms/step - loss: 0.0843 - accuracy: 0.9797\n", 322 | "Test accuracy: 0.9797000288963318\n" 323 | ], 324 | "name": "stdout" 325 | } 326 | ] 327 | }, 328 | { 329 | "cell_type": "markdown", 330 | "metadata": { 331 | "id": "9a8vswFYhuGL" 332 | }, 333 | "source": [ 334 | "## 6. Création d'un modele prédictif" 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "metadata": { 340 | "colab": { 341 | "base_uri": "https://localhost:8080/" 342 | }, 343 | "id": "TFv035qwg-Q6", 344 | "outputId": "38e6dd3a-b674-4e30-f87b-84247e779e37" 345 | }, 346 | "source": [ 347 | "# modele prédictif (softmax)\r\n", 348 | "prediction_model = keras.Sequential([model, keras.layers.Softmax()])\r\n", 349 | "predict_proba = prediction_model.predict(X_test)\r\n", 350 | "predictions = np.argmax(predict_proba, axis=1)\r\n", 351 | "\r\n", 352 | "print(predictions[:10])\r\n", 353 | "print(y_test[:10])" 354 | ], 355 | "execution_count": null, 356 | "outputs": [ 357 | { 358 | "output_type": "stream", 359 | "text": [ 360 | "[7 2 1 0 4 1 4 9 5 9]\n", 361 | "[7 2 1 0 4 1 4 9 5 9]\n" 362 | ], 363 | "name": "stdout" 364 | } 365 | ] 366 | } 367 | ] 368 | } -------------------------------------------------------------------------------- /datasets/testset.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MachineLearnia/Deep-Learning-Youtube/6fec1555d012dc9f9dd38a26c97ced2cf29b7bbf/datasets/testset.hdf5 -------------------------------------------------------------------------------- /datasets/trainset.hdf5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MachineLearnia/Deep-Learning-Youtube/6fec1555d012dc9f9dd38a26c97ced2cf29b7bbf/datasets/trainset.hdf5 -------------------------------------------------------------------------------- /utilities.py: -------------------------------------------------------------------------------- 1 | import h5py 2 | import numpy as np 3 | 4 | 5 | def load_data(): 6 | train_dataset = h5py.File('datasets/trainset.hdf5', "r") 7 | X_train = np.array(train_dataset["X_train"][:]) # your train set features 8 | y_train = np.array(train_dataset["Y_train"][:]) # your train set labels 9 | 10 | test_dataset = h5py.File('datasets/testset.hdf5', "r") 11 | X_test = np.array(test_dataset["X_test"][:]) # your train set features 12 | y_test = np.array(test_dataset["Y_test"][:]) # your train set labels 13 | 14 | return X_train, y_train, X_test, y_test --------------------------------------------------------------------------------