Compila un modelo de visión artificial con TensorFlow

1. Antes de comenzar

En este codelab, crearás un modelo de visión artificial que puede reconocer artículos de indumentaria con TensorFlow.

Requisitos previos

  • Un conocimiento sólido de Python
  • Habilidades básicas de programación

Qué aprenderás

En este codelab, podrás hacer lo siguiente:

  • Entrena una red neuronal para que reconozca artículos de ropa
  • Completa una serie de ejercicios para guiarte en la experimentación con las diferentes capas de la red

Qué compilarás

  • Una red neuronal que identifica artículos de ropa

Requisitos

Si nunca creaste una red neuronal para la visión artificial con TensorFlow, puedes usar Colaboratory, un entorno basado en el navegador que contiene todas las dependencias requeridas. Puedes encontrar el código para el resto del codelab que se ejecuta en Colab.

De lo contrario, el lenguaje principal que usarás para entrenar modelos es Python, por lo que deberás instalarlo. Además, necesitarás la biblioteca de NumPy y TensorFlow. Obtén más información e instala TensorFlow aquí. Instala NumPy aquí.

2. Comenzar a programar

Primero, repasa el notebook ejecutable de Colab.

Para comenzar, importa TensorFlow.

import tensorflow as tf
print(tf.__version__)

Entrenarás una red neuronal para que reconozca artículos de ropa de un conjunto de datos común llamado Fashion MNIST. Contiene 70,000 prendas de ropa en 10 categorías diferentes. Cada ropa está en una imagen en escala de grises de 28 × 28. Aquí encontrarás algunos ejemplos:

Las etiquetas asociadas con el conjunto de datos son las siguientes:

Etiqueta

Descripción

0

Camiseta/top

1

Pantalón

2

Suéter

3

Vestido

4

Abrigo

5

Sandalias

6

Camisa

7

Zapatos deportivos

8

Bag

9

Botas al tobillo

Los datos de Fashion MNIST están disponibles en la API de tf.keras.datasets. Cárgalo de la siguiente manera:

mnist = tf.keras.datasets.fashion_mnist

Si llamas a load_data en ese objeto, obtendrás dos conjuntos de dos listas: valores training y testing, que representan gráficos que muestran artículos de ropa y sus etiquetas.

(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

¿Cómo son esos valores? Imprime una imagen de entrenamiento y una etiqueta de entrenamiento para ver. Puedes experimentar con diferentes índices en el array.

import matplotlib.pyplot as plt
plt.imshow(training_images[0])
print(training_labels[0])
print(training_images[0])

La impresión de los datos del elemento 0 se ve de la siguiente manera:

Notarás que todos los valores son números enteros entre 0 y 255. Cuando se entrena una red neuronal, es más fácil tratar todos los valores entre 0 y 1, un proceso llamado normalización. Afortunadamente, Python proporciona una forma fácil de normalizar una lista como esta sin bucles.

training_images  = training_images / 255.0
test_images = test_images / 255.0

También es posible que desees ver 42, un inicio diferente al del índice 0.

Ahora, es posible que se pregunte por qué hay dos conjuntos de datos: entrenamiento y pruebas.

La idea es tener un conjunto de datos para el entrenamiento y otro conjunto de datos que el modelo aún no encuentre a fin de ver cómo clasificar los valores. Después de todo, cuando termines, tendrás que usar el modelo con datos que no había visto antes. Además, sin datos de prueba independientes, correrás el riesgo de que la red solo memorice los datos de entrenamiento sin generalizar sus conocimientos.

3. Diseña el modelo

Ahora, diseña el modelo. Tendrás tres capas. Revíselas una por una y explore los diferentes tipos de capas y los parámetros que se utilizan para cada una.

model = tf.keras.models.Sequential([tf.keras.layers.Flatten(), 
                                    tf.keras.layers.Dense(128, activation=tf.nn.relu), 
                                    tf.keras.layers.Dense(10, activation=tf.nn.softmax)])
  • Sequential define una secuencia de capas en la red neuronal.
  • Flatten toma un cuadrado y lo convierte en un vector unidimensional.
  • Dense agrega una capa de neuronas.
  • Las funciones Activation indican a cada capa de neuronas qué hacer. Hay muchas opciones, pero úsalas por ahora:
  • Relu significa que, si X es mayor que 0, se muestra X; de lo contrario, se muestra 0. Solo pasa valores de 0 o mayores a la siguiente capa de la red.
  • Softmax toma un conjunto de valores y elige el más alto con eficacia. Por ejemplo, si el resultado de la última capa es [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05], evita que debas ordenar por el valor más grande; muestra [0,0,0,0,1,0,0,0,0.

4. Compila y entrena el modelo

Ahora que el modelo está definido, lo siguiente que debes hacer es compilarlo. Para crear un modelo, primero debes compilarlo con una función optimizer y loss y, luego, entrenarlo con tus datos y etiquetas de entrenamiento. El objetivo es que el modelo descubra la relación entre los datos de entrenamiento y sus etiquetas de entrenamiento. Más adelante, deseas que el modelo vea datos que se asemejen a los de entrenamiento y, luego, haga una predicción sobre cómo deberían verse.

Observa el uso de metrics= como parámetro, lo que permite que TensorFlow informe sobre la exactitud del entrenamiento verificando los resultados previstos con las respuestas conocidas (las etiquetas).

model.compile(optimizer = tf.keras.optimizers.Adam(),
              loss = 'sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(training_images, training_labels, epochs=5)

Cuando se ejecute model.fit, verás la pérdida y la precisión:

Epoch 1/5
60000/60000 [=======] - 6s 101us/sample - loss: 0.4964 - acc: 0.8247
Epoch 2/5
60000/60000 [=======] - 5s 86us/sample - loss: 0.3720 - acc: 0.8656
Epoch 3/5
60000/60000 [=======] - 5s 85us/sample - loss: 0.3335 - acc: 0.8780
Epoch 4/5
60000/60000 [=======] - 6s 103us/sample - loss: 0.3134 - acc: 0.8844
Epoch 5/5
60000/60000 [=======] - 6s 94us/sample - loss: 0.2931 - acc: 0.8926

Cuando el modelo se complete, verás un valor de exactitud al final del ciclo de entrenamiento final. Puede ser similar a 0.8926, como más arriba. Esto indica que tu red neuronal es aproximadamente un 89% precisa en la clasificación de los datos de entrenamiento. En otras palabras, descubrió una coincidencia de patrones entre la imagen y las etiquetas que funcionaron en el 89% de las veces. No es la mejor opción, pero no es nada mala, ya que solo se entrenó durante cinco ciclos y se completó rápidamente.

5. Prueba el modelo

¿Cuál sería el rendimiento del modelo con los datos que no vio? Por eso, tienes el conjunto de pruebas. Llamas a model.evaluate y pasas los dos conjuntos, que informa la pérdida de cada uno. Pruebe lo siguiente:

model.evaluate(test_images, test_labels)

Este es el resultado:

10000/10000 [=====] - 1s 56us/sample - loss: 0.3365 - acc: 0.8789
[0.33648381242752073, 0.8789]

Ese ejemplo mostró una exactitud de 0 .8789, lo que significa que fue de aproximadamente un 88% de exactitud. (Es posible que tenga valores ligeramente diferentes).

Como era de esperar, el modelo no es tan preciso con los datos desconocidos como con los datos con los que se entrenó. A medida que aprendas más sobre TensorFlow, encontrarás formas de mejorarlo.

Para explorar más, prueba los ejercicios que aparecen en el siguiente paso.

6. Ejercicios de exploración

Ejercicio 1

En este primer ejercicio, ejecuta el siguiente código:

classifications = model.predict(test_images)
print(classifications[0])

Crea un conjunto de clasificaciones para cada una de las imágenes de prueba y, luego, imprime la primera entrada de las clasificaciones. El resultado después de que lo ejecutes es una lista de números. ¿Por qué crees que es eso y qué representan esas cifras?

Intenta ejecutar print(test_labels[0]) y obtendrás un 9. ¿Esto ayuda a entender por qué la lista se ve como lo hace?

El resultado del modelo es una lista de 10 números. Esos números son una probabilidad de que el valor que se clasifique sea la etiqueta correspondiente. Por ejemplo, el primer valor de la lista es la probabilidad de que la indumentaria sea de clase 0 y el siguiente es un 1. Tengan en cuenta que todas las probabilidades son muy bajas, excepto una. Además, debido a Softmax, todas las probabilidades de la lista suman 1.0.

La lista y las etiquetas se basan en 0, por lo que el botín que tiene la etiqueta 9 significa que es la décima de las 10 clases. La lista en la que el décimo elemento tiene el valor más alto significa que la red neuronal predijo que el elemento que está clasificando es, probablemente, un tobillo.

Ejercicio 2

Observa las capas del modelo. Experimenta con diferentes valores para la capa densa con 512 neuronas.

¿Qué resultados se obtienen con la pérdida y el tiempo de entrenamiento? ¿Por qué crees que es así?

Por ejemplo, si aumentas a 1,024 neuronas, debes hacer más cálculos, lo que ralentiza el proceso. Pero en este caso tienen un buen impacto, ya que el modelo es más preciso. Eso no quiere decir que siempre es mejor. Puedes cumplir con la ley de rendimiento que disminuye muy rápido.

Ejercicio 3

¿Qué sucedería si quitaras la capa Flatten()? ¿Por qué crees que es así?

Recibes un error sobre la forma de los datos. Los detalles del error pueden parecer poco precisos en este momento, pero refuerzan la regla general de que la primera capa de la red debería tener la misma forma que sus datos. En este momento, tus datos son de 28 x 28, y son imposibles de utilizar 28 capas de 28 neuronas, por lo que tiene más sentido compactar esos 28,28 en 784 x 1.

En lugar de escribir todo el código, agrega la capa Flatten() al principio. Cuando los arrays se carguen después en el modelo, se acoplarán automáticamente.

Ejercicio 4

Considera las capas finales (salida). ¿Por qué hay 10? ¿Qué sucedería si tuviera un importe diferente a 10?

Intenta entrenar la red con 5. Verás un error en cuanto encuentre un valor inesperado. Otra regla general: la cantidad de neuronas en la última capa debe coincidir con la cantidad de clases que se están clasificando. En este caso, se trata de los dígitos del 0 al 9, por lo que hay 10 de ellos y, por lo tanto, deberías tener 10 neuronas en la capa final.

Ejercicio 5

Considera los efectos de las capas adicionales en la red. ¿Qué sucede si agregas otra capa entre la que tiene el 512 y la final con el 10?

No hay un impacto significativo porque se trata de datos relativamente simples. Para datos mucho más complejos, a menudo se necesitan capas adicionales.

Ejercicio 6

Antes de entrenar, normalizó los datos, pasando de valores de 0 a 255, y de 0 a 1. ¿Cuál sería el impacto de quitarla? Este es el código completo que deseas probar. Ten en cuenta que se comentan las dos líneas que normalizan los datos.

¿Por qué crees que obtienes distintos resultados? Hay una muy buena respuesta aquí en Stack Overflow.

import tensorflow as tf
print(tf.__version__)
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
#training_images=training_images/255.0
#test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
model.fit(training_images, training_labels, epochs=5)
model.evaluate(test_images, test_labels)
classifications = model.predict(test_images)
print(classifications[0])
print(test_labels[0])

7. Explorar devoluciones de llamada

Anteriormente, cuando se entrenaba para ciclos de entrenamiento adicionales, tenías un problema en el que la pérdida podía cambiar. Es posible que hayas esperado un poco para esperar a que se realizara la capacitación. Tal vez pensaste que sería beneficioso si pudieras detener la capacitación cuando alcances un valor deseado, como una precisión del 95%. Si alcanzas eso después de las 3 etapas, ¿por qué esperas a que terminen muchas más?

Como cualquier otro programa, tienes devoluciones de llamada. Observa cómo funcionan:

import tensorflow as tf

class myCallback(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs={}):
    if(logs.get('accuracy')>0.95):
      print("\nReached 95% accuracy so cancelling training!")
      self.model.stop_training = True

callbacks = myCallback()
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images/255.0
test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])

8. Felicitaciones

Creaste tu primer modelo de visión artificial. Para obtener información sobre cómo mejorar los modelos de visión artificial, consulta Cómo crear convoluciones y agruparlos.