├── 04_Redes_neuronales_densamente_conectadas.ipynb ├── 05_redes_neuronales_en_keras.ipynb ├── 08_redes_neuronales_convolucionales.ipynb ├── 09_etapas_de_un_proyecto_deep_learning.ipynb ├── 10_datos_para_entrenar_redes_neuronales.ipynb ├── 11_DataAugmentation_y_TransferLearning.ipynb ├── 12_Arquitecturas_avanzadas_redes_neuronales.ipynb ├── 13_Redes_neuronales_recurrentes.ipynb ├── 14_Generative_Adversarial_Networks.ipynb └── README.md /04_Redes_neuronales_densamente_conectadas.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "04_Redes_neuronales_densamente_conectadas.ipynb", 7 | "provenance": [] 8 | }, 9 | "kernelspec": { 10 | "name": "python3", 11 | "display_name": "Python 3" 12 | }, 13 | "accelerator": "GPU" 14 | }, 15 | "cells": [ 16 | { 17 | "cell_type": "markdown", 18 | "metadata": { 19 | "id": "0M4J-yXFSOTa", 20 | "colab_type": "text" 21 | }, 22 | "source": [ 23 | "# 04. Redes neuronales densamente conectadas\n", 24 | "[**Python Deep Learning** Introducción práctica con Keras y TensorFlow 2. Jordi Torres. Editorial Marcombo ISBN: 9788426728289 ](https://www.marcombo.com/python-deep-learning-9788426728289/)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "id": "ryl6ALGLSdUP", 31 | "colab_type": "text" 32 | }, 33 | "source": [ 34 | "## Inicializaciones" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "metadata": { 40 | "id": "s3KzA9ZUuLRB", 41 | "colab_type": "code", 42 | "outputId": "5e07b15d-84e7-4f5d-e2a0-652d3d5b0524", 43 | "colab": { 44 | "base_uri": "https://localhost:8080/", 45 | "height": 52 46 | } 47 | }, 48 | "source": [ 49 | "try:\n", 50 | " # %tensorflow_version solo existe en Colab.\n", 51 | " %tensorflow_version 2.x\n", 52 | "except Exception:\n", 53 | " pass\n", 54 | "\n", 55 | "import tensorflow as tf\n", 56 | "import numpy as np\n", 57 | "import matplotlib.pyplot as plt\n", 58 | "\n", 59 | "print(tf.__version__)" 60 | ], 61 | "execution_count": 1, 62 | "outputs": [ 63 | { 64 | "output_type": "stream", 65 | "text": [ 66 | "TensorFlow 2.x selected.\n", 67 | "2.1.0-rc1\n" 68 | ], 69 | "name": "stdout" 70 | } 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": { 76 | "id": "w2B0J5r5SzrT", 77 | "colab_type": "text" 78 | }, 79 | "source": [ 80 | "## 4.1 Caso de estudio: reconocimiento de dígitos" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "metadata": { 86 | "id": "715hLvWqwPrJ", 87 | "colab_type": "code", 88 | "colab": { 89 | "base_uri": "https://localhost:8080/", 90 | "height": 52 91 | }, 92 | "outputId": "4ebe1083-7586-427d-a9d1-4a12f5184391" 93 | }, 94 | "source": [ 95 | "mnist = tf.keras.datasets.mnist\n", 96 | "\n", 97 | "(x_train, y_train), (x_test, y_test) = mnist.load_data()" 98 | ], 99 | "execution_count": 2, 100 | "outputs": [ 101 | { 102 | "output_type": "stream", 103 | "text": [ 104 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n", 105 | "11493376/11490434 [==============================] - 0s 0us/step\n" 106 | ], 107 | "name": "stdout" 108 | } 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "metadata": { 114 | "id": "RGWzf-U5TBhm", 115 | "colab_type": "code", 116 | "outputId": "5e25eba7-da8a-484a-de89-86d8d48015b0", 117 | "colab": { 118 | "base_uri": "https://localhost:8080/", 119 | "height": 282 120 | } 121 | }, 122 | "source": [ 123 | "plt.imshow(x_train[8], cmap=plt.cm.binary)\n", 124 | "print(y_train[8])" 125 | ], 126 | "execution_count": 3, 127 | "outputs": [ 128 | { 129 | "output_type": "stream", 130 | "text": [ 131 | "1\n" 132 | ], 133 | "name": "stdout" 134 | }, 135 | { 136 | "output_type": "display_data", 137 | "data": { 138 | "image/png": "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\n", 139 | "text/plain": [ 140 | "
" 141 | ] 142 | }, 143 | "metadata": { 144 | "tags": [] 145 | } 146 | } 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "metadata": { 152 | "id": "OOVttVw2TMuU", 153 | "colab_type": "code", 154 | "outputId": "64d1edfa-5004-4ac1-ed22-5e727e096a6d", 155 | "colab": { 156 | "base_uri": "https://localhost:8080/", 157 | "height": 501 158 | } 159 | }, 160 | "source": [ 161 | "np.set_printoptions(precision=2, suppress=True, linewidth=120)\n", 162 | "print(np.matrix(x_train[8]))" 163 | ], 164 | "execution_count": 4, 165 | "outputs": [ 166 | { 167 | "output_type": "stream", 168 | "text": [ 169 | "[[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n", 170 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n", 171 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n", 172 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n", 173 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n", 174 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 5 63 197 0 0 0 0 0 0 0 0 0 0 0 0 0]\n", 175 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 20 254 230 24 0 0 0 0 0 0 0 0 0 0 0 0]\n", 176 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 20 254 254 48 0 0 0 0 0 0 0 0 0 0 0 0]\n", 177 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 20 254 255 48 0 0 0 0 0 0 0 0 0 0 0 0]\n", 178 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 20 254 254 57 0 0 0 0 0 0 0 0 0 0 0 0]\n", 179 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 20 254 254 108 0 0 0 0 0 0 0 0 0 0 0 0]\n", 180 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 16 239 254 143 0 0 0 0 0 0 0 0 0 0 0 0]\n", 181 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 178 254 143 0 0 0 0 0 0 0 0 0 0 0 0]\n", 182 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 178 254 143 0 0 0 0 0 0 0 0 0 0 0 0]\n", 183 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 178 254 162 0 0 0 0 0 0 0 0 0 0 0 0]\n", 184 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 178 254 240 0 0 0 0 0 0 0 0 0 0 0 0]\n", 185 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 113 254 240 0 0 0 0 0 0 0 0 0 0 0 0]\n", 186 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 83 254 245 31 0 0 0 0 0 0 0 0 0 0 0]\n", 187 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 79 254 246 38 0 0 0 0 0 0 0 0 0 0 0]\n", 188 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 214 254 150 0 0 0 0 0 0 0 0 0 0 0]\n", 189 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 144 241 8 0 0 0 0 0 0 0 0 0 0 0]\n", 190 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 144 240 2 0 0 0 0 0 0 0 0 0 0 0]\n", 191 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 144 254 82 0 0 0 0 0 0 0 0 0 0 0]\n", 192 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 230 247 40 0 0 0 0 0 0 0 0 0 0 0]\n", 193 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 168 209 31 0 0 0 0 0 0 0 0 0 0 0]\n", 194 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n", 195 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n", 196 | " [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]\n" 197 | ], 198 | "name": "stdout" 199 | } 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": { 205 | "id": "lqciPxRNU99j", 206 | "colab_type": "text" 207 | }, 208 | "source": [ 209 | "## 4.4 Función de activación softmax" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "metadata": { 215 | "id": "eY_9fDfkVExh", 216 | "colab_type": "text" 217 | }, 218 | "source": [ 219 | "Modelo con una capa softmax para visualizar los modelos aprendidos" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "metadata": { 225 | "id": "wpaiBuKeTNGr", 226 | "colab_type": "code", 227 | "outputId": "db2b0d59-96e9-4cc9-d10e-fe31f6490202", 228 | "colab": { 229 | "base_uri": "https://localhost:8080/", 230 | "height": 259 231 | } 232 | }, 233 | "source": [ 234 | "x_train = x_train.reshape((60000, 784))\n", 235 | "x_test = x_test.reshape((10000, 784))\n", 236 | "x_train, x_test = x_train / 255.0, x_test / 255.0\n", 237 | "\n", 238 | "model = tf.keras.models.Sequential([\n", 239 | " tf.keras.layers.Dense(10, activation='softmax', name=\"FC1\", input_shape=(784,))\n", 240 | "])\n", 241 | "model.summary()\n", 242 | "\n", 243 | "model.compile(optimizer='adam',\n", 244 | " loss='sparse_categorical_crossentropy',\n", 245 | " metrics=['accuracy'])\n", 246 | "\n", 247 | "model.fit(x_train, y_train, epochs=1)\n", 248 | "\n", 249 | "model.evaluate(x_test, y_test, verbose=2)" 250 | ], 251 | "execution_count": 5, 252 | "outputs": [ 253 | { 254 | "output_type": "stream", 255 | "text": [ 256 | "Model: \"sequential\"\n", 257 | "_________________________________________________________________\n", 258 | "Layer (type) Output Shape Param # \n", 259 | "=================================================================\n", 260 | "FC1 (Dense) (None, 10) 7850 \n", 261 | "=================================================================\n", 262 | "Total params: 7,850\n", 263 | "Trainable params: 7,850\n", 264 | "Non-trainable params: 0\n", 265 | "_________________________________________________________________\n", 266 | "Train on 60000 samples\n", 267 | "60000/60000 [==============================] - 6s 98us/sample - loss: 0.4711 - accuracy: 0.8768\n", 268 | "10000/10000 - 1s - loss: 0.3086 - accuracy: 0.9162\n" 269 | ], 270 | "name": "stdout" 271 | }, 272 | { 273 | "output_type": "execute_result", 274 | "data": { 275 | "text/plain": [ 276 | "[0.3085567438960075, 0.9162]" 277 | ] 278 | }, 279 | "metadata": { 280 | "tags": [] 281 | }, 282 | "execution_count": 5 283 | } 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": { 289 | "id": "Nhi-XHXoVqpn", 290 | "colab_type": "text" 291 | }, 292 | "source": [ 293 | "Figura 4.14 Modelo aprendido correspondiente al número 0" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "metadata": { 299 | "id": "2L96kEYlVSdQ", 300 | "colab_type": "code", 301 | "outputId": "90a74549-adeb-49ff-c41b-693508130ee1", 302 | "colab": { 303 | "base_uri": "https://localhost:8080/", 304 | "height": 282 305 | } 306 | }, 307 | "source": [ 308 | "w = model.get_weights()\n", 309 | "w = np.asarray(w[0])\n", 310 | "plt.figure()\n", 311 | "plt.imshow(w[:,0].reshape([28,28]), cmap=plt.get_cmap('seismic_r'))" 312 | ], 313 | "execution_count": 6, 314 | "outputs": [ 315 | { 316 | "output_type": "execute_result", 317 | "data": { 318 | "text/plain": [ 319 | "" 320 | ] 321 | }, 322 | "metadata": { 323 | "tags": [] 324 | }, 325 | "execution_count": 6 326 | }, 327 | { 328 | "output_type": "display_data", 329 | "data": { 330 | "image/png": "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\n", 331 | "text/plain": [ 332 | "
" 333 | ] 334 | }, 335 | "metadata": { 336 | "tags": [] 337 | } 338 | } 339 | ] 340 | }, 341 | { 342 | "cell_type": "markdown", 343 | "metadata": { 344 | "id": "JF1cc6xoWtGE", 345 | "colab_type": "text" 346 | }, 347 | "source": [ 348 | "Figura 4.5 Matriz de parámetros correspondiente al modelo de la categoría cero" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "metadata": { 354 | "id": "Z0EhD5-QVSgA", 355 | "colab_type": "code", 356 | "outputId": "a4b81181-c72f-4c28-de1b-f51b67123cc5", 357 | "colab": { 358 | "base_uri": "https://localhost:8080/", 359 | "height": 521 360 | } 361 | }, 362 | "source": [ 363 | "np.set_printoptions(precision=0, suppress = True, linewidth=220)\n", 364 | "print(np.matrix (255*(w[:,0].reshape([28,28]))))" 365 | ], 366 | "execution_count": 7, 367 | "outputs": [ 368 | { 369 | "output_type": "stream", 370 | "text": [ 371 | "[[ 13. 19. 18. 17. -21. -12. 10. -11. -16. 20. 3. 22. 15. -8. -15. -7. 1. 14. -6. -20. -13. 17. -6. 18. -15. -12. 12. 1.]\n", 372 | " [ 10. -8. 8. 19. 11. 15. 2. 12. 16. -2. -20. -21. 4. 9. -7. -2. -33. -18. -17. -46. -37. -28. -30. -18. -5. 6. 21. 7.]\n", 373 | " [ 9. 4. -6. 3. 14. -34. -11. -30. -32. -37. -39. -53. -18. -18. -37. -37. -67. -79. -41. -60. -24. -53. -23. -1. -2. -13. -19. 8.]\n", 374 | " [ 5. 18. -0. 17. -28. -28. -32. -21. -15. -24. -52. -20. -15. -13. -51. -46. -51. -22. -52. -36. -63. -41. -38. -29. -5. -23. 1. -8.]\n", 375 | " [ -16. 15. 6. -21. -47. -53. -43. -45. -26. -19. -2. -13. -25. -5. -12. -10. 16. -25. -9. -5. -2. -34. -32. -18. -33. -26. -12. -25.]\n", 376 | " [ 12. -6. 12. 3. -36. -74. -24. -24. -22. -38. -22. -31. 14. 19. 22. 19. 19. 18. 9. 20. 8. -2. -1. -43. -38. -81. -31. -2.]\n", 377 | " [ 0. 13. -5. -33. -26. -17. -19. -25. -25. -10. -15. -20. -11. 3. 16. 10. 44. 45. 21. 27. 7. 22. -6. -26. -60. -72. -31. -25.]\n", 378 | " [ -4. -7. -10. -42. -29. -39. -34. -46. -28. -38. -1. 5. -18. 24. 15. 29. 32. 46. 36. 18. 5. -7. 20. 9. -41. -79. -66. 7.]\n", 379 | " [ 8. 9. -17. -37. -53. -46. -25. -13. -39. -20. 4. -0. -13. -6. 18. 4. 39. 57. 28. 43. 31. 3. 14. -3. -42. -89. -57. -28.]\n", 380 | " [ -18. -5. -2. -22. -51. -29. -16. -29. -13. -14. -27. -8. -9. 32. 9. -0. 16. 19. 26. 21. 7. 2. 11. 33. -18. -61. -74. -1.]\n", 381 | " [ -4. -25. -20. -7. -42. -11. -34. -14. 0. 4. -3. 1. 21. 31. 15. -19. -20. 0. 43. 30. 23. 20. 44. 34. 23. -80. -64. -27.]\n", 382 | " [ 11. 13. -10. -38. -60. -3. -24. 10. -30. -11. 3. 10. -3. -33. -65. -76. -66. -44. 7. 25. 33. 48. 25. 36. 28. -53. -57. -27.]\n", 383 | " [ -0. -13. -30. -52. -46. -20. -7. -10. -15. -6. 28. -5. 12. -44. -75. -87. -97. -54. -38. -15. -4. 26. 41. 59. 30. -26. -43. -22.]\n", 384 | " [ -20. 15. 4. -24. -6. 1. 36. 14. 11. -5. 27. -1. -9. -56. -106. -109. -81. -69. -12. 13. -4. 36. 50. 69. 40. 11. -13. -2.]\n", 385 | " [ -24. -21. 4. -51. -28. 1. 35. 9. 29. 15. 25. 4. -44. -107. -120. -122. -96. -57. -44. -14. -8. 31. 45. 49. 33. -5. -27. -17.]\n", 386 | " [ -8. -28. -29. -39. -17. 8. 25. 36. 44. 36. 44. -13. -58. -87. -89. -116. -94. -37. 3. 3. 30. 7. 34. 21. 31. -9. -40. -37.]\n", 387 | " [ -16. -25. -39. -67. 8. 31. 24. 21. 23. 42. 35. -21. -71. -88. -118. -99. -38. -40. -7. -8. 15. 18. 8. 37. -9. -16. -30. -6.]\n", 388 | " [ 16. -10. -42. -44. -25. 34. 17. 42. 19. 23. 47. -38. -60. -107. -90. -71. -51. -13. -1. 16. -15. 26. 20. 8. 8. -8. -8. 10.]\n", 389 | " [ -13. 8. -33. -49. -25. 0. 11. 22. 37. 43. 41. -9. -33. -86. -59. -30. -15. 7. 17. -21. -16. 19. 20. -16. -0. -13. -29. -22.]\n", 390 | " [ -7. 3. -22. -40. -7. 14. 8. 23. 13. 16. 42. 11. -21. -31. -26. -22. -11. -19. 2. -4. -8. 6. 5. -1. 1. -28. -57. -34.]\n", 391 | " [ -5. -3. -21. -61. -21. 1. -15. 5. 19. 44. 37. 30. -1. -0. 5. 3. 1. 9. -3. -3. -21. -18. -25. -5. -17. -25. -3. -14.]\n", 392 | " [ -17. 8. 5. -17. -39. -12. 24. 15. -7. 30. 13. 52. 19. 16. 13. -3. -7. -13. -25. -29. -4. -13. -11. -44. -5. -11. -21. 12.]\n", 393 | " [ -16. -19. -21. -15. -32. -6. -1. 23. -1. 35. 35. 28. 21. 24. 20. 13. -14. -7. -7. 1. -30. -5. -39. -38. -11. 11. 20. 2.]\n", 394 | " [ -0. -6. 2. -24. -60. -42. -29. 17. -10. 36. 49. 33. 37. 39. 16. 28. 12. -4. -44. -38. -35. -31. -35. -44. -2. -42. -7. -11.]\n", 395 | " [ -9. -0. -4. -15. -24. -19. -29. -18. -40. -17. -12. -15. -6. -3. -17. -36. -46. -24. -44. -54. -73. -56. -33. -17. -18. -7. 9. 12.]\n", 396 | " [ 13. -2. 16. -4. -24. -48. -43. -72. -67. -74. -76. -76. -70. -74. -95. -101. -93. -69. -68. -76. -51. -49. -21. -35. -6. -17. -9. -17.]\n", 397 | " [ -1. 5. 21. 16. -12. -8. -6. -37. -19. -61. -70. -52. -41. -78. -36. -38. -41. -60. -54. -17. -45. -31. -32. -29. -18. 12. -0. -20.]\n", 398 | " [ 4. -8. -1. 14. -21. -4. -22. -5. -39. 1. -14. -18. -7. -22. -9. -12. -4. -9. -22. -23. -12. -31. -4. -10. -21. -19. 10. -11.]]\n" 399 | ], 400 | "name": "stdout" 401 | } 402 | ] 403 | }, 404 | { 405 | "cell_type": "markdown", 406 | "metadata": { 407 | "id": "vDEEuEtgW9qV", 408 | "colab_type": "text" 409 | }, 410 | "source": [ 411 | "Figura 4.16 Modelo aprendido correspondiente al número 3" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "metadata": { 417 | "id": "227dP4lWVSji", 418 | "colab_type": "code", 419 | "outputId": "a7bd822d-72ed-4bd0-fa95-965c4f706a8b", 420 | "colab": { 421 | "base_uri": "https://localhost:8080/", 422 | "height": 282 423 | } 424 | }, 425 | "source": [ 426 | "w = model.get_weights()\n", 427 | "w = np.asarray(w[0])\n", 428 | "plt.figure()\n", 429 | "plt.imshow(w[:,3].reshape([28,28]), cmap=plt.get_cmap('seismic_r'))" 430 | ], 431 | "execution_count": 8, 432 | "outputs": [ 433 | { 434 | "output_type": "execute_result", 435 | "data": { 436 | "text/plain": [ 437 | "" 438 | ] 439 | }, 440 | "metadata": { 441 | "tags": [] 442 | }, 443 | "execution_count": 8 444 | }, 445 | { 446 | "output_type": "display_data", 447 | "data": { 448 | "image/png": "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\nD+YAAAAASUVORK5CYII=\n", 449 | "text/plain": [ 450 | "
" 451 | ] 452 | }, 453 | "metadata": { 454 | "tags": [] 455 | } 456 | } 457 | ] 458 | } 459 | ] 460 | } -------------------------------------------------------------------------------- /10_datos_para_entrenar_redes_neuronales.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "10-datos-para-entrenar-redes-neuronales.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [] 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "accelerator": "GPU" 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "1Lq8oCcoWTNg", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "# 10. Datos para entrenar redes neuronales\n", 25 | "[**Python Deep Learning** Introducción práctica con Keras y TensorFlow 2. Jordi Torres. Editorial Marcombo ISBN: 9788426728289 ](https://www.marcombo.com/python-deep-learning-9788426728289/)" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "metadata": { 31 | "id": "Sl1ylYJMKxZD", 32 | "colab_type": "code", 33 | "outputId": "aa1f8e85-068b-4faa-fc05-14869cd8c162", 34 | "colab": { 35 | "base_uri": "https://localhost:8080/", 36 | "height": 50 37 | } 38 | }, 39 | "source": [ 40 | "%tensorflow_version 2.x\n", 41 | "import tensorflow as tf\n", 42 | "from tensorflow import keras\n", 43 | "\n", 44 | "print(tf.__version__)" 45 | ], 46 | "execution_count": 1, 47 | "outputs": [ 48 | { 49 | "output_type": "stream", 50 | "text": [ 51 | "TensorFlow 2.x selected.\n", 52 | "2.1.0-rc1\n" 53 | ], 54 | "name": "stdout" 55 | } 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": { 61 | "id": "ncHRrSLEhMsh", 62 | "colab_type": "text" 63 | }, 64 | "source": [ 65 | "### Datos" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "metadata": { 71 | "id": "UEPYd6aBB1kK", 72 | "colab_type": "code", 73 | "outputId": "5c584b01-8538-4a7a-cd1a-b022d65c58a6", 74 | "colab": { 75 | "resources": { 76 | "http://localhost:8080/nbextensions/google.colab/files.js": { 77 | "data": "Ly8gQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQwovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLy8KLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQovLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAovLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAovLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCi8qKgogKiBAZmlsZW92ZXJ2aWV3IEhlbHBlcnMgZm9yIGdvb2dsZS5jb2xhYiBQeXRob24gbW9kdWxlLgogKi8KKGZ1bmN0aW9uKHNjb3BlKSB7CmZ1bmN0aW9uIHNwYW4odGV4dCwgc3R5bGVBdHRyaWJ1dGVzID0ge30pIHsKICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0ZXh0OwogIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0eWxlQXR0cmlidXRlcykpIHsKICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IHN0eWxlQXR0cmlidXRlc1trZXldOwogIH0KICByZXR1cm4gZWxlbWVudDsKfQoKLy8gTWF4IG51bWJlciBvZiBieXRlcyB3aGljaCB3aWxsIGJlIHVwbG9hZGVkIGF0IGEgdGltZS4KY29uc3QgTUFYX1BBWUxPQURfU0laRSA9IDEwMCAqIDEwMjQ7Ci8vIE1heCBhbW91bnQgb2YgdGltZSB0byBibG9jayB3YWl0aW5nIGZvciB0aGUgdXNlci4KY29uc3QgRklMRV9DSEFOR0VfVElNRU9VVF9NUyA9IDMwICogMTAwMDsKCmZ1bmN0aW9uIF91cGxvYWRGaWxlcyhpbnB1dElkLCBvdXRwdXRJZCkgewogIGNvbnN0IHN0ZXBzID0gdXBsb2FkRmlsZXNTdGVwKGlucHV0SWQsIG91dHB1dElkKTsKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIC8vIENhY2hlIHN0ZXBzIG9uIHRoZSBvdXRwdXRFbGVtZW50IHRvIG1ha2UgaXQgYXZhaWxhYmxlIGZvciB0aGUgbmV4dCBjYWxsCiAgLy8gdG8gdXBsb2FkRmlsZXNDb250aW51ZSBmcm9tIFB5dGhvbi4KICBvdXRwdXRFbGVtZW50LnN0ZXBzID0gc3RlcHM7CgogIHJldHVybiBfdXBsb2FkRmlsZXNDb250aW51ZShvdXRwdXRJZCk7Cn0KCi8vIFRoaXMgaXMgcm91Z2hseSBhbiBhc3luYyBnZW5lcmF0b3IgKG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGJyb3dzZXIgeWV0KSwKLy8gd2hlcmUgdGhlcmUgYXJlIG11bHRpcGxlIGFzeW5jaHJvbm91cyBzdGVwcyBhbmQgdGhlIFB5dGhvbiBzaWRlIGlzIGdvaW5nCi8vIHRvIHBvbGwgZm9yIGNvbXBsZXRpb24gb2YgZWFjaCBzdGVwLgovLyBUaGlzIHVzZXMgYSBQcm9taXNlIHRvIGJsb2NrIHRoZSBweXRob24gc2lkZSBvbiBjb21wbGV0aW9uIG9mIGVhY2ggc3RlcCwKLy8gdGhlbiBwYXNzZXMgdGhlIHJlc3VsdCBvZiB0aGUgcHJldmlvdXMgc3RlcCBhcyB0aGUgaW5wdXQgdG8gdGhlIG5leHQgc3RlcC4KZnVuY3Rpb24gX3VwbG9hZEZpbGVzQ29udGludWUob3V0cHV0SWQpIHsKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIGNvbnN0IHN0ZXBzID0gb3V0cHV0RWxlbWVudC5zdGVwczsKCiAgY29uc3QgbmV4dCA9IHN0ZXBzLm5leHQob3V0cHV0RWxlbWVudC5sYXN0UHJvbWlzZVZhbHVlKTsKICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5leHQudmFsdWUucHJvbWlzZSkudGhlbigodmFsdWUpID0+IHsKICAgIC8vIENhY2hlIHRoZSBsYXN0IHByb21pc2UgdmFsdWUgdG8gbWFrZSBpdCBhdmFpbGFibGUgdG8gdGhlIG5leHQKICAgIC8vIHN0ZXAgb2YgdGhlIGdlbmVyYXRvci4KICAgIG91dHB1dEVsZW1lbnQubGFzdFByb21pc2VWYWx1ZSA9IHZhbHVlOwogICAgcmV0dXJuIG5leHQudmFsdWUucmVzcG9uc2U7CiAgfSk7Cn0KCi8qKgogKiBHZW5lcmF0b3IgZnVuY3Rpb24gd2hpY2ggaXMgY2FsbGVkIGJldHdlZW4gZWFjaCBhc3luYyBzdGVwIG9mIHRoZSB1cGxvYWQKICogcHJvY2Vzcy4KICogQHBhcmFtIHtzdHJpbmd9IGlucHV0SWQgRWxlbWVudCBJRCBvZiB0aGUgaW5wdXQgZmlsZSBwaWNrZXIgZWxlbWVudC4KICogQHBhcmFtIHtzdHJpbmd9IG91dHB1dElkIEVsZW1lbnQgSUQgb2YgdGhlIG91dHB1dCBkaXNwbGF5LgogKiBAcmV0dXJuIHshSXRlcmFibGU8IU9iamVjdD59IEl0ZXJhYmxlIG9mIG5leHQgc3RlcHMuCiAqLwpmdW5jdGlvbiogdXBsb2FkRmlsZXNTdGVwKGlucHV0SWQsIG91dHB1dElkKSB7CiAgY29uc3QgaW5wdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaW5wdXRJZCk7CiAgaW5wdXRFbGVtZW50LmRpc2FibGVkID0gZmFsc2U7CgogIGNvbnN0IG91dHB1dEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvdXRwdXRJZCk7CiAgb3V0cHV0RWxlbWVudC5pbm5lckhUTUwgPSAnJzsKCiAgY29uc3QgcGlja2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICBpbnB1dEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGUpID0+IHsKICAgICAgcmVzb2x2ZShlLnRhcmdldC5maWxlcyk7CiAgICB9KTsKICB9KTsKCiAgY29uc3QgY2FuY2VsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7CiAgaW5wdXRFbGVtZW50LnBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoY2FuY2VsKTsKICBjYW5jZWwudGV4dENvbnRlbnQgPSAnQ2FuY2VsIHVwbG9hZCc7CiAgY29uc3QgY2FuY2VsUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICBjYW5jZWwub25jbGljayA9ICgpID0+IHsKICAgICAgcmVzb2x2ZShudWxsKTsKICAgIH07CiAgfSk7CgogIC8vIENhbmNlbCB1cGxvYWQgaWYgdXNlciBoYXNuJ3QgcGlja2VkIGFueXRoaW5nIGluIHRpbWVvdXQuCiAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgc2V0VGltZW91dCgoKSA9PiB7CiAgICAgIHJlc29sdmUobnVsbCk7CiAgICB9LCBGSUxFX0NIQU5HRV9USU1FT1VUX01TKTsKICB9KTsKCiAgLy8gV2FpdCBmb3IgdGhlIHVzZXIgdG8gcGljayB0aGUgZmlsZXMuCiAgY29uc3QgZmlsZXMgPSB5aWVsZCB7CiAgICBwcm9taXNlOiBQcm9taXNlLnJhY2UoW3BpY2tlZFByb21pc2UsIHRpbWVvdXRQcm9taXNlLCBjYW5jZWxQcm9taXNlXSksCiAgICByZXNwb25zZTogewogICAgICBhY3Rpb246ICdzdGFydGluZycsCiAgICB9CiAgfTsKCiAgaWYgKCFmaWxlcykgewogICAgcmV0dXJuIHsKICAgICAgcmVzcG9uc2U6IHsKICAgICAgICBhY3Rpb246ICdjb21wbGV0ZScsCiAgICAgIH0KICAgIH07CiAgfQoKICBjYW5jZWwucmVtb3ZlKCk7CgogIC8vIERpc2FibGUgdGhlIGlucHV0IGVsZW1lbnQgc2luY2UgZnVydGhlciBwaWNrcyBhcmUgbm90IGFsbG93ZWQuCiAgaW5wdXRFbGVtZW50LmRpc2FibGVkID0gdHJ1ZTsKCiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7CiAgICBjb25zdCBsaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7CiAgICBsaS5hcHBlbmQoc3BhbihmaWxlLm5hbWUsIHtmb250V2VpZ2h0OiAnYm9sZCd9KSk7CiAgICBsaS5hcHBlbmQoc3BhbigKICAgICAgICBgKCR7ZmlsZS50eXBlIHx8ICduL2EnfSkgLSAke2ZpbGUuc2l6ZX0gYnl0ZXMsIGAgKwogICAgICAgIGBsYXN0IG1vZGlmaWVkOiAkewogICAgICAgICAgICBmaWxlLmxhc3RNb2RpZmllZERhdGUgPyBmaWxlLmxhc3RNb2RpZmllZERhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbi9hJ30gLSBgKSk7CiAgICBjb25zdCBwZXJjZW50ID0gc3BhbignMCUgZG9uZScpOwogICAgbGkuYXBwZW5kQ2hpbGQocGVyY2VudCk7CgogICAgb3V0cHV0RWxlbWVudC5hcHBlbmRDaGlsZChsaSk7CgogICAgY29uc3QgZmlsZURhdGFQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHsKICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgICAgcmVhZGVyLm9ubG9hZCA9IChlKSA9PiB7CiAgICAgICAgcmVzb2x2ZShlLnRhcmdldC5yZXN1bHQpOwogICAgICB9OwogICAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZSk7CiAgICB9KTsKICAgIC8vIFdhaXQgZm9yIHRoZSBkYXRhIHRvIGJlIHJlYWR5LgogICAgbGV0IGZpbGVEYXRhID0geWllbGQgewogICAgICBwcm9taXNlOiBmaWxlRGF0YVByb21pc2UsCiAgICAgIHJlc3BvbnNlOiB7CiAgICAgICAgYWN0aW9uOiAnY29udGludWUnLAogICAgICB9CiAgICB9OwoKICAgIC8vIFVzZSBhIGNodW5rZWQgc2VuZGluZyB0byBhdm9pZCBtZXNzYWdlIHNpemUgbGltaXRzLiBTZWUgYi82MjExNTY2MC4KICAgIGxldCBwb3NpdGlvbiA9IDA7CiAgICB3aGlsZSAocG9zaXRpb24gPCBmaWxlRGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWluKGZpbGVEYXRhLmJ5dGVMZW5ndGggLSBwb3NpdGlvbiwgTUFYX1BBWUxPQURfU0laRSk7CiAgICAgIGNvbnN0IGNodW5rID0gbmV3IFVpbnQ4QXJyYXkoZmlsZURhdGEsIHBvc2l0aW9uLCBsZW5ndGgpOwogICAgICBwb3NpdGlvbiArPSBsZW5ndGg7CgogICAgICBjb25zdCBiYXNlNjQgPSBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgY2h1bmspKTsKICAgICAgeWllbGQgewogICAgICAgIHJlc3BvbnNlOiB7CiAgICAgICAgICBhY3Rpb246ICdhcHBlbmQnLAogICAgICAgICAgZmlsZTogZmlsZS5uYW1lLAogICAgICAgICAgZGF0YTogYmFzZTY0LAogICAgICAgIH0sCiAgICAgIH07CiAgICAgIHBlcmNlbnQudGV4dENvbnRlbnQgPQogICAgICAgICAgYCR7TWF0aC5yb3VuZCgocG9zaXRpb24gLyBmaWxlRGF0YS5ieXRlTGVuZ3RoKSAqIDEwMCl9JSBkb25lYDsKICAgIH0KICB9CgogIC8vIEFsbCBkb25lLgogIHlpZWxkIHsKICAgIHJlc3BvbnNlOiB7CiAgICAgIGFjdGlvbjogJ2NvbXBsZXRlJywKICAgIH0KICB9Owp9CgpzY29wZS5nb29nbGUgPSBzY29wZS5nb29nbGUgfHwge307CnNjb3BlLmdvb2dsZS5jb2xhYiA9IHNjb3BlLmdvb2dsZS5jb2xhYiB8fCB7fTsKc2NvcGUuZ29vZ2xlLmNvbGFiLl9maWxlcyA9IHsKICBfdXBsb2FkRmlsZXMsCiAgX3VwbG9hZEZpbGVzQ29udGludWUsCn07Cn0pKHNlbGYpOwo=", 78 | "ok": true, 79 | "headers": [ 80 | [ 81 | "content-type", 82 | "application/javascript" 83 | ] 84 | ], 85 | "status": 200, 86 | "status_text": "" 87 | } 88 | }, 89 | "base_uri": "https://localhost:8080/", 90 | "height": 70 91 | } 92 | }, 93 | "source": [ 94 | "from google.colab import files\n", 95 | "# se debe cargar el fichero “cats_and_dogs_small.zip”\n", 96 | "files.upload()" 97 | ], 98 | "execution_count": 2, 99 | "outputs": [ 100 | { 101 | "output_type": "display_data", 102 | "data": { 103 | "text/html": [ 104 | "\n", 105 | " \n", 106 | " \n", 107 | " Upload widget is only available when the cell has been executed in the\n", 108 | " current browser session. Please rerun this cell to enable.\n", 109 | " \n", 110 | " " 111 | ], 112 | "text/plain": [ 113 | "" 114 | ] 115 | }, 116 | "metadata": { 117 | "tags": [] 118 | } 119 | }, 120 | { 121 | "output_type": "stream", 122 | "text": [ 123 | "Saving cats_and_dogs_small.zip to cats_and_dogs_small.zip\n" 124 | ], 125 | "name": "stdout" 126 | } 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "metadata": { 132 | "id": "fQYQSOKfGtfN", 133 | "colab_type": "code", 134 | "colab": {} 135 | }, 136 | "source": [ 137 | "!ls" 138 | ], 139 | "execution_count": 0, 140 | "outputs": [] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "metadata": { 145 | "id": "sJN-eZ0YBsYl", 146 | "colab_type": "code", 147 | "colab": {} 148 | }, 149 | "source": [ 150 | "import os\n", 151 | "import zipfile\n", 152 | "\n", 153 | "local_zip = '/content/cats_and_dogs_small.zip'\n", 154 | "\n", 155 | "zip_ref = zipfile.ZipFile(local_zip, 'r')\n", 156 | "\n", 157 | "zip_ref.extractall('/content')\n", 158 | "zip_ref.close()\n" 159 | ], 160 | "execution_count": 0, 161 | "outputs": [] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "metadata": { 166 | "id": "ZtsbWwXcBscw", 167 | "colab_type": "code", 168 | "colab": {} 169 | }, 170 | "source": [ 171 | "\n", 172 | "base_dir = '/content/cats_and_dogs_small'\n", 173 | "\n", 174 | "train_dir = os.path.join(base_dir, 'train')\n", 175 | "validation_dir = os.path.join(base_dir, 'validation')\n", 176 | "test_dir = os.path.join(base_dir, 'test')\n", 177 | "\n", 178 | "# Directorio con las imagenes de training \n", 179 | "train_cats_dir = os.path.join(train_dir, 'cats')\n", 180 | "train_dogs_dir = os.path.join(train_dir, 'dogs')\n", 181 | "\n", 182 | "# Directorio con las imagenes de validation\n", 183 | "validation_cats_dir = os.path.join(validation_dir, 'cats')\n", 184 | "validation_dogs_dir = os.path.join(validation_dir, 'dogs')\n", 185 | "\n", 186 | "# Directorio con las imagenes de test\n", 187 | "test_cats_dir = os.path.join(test_dir, 'cats')\n", 188 | "test_dogs_dir = os.path.join(test_dir, 'dogs')\n", 189 | "\n" 190 | ], 191 | "execution_count": 0, 192 | "outputs": [] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "metadata": { 197 | "id": "5ZxZqYgkBsgI", 198 | "colab_type": "code", 199 | "colab": {} 200 | }, 201 | "source": [ 202 | "train_cat_fnames = os.listdir( train_cats_dir )\n", 203 | "print(train_cat_fnames[:5])\n", 204 | "\n", 205 | "train_dog_fnames = os.listdir( train_dogs_dir )\n", 206 | "print(train_dog_fnames[:5])\n", 207 | "\n", 208 | "validation_cat_fnames = os.listdir( validation_cats_dir )\n", 209 | "print(validation_cat_fnames[:5])\n", 210 | "\n", 211 | "validation_dog_fnames = os.listdir( validation_dogs_dir )\n", 212 | "print(validation_dog_fnames[:5])\n", 213 | "\n", 214 | "test_cat_fnames = os.listdir( test_cats_dir )\n", 215 | "print(test_cat_fnames[:5])\n", 216 | "\n", 217 | "test_dog_fnames = os.listdir( test_dogs_dir )\n", 218 | "print(test_dog_fnames[:5])\n" 219 | ], 220 | "execution_count": 0, 221 | "outputs": [] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "metadata": { 226 | "id": "W9r7wCYmBsix", 227 | "colab_type": "code", 228 | "colab": {} 229 | }, 230 | "source": [ 231 | "print('total training cat images :', len(os.listdir(train_cats_dir ) ))\n", 232 | "print('total training dog images :', len(os.listdir(train_dogs_dir ) ))\n", 233 | "\n", 234 | "print('total validation cat images :', len(os.listdir( validation_cats_dir ) ))\n", 235 | "print('total validation dog images :', len(os.listdir( validation_dogs_dir ) ))\n", 236 | "\n", 237 | "print('total test cat images :', len(os.listdir( test_cats_dir ) ))\n", 238 | "print('total test dog images :', len(os.listdir( test_dogs_dir ) ))\n" 239 | ], 240 | "execution_count": 0, 241 | "outputs": [] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "metadata": { 246 | "id": "IUsLM3cgDh3x", 247 | "colab_type": "code", 248 | "colab": {} 249 | }, 250 | "source": [ 251 | "\n", 252 | "import matplotlib.image as mpimg\n", 253 | "import matplotlib.pyplot as plt\n", 254 | "\n", 255 | "def print_pictures(dir, fnames):\n", 256 | " # presentaremos images en una configuración de 4x4\n", 257 | " nrows = 4\n", 258 | " ncols = 4\n", 259 | "\n", 260 | " pic_index = 0 # Índice para iterar sobre las imagenes\n", 261 | "\n", 262 | " fig = plt.gcf()\n", 263 | " fig.set_size_inches(ncols*4, nrows*4)\n", 264 | "\n", 265 | " pic_index+=8\n", 266 | "\n", 267 | " next_pix = [os.path.join(dir, fname) \n", 268 | " for fname in fnames[ pic_index-8:pic_index] \n", 269 | " ]\n", 270 | "\n", 271 | " for i, img_path in enumerate(next_pix):\n", 272 | " sp = plt.subplot(nrows, ncols, i + 1)\n", 273 | " img = mpimg.imread(img_path)\n", 274 | " plt.imshow(img)\n", 275 | "\n", 276 | " plt.show()\n", 277 | "\n", 278 | " \n", 279 | "print(\"Figura 10.3\")\n", 280 | "print_pictures(train_cats_dir, train_cat_fnames)\n", 281 | "print(\"Figura 10.4\")\n", 282 | "print_pictures(train_dogs_dir, train_dog_fnames)\n", 283 | "print(\"Figura 10.5\")\n", 284 | "print_pictures(validation_cats_dir, validation_cat_fnames)\n", 285 | "print(\"Figura 10.6\")\n", 286 | "print_pictures(validation_dogs_dir, validation_dog_fnames)\n", 287 | "print(\"Figura 10.7\")\n", 288 | "print_pictures(test_cats_dir, test_cat_fnames)\n", 289 | "print(\"Figura 10.8\")\n", 290 | "print_pictures(test_dogs_dir, test_dog_fnames)" 291 | ], 292 | "execution_count": 0, 293 | "outputs": [] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": { 298 | "id": "h4HOHpREWj4B", 299 | "colab_type": "text" 300 | }, 301 | "source": [ 302 | "## Modelo básico" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "metadata": { 308 | "id": "_0l8ngplBspl", 309 | "colab_type": "code", 310 | "colab": {} 311 | }, 312 | "source": [ 313 | "import tensorflow as tf\n", 314 | "from tensorflow.keras import Model\n", 315 | "\n", 316 | "from tensorflow.keras import Sequential\n", 317 | "from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense\n", 318 | "\n", 319 | "model = Sequential()\n", 320 | "model.add(Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)))\n", 321 | "model.add(MaxPooling2D(2, 2))\n", 322 | "model.add(Conv2D(64, (3,3), activation='relu'))\n", 323 | "model.add(MaxPooling2D(2,2))\n", 324 | "model.add(Conv2D(128, (3,3), activation='relu'))\n", 325 | "model.add(MaxPooling2D(2,2))\n", 326 | "model.add(Conv2D(128, (3,3), activation='relu'))\n", 327 | "model.add(MaxPooling2D(2,2))\n", 328 | "model.add(Flatten())\n", 329 | "model.add(Dense(512, activation='relu'))\n", 330 | "model.add(Dense(1, activation='sigmoid'))" 331 | ], 332 | "execution_count": 0, 333 | "outputs": [] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "metadata": { 338 | "id": "G44sCFCGBssr", 339 | "colab_type": "code", 340 | "colab": {} 341 | }, 342 | "source": [ 343 | "model.summary()" 344 | ], 345 | "execution_count": 0, 346 | "outputs": [] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "metadata": { 351 | "id": "IOTnd5RWBsn-", 352 | "colab_type": "code", 353 | "colab": {} 354 | }, 355 | "source": [ 356 | "\n", 357 | "from tensorflow.keras.optimizers import RMSprop\n", 358 | "\n", 359 | "model.compile(optimizer=RMSprop(lr=1e-4),\n", 360 | " loss='binary_crossentropy',\n", 361 | " metrics = ['acc'])\n" 362 | ], 363 | "execution_count": 0, 364 | "outputs": [] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "metadata": { 369 | "id": "PUcRl1y4UKze", 370 | "colab_type": "code", 371 | "colab": {} 372 | }, 373 | "source": [ 374 | "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 375 | "\n", 376 | "train_datagen = ImageDataGenerator( rescale = 1.0/255. )\n", 377 | "validation_datagen = ImageDataGenerator( rescale = 1.0/255. )\n", 378 | "test_datagen = ImageDataGenerator( rescale = 1.0/255. )\n", 379 | "\n", 380 | "\n", 381 | "train_generator = train_datagen.flow_from_directory(train_dir,\n", 382 | " batch_size=20,\n", 383 | " class_mode='binary',\n", 384 | " target_size=(150, 150)) \n", 385 | "\n", 386 | "validation_generator = validation_datagen.flow_from_directory(validation_dir,\n", 387 | " batch_size=20,\n", 388 | " class_mode = 'binary',\n", 389 | " target_size = (150, 150))\n", 390 | "\n", 391 | "\n", 392 | "test_generator = test_datagen.flow_from_directory(validation_dir,\n", 393 | " batch_size=20,\n", 394 | " class_mode = 'binary',\n", 395 | " target_size = (150, 150))\n", 396 | "\n" 397 | ], 398 | "execution_count": 0, 399 | "outputs": [] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "metadata": { 404 | "id": "XIxcj4cUDl2F", 405 | "colab_type": "code", 406 | "colab": {} 407 | }, 408 | "source": [ 409 | "batch_size = 20\n", 410 | "steps_per_epoch = train_generator.n // batch_size\n", 411 | "validation_steps = validation_generator.n // batch_size\n", 412 | "\n", 413 | "print (steps_per_epoch)\n", 414 | "print (validation_steps)\n" 415 | ], 416 | "execution_count": 0, 417 | "outputs": [] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "metadata": { 422 | "id": "gWbVvdVgVfDE", 423 | "colab_type": "code", 424 | "colab": {} 425 | }, 426 | "source": [ 427 | "history = model.fit(\n", 428 | " train_generator,\n", 429 | " steps_per_epoch= steps_per_epoch, \n", 430 | " epochs=100,\n", 431 | " validation_data=validation_generator,\n", 432 | " validation_steps= validation_steps, \n", 433 | " verbose=2)\n", 434 | "\n" 435 | ], 436 | "execution_count": 0, 437 | "outputs": [] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "metadata": { 442 | "id": "vzKpIV7uWRMU", 443 | "colab_type": "code", 444 | "colab": {} 445 | }, 446 | "source": [ 447 | "history_dict = history.history\n", 448 | "print(history_dict.keys())" 449 | ], 450 | "execution_count": 0, 451 | "outputs": [] 452 | }, 453 | { 454 | "cell_type": "code", 455 | "metadata": { 456 | "id": "ifCCbV9AM_3Y", 457 | "colab_type": "code", 458 | "colab": {} 459 | }, 460 | "source": [ 461 | "acc = history.history[ 'acc' ]\n", 462 | "val_acc = history.history[ 'val_acc' ]\n", 463 | "loss = history.history[ 'loss' ]\n", 464 | "val_loss = history.history['val_loss' ]\n", 465 | "\n", 466 | "epochs = range(1,len(acc)+1,1) # obtener número de epochs del eje X\n", 467 | "\n", 468 | "plt.plot ( epochs, acc, 'r--', label='Training acc' )\n", 469 | "plt.plot ( epochs, val_acc, 'b', label='Validation acc')\n", 470 | "plt.title ('Training and Validation Accuracy')\n", 471 | "plt.ylabel('acc')\n", 472 | "plt.xlabel('epochs')\n", 473 | "\n", 474 | "plt.legend()\n", 475 | "plt.figure()\n", 476 | "\n", 477 | "\n", 478 | "plt.plot ( epochs, loss, 'r--', label='Training acc' )\n", 479 | "plt.plot ( epochs, val_loss , 'b', label='Validation acc' )\n", 480 | "plt.title ('Training and Validation Loss' )\n", 481 | "plt.ylabel('loss')\n", 482 | "plt.xlabel('epochs')\n", 483 | "\n", 484 | "plt.legend()\n", 485 | "plt.figure()\n", 486 | "\n", 487 | "\n" 488 | ], 489 | "execution_count": 0, 490 | "outputs": [] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "metadata": { 495 | "id": "Vs_ur5y7Wi9C", 496 | "colab_type": "code", 497 | "outputId": "f7bb2fd5-f66a-40e8-ac3a-801a90af91e9", 498 | "colab": { 499 | "base_uri": "https://localhost:8080/", 500 | "height": 118 501 | } 502 | }, 503 | "source": [ 504 | "test_lost, test_acc= model.evaluate(test_generator)\n", 505 | "print (\"Test Accuracy:\", test_acc)" 506 | ], 507 | "execution_count": 0, 508 | "outputs": [ 509 | { 510 | "output_type": "stream", 511 | "text": [ 512 | "WARNING:tensorflow:sample_weight modes were coerced from\n", 513 | " ...\n", 514 | " to \n", 515 | " ['...']\n", 516 | "50/50 [==============================] - 3s 57ms/step - loss: 2.8565 - acc: 0.7320\n", 517 | "Test Accuracy: 0.732\n" 518 | ], 519 | "name": "stdout" 520 | } 521 | ] 522 | }, 523 | { 524 | "cell_type": "code", 525 | "metadata": { 526 | "id": "qCCpbkckjKLa", 527 | "colab_type": "code", 528 | "outputId": "d753829f-43a2-407d-f558-142f9aa1016d", 529 | "colab": { 530 | "base_uri": "https://localhost:8080/", 531 | "height": 34 532 | } 533 | }, 534 | "source": [ 535 | "history_dict = history.history\n", 536 | "print(history_dict.keys())\n" 537 | ], 538 | "execution_count": 0, 539 | "outputs": [ 540 | { 541 | "output_type": "stream", 542 | "text": [ 543 | "dict_keys(['loss', 'acc', 'val_loss', 'val_acc'])\n" 544 | ], 545 | "name": "stdout" 546 | } 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "metadata": { 552 | "id": "Nn66yR2yUNDD", 553 | "colab_type": "code", 554 | "outputId": "f173a472-28fc-49f8-eae1-2f3f1c6f2833", 555 | "colab": { 556 | "resources": { 557 | "http://localhost:8080/nbextensions/google.colab/files.js": { 558 | "data": "Ly8gQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQwovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLy8KLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQovLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAovLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAovLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCi8qKgogKiBAZmlsZW92ZXJ2aWV3IEhlbHBlcnMgZm9yIGdvb2dsZS5jb2xhYiBQeXRob24gbW9kdWxlLgogKi8KKGZ1bmN0aW9uKHNjb3BlKSB7CmZ1bmN0aW9uIHNwYW4odGV4dCwgc3R5bGVBdHRyaWJ1dGVzID0ge30pIHsKICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0ZXh0OwogIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0eWxlQXR0cmlidXRlcykpIHsKICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IHN0eWxlQXR0cmlidXRlc1trZXldOwogIH0KICByZXR1cm4gZWxlbWVudDsKfQoKLy8gTWF4IG51bWJlciBvZiBieXRlcyB3aGljaCB3aWxsIGJlIHVwbG9hZGVkIGF0IGEgdGltZS4KY29uc3QgTUFYX1BBWUxPQURfU0laRSA9IDEwMCAqIDEwMjQ7Ci8vIE1heCBhbW91bnQgb2YgdGltZSB0byBibG9jayB3YWl0aW5nIGZvciB0aGUgdXNlci4KY29uc3QgRklMRV9DSEFOR0VfVElNRU9VVF9NUyA9IDMwICogMTAwMDsKCmZ1bmN0aW9uIF91cGxvYWRGaWxlcyhpbnB1dElkLCBvdXRwdXRJZCkgewogIGNvbnN0IHN0ZXBzID0gdXBsb2FkRmlsZXNTdGVwKGlucHV0SWQsIG91dHB1dElkKTsKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIC8vIENhY2hlIHN0ZXBzIG9uIHRoZSBvdXRwdXRFbGVtZW50IHRvIG1ha2UgaXQgYXZhaWxhYmxlIGZvciB0aGUgbmV4dCBjYWxsCiAgLy8gdG8gdXBsb2FkRmlsZXNDb250aW51ZSBmcm9tIFB5dGhvbi4KICBvdXRwdXRFbGVtZW50LnN0ZXBzID0gc3RlcHM7CgogIHJldHVybiBfdXBsb2FkRmlsZXNDb250aW51ZShvdXRwdXRJZCk7Cn0KCi8vIFRoaXMgaXMgcm91Z2hseSBhbiBhc3luYyBnZW5lcmF0b3IgKG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGJyb3dzZXIgeWV0KSwKLy8gd2hlcmUgdGhlcmUgYXJlIG11bHRpcGxlIGFzeW5jaHJvbm91cyBzdGVwcyBhbmQgdGhlIFB5dGhvbiBzaWRlIGlzIGdvaW5nCi8vIHRvIHBvbGwgZm9yIGNvbXBsZXRpb24gb2YgZWFjaCBzdGVwLgovLyBUaGlzIHVzZXMgYSBQcm9taXNlIHRvIGJsb2NrIHRoZSBweXRob24gc2lkZSBvbiBjb21wbGV0aW9uIG9mIGVhY2ggc3RlcCwKLy8gdGhlbiBwYXNzZXMgdGhlIHJlc3VsdCBvZiB0aGUgcHJldmlvdXMgc3RlcCBhcyB0aGUgaW5wdXQgdG8gdGhlIG5leHQgc3RlcC4KZnVuY3Rpb24gX3VwbG9hZEZpbGVzQ29udGludWUob3V0cHV0SWQpIHsKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIGNvbnN0IHN0ZXBzID0gb3V0cHV0RWxlbWVudC5zdGVwczsKCiAgY29uc3QgbmV4dCA9IHN0ZXBzLm5leHQob3V0cHV0RWxlbWVudC5sYXN0UHJvbWlzZVZhbHVlKTsKICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5leHQudmFsdWUucHJvbWlzZSkudGhlbigodmFsdWUpID0+IHsKICAgIC8vIENhY2hlIHRoZSBsYXN0IHByb21pc2UgdmFsdWUgdG8gbWFrZSBpdCBhdmFpbGFibGUgdG8gdGhlIG5leHQKICAgIC8vIHN0ZXAgb2YgdGhlIGdlbmVyYXRvci4KICAgIG91dHB1dEVsZW1lbnQubGFzdFByb21pc2VWYWx1ZSA9IHZhbHVlOwogICAgcmV0dXJuIG5leHQudmFsdWUucmVzcG9uc2U7CiAgfSk7Cn0KCi8qKgogKiBHZW5lcmF0b3IgZnVuY3Rpb24gd2hpY2ggaXMgY2FsbGVkIGJldHdlZW4gZWFjaCBhc3luYyBzdGVwIG9mIHRoZSB1cGxvYWQKICogcHJvY2Vzcy4KICogQHBhcmFtIHtzdHJpbmd9IGlucHV0SWQgRWxlbWVudCBJRCBvZiB0aGUgaW5wdXQgZmlsZSBwaWNrZXIgZWxlbWVudC4KICogQHBhcmFtIHtzdHJpbmd9IG91dHB1dElkIEVsZW1lbnQgSUQgb2YgdGhlIG91dHB1dCBkaXNwbGF5LgogKiBAcmV0dXJuIHshSXRlcmFibGU8IU9iamVjdD59IEl0ZXJhYmxlIG9mIG5leHQgc3RlcHMuCiAqLwpmdW5jdGlvbiogdXBsb2FkRmlsZXNTdGVwKGlucHV0SWQsIG91dHB1dElkKSB7CiAgY29uc3QgaW5wdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaW5wdXRJZCk7CiAgaW5wdXRFbGVtZW50LmRpc2FibGVkID0gZmFsc2U7CgogIGNvbnN0IG91dHB1dEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvdXRwdXRJZCk7CiAgb3V0cHV0RWxlbWVudC5pbm5lckhUTUwgPSAnJzsKCiAgY29uc3QgcGlja2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICBpbnB1dEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGUpID0+IHsKICAgICAgcmVzb2x2ZShlLnRhcmdldC5maWxlcyk7CiAgICB9KTsKICB9KTsKCiAgY29uc3QgY2FuY2VsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7CiAgaW5wdXRFbGVtZW50LnBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoY2FuY2VsKTsKICBjYW5jZWwudGV4dENvbnRlbnQgPSAnQ2FuY2VsIHVwbG9hZCc7CiAgY29uc3QgY2FuY2VsUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICBjYW5jZWwub25jbGljayA9ICgpID0+IHsKICAgICAgcmVzb2x2ZShudWxsKTsKICAgIH07CiAgfSk7CgogIC8vIENhbmNlbCB1cGxvYWQgaWYgdXNlciBoYXNuJ3QgcGlja2VkIGFueXRoaW5nIGluIHRpbWVvdXQuCiAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgc2V0VGltZW91dCgoKSA9PiB7CiAgICAgIHJlc29sdmUobnVsbCk7CiAgICB9LCBGSUxFX0NIQU5HRV9USU1FT1VUX01TKTsKICB9KTsKCiAgLy8gV2FpdCBmb3IgdGhlIHVzZXIgdG8gcGljayB0aGUgZmlsZXMuCiAgY29uc3QgZmlsZXMgPSB5aWVsZCB7CiAgICBwcm9taXNlOiBQcm9taXNlLnJhY2UoW3BpY2tlZFByb21pc2UsIHRpbWVvdXRQcm9taXNlLCBjYW5jZWxQcm9taXNlXSksCiAgICByZXNwb25zZTogewogICAgICBhY3Rpb246ICdzdGFydGluZycsCiAgICB9CiAgfTsKCiAgaWYgKCFmaWxlcykgewogICAgcmV0dXJuIHsKICAgICAgcmVzcG9uc2U6IHsKICAgICAgICBhY3Rpb246ICdjb21wbGV0ZScsCiAgICAgIH0KICAgIH07CiAgfQoKICBjYW5jZWwucmVtb3ZlKCk7CgogIC8vIERpc2FibGUgdGhlIGlucHV0IGVsZW1lbnQgc2luY2UgZnVydGhlciBwaWNrcyBhcmUgbm90IGFsbG93ZWQuCiAgaW5wdXRFbGVtZW50LmRpc2FibGVkID0gdHJ1ZTsKCiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7CiAgICBjb25zdCBsaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7CiAgICBsaS5hcHBlbmQoc3BhbihmaWxlLm5hbWUsIHtmb250V2VpZ2h0OiAnYm9sZCd9KSk7CiAgICBsaS5hcHBlbmQoc3BhbigKICAgICAgICBgKCR7ZmlsZS50eXBlIHx8ICduL2EnfSkgLSAke2ZpbGUuc2l6ZX0gYnl0ZXMsIGAgKwogICAgICAgIGBsYXN0IG1vZGlmaWVkOiAkewogICAgICAgICAgICBmaWxlLmxhc3RNb2RpZmllZERhdGUgPyBmaWxlLmxhc3RNb2RpZmllZERhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbi9hJ30gLSBgKSk7CiAgICBjb25zdCBwZXJjZW50ID0gc3BhbignMCUgZG9uZScpOwogICAgbGkuYXBwZW5kQ2hpbGQocGVyY2VudCk7CgogICAgb3V0cHV0RWxlbWVudC5hcHBlbmRDaGlsZChsaSk7CgogICAgY29uc3QgZmlsZURhdGFQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHsKICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgICAgcmVhZGVyLm9ubG9hZCA9IChlKSA9PiB7CiAgICAgICAgcmVzb2x2ZShlLnRhcmdldC5yZXN1bHQpOwogICAgICB9OwogICAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZSk7CiAgICB9KTsKICAgIC8vIFdhaXQgZm9yIHRoZSBkYXRhIHRvIGJlIHJlYWR5LgogICAgbGV0IGZpbGVEYXRhID0geWllbGQgewogICAgICBwcm9taXNlOiBmaWxlRGF0YVByb21pc2UsCiAgICAgIHJlc3BvbnNlOiB7CiAgICAgICAgYWN0aW9uOiAnY29udGludWUnLAogICAgICB9CiAgICB9OwoKICAgIC8vIFVzZSBhIGNodW5rZWQgc2VuZGluZyB0byBhdm9pZCBtZXNzYWdlIHNpemUgbGltaXRzLiBTZWUgYi82MjExNTY2MC4KICAgIGxldCBwb3NpdGlvbiA9IDA7CiAgICB3aGlsZSAocG9zaXRpb24gPCBmaWxlRGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWluKGZpbGVEYXRhLmJ5dGVMZW5ndGggLSBwb3NpdGlvbiwgTUFYX1BBWUxPQURfU0laRSk7CiAgICAgIGNvbnN0IGNodW5rID0gbmV3IFVpbnQ4QXJyYXkoZmlsZURhdGEsIHBvc2l0aW9uLCBsZW5ndGgpOwogICAgICBwb3NpdGlvbiArPSBsZW5ndGg7CgogICAgICBjb25zdCBiYXNlNjQgPSBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgY2h1bmspKTsKICAgICAgeWllbGQgewogICAgICAgIHJlc3BvbnNlOiB7CiAgICAgICAgICBhY3Rpb246ICdhcHBlbmQnLAogICAgICAgICAgZmlsZTogZmlsZS5uYW1lLAogICAgICAgICAgZGF0YTogYmFzZTY0LAogICAgICAgIH0sCiAgICAgIH07CiAgICAgIHBlcmNlbnQudGV4dENvbnRlbnQgPQogICAgICAgICAgYCR7TWF0aC5yb3VuZCgocG9zaXRpb24gLyBmaWxlRGF0YS5ieXRlTGVuZ3RoKSAqIDEwMCl9JSBkb25lYDsKICAgIH0KICB9CgogIC8vIEFsbCBkb25lLgogIHlpZWxkIHsKICAgIHJlc3BvbnNlOiB7CiAgICAgIGFjdGlvbjogJ2NvbXBsZXRlJywKICAgIH0KICB9Owp9CgpzY29wZS5nb29nbGUgPSBzY29wZS5nb29nbGUgfHwge307CnNjb3BlLmdvb2dsZS5jb2xhYiA9IHNjb3BlLmdvb2dsZS5jb2xhYiB8fCB7fTsKc2NvcGUuZ29vZ2xlLmNvbGFiLl9maWxlcyA9IHsKICBfdXBsb2FkRmlsZXMsCiAgX3VwbG9hZEZpbGVzQ29udGludWUsCn07Cn0pKHNlbGYpOwo=", 559 | "ok": true, 560 | "headers": [ 561 | [ 562 | "content-type", 563 | "application/javascript" 564 | ] 565 | ], 566 | "status": 200, 567 | "status_text": "" 568 | } 569 | }, 570 | "base_uri": "https://localhost:8080/", 571 | "height": 356 572 | } 573 | }, 574 | "source": [ 575 | "import numpy as np\n", 576 | "\n", 577 | "from google.colab import files\n", 578 | "from tensorflow.keras.preprocessing import image\n", 579 | "\n", 580 | "uploaded=files.upload()\n", 581 | "file=list(uploaded.keys())[0]\n", 582 | "\n", 583 | "path='/content/' + file\n", 584 | "img=image.load_img(path, target_size=(150, 150))\n", 585 | "\n", 586 | "x=image.img_to_array(img)\n", 587 | "image=np.expand_dims(x, axis=0) \n", 588 | "\n", 589 | "classes = model.predict(image)\n", 590 | "print(classes)\n", 591 | "\n", 592 | "plt.imshow(img)\n", 593 | "plt.show()\n", 594 | "\n", 595 | "if classes>0: print( fn + \" IS A DOG\")\n", 596 | "else: print( fn + \" IS A CAT\")" 597 | ], 598 | "execution_count": 0, 599 | "outputs": [ 600 | { 601 | "output_type": "display_data", 602 | "data": { 603 | "text/html": [ 604 | "\n", 605 | " \n", 606 | " \n", 607 | " Upload widget is only available when the cell has been executed in the\n", 608 | " current browser session. Please rerun this cell to enable.\n", 609 | " \n", 610 | " " 611 | ], 612 | "text/plain": [ 613 | "" 614 | ] 615 | }, 616 | "metadata": { 617 | "tags": [] 618 | } 619 | }, 620 | { 621 | "output_type": "stream", 622 | "text": [ 623 | "Saving Wiliams-foto1.png to Wiliams-foto1 (4).png\n", 624 | "[[8.649538e-36]]\n" 625 | ], 626 | "name": "stdout" 627 | }, 628 | { 629 | "output_type": "display_data", 630 | "data": { 631 | "image/png": "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\n3P5/G7pyv4XR/UMAAAAASUVORK5CYII=\n", 632 | "text/plain": [ 633 | "
" 634 | ] 635 | }, 636 | "metadata": { 637 | "tags": [] 638 | } 639 | }, 640 | { 641 | "output_type": "stream", 642 | "text": [ 643 | "Wiliams-foto1.png IS A DOG\n" 644 | ], 645 | "name": "stdout" 646 | } 647 | ] 648 | } 649 | ] 650 | } -------------------------------------------------------------------------------- /13_Redes_neuronales_recurrentes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "accelerator": "GPU", 6 | "colab": { 7 | "name": "13-Redes-neuronales-recurrentes.ipynb", 8 | "provenance": [], 9 | "collapsed_sections": [] 10 | }, 11 | "kernelspec": { 12 | "name": "python3", 13 | "display_name": "Python 3" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "eK8eUOQU7q2V", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "# 13. Redes neuronales recurrentes\n", 25 | "[**Python Deep Learning** Introducción práctica con Keras y TensorFlow 2. Jordi Torres. Editorial Marcombo ISBN: 9788426728289 ](https://www.marcombo.com/python-deep-learning-9788426728289/)" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": { 31 | "colab_type": "text", 32 | "id": "WGyKZj3bzf9p" 33 | }, 34 | "source": [ 35 | "### Importar TensorFlow 2.0 y otras librerias" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "metadata": { 41 | "id": "zWrJnG1jZd00", 42 | "colab_type": "code", 43 | "outputId": "5dd18238-f276-437c-ac84-9b72b5fbbf54", 44 | "colab": { 45 | "base_uri": "https://localhost:8080/", 46 | "height": 34 47 | } 48 | }, 49 | "source": [ 50 | "%tensorflow_version 2.x\n", 51 | "import tensorflow as tf\n", 52 | "from tensorflow import keras\n", 53 | "\n", 54 | "import numpy as np\n", 55 | "import os\n", 56 | "import time" 57 | ], 58 | "execution_count": 1, 59 | "outputs": [ 60 | { 61 | "output_type": "stream", 62 | "text": [ 63 | "TensorFlow 2.x selected.\n" 64 | ], 65 | "name": "stdout" 66 | } 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": { 72 | "colab_type": "text", 73 | "id": "EHDoRoc5PKWz" 74 | }, 75 | "source": [ 76 | "### Descarga del conjunto de datos" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "metadata": { 82 | "id": "qEt4CQ0ru7O5", 83 | "colab_type": "code", 84 | "colab": { 85 | "resources": { 86 | "http://localhost:8080/nbextensions/google.colab/files.js": { 87 | "data": "Ly8gQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQwovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLy8KLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQovLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAovLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAovLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCi8qKgogKiBAZmlsZW92ZXJ2aWV3IEhlbHBlcnMgZm9yIGdvb2dsZS5jb2xhYiBQeXRob24gbW9kdWxlLgogKi8KKGZ1bmN0aW9uKHNjb3BlKSB7CmZ1bmN0aW9uIHNwYW4odGV4dCwgc3R5bGVBdHRyaWJ1dGVzID0ge30pIHsKICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0ZXh0OwogIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0eWxlQXR0cmlidXRlcykpIHsKICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IHN0eWxlQXR0cmlidXRlc1trZXldOwogIH0KICByZXR1cm4gZWxlbWVudDsKfQoKLy8gTWF4IG51bWJlciBvZiBieXRlcyB3aGljaCB3aWxsIGJlIHVwbG9hZGVkIGF0IGEgdGltZS4KY29uc3QgTUFYX1BBWUxPQURfU0laRSA9IDEwMCAqIDEwMjQ7Ci8vIE1heCBhbW91bnQgb2YgdGltZSB0byBibG9jayB3YWl0aW5nIGZvciB0aGUgdXNlci4KY29uc3QgRklMRV9DSEFOR0VfVElNRU9VVF9NUyA9IDMwICogMTAwMDsKCmZ1bmN0aW9uIF91cGxvYWRGaWxlcyhpbnB1dElkLCBvdXRwdXRJZCkgewogIGNvbnN0IHN0ZXBzID0gdXBsb2FkRmlsZXNTdGVwKGlucHV0SWQsIG91dHB1dElkKTsKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIC8vIENhY2hlIHN0ZXBzIG9uIHRoZSBvdXRwdXRFbGVtZW50IHRvIG1ha2UgaXQgYXZhaWxhYmxlIGZvciB0aGUgbmV4dCBjYWxsCiAgLy8gdG8gdXBsb2FkRmlsZXNDb250aW51ZSBmcm9tIFB5dGhvbi4KICBvdXRwdXRFbGVtZW50LnN0ZXBzID0gc3RlcHM7CgogIHJldHVybiBfdXBsb2FkRmlsZXNDb250aW51ZShvdXRwdXRJZCk7Cn0KCi8vIFRoaXMgaXMgcm91Z2hseSBhbiBhc3luYyBnZW5lcmF0b3IgKG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGJyb3dzZXIgeWV0KSwKLy8gd2hlcmUgdGhlcmUgYXJlIG11bHRpcGxlIGFzeW5jaHJvbm91cyBzdGVwcyBhbmQgdGhlIFB5dGhvbiBzaWRlIGlzIGdvaW5nCi8vIHRvIHBvbGwgZm9yIGNvbXBsZXRpb24gb2YgZWFjaCBzdGVwLgovLyBUaGlzIHVzZXMgYSBQcm9taXNlIHRvIGJsb2NrIHRoZSBweXRob24gc2lkZSBvbiBjb21wbGV0aW9uIG9mIGVhY2ggc3RlcCwKLy8gdGhlbiBwYXNzZXMgdGhlIHJlc3VsdCBvZiB0aGUgcHJldmlvdXMgc3RlcCBhcyB0aGUgaW5wdXQgdG8gdGhlIG5leHQgc3RlcC4KZnVuY3Rpb24gX3VwbG9hZEZpbGVzQ29udGludWUob3V0cHV0SWQpIHsKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIGNvbnN0IHN0ZXBzID0gb3V0cHV0RWxlbWVudC5zdGVwczsKCiAgY29uc3QgbmV4dCA9IHN0ZXBzLm5leHQob3V0cHV0RWxlbWVudC5sYXN0UHJvbWlzZVZhbHVlKTsKICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5leHQudmFsdWUucHJvbWlzZSkudGhlbigodmFsdWUpID0+IHsKICAgIC8vIENhY2hlIHRoZSBsYXN0IHByb21pc2UgdmFsdWUgdG8gbWFrZSBpdCBhdmFpbGFibGUgdG8gdGhlIG5leHQKICAgIC8vIHN0ZXAgb2YgdGhlIGdlbmVyYXRvci4KICAgIG91dHB1dEVsZW1lbnQubGFzdFByb21pc2VWYWx1ZSA9IHZhbHVlOwogICAgcmV0dXJuIG5leHQudmFsdWUucmVzcG9uc2U7CiAgfSk7Cn0KCi8qKgogKiBHZW5lcmF0b3IgZnVuY3Rpb24gd2hpY2ggaXMgY2FsbGVkIGJldHdlZW4gZWFjaCBhc3luYyBzdGVwIG9mIHRoZSB1cGxvYWQKICogcHJvY2Vzcy4KICogQHBhcmFtIHtzdHJpbmd9IGlucHV0SWQgRWxlbWVudCBJRCBvZiB0aGUgaW5wdXQgZmlsZSBwaWNrZXIgZWxlbWVudC4KICogQHBhcmFtIHtzdHJpbmd9IG91dHB1dElkIEVsZW1lbnQgSUQgb2YgdGhlIG91dHB1dCBkaXNwbGF5LgogKiBAcmV0dXJuIHshSXRlcmFibGU8IU9iamVjdD59IEl0ZXJhYmxlIG9mIG5leHQgc3RlcHMuCiAqLwpmdW5jdGlvbiogdXBsb2FkRmlsZXNTdGVwKGlucHV0SWQsIG91dHB1dElkKSB7CiAgY29uc3QgaW5wdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaW5wdXRJZCk7CiAgaW5wdXRFbGVtZW50LmRpc2FibGVkID0gZmFsc2U7CgogIGNvbnN0IG91dHB1dEVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvdXRwdXRJZCk7CiAgb3V0cHV0RWxlbWVudC5pbm5lckhUTUwgPSAnJzsKCiAgY29uc3QgcGlja2VkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICBpbnB1dEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGUpID0+IHsKICAgICAgcmVzb2x2ZShlLnRhcmdldC5maWxlcyk7CiAgICB9KTsKICB9KTsKCiAgY29uc3QgY2FuY2VsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7CiAgaW5wdXRFbGVtZW50LnBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoY2FuY2VsKTsKICBjYW5jZWwudGV4dENvbnRlbnQgPSAnQ2FuY2VsIHVwbG9hZCc7CiAgY29uc3QgY2FuY2VsUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICBjYW5jZWwub25jbGljayA9ICgpID0+IHsKICAgICAgcmVzb2x2ZShudWxsKTsKICAgIH07CiAgfSk7CgogIC8vIENhbmNlbCB1cGxvYWQgaWYgdXNlciBoYXNuJ3QgcGlja2VkIGFueXRoaW5nIGluIHRpbWVvdXQuCiAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgc2V0VGltZW91dCgoKSA9PiB7CiAgICAgIHJlc29sdmUobnVsbCk7CiAgICB9LCBGSUxFX0NIQU5HRV9USU1FT1VUX01TKTsKICB9KTsKCiAgLy8gV2FpdCBmb3IgdGhlIHVzZXIgdG8gcGljayB0aGUgZmlsZXMuCiAgY29uc3QgZmlsZXMgPSB5aWVsZCB7CiAgICBwcm9taXNlOiBQcm9taXNlLnJhY2UoW3BpY2tlZFByb21pc2UsIHRpbWVvdXRQcm9taXNlLCBjYW5jZWxQcm9taXNlXSksCiAgICByZXNwb25zZTogewogICAgICBhY3Rpb246ICdzdGFydGluZycsCiAgICB9CiAgfTsKCiAgaWYgKCFmaWxlcykgewogICAgcmV0dXJuIHsKICAgICAgcmVzcG9uc2U6IHsKICAgICAgICBhY3Rpb246ICdjb21wbGV0ZScsCiAgICAgIH0KICAgIH07CiAgfQoKICBjYW5jZWwucmVtb3ZlKCk7CgogIC8vIERpc2FibGUgdGhlIGlucHV0IGVsZW1lbnQgc2luY2UgZnVydGhlciBwaWNrcyBhcmUgbm90IGFsbG93ZWQuCiAgaW5wdXRFbGVtZW50LmRpc2FibGVkID0gdHJ1ZTsKCiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7CiAgICBjb25zdCBsaSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7CiAgICBsaS5hcHBlbmQoc3BhbihmaWxlLm5hbWUsIHtmb250V2VpZ2h0OiAnYm9sZCd9KSk7CiAgICBsaS5hcHBlbmQoc3BhbigKICAgICAgICBgKCR7ZmlsZS50eXBlIHx8ICduL2EnfSkgLSAke2ZpbGUuc2l6ZX0gYnl0ZXMsIGAgKwogICAgICAgIGBsYXN0IG1vZGlmaWVkOiAkewogICAgICAgICAgICBmaWxlLmxhc3RNb2RpZmllZERhdGUgPyBmaWxlLmxhc3RNb2RpZmllZERhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKCkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbi9hJ30gLSBgKSk7CiAgICBjb25zdCBwZXJjZW50ID0gc3BhbignMCUgZG9uZScpOwogICAgbGkuYXBwZW5kQ2hpbGQocGVyY2VudCk7CgogICAgb3V0cHV0RWxlbWVudC5hcHBlbmRDaGlsZChsaSk7CgogICAgY29uc3QgZmlsZURhdGFQcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHsKICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgICAgcmVhZGVyLm9ubG9hZCA9IChlKSA9PiB7CiAgICAgICAgcmVzb2x2ZShlLnRhcmdldC5yZXN1bHQpOwogICAgICB9OwogICAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZSk7CiAgICB9KTsKICAgIC8vIFdhaXQgZm9yIHRoZSBkYXRhIHRvIGJlIHJlYWR5LgogICAgbGV0IGZpbGVEYXRhID0geWllbGQgewogICAgICBwcm9taXNlOiBmaWxlRGF0YVByb21pc2UsCiAgICAgIHJlc3BvbnNlOiB7CiAgICAgICAgYWN0aW9uOiAnY29udGludWUnLAogICAgICB9CiAgICB9OwoKICAgIC8vIFVzZSBhIGNodW5rZWQgc2VuZGluZyB0byBhdm9pZCBtZXNzYWdlIHNpemUgbGltaXRzLiBTZWUgYi82MjExNTY2MC4KICAgIGxldCBwb3NpdGlvbiA9IDA7CiAgICB3aGlsZSAocG9zaXRpb24gPCBmaWxlRGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWluKGZpbGVEYXRhLmJ5dGVMZW5ndGggLSBwb3NpdGlvbiwgTUFYX1BBWUxPQURfU0laRSk7CiAgICAgIGNvbnN0IGNodW5rID0gbmV3IFVpbnQ4QXJyYXkoZmlsZURhdGEsIHBvc2l0aW9uLCBsZW5ndGgpOwogICAgICBwb3NpdGlvbiArPSBsZW5ndGg7CgogICAgICBjb25zdCBiYXNlNjQgPSBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgY2h1bmspKTsKICAgICAgeWllbGQgewogICAgICAgIHJlc3BvbnNlOiB7CiAgICAgICAgICBhY3Rpb246ICdhcHBlbmQnLAogICAgICAgICAgZmlsZTogZmlsZS5uYW1lLAogICAgICAgICAgZGF0YTogYmFzZTY0LAogICAgICAgIH0sCiAgICAgIH07CiAgICAgIHBlcmNlbnQudGV4dENvbnRlbnQgPQogICAgICAgICAgYCR7TWF0aC5yb3VuZCgocG9zaXRpb24gLyBmaWxlRGF0YS5ieXRlTGVuZ3RoKSAqIDEwMCl9JSBkb25lYDsKICAgIH0KICB9CgogIC8vIEFsbCBkb25lLgogIHlpZWxkIHsKICAgIHJlc3BvbnNlOiB7CiAgICAgIGFjdGlvbjogJ2NvbXBsZXRlJywKICAgIH0KICB9Owp9CgpzY29wZS5nb29nbGUgPSBzY29wZS5nb29nbGUgfHwge307CnNjb3BlLmdvb2dsZS5jb2xhYiA9IHNjb3BlLmdvb2dsZS5jb2xhYiB8fCB7fTsKc2NvcGUuZ29vZ2xlLmNvbGFiLl9maWxlcyA9IHsKICBfdXBsb2FkRmlsZXMsCiAgX3VwbG9hZEZpbGVzQ29udGludWUsCn07Cn0pKHNlbGYpOwo=", 88 | "ok": true, 89 | "headers": [ 90 | [ 91 | "content-type", 92 | "application/javascript" 93 | ] 94 | ], 95 | "status": 200, 96 | "status_text": "" 97 | } 98 | }, 99 | "base_uri": "https://localhost:8080/", 100 | "height": 107 101 | }, 102 | "outputId": "a25fcbf9-4b76-4ed7-b654-17963146d458" 103 | }, 104 | "source": [ 105 | "\n", 106 | "from google.colab import files\n", 107 | "#se debe cargar el fichero “Libro-Deep-Learning-introduccion-practica-con-Keras-1a-parte.txt”\n", 108 | "files.upload()\n", 109 | "\n", 110 | "path_to_fileDL ='/content/Libro-Deep-Learning-introduccion-practica-con-Keras-1a-parte.txt'\n", 111 | "\n", 112 | "#path_to_fileDL = tf.keras.utils.get_file('Shakespear.txt', 'https://cs.stanford.edu/people/karpathy/char-rnn/shakespear.txt')\n" 113 | ], 114 | "execution_count": 2, 115 | "outputs": [ 116 | { 117 | "output_type": "display_data", 118 | "data": { 119 | "text/html": [ 120 | "\n", 121 | " \n", 122 | " \n", 123 | " Upload widget is only available when the cell has been executed in the\n", 124 | " current browser session. Please rerun this cell to enable.\n", 125 | " \n", 126 | " " 127 | ], 128 | "text/plain": [ 129 | "" 130 | ] 131 | }, 132 | "metadata": { 133 | "tags": [] 134 | } 135 | }, 136 | { 137 | "output_type": "stream", 138 | "text": [ 139 | "Saving Libro-Deep-Learning-introduccion-practica-con-Keras-1a-parte.txt to Libro-Deep-Learning-introduccion-practica-con-Keras-1a-parte.txt\n" 140 | ], 141 | "name": "stdout" 142 | } 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "metadata": { 148 | "colab_type": "code", 149 | "id": "pD_55cOxLkAb", 150 | "outputId": "37cd06ca-04d1-484b-c5a9-a232bffe319c", 151 | "colab": { 152 | "base_uri": "https://localhost:8080/", 153 | "height": 87 154 | } 155 | }, 156 | "source": [ 157 | "\n", 158 | "\n", 159 | "text = open(path_to_fileDL, 'rb').read().decode(encoding='utf-8')\n", 160 | "print('Longitud del texto: {} carácteres'.format(len(text)))\n", 161 | "\n", 162 | "vocab = sorted(set(text))\n", 163 | "\n", 164 | "print ('El texto está compuesto de estos {} carácteres:'.format(len(vocab)))\n", 165 | "print (vocab)" 166 | ], 167 | "execution_count": 3, 168 | "outputs": [ 169 | { 170 | "output_type": "stream", 171 | "text": [ 172 | "Longitud del texto: 201709 carácteres\n", 173 | "El texto está compuesto de estos 91 carácteres:\n", 174 | "['\\n', ' ', '!', '\"', '#', '%', \"'\", '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', '[', ']', '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\\xad', 'ÿ', 'Š', '‡', '…']\n" 175 | ], 176 | "name": "stdout" 177 | } 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "metadata": { 183 | "colab_type": "code", 184 | "id": "IalZLbvOzf-F", 185 | "outputId": "fd81ff07-a95d-46f7-942d-6cbffc0c3989", 186 | "colab": { 187 | "base_uri": "https://localhost:8080/", 188 | "height": 1000 189 | } 190 | }, 191 | "source": [ 192 | "char2idx = {u:i for i, u in enumerate(vocab)}\n", 193 | "idx2char = np.array(vocab)\n", 194 | "\n", 195 | "for char,_ in zip(char2idx, range(len(vocab))):\n", 196 | " print(' {:4s}: {:3d},'.format(repr(char), char2idx[char]))" 197 | ], 198 | "execution_count": 4, 199 | "outputs": [ 200 | { 201 | "output_type": "stream", 202 | "text": [ 203 | " '\\n': 0,\n", 204 | " ' ' : 1,\n", 205 | " '!' : 2,\n", 206 | " '\"' : 3,\n", 207 | " '#' : 4,\n", 208 | " '%' : 5,\n", 209 | " \"'\" : 6,\n", 210 | " '(' : 7,\n", 211 | " ')' : 8,\n", 212 | " '*' : 9,\n", 213 | " '+' : 10,\n", 214 | " ',' : 11,\n", 215 | " '-' : 12,\n", 216 | " '.' : 13,\n", 217 | " '/' : 14,\n", 218 | " '0' : 15,\n", 219 | " '1' : 16,\n", 220 | " '2' : 17,\n", 221 | " '3' : 18,\n", 222 | " '4' : 19,\n", 223 | " '5' : 20,\n", 224 | " '6' : 21,\n", 225 | " '7' : 22,\n", 226 | " '8' : 23,\n", 227 | " '9' : 24,\n", 228 | " ':' : 25,\n", 229 | " ';' : 26,\n", 230 | " '<' : 27,\n", 231 | " '=' : 28,\n", 232 | " '>' : 29,\n", 233 | " '?' : 30,\n", 234 | " '@' : 31,\n", 235 | " 'A' : 32,\n", 236 | " 'B' : 33,\n", 237 | " 'C' : 34,\n", 238 | " 'D' : 35,\n", 239 | " 'E' : 36,\n", 240 | " 'F' : 37,\n", 241 | " 'G' : 38,\n", 242 | " 'H' : 39,\n", 243 | " 'I' : 40,\n", 244 | " 'J' : 41,\n", 245 | " 'K' : 42,\n", 246 | " 'L' : 43,\n", 247 | " 'M' : 44,\n", 248 | " 'N' : 45,\n", 249 | " 'O' : 46,\n", 250 | " 'P' : 47,\n", 251 | " 'Q' : 48,\n", 252 | " 'R' : 49,\n", 253 | " 'S' : 50,\n", 254 | " 'T' : 51,\n", 255 | " 'U' : 52,\n", 256 | " 'V' : 53,\n", 257 | " 'W' : 54,\n", 258 | " 'X' : 55,\n", 259 | " 'Y' : 56,\n", 260 | " '[' : 57,\n", 261 | " ']' : 58,\n", 262 | " '_' : 59,\n", 263 | " 'a' : 60,\n", 264 | " 'b' : 61,\n", 265 | " 'c' : 62,\n", 266 | " 'd' : 63,\n", 267 | " 'e' : 64,\n", 268 | " 'f' : 65,\n", 269 | " 'g' : 66,\n", 270 | " 'h' : 67,\n", 271 | " 'i' : 68,\n", 272 | " 'j' : 69,\n", 273 | " 'k' : 70,\n", 274 | " 'l' : 71,\n", 275 | " 'm' : 72,\n", 276 | " 'n' : 73,\n", 277 | " 'o' : 74,\n", 278 | " 'p' : 75,\n", 279 | " 'q' : 76,\n", 280 | " 'r' : 77,\n", 281 | " 's' : 78,\n", 282 | " 't' : 79,\n", 283 | " 'u' : 80,\n", 284 | " 'v' : 81,\n", 285 | " 'w' : 82,\n", 286 | " 'x' : 83,\n", 287 | " 'y' : 84,\n", 288 | " 'z' : 85,\n", 289 | " '\\xad': 86,\n", 290 | " 'ÿ' : 87,\n", 291 | " 'Š' : 88,\n", 292 | " '‡' : 89,\n", 293 | " '…' : 90,\n" 294 | ], 295 | "name": "stdout" 296 | } 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "metadata": { 302 | "id": "ML-DuUyi_aHy", 303 | "colab_type": "code", 304 | "colab": {} 305 | }, 306 | "source": [ 307 | "text_as_int = np.array([char2idx[c] for c in text])" 308 | ], 309 | "execution_count": 0, 310 | "outputs": [] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "metadata": { 315 | "colab_type": "code", 316 | "id": "l1VKcQHcymwb", 317 | "outputId": "0ef61420-a0eb-4164-f732-37239c69cdf0", 318 | "colab": { 319 | "base_uri": "https://localhost:8080/", 320 | "height": 84 321 | } 322 | }, 323 | "source": [ 324 | "print ('texto: {}'.format(repr(text[:50])))\n", 325 | "print ('{}'.format(repr(text_as_int[:50])))" 326 | ], 327 | "execution_count": 6, 328 | "outputs": [ 329 | { 330 | "output_type": "stream", 331 | "text": [ 332 | "texto: 'Prologo\\nEn 1953, Isaac Asimov publico Segunda Fund'\n", 333 | "array([47, 77, 74, 71, 74, 66, 74, 0, 36, 73, 1, 16, 24, 20, 18, 11, 1,\n", 334 | " 40, 78, 60, 60, 62, 1, 32, 78, 68, 72, 74, 81, 1, 75, 80, 61, 71,\n", 335 | " 68, 62, 74, 1, 50, 64, 66, 80, 73, 63, 60, 1, 37, 80, 73, 63])\n" 336 | ], 337 | "name": "stdout" 338 | } 339 | ] 340 | }, 341 | { 342 | "cell_type": "markdown", 343 | "metadata": { 344 | "colab_type": "text", 345 | "id": "hgsVvVxnymwf" 346 | }, 347 | "source": [ 348 | "### Preparar los datos para entrenar la RNN\n" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "metadata": { 354 | "colab_type": "code", 355 | "id": "0UHJDA39zf-O", 356 | "colab": {} 357 | }, 358 | "source": [ 359 | "char_dataset = tf.data.Dataset.from_tensor_slices(text_as_int)\n", 360 | "\n", 361 | "seq_length = 100\n", 362 | " \n", 363 | "sequences = char_dataset.batch(seq_length+1, drop_remainder=True)\n", 364 | "\n" 365 | ], 366 | "execution_count": 0, 367 | "outputs": [] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "metadata": { 372 | "colab_type": "code", 373 | "id": "l4hkDU3i7ozi", 374 | "outputId": "4b0f9234-3e2c-4a97-c253-b271d82b9520", 375 | "colab": { 376 | "base_uri": "https://localhost:8080/", 377 | "height": 205 378 | } 379 | }, 380 | "source": [ 381 | "for item in sequences.take(10):\n", 382 | " print(repr(''.join(idx2char[item.numpy()])))" 383 | ], 384 | "execution_count": 8, 385 | "outputs": [ 386 | { 387 | "output_type": "stream", 388 | "text": [ 389 | "'Prologo\\nEn 1953, Isaac Asimov publico Segunda Fundacion, el tercer libro de la saga de la Fundacion ('\n", 390 | "'o el decimotercero segun otras fuentes, este es un tema de debate). En Segunda Fundacion aparece por '\n", 391 | "'primera vez Arkady Darell, uno de los principales personajes de la parte final de la saga. En su prim'\n", 392 | "'era escena, Arkady, que tiene 14 anos, esta haciendo sus tareas escolares. En concreto, una redaccion'\n", 393 | "' que lleva por titulo ?El Futuro del Plan Sheldon?. Para hacer la redaccion, Arkady esta utilizando u'\n", 394 | "'n ?transcriptor?,un dispositivo que convierte su voz en palabras escritas. Este tipo de dispositivo, '\n", 395 | "'que para Isaac Asimov era ciencia ficcion en 1953, lo tenemos al alcance de la mano en la mayoria de '\n", 396 | "'nuestros smartphones, y el Deep Learning es uno de los responsables de que ya tengamos este tipo de a'\n", 397 | "'plicaciones, siendo la tecnologia otro de ellos.En la actualidad disponemos de GPUs (Graphics Process'\n", 398 | "'or Units), que solo cuestan alrededor de 100 euros, que estarian en la lista del Top500 hace unos poc'\n" 399 | ], 400 | "name": "stdout" 401 | } 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "metadata": { 407 | "colab_type": "code", 408 | "id": "9NGu-FkO_kYU", 409 | "colab": {} 410 | }, 411 | "source": [ 412 | "def split_input_target(chunk):\n", 413 | " input_text = chunk[:-1]\n", 414 | " target_text = chunk[1:]\n", 415 | " return input_text, target_text\n", 416 | "\n", 417 | "dataset = sequences.map(split_input_target)\n" 418 | ], 419 | "execution_count": 0, 420 | "outputs": [] 421 | }, 422 | { 423 | "cell_type": "code", 424 | "metadata": { 425 | "colab_type": "code", 426 | "id": "GNbw-iR0ymwj", 427 | "outputId": "fda91b1a-1845-46dd-915e-490953b99144", 428 | "colab": { 429 | "base_uri": "https://localhost:8080/", 430 | "height": 70 431 | } 432 | }, 433 | "source": [ 434 | "for input_example, target_example in dataset.take(1):\n", 435 | " print ('Input data: ', repr(''.join(idx2char[input_example.numpy()])))\n", 436 | " print ('Target data:', repr(''.join(idx2char[target_example.numpy()])))" 437 | ], 438 | "execution_count": 10, 439 | "outputs": [ 440 | { 441 | "output_type": "stream", 442 | "text": [ 443 | "Input data: 'Prologo\\nEn 1953, Isaac Asimov publico Segunda Fundacion, el tercer libro de la saga de la Fundacion '\n", 444 | "Target data: 'rologo\\nEn 1953, Isaac Asimov publico Segunda Fundacion, el tercer libro de la saga de la Fundacion ('\n" 445 | ], 446 | "name": "stdout" 447 | } 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "metadata": { 453 | "colab_type": "code", 454 | "id": "0eBu9WZG84i0", 455 | "outputId": "fe45c87d-9085-463f-bfd1-a4f23d2c2a8f", 456 | "colab": { 457 | "base_uri": "https://localhost:8080/", 458 | "height": 34 459 | } 460 | }, 461 | "source": [ 462 | "print (dataset)" 463 | ], 464 | "execution_count": 11, 465 | "outputs": [ 466 | { 467 | "output_type": "stream", 468 | "text": [ 469 | "\n" 470 | ], 471 | "name": "stdout" 472 | } 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "metadata": { 478 | "colab_type": "code", 479 | "id": "p2pGotuNzf-S", 480 | "outputId": "dee41632-e0b6-4102-89c1-c37064974de0", 481 | "colab": { 482 | "base_uri": "https://localhost:8080/", 483 | "height": 34 484 | } 485 | }, 486 | "source": [ 487 | "BATCH_SIZE = 64\n", 488 | "\n", 489 | "BUFFER_SIZE = 10000\n", 490 | "\n", 491 | "dataset = dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE, drop_remainder=True)\n", 492 | "\n", 493 | "print (dataset)" 494 | ], 495 | "execution_count": 12, 496 | "outputs": [ 497 | { 498 | "output_type": "stream", 499 | "text": [ 500 | "\n" 501 | ], 502 | "name": "stdout" 503 | } 504 | ] 505 | }, 506 | { 507 | "cell_type": "markdown", 508 | "metadata": { 509 | "colab_type": "text", 510 | "id": "r6oUuElIMgVx" 511 | }, 512 | "source": [ 513 | "### Construcción del modelo" 514 | ] 515 | }, 516 | { 517 | "cell_type": "code", 518 | "metadata": { 519 | "colab_type": "code", 520 | "id": "zHT8cLh7EAsg", 521 | "colab": {} 522 | }, 523 | "source": [ 524 | "vocab_size = len(vocab)\n", 525 | "embedding_dim = 256\n", 526 | "rnn_units = 1024" 527 | ], 528 | "execution_count": 0, 529 | "outputs": [] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "metadata": { 534 | "id": "3pKJl2dqwHRl", 535 | "colab_type": "code", 536 | "colab": {} 537 | }, 538 | "source": [ 539 | "from tensorflow.keras import Sequential\n", 540 | "from tensorflow.keras.layers import Embedding, LSTM, Dense\n", 541 | "\n", 542 | "def build_model(vocab_size, embedding_dim, rnn_units, batch_size):\n", 543 | " model = Sequential()\n", 544 | " model.add(Embedding(input_dim=vocab_size, \n", 545 | " output_dim=embedding_dim, \n", 546 | " batch_input_shape=[batch_size, None]))\n", 547 | " model.add(LSTM(rnn_units,\n", 548 | " return_sequences=True,\n", 549 | " stateful=True,\n", 550 | " recurrent_initializer='glorot_uniform'))\n", 551 | " model.add(Dense(vocab_size))\n", 552 | " return model" 553 | ], 554 | "execution_count": 0, 555 | "outputs": [] 556 | }, 557 | { 558 | "cell_type": "code", 559 | "metadata": { 560 | "colab_type": "code", 561 | "id": "wwsrpOik5zhv", 562 | "colab": {} 563 | }, 564 | "source": [ 565 | "model = build_model(\n", 566 | " vocab_size = len(vocab),\n", 567 | " embedding_dim=embedding_dim,\n", 568 | " rnn_units=rnn_units,\n", 569 | " batch_size=BATCH_SIZE)" 570 | ], 571 | "execution_count": 0, 572 | "outputs": [] 573 | }, 574 | { 575 | "cell_type": "code", 576 | "metadata": { 577 | "id": "PpHGXDMcZ0Zt", 578 | "colab_type": "code", 579 | "outputId": "086470f9-57f7-4d3d-d446-55f945fed488", 580 | "colab": { 581 | "base_uri": "https://localhost:8080/", 582 | "height": 252 583 | } 584 | }, 585 | "source": [ 586 | "model.summary()" 587 | ], 588 | "execution_count": 16, 589 | "outputs": [ 590 | { 591 | "output_type": "stream", 592 | "text": [ 593 | "Model: \"sequential\"\n", 594 | "_________________________________________________________________\n", 595 | "Layer (type) Output Shape Param # \n", 596 | "=================================================================\n", 597 | "embedding (Embedding) (64, None, 256) 23296 \n", 598 | "_________________________________________________________________\n", 599 | "lstm (LSTM) (64, None, 1024) 5246976 \n", 600 | "_________________________________________________________________\n", 601 | "dense (Dense) (64, None, 91) 93275 \n", 602 | "=================================================================\n", 603 | "Total params: 5,363,547\n", 604 | "Trainable params: 5,363,547\n", 605 | "Non-trainable params: 0\n", 606 | "_________________________________________________________________\n" 607 | ], 608 | "name": "stdout" 609 | } 610 | ] 611 | }, 612 | { 613 | "cell_type": "code", 614 | "metadata": { 615 | "colab_type": "code", 616 | "id": "C-_70kKAPrPU", 617 | "outputId": "b71d7b4f-c635-4774-f058-d67067a72eae", 618 | "colab": { 619 | "base_uri": "https://localhost:8080/", 620 | "height": 50 621 | } 622 | }, 623 | "source": [ 624 | "for input_example_batch, target_example_batch in dataset.take(1):\n", 625 | " print(\"Input:\", input_example_batch.shape, \"# (batch_size, sequence_length)\")\n", 626 | " print(\"Target:\", target_example_batch.shape, \"# (batch_size, sequence_length)\")\n" 627 | ], 628 | "execution_count": 17, 629 | "outputs": [ 630 | { 631 | "output_type": "stream", 632 | "text": [ 633 | "Input: (64, 100) # (batch_size, sequence_length)\n", 634 | "Target: (64, 100) # (batch_size, sequence_length)\n" 635 | ], 636 | "name": "stdout" 637 | } 638 | ] 639 | }, 640 | { 641 | "cell_type": "code", 642 | "metadata": { 643 | "id": "udE_6eTldMhB", 644 | "colab_type": "code", 645 | "outputId": "56ea08dd-4b13-45dd-d665-04c6bcc7c58a", 646 | "colab": { 647 | "base_uri": "https://localhost:8080/", 648 | "height": 34 649 | } 650 | }, 651 | "source": [ 652 | "for input_example_batch, target_example_batch in dataset.take(1): \n", 653 | " example_batch_predictions = model(input_example_batch)\n", 654 | " print(\"Prediction: \", example_batch_predictions.shape, \"# (batch_size, sequence_length, vocab_size)\")" 655 | ], 656 | "execution_count": 18, 657 | "outputs": [ 658 | { 659 | "output_type": "stream", 660 | "text": [ 661 | "Prediction: (64, 100, 91) # (batch_size, sequence_length, vocab_size)\n" 662 | ], 663 | "name": "stdout" 664 | } 665 | ] 666 | }, 667 | { 668 | "cell_type": "code", 669 | "metadata": { 670 | "colab_type": "code", 671 | "id": "4V4MfFg0RQJg", 672 | "colab": {} 673 | }, 674 | "source": [ 675 | "sampled_indices = tf.random.categorical(example_batch_predictions[0], num_samples=1)\n", 676 | "sampled_indices_characters = tf.squeeze(sampled_indices,axis=-1).numpy()" 677 | ], 678 | "execution_count": 0, 679 | "outputs": [] 680 | }, 681 | { 682 | "cell_type": "code", 683 | "metadata": { 684 | "colab_type": "code", 685 | "id": "YqFMUQc_UFgM", 686 | "outputId": "62cd2cbb-80bc-4f6d-9161-6471e8eb4d4d", 687 | "colab": { 688 | "base_uri": "https://localhost:8080/", 689 | "height": 118 690 | } 691 | }, 692 | "source": [ 693 | "sampled_indices_characters" 694 | ], 695 | "execution_count": 20, 696 | "outputs": [ 697 | { 698 | "output_type": "execute_result", 699 | "data": { 700 | "text/plain": [ 701 | "array([58, 90, 3, 45, 16, 77, 39, 73, 66, 15, 86, 83, 18, 62, 45, 15, 25,\n", 702 | " 45, 29, 29, 79, 42, 54, 59, 65, 76, 33, 62, 80, 48, 24, 15, 71, 87,\n", 703 | " 8, 12, 3, 85, 81, 26, 48, 78, 82, 14, 0, 9, 60, 10, 68, 6, 66,\n", 704 | " 69, 10, 34, 69, 33, 74, 4, 12, 51, 25, 75, 42, 64, 37, 57, 43, 80,\n", 705 | " 33, 11, 24, 26, 48, 69, 48, 77, 61, 38, 90, 57, 73, 5, 22, 50, 22,\n", 706 | " 6, 42, 3, 18, 28, 25, 24, 79, 68, 43, 66, 30, 89, 19, 48])" 707 | ] 708 | }, 709 | "metadata": { 710 | "tags": [] 711 | }, 712 | "execution_count": 20 713 | } 714 | ] 715 | }, 716 | { 717 | "cell_type": "markdown", 718 | "metadata": { 719 | "colab_type": "text", 720 | "id": "trpqTWyvk0nr" 721 | }, 722 | "source": [ 723 | "Entrenar el modelo" 724 | ] 725 | }, 726 | { 727 | "cell_type": "code", 728 | "metadata": { 729 | "colab_type": "code", 730 | "id": "4HrXTACTdzY-", 731 | "colab": {} 732 | }, 733 | "source": [ 734 | "def loss(labels, logits):\n", 735 | " return tf.keras.losses.sparse_categorical_crossentropy(labels, logits, from_logits=True)" 736 | ], 737 | "execution_count": 0, 738 | "outputs": [] 739 | }, 740 | { 741 | "cell_type": "code", 742 | "metadata": { 743 | "colab_type": "code", 744 | "id": "DDl1_Een6rL0", 745 | "colab": {} 746 | }, 747 | "source": [ 748 | "model.compile(optimizer='adam', loss=loss)" 749 | ], 750 | "execution_count": 0, 751 | "outputs": [] 752 | }, 753 | { 754 | "cell_type": "markdown", 755 | "metadata": { 756 | "colab_type": "text", 757 | "id": "ieSJdchZggUj" 758 | }, 759 | "source": [ 760 | "Configurar el *checkpoints*" 761 | ] 762 | }, 763 | { 764 | "cell_type": "code", 765 | "metadata": { 766 | "colab_type": "code", 767 | "id": "W6fWTriUZP-n", 768 | "colab": {} 769 | }, 770 | "source": [ 771 | " # directorio\n", 772 | "checkpoint_dir = './training_checkpoints'\n", 773 | "# nombre fichero\n", 774 | "checkpoint_prefix = os.path.join(checkpoint_dir, \"ckpt_{epoch}\")\n", 775 | "\n", 776 | "checkpoint_callback=tf.keras.callbacks.ModelCheckpoint(\n", 777 | " filepath=checkpoint_prefix,\n", 778 | " save_weights_only=True)" 779 | ], 780 | "execution_count": 0, 781 | "outputs": [] 782 | }, 783 | { 784 | "cell_type": "markdown", 785 | "metadata": { 786 | "colab_type": "text", 787 | "id": "3Ky3F_BhgkTW" 788 | }, 789 | "source": [ 790 | "*Training*" 791 | ] 792 | }, 793 | { 794 | "cell_type": "code", 795 | "metadata": { 796 | "colab_type": "code", 797 | "id": "UK-hmKjYVoll", 798 | "outputId": "1ecb5c0b-068a-41e5-9e13-e47a432035cf", 799 | "colab": { 800 | "base_uri": "https://localhost:8080/", 801 | "height": 1000 802 | } 803 | }, 804 | "source": [ 805 | "EPOCHS=50\n", 806 | "history = model.fit(dataset, epochs=EPOCHS, callbacks=[checkpoint_callback])" 807 | ], 808 | "execution_count": 24, 809 | "outputs": [ 810 | { 811 | "output_type": "stream", 812 | "text": [ 813 | "Train for 31 steps\n", 814 | "Epoch 1/50\n", 815 | "31/31 [==============================] - 4s 118ms/step - loss: 3.2045\n", 816 | "Epoch 2/50\n", 817 | "31/31 [==============================] - 3s 83ms/step - loss: 2.7431\n", 818 | "Epoch 3/50\n", 819 | "31/31 [==============================] - 3s 84ms/step - loss: 2.4256\n", 820 | "Epoch 4/50\n", 821 | "31/31 [==============================] - 3s 86ms/step - loss: 2.2234\n", 822 | "Epoch 5/50\n", 823 | "31/31 [==============================] - 3s 85ms/step - loss: 2.1082\n", 824 | "Epoch 6/50\n", 825 | "31/31 [==============================] - 3s 88ms/step - loss: 1.9897\n", 826 | "Epoch 7/50\n", 827 | "31/31 [==============================] - 3s 86ms/step - loss: 1.8694\n", 828 | "Epoch 8/50\n", 829 | "31/31 [==============================] - 3s 87ms/step - loss: 1.7514\n", 830 | "Epoch 9/50\n", 831 | "31/31 [==============================] - 3s 91ms/step - loss: 1.6377\n", 832 | "Epoch 10/50\n", 833 | "31/31 [==============================] - 3s 87ms/step - loss: 1.5351\n", 834 | "Epoch 11/50\n", 835 | "31/31 [==============================] - 3s 86ms/step - loss: 1.4452\n", 836 | "Epoch 12/50\n", 837 | "31/31 [==============================] - 3s 88ms/step - loss: 1.3659\n", 838 | "Epoch 13/50\n", 839 | "31/31 [==============================] - 3s 86ms/step - loss: 1.2965\n", 840 | "Epoch 14/50\n", 841 | "31/31 [==============================] - 3s 88ms/step - loss: 1.2330\n", 842 | "Epoch 15/50\n", 843 | "31/31 [==============================] - 3s 87ms/step - loss: 1.1749\n", 844 | "Epoch 16/50\n", 845 | "31/31 [==============================] - 3s 90ms/step - loss: 1.1243\n", 846 | "Epoch 17/50\n", 847 | "31/31 [==============================] - 3s 92ms/step - loss: 1.0778\n", 848 | "Epoch 18/50\n", 849 | "31/31 [==============================] - 3s 89ms/step - loss: 1.0308\n", 850 | "Epoch 19/50\n", 851 | "31/31 [==============================] - 3s 92ms/step - loss: 0.9881\n", 852 | "Epoch 20/50\n", 853 | "31/31 [==============================] - 3s 90ms/step - loss: 0.9476\n", 854 | "Epoch 21/50\n", 855 | "31/31 [==============================] - 3s 91ms/step - loss: 0.9055\n", 856 | "Epoch 22/50\n", 857 | "31/31 [==============================] - 3s 88ms/step - loss: 0.8667\n", 858 | "Epoch 23/50\n", 859 | "31/31 [==============================] - 3s 89ms/step - loss: 0.8295\n", 860 | "Epoch 24/50\n", 861 | "31/31 [==============================] - 3s 91ms/step - loss: 0.7871\n", 862 | "Epoch 25/50\n", 863 | "31/31 [==============================] - 3s 90ms/step - loss: 0.7505\n", 864 | "Epoch 26/50\n", 865 | "31/31 [==============================] - 3s 90ms/step - loss: 0.7102\n", 866 | "Epoch 27/50\n", 867 | "31/31 [==============================] - 3s 89ms/step - loss: 0.6740\n", 868 | "Epoch 28/50\n", 869 | "31/31 [==============================] - 3s 87ms/step - loss: 0.6357\n", 870 | "Epoch 29/50\n", 871 | "31/31 [==============================] - 3s 89ms/step - loss: 0.6002\n", 872 | "Epoch 30/50\n", 873 | "31/31 [==============================] - 3s 90ms/step - loss: 0.5638\n", 874 | "Epoch 31/50\n", 875 | "31/31 [==============================] - 3s 86ms/step - loss: 0.5290\n", 876 | "Epoch 32/50\n", 877 | "31/31 [==============================] - 3s 90ms/step - loss: 0.4992\n", 878 | "Epoch 33/50\n", 879 | "31/31 [==============================] - 3s 88ms/step - loss: 0.4694\n", 880 | "Epoch 34/50\n", 881 | "31/31 [==============================] - 3s 90ms/step - loss: 0.4400\n", 882 | "Epoch 35/50\n", 883 | "31/31 [==============================] - 3s 86ms/step - loss: 0.4162\n", 884 | "Epoch 36/50\n", 885 | "31/31 [==============================] - 3s 90ms/step - loss: 0.3946\n", 886 | "Epoch 37/50\n", 887 | "31/31 [==============================] - 3s 87ms/step - loss: 0.3735\n", 888 | "Epoch 38/50\n", 889 | "31/31 [==============================] - 3s 90ms/step - loss: 0.3546\n", 890 | "Epoch 39/50\n", 891 | "31/31 [==============================] - 3s 89ms/step - loss: 0.3399\n", 892 | "Epoch 40/50\n", 893 | "31/31 [==============================] - 3s 90ms/step - loss: 0.3245\n", 894 | "Epoch 41/50\n", 895 | "31/31 [==============================] - 3s 90ms/step - loss: 0.3136\n", 896 | "Epoch 42/50\n", 897 | "31/31 [==============================] - 3s 87ms/step - loss: 0.3014\n", 898 | "Epoch 43/50\n", 899 | "31/31 [==============================] - 3s 88ms/step - loss: 0.2899\n", 900 | "Epoch 44/50\n", 901 | "31/31 [==============================] - 3s 87ms/step - loss: 0.2826\n", 902 | "Epoch 45/50\n", 903 | "31/31 [==============================] - 3s 88ms/step - loss: 0.2730\n", 904 | "Epoch 46/50\n", 905 | "31/31 [==============================] - 3s 90ms/step - loss: 0.2674\n", 906 | "Epoch 47/50\n", 907 | "31/31 [==============================] - 3s 88ms/step - loss: 0.2606\n", 908 | "Epoch 48/50\n", 909 | "31/31 [==============================] - 3s 89ms/step - loss: 0.2546\n", 910 | "Epoch 49/50\n", 911 | "31/31 [==============================] - 3s 90ms/step - loss: 0.2482\n", 912 | "Epoch 50/50\n", 913 | "31/31 [==============================] - 3s 88ms/step - loss: 0.2460\n" 914 | ], 915 | "name": "stdout" 916 | } 917 | ] 918 | }, 919 | { 920 | "cell_type": "markdown", 921 | "metadata": { 922 | "colab_type": "text", 923 | "id": "kKkD5M6eoSiN" 924 | }, 925 | "source": [ 926 | "### Generación de texto" 927 | ] 928 | }, 929 | { 930 | "cell_type": "code", 931 | "metadata": { 932 | "colab_type": "code", 933 | "id": "zk2WJ2-XjkGz", 934 | "outputId": "ef8b7f87-a25c-4b48-e662-cc13a2876a30", 935 | "colab": { 936 | "base_uri": "https://localhost:8080/", 937 | "height": 34 938 | } 939 | }, 940 | "source": [ 941 | "tf.train.latest_checkpoint(checkpoint_dir)" 942 | ], 943 | "execution_count": 25, 944 | "outputs": [ 945 | { 946 | "output_type": "execute_result", 947 | "data": { 948 | "text/plain": [ 949 | "'./training_checkpoints/ckpt_50'" 950 | ] 951 | }, 952 | "metadata": { 953 | "tags": [] 954 | }, 955 | "execution_count": 25 956 | } 957 | ] 958 | }, 959 | { 960 | "cell_type": "code", 961 | "metadata": { 962 | "colab_type": "code", 963 | "id": "LycQ-ot_jjyu", 964 | "colab": {} 965 | }, 966 | "source": [ 967 | "model = build_model(vocab_size, embedding_dim, rnn_units, batch_size=1)\n", 968 | "\n", 969 | "model.load_weights(tf.train.latest_checkpoint(checkpoint_dir))\n", 970 | "\n", 971 | "model.build(tf.TensorShape([1, None]))" 972 | ], 973 | "execution_count": 0, 974 | "outputs": [] 975 | }, 976 | { 977 | "cell_type": "code", 978 | "metadata": { 979 | "colab_type": "code", 980 | "id": "WvuwZBX5Ogfd", 981 | "colab": {} 982 | }, 983 | "source": [ 984 | "def generate_text(model, start_string):\n", 985 | "\n", 986 | " num_generate = 500\n", 987 | " input_eval = [char2idx[s] for s in start_string]\n", 988 | "\n", 989 | " input_eval = tf.expand_dims(input_eval, 0)\n", 990 | " text_generated = []\n", 991 | "\n", 992 | "\n", 993 | " temperature = 0.5\n", 994 | "\n", 995 | " model.reset_states()\n", 996 | " for i in range(num_generate):\n", 997 | " predictions = model(input_eval)\n", 998 | " \n", 999 | " predictions = tf.squeeze(predictions, 0)\n", 1000 | "\n", 1001 | " predictions = predictions / temperature\n", 1002 | " predicted_id = tf.random.categorical(predictions, num_samples=1)[-1,0].numpy()\n", 1003 | "\n", 1004 | "\n", 1005 | " input_eval = tf.expand_dims([predicted_id], 0)\n", 1006 | "\n", 1007 | " text_generated.append(idx2char[predicted_id])\n", 1008 | "\n", 1009 | " return (start_string + ''.join(text_generated))" 1010 | ], 1011 | "execution_count": 0, 1012 | "outputs": [] 1013 | }, 1014 | { 1015 | "cell_type": "code", 1016 | "metadata": { 1017 | "colab_type": "code", 1018 | "id": "ktovv0RFhrkn", 1019 | "outputId": "2b110c21-3286-4f43-98fa-7bcda1a9f209", 1020 | "colab": { 1021 | "base_uri": "https://localhost:8080/", 1022 | "height": 87 1023 | } 1024 | }, 1025 | "source": [ 1026 | "print(generate_text(model, start_string=u\"a\"))" 1027 | ], 1028 | "execution_count": 28, 1029 | "outputs": [ 1030 | { 1031 | "output_type": "stream", 1032 | "text": [ 1033 | "arte de la primera parte del libro puede expresar de la solucion de esta manera se consigue que estamos en un espacio de neuronas. VGD en la capa de pooling. Visualmente, se puede pensar en una ventana del tamano de 5?5 que va recorriendo toda la capa de 28?28 de la capa siguiente.\n", 1034 | "Como veremos en el siguiente capitulo, hay varias funciones de activacion de la primera parte de los datos de entrenamiento y de prueba.\n", 1035 | "Si queremos comprobar que justo con el lector, programaremos una red neuronal con\n" 1036 | ], 1037 | "name": "stdout" 1038 | } 1039 | ] 1040 | } 1041 | ] 1042 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **Python Deep Learning** (#PythonDL) 2 | ## Introducción práctica con Keras y TensorFlow 2 3 | ### por [Jordi Torres](https://torres.ai) 4 | 5 | 6 | Python Deep Learning 7 | 8 | **Este github contiene el código del libro [Python Deep Learning](https://www.marcombo.com/python-deep-learning-9788426728289/), publicado por Marcombo** 9 | 10 | 11 | ### Acerca del libro 12 | 13 | La inteligencia artificial permite la innovación y el cambio en todos los aspectos de la vida moderna. La mayoría de los avances actuales se basan en Deep Learning, un área de conocimiento muy madura que permite a las empresas desarrollar y poner en producción sus algoritmos de aprendizaje automático y usar los algoritmos preentrenados ofrecidos por las principales plataformas Cloud. 14 | 15 | Muchos profesionales interesados en comprender el Deep Learning tienen dificultades en establecer una ruta adecuada para empezar y saltar la barrera de entrada en este campo de innovación, debido a su complejidad y falta de manuales sobre el tema. Por ello, este libro proporciona todos los contenidos necesarios para entender qué es el Deep Learning y conocer las posibilidades de esta tecnología. 16 | 17 | Gracias a la combinación de los principios teóricos del Deep Learning y el enfoque práctico de codificación, se iniciará en este apasionante mundo mediante el lenguaje Python y la API Keras de la librería TensorFlow, el entorno más popular para desarrollar aplicaciones Deep Learning tanto a nivel de empresa como de proveedores Cloud. Asimismo, conocerá las principales redes neuronales actuales, como las redes neuronales convolucionales, las redes neuronales recurrentes o las Generative Adversarial Network, entre otras. 18 | --------------------------------------------------------------------------------