Reconocimiento de imágenes en Python con TensorFlow y Keras

Introducción

Una de las aplicaciones más comunes de TensorFlow y Keras es el reconocimiento / clasificación de imágenes. Si desea aprender a usar Keras para clasificar o reconocer imágenes, este artículo le enseñará cómo.

Definiciones

Si no está claro en los conceptos básicos detrás del reconocimiento de imágenes, será difícil entender completamente el resto de este artículo. Entonces, antes de continuar, tomemos un momento para definir algunos términos.

TensorFlow / Keras

 Crédito: commons.wikimedia.org
TensorFlow es una biblioteca de código abierto creada para Python por el equipo de Google Brain. TensorFlow compila muchos algoritmos y modelos diferentes juntos, lo que permite al usuario implementar redes neuronales profundas para usar en tareas como reconocimiento / clasificación de imágenes y procesamiento de lenguaje natural . TensorFlow es un marco poderoso que funciona mediante la implementación de una serie de nodos de procesamiento, cada uno de los cuales representa una operación matemática, y la serie completa de nodos se denomina "gráfico".
En términos de Keras , es una API de alto nivel (interfaz de programación de aplicaciones) que puede usar las funciones de TensorFlow (así como otras bibliotecas de ML como Theano). Keras fue diseñado con facilidad de uso y modularidad como principios rectores. En términos prácticos, Keras hace que la implementación de las muchas funciones potentes pero a menudo complejas de TensorFlow sea lo más simple posible, y está configurada para trabajar con Python sin modificaciones o configuraciones importantes.

Reconocimiento de Imágenes (Clasificación)

El reconocimiento de imágenes se refiere a la tarea de ingresar una imagen en una red neuronal y hacer que produzca algún tipo de etiqueta para esa imagen. La etiqueta que la red de salida corresponderá a una clase predefinida. Puede haber varias clases en las que la imagen se puede etiquetar como, o solo una. Si hay una sola clase, el término "reconocimiento" se aplica a menudo, mientras que una tarea de reconocimiento de múltiples clases a menudo se llama "clasificación".
Un subconjunto de clasificación de imágenes es la detección de objetos, donde se identifican instancias específicas de objetos que pertenecen a cierta clase, como animales, automóviles o personas.

Extracción de características

Para llevar a cabo el reconocimiento / clasificación de imágenes, la red neuronal debe realizar la extracción de características . Las características son los elementos de los datos que le interesan y que se alimentarán a través de la red. En el caso específico del reconocimiento de imágenes, las características son los grupos de píxeles, como bordes y puntos, de un objeto que la red analizará en busca de patrones.
El reconocimiento de características (o extracción de características) es el proceso de extraer las características relevantes de una imagen de entrada para que estas características puedan ser analizadas. Muchas imágenes contienen anotaciones o metadatos sobre la imagen que ayudan a la red a encontrar las funciones relevantes.

Cómo las redes neuronales aprenden a reconocer imágenes

Obtener una intuición de cómo una red neuronal reconoce las imágenes lo ayudará cuando esté implementando un modelo de red neuronal, así que exploremos brevemente el proceso de reconocimiento de imágenes en las siguientes secciones.

Extracción de características con filtros

Crédito: commons.wikimedia.org
La primera capa de una red neuronal toma todos los píxeles dentro de una imagen. Una vez que todos los datos se han introducido en la red, se aplican diferentes filtros a la imagen, que forman representaciones de diferentes partes de la imagen. Esta es la extracción de características y crea "mapas de características".
Este proceso de extracción de características de una imagen se realiza con una "capa convolucional", y la convolución simplemente forma una representación de parte de una imagen. Es a partir de este concepto de convolución que obtenemos el término Red neuronal convolucional (CNN), el tipo de red neuronal más utilizada en la clasificación / reconocimiento de imágenes.
Si desea visualizar cómo funciona la creación de mapas de entidades, piense en encender una linterna sobre una imagen en una habitación oscura. A medida que desliza el haz sobre la imagen, está aprendiendo acerca de las características de la imagen. Un filtro es lo que la red usa para formar una representación de la imagen, y en esta metáfora, la luz de la linterna es el filtro.
El ancho del haz de su linterna controla la cantidad de imagen que examina al mismo tiempo, y las redes neuronales tienen un parámetro similar, el tamaño del filtro. El tamaño del filtro afecta la cantidad de la imagen, la cantidad de píxeles que se están examinando a la vez. Un tamaño de filtro común usado en las CNN es 3, y esto cubre tanto la altura como el ancho, por lo que el filtro examina un área de 3 x 3 píxeles.
Crédito: commons.wikimedia.org
Si bien el tamaño del filtro cubre la altura y el ancho del filtro, también se debe especificar la profundidad del filtro .
¿Cómo tiene profundidad una imagen 2D?
Las imágenes digitales se representan como altura, anchura y algún valor RGB que define los colores del píxel, por lo que la "profundidad" que se rastrea es la cantidad de canales de color que tiene la imagen. Las imágenes en escala de grises (sin color) solo tienen 1 canal de color, mientras que las imágenes en color tienen 3 canales de profundidad.
Todo esto significa que para un filtro de tamaño 3 aplicado a una imagen a todo color, las dimensiones de ese filtro serán 3 x 3 x 3. Por cada píxel cubierto por ese filtro, la red multiplica los valores de filtro con los valores en los píxeles mismos para obtener una representación numérica de ese píxel. Este proceso se realiza para que toda la imagen logre una representación completa. El filtro se mueve a través del resto de la imagen de acuerdo con un parámetro llamado "zancada", que define cuántos píxeles se moverá el filtro después de que calcule el valor en su posición actual. Un tamaño de zancada convencional para una CNN es 2.
El resultado final de todo este cálculo es un mapa de características. Este proceso generalmente se realiza con más de un filtro, lo que ayuda a preservar la complejidad de la imagen.

Funciones de activacion

Una vez creado el mapa de características de la imagen, los valores que representan la imagen pasan a través de una función de activación o capa de activación. La función de activación toma valores que representan la imagen, que están en forma lineal (es decir, solo una lista de números) gracias a la capa convolucional, y aumenta su no linealidad, ya que las imágenes en sí no son lineales.
La función de activación típica que se usa para lograr esto es una unidad lineal rectificada (ReLU), aunque hay algunas otras funciones de activación que se usan ocasionalmente (puede leer sobre ellas aquí ).

Capas de agrupación

Una vez que los datos se activan, se envían a través de una capa de agrupación . Agrupar "tomas de muestra" de una imagen, lo que significa que toma la información que representa la imagen y la comprime, haciéndola más pequeña. El proceso de agrupación hace que la red sea más flexible y más adepta a reconocer objetos / imágenes en función de las características relevantes.
Cuando miramos una imagen, generalmente no nos preocupa la información que se encuentra en el fondo de la imagen, solo las características que nos interesan, como las personas o los animales.
De manera similar, una capa de agrupación en una CNN abstraerá las partes innecesarias de la imagen, manteniendo solo las partes de la imagen que considera relevantes, según lo controlado por el tamaño especificado de la capa de agrupación.
Debido a que tiene que tomar decisiones sobre las partes más relevantes de la imagen, la esperanza es que la red aprenda solo las partes de la imagen que realmente representan el objeto en cuestión. Esto ayuda a evitar el sobreajuste , donde la red aprende demasiado bien los aspectos del caso de capacitación y no logra generalizar los datos nuevos.
 Crédito: commons.wikimedia.org
Hay varias formas de agrupar los valores, pero la agrupación máxima es la más utilizada. La agrupación máxima obtiene el valor máximo de los píxeles dentro de un solo filtro (dentro de un solo punto en la imagen). Esto elimina 3/4 de información, suponiendo que se utilicen filtros 2 x 2.
Los valores máximos de los píxeles se utilizan para tener en cuenta las posibles distorsiones de la imagen, y los parámetros / tamaño de la imagen se reducen para controlar el sobreajuste. Existen otros tipos de agrupación, como la agrupación promedio o la agrupación de sumas, pero no se utilizan con tanta frecuencia porque la agrupación máxima tiende a producir una mayor precisión.

Aplastamiento

Las capas finales de nuestra CNN, las capas densamente conectadas, requieren que los datos estén en forma de un vector para ser procesados. Por esta razón, los datos deben ser "aplanados". Los valores se comprimen en un vector largo o en una columna de números ordenados secuencialmente.

Capa completamente conectada

Las capas finales de la CNN son capas densamente conectadas, o una red neuronal artificial (ANN). La función principal de la ANN es analizar las características de entrada y combinarlas en diferentes atributos que ayudarán en la clasificación. Estas capas son esencialmente formaciones de neuronas que representan diferentes partes del objeto en cuestión, y una colección de neuronas puede representar las orejas flojas de un perro o el enrojecimiento de una manzana. Cuando se activen suficientes neuronas en respuesta a una imagen de entrada, la imagen se clasificará como un objeto.
Crédito: commons.wikimedia.org
El error, o la diferencia entre los valores calculados y el valor esperado en el conjunto de entrenamiento, se calcula mediante la ANN. Luego, la red experimenta una propagación hacia atrás , donde se calcula la influencia de una neurona determinada en una neurona en la siguiente capa y se ajusta su influencia. Esto se hace para optimizar el rendimiento del modelo. Este proceso se repite una y otra vez. Así es como la red entrena en los datos y aprende las asociaciones entre las características de entrada y las clases de salida.
Las neuronas en el medio de las capas totalmente conectadas emitirán valores binarios relacionados con las posibles clases. Si tiene cuatro clases diferentes (digamos un perro, un carro, una casa y una persona), la neurona tendrá un valor de "1" para la clase que cree que representa la imagen y un valor de "0" para las otras clases. .
La capa final completamente conectada recibirá la salida de la capa anterior y entregará una probabilidad para cada una de las clases, sumando una. Si hay un valor de 0.75 en la categoría "perro", representa un 75% de certeza de que la imagen es un perro.
El clasificador de imágenes ahora ha sido entrenado, y las imágenes se pueden pasar a la CNN, que ahora arrojará una conjetura sobre el contenido de esa imagen.

El flujo de trabajo de aprendizaje automático

Antes de pasar a un ejemplo de entrenamiento de un clasificador de imágenes, tomemos un momento para comprender el flujo de trabajo de aprendizaje automático o la tubería. El proceso para entrenar un modelo de red neuronal es bastante estándar y se puede dividir en cuatro fases diferentes.

Preparación de datos

Primero, deberá recopilar sus datos y ponerlos en una forma en la que la red pueda entrenarse. Esto implica recoger imágenes y etiquetarlas. Incluso si ha descargado un conjunto de datos que alguien más ha preparado, es probable que haya un preprocesamiento o preparación que debe hacer antes de poder usarlo para la capacitación. La preparación de datos es un arte en sí mismo, involucrando el manejo de cosas como valores perdidos, datos corruptos, datos en el formato incorrecto, etiquetas incorrectas, etc.
En este artículo, utilizaremos un conjunto de datos preprocesados.

Creando el Modelo

La creación del modelo de red neuronal implica realizar elecciones sobre diversos parámetros e hiperparámetros. Debe tomar decisiones sobre la cantidad de capas que se usarán en su modelo, cuáles serán los tamaños de entrada y salida de las capas, qué tipo de funciones de activación utilizará, si utilizará o no el abandono, etc.
Aprender qué parámetros e hiperparámetros usar vendrá con el tiempo (y mucho estudio), pero desde el principio hay algunas heurísticas que puedes usar para ponerte en marcha y cubriremos algunos de ellos durante el ejemplo de implementación.

Entrenando el modelo

Una vez que haya creado su modelo, simplemente cree una instancia del modelo y ajústelo a sus datos de entrenamiento. La mayor consideración cuando se entrena un modelo es la cantidad de tiempo que el modelo necesita para entrenar. Puede especificar la duración de la capacitación para una red especificando el número de épocas para entrenar. Cuanto más tiempo entrene a un modelo, mejor será su rendimiento, pero demasiadas épocas de entrenamiento y usted corre el riesgo de un exceso de adaptación.
Elegir la cantidad de épocas para las que se entrenará es algo que tendrá la sensación de sentir, y es costumbre guardar el peso de una red entre las sesiones de capacitación para que no tenga que volver a empezar una vez que haya progresado en la red.

Evaluación del modelo

Hay múltiples pasos para evaluar el modelo. El primer paso para evaluar el modelo es comparar el rendimiento del modelo con un conjunto de datos de validación , un conjunto de datos en el que no se ha capacitado al modelo. Comparará el rendimiento del modelo con este conjunto de validación y analizará su rendimiento a través de diferentes métricas.
Existen varias métricas para determinar el rendimiento de un modelo de red neuronal, pero la métrica más común es la "precisión", la cantidad de imágenes clasificadas correctamente dividida por el número total de imágenes en su conjunto de datos.
Después de haber visto la precisión del rendimiento del modelo en un conjunto de datos de validación, normalmente volverá y capacitará la red utilizando parámetros ligeramente modificados, ya que es poco probable que esté satisfecho con el rendimiento de su red la primera vez que entrene. Seguirá ajustando los parámetros de su red, volviendo a capacitarla y midiendo su rendimiento hasta que esté satisfecho con la precisión de la red.
Finalmente, probará el rendimiento de la red en un conjunto de pruebas . Este conjunto de pruebas es otro conjunto de datos que su modelo nunca ha visto antes.
Quizás te estés preguntando:
¿Por qué molestarse con el conjunto de pruebas? Si tiene una idea de la precisión de su modelo, ¿no es ese el propósito del conjunto de validación?
Es una buena idea mantener un lote de datos que la red nunca ha visto para la prueba porque todos los ajustes de los parámetros que realiza, combinados con la nueva prueba en el conjunto de validación, podrían significar que su red ha aprendido algunas idiosincrasias del conjunto de validación que No se generalizará a los datos fuera de la muestra.
Por lo tanto, el propósito del conjunto de pruebas es verificar problemas como el sobreajuste y tener más confianza de que su modelo está realmente preparado para funcionar en el mundo real.

Reconocimiento de imágenes con una CNN

Hemos cubierto mucho hasta ahora, y si toda esta información ha sido un poco abrumadora, ver estos conceptos reunidos en un clasificador de muestra capacitado en un conjunto de datos debería hacer que estos conceptos sean más concretos. Así que veamos un ejemplo completo de reconocimiento de imagen con Keras, desde la carga de datos hasta la evaluación.
 Crédito: www.cs.toronto.edu
Para empezar, necesitaremos un conjunto de datos para entrenar. En este ejemplo, usaremos el famoso conjunto de datos CIFAR-10 . CIFAR-10 es un gran conjunto de datos de imágenes que contiene más de 60,000 imágenes que representan 10 clases diferentes de objetos como gatos, aviones y autos.
Las imágenes son RGB a todo color, pero son bastante pequeñas, solo 32 x 32. Una gran cosa acerca del conjunto de datos CIFAR-10 es que viene preempaquetado con Keras, por lo que es muy fácil cargar el conjunto de datos y las imágenes necesitan muy poco preprocesamiento.
Lo primero que debemos hacer es importar las bibliotecas necesarias. Mostraré cómo se usan estas importaciones a medida que avanzamos, pero por ahora sabemos que usaremos Numpy y varios módulos asociados con Keras:
import numpy  
from keras.models import Sequential  
from keras.layers import Dense, Dropout, Flatten, BatchNormalization, Activation  
from keras.layers.convolutional import Conv2D, MaxPooling2D  
from keras.constraints import maxnorm  
from keras.utils import np_utils  
Vamos a utilizar una semilla aleatoria aquí para que usted pueda replicar los resultados obtenidos en este artículo, por lo que necesitamos numpy:
# Set random seed for purposes of reproducibility
seed = 21  

Preparando los datos

Necesitamos una importación más: el conjunto de datos.
from keras.datasets import cifar10  
Ahora vamos a cargar en el conjunto de datos. Podemos hacerlo simplemente especificando en qué variables queremos cargar los datos y luego usando la load_data()función:
# loading in the data

(X_train, y_train), (X_test, y_test) = cifar10.load_data()
En la mayoría de los casos, deberá realizar un procesamiento previo de sus datos para prepararlos para su uso, pero como estamos usando un conjunto de datos preempaquetado, es necesario realizar muy poco procesamiento previo. Una cosa que queremos hacer es normalizar los datos de entrada.
Si los valores de los datos de entrada están en un rango demasiado amplio, puede afectar negativamente el rendimiento de la red. En este caso, los valores de entrada son los píxeles de la imagen, que tienen un valor entre 0 y 255.
Entonces, para normalizar los datos, simplemente podemos dividir los valores de la imagen por 255. Para hacer esto, primero necesitamos hacer que los datos sean de tipo flotante, ya que actualmente son enteros. Podemos hacer esto usando el astype()comando Numpy y luego declarando qué tipo de datos queremos:
# normalize the inputs from 0-255 to between 0 and 1 by dividing by 255

X_train = X_train.astype('float32')  
X_test = X_test.astype('float32')  
X_train = X_train / 255.0  
X_test = X_test / 255.0  
Otra cosa que tendremos que hacer para preparar los datos para la red es codificar los valores de forma instantánea. No voy a entrar en los detalles específicos de la codificación one-hot aquí, pero por ahora sé que la red no puede usar las imágenes tal como están, deben ser codificadas primero y la codificación one-hot se utiliza mejor cuando se hace clasificación binaria.
Efectivamente, estamos haciendo una clasificación binaria aquí porque una imagen pertenece a una clase o no, no puede caer en un punto intermedio. El comando Numpy to_categorical()se utiliza para la codificación en caliente. Es por esto que importamos la np_utilsfunción de Keras, ya que contiene to_categorical().
También necesitamos especificar el número de clases que están en el conjunto de datos, por lo que sabemos cuántas neuronas comprimen la capa final hasta:
# one hot encode outputs
y_train = np_utils.to_categorical(y_train)  
y_test = np_utils.to_categorical(y_test)  
class_num = y_test.shape[1]  

Diseñando el modelo

Hemos llegado a la etapa en la que diseñamos el modelo CNN. Lo primero que debe hacer es definir el formato que nos gustaría usar para el modelo, Keras tiene varios formatos o planos diferentes para construir modelos, pero Sequentiales el más usado, y por esa razón, lo hemos importado de Keras.

Crear el modelo

model = Sequential()  
La primera capa de nuestro modelo es una capa convolucional. Tomará en las entradas y ejecutará filtros convolucionales en ellos.
Al implementar estos en Keras, tenemos que especificar el número de canales / filtros que queremos (que son los 32 a continuación), el tamaño del filtro que queremos (3 x 3 en este caso), la forma de entrada (cuando se crea la primera capa). ) y la activación y el relleno que necesitamos.
Como se mencionó, relues la activación más común, y padding='same'solo significa que no estamos cambiando el tamaño de la imagen en absoluto:
model.add(Conv2D(32, (3, 3), input_shape=X_train.shape[1:], padding='same'))  
model.add(Activation('relu'))  
Nota : También puede encadenar las activaciones y agrupaciones juntas de esta manera:
model.add(Conv2D(32, (3, 3), input_shape=(3, 32, 32), activation='relu', padding='same'))  
Ahora haremos una capa de exclusión para evitar el sobreajuste, que funciona al eliminar al azar algunas de las conexiones entre las capas (0.2 significa que elimina el 20% de las conexiones existentes):
model.add(Dropout(0.2))  
También podemos querer hacer la normalización de lotes aquí. La normalización de lotes normaliza las entradas que se dirigen a la siguiente capa, asegurando que la red siempre cree activaciones con la misma distribución que deseamos:
model.add(BatchNormalization())  
Ahora viene otra capa convolucional, pero el tamaño del filtro aumenta para que la red pueda aprender representaciones más complejas:
model.add(Conv2D(64, (3, 3), padding='same'))  
model.add(Activation('relu'))  
Aquí está la capa de agrupación, como se explicó antes, esto ayuda a hacer que el clasificador de imágenes sea más robusto para que pueda aprender patrones relevantes. También está la deserción y la normalización de lotes:
model.add(MaxPooling2D(pool_size=(2, 2)))  
model.add(Dropout(0.2))  
model.add(BatchNormalization())  
Ese es el flujo básico para la primera mitad de una implementación de CNN: convolucional, activación, deserción, agrupación . Ahora puede ver por qué hemos importado DropoutBatchNormalizationActivationConv2d, y MaxPooling2d.
Puede variar la cantidad exacta de capas convolucionales que tiene a su gusto, aunque cada una de ellas agrega más gastos de cómputo. Tenga en cuenta que a medida que agrega capas convolucionales, generalmente aumenta su número de filtros para que el modelo pueda aprender representaciones más complejas. Si los números elegidos para estas capas parecen un tanto arbitrarios, solo sepan que, en general, aumentan los filtros a medida que avanza y se recomienda que tengan 2 poderes que pueden otorgar un ligero beneficio cuando se entrena en una GPU.
Es importante no tener demasiadas capas de agrupación, ya que cada agrupación descarta algunos datos. La agrupación demasiado a menudo conducirá a que no haya casi nada para que las capas densamente conectadas aprendan cuando los datos llegan a ellas.
El número exacto de capas de agrupación que debe usar dependerá de la tarea que esté realizando, y es algo que experimentará con el tiempo. Ya que las imágenes son tan pequeñas aquí ya no agruparemos más de dos veces.
Ahora puede repetir estas capas para darle a su red más representaciones para trabajar:
model.add(Conv2D(64, (3, 3), padding='same'))  
model.add(Activation('relu'))  
model.add(MaxPooling2D(pool_size=(2, 2)))  
model.add(Dropout(0.2))  
model.add(BatchNormalization())

model.add(Conv2D(128, (3, 3), padding='same'))  
model.add(Activation('relu'))  
model.add(Dropout(0.2))  
model.add(BatchNormalization())  
Una vez que hayamos terminado con las capas convolucionales, necesitamos Flattenlos datos, por eso importamos la función anterior. También agregaremos una capa de abandono nuevamente:
model.add(Flatten())  
model.add(Dropout(0.2))  
Ahora hacemos uso de la Denseimportación y creamos la primera capa densamente conectada. Necesitamos especificar el número de neuronas en la capa densa. Tenga en cuenta que el número de neuronas en las capas siguientes disminuye, acercándose finalmente al mismo número de neuronas que hay clases en el conjunto de datos (en este caso 10). La restricción del kernel puede regularizar los datos a medida que se aprende, otra cosa que ayuda a evitar el sobreajuste. Es por eso que hemos importado maxnormanteriormente.
model.add(Dense(256, kernel_constraint=maxnorm(3)))  
model.add(Activation('relu'))  
model.add(Dropout(0.2))  
model.add(BatchNormalization())

model.add(Dense(128, kernel_constraint=maxnorm(3)))  
model.add(Activation('relu'))  
model.add(Dropout(0.2))  
model.add(BatchNormalization())  
En esta capa final, pasamos en el número de clases para el número de neuronas. Cada neurona representa una clase, y la salida de esta capa será un vector de 10 neuronas con cada neurona almacenando alguna probabilidad de que la imagen en cuestión pertenezca a la clase que representa.
Finalmente, la softmaxfunción de activación selecciona la neurona con la mayor probabilidad de salida, votando que la imagen pertenece a esa clase:
model.add(Dense(class_num))  
model.add(Activation('softmax'))  
Ahora que hemos diseñado el modelo que queremos usar, solo tenemos que compilarlo. Especifiquemos la cantidad de épocas para las que queremos entrenarnos, así como el optimizadorque queremos usar.
El optimizador es lo que ajustará los pesos en su red para acercarse al punto de pérdida más bajo. El Adamalgoritmo es uno de los optimizadores más utilizados porque brinda un gran rendimiento en la mayoría de los problemas:
epochs = 25  
optimizer = 'adam'  
Ahora compilemos el modelo con nuestros parámetros elegidos. Especifiquemos también una métrica para usar.
model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])  
Podemos imprimir el resumen del modelo para ver cómo se ve todo el modelo.
print(model.summary())  
Imprimir el resumen nos dará bastante información:
Results:

Layer (type) Output Shape Param #  
=================================================================
conv2d_1 (Conv2D) (None, 32, 32, 32) 896  
_________________________________________________________________  
activation_1 (Activation) (None, 32, 32, 32) 0  
_________________________________________________________________  
dropout_1 (Dropout) (None, 32, 32, 32) 0  
_________________________________________________________________  
batch_normalization_1 (Batch (None, 32, 32, 32) 128  
_________________________________________________________________  
conv2d_2 (Conv2D) (None, 32, 32, 64) 18496  
_________________________________________________________________  
activation_2 (Activation) (None, 32, 32, 64) 0  
_________________________________________________________________  
max_pooling2d_1 (MaxPooling2 (None, 16, 16, 64) 0  
_________________________________________________________________  
dropout_2 (Dropout) (None, 16, 16, 64) 0  
_________________________________________________________________  
batch_normalization_2 (Batch (None, 16, 16, 64) 256  
_________________________________________________________________  
conv2d_3 (Conv2D) (None, 16, 16, 64) 36928  
_________________________________________________________________  
activation_3 (Activation) (None, 16, 16, 64) 0  
_________________________________________________________________  
max_pooling2d_2 (MaxPooling2 (None, 8, 8, 64) 0  
_________________________________________________________________  
dropout_3 (Dropout) (None, 8, 8, 64) 0  
_________________________________________________________________  
batch_normalization_3 (Batch (None, 8, 8, 64) 256  
_________________________________________________________________  
conv2d_4 (Conv2D) (None, 8, 8, 128) 73856  
_________________________________________________________________  
activation_4 (Activation) (None, 8, 8, 128) 0  
_________________________________________________________________  
dropout_4 (Dropout) (None, 8, 8, 128) 0  
_________________________________________________________________  
batch_normalization_4 (Batch (None, 8, 8, 128) 512  
_________________________________________________________________  
flatten_1 (Flatten) (None, 8192) 0  
_________________________________________________________________  
dropout_5 (Dropout) (None, 8192) 0  
_________________________________________________________________  
dense_1 (Dense) (None, 256) 2097408  
_________________________________________________________________  
activation_5 (Activation) (None, 256) 0  
_________________________________________________________________  
dropout_6 (Dropout) (None, 256) 0  
_________________________________________________________________  
batch_normalization_5 (Batch (None, 256) 1024  
_________________________________________________________________  
dense_2 (Dense) (None, 128) 32896  
_________________________________________________________________  
activation_6 (Activation) (None, 128) 0  
_________________________________________________________________  
dropout_7 (Dropout) (None, 128) 0  
_________________________________________________________________  
batch_normalization_6 (Batch (None, 128) 512  
_________________________________________________________________  
dense_3 (Dense) (None, 10) 1290  
_________________________________________________________________  
activation_7 (Activation) (None, 10) 0  
=================================================================
Total params: 2,264,458  
Trainable params: 2,263,114  
Non-trainable params: 1,344  
Ahora llegamos a entrenar el modelo. Para hacer esto, todo lo que tenemos que hacer es llamar a la fit()función en el modelo y pasar los parámetros elegidos.
Aquí es donde uso la semilla que elegí, con el propósito de reproducibilidad.
numpy.random.seed(seed)  
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=64)  
Estaremos entrenando en 50000 muestras y validando en 10000 muestras.
Ejecutar este fragmento de código dará como resultado:
Epoch 1/25

64/50000 [..............................] - ETA: 16:57 - loss: 3.1479 - acc: 0.0938  
128/50000 [..............................] - ETA: 10:12 - loss: 3.0212 - acc: 0.0938  
192/50000 [..............................] - ETA: 7:57 - loss: 2.9781 - acc: 0.1250  
256/50000 [..............................] - ETA: 6:48 - loss: 2.8830 - acc: 0.1484  
320/50000 [..............................] - ETA: 6:07 - loss: 2.8878 - acc: 0.1469  
384/50000 [..............................] - ETA: 5:40 - loss: 2.8732 - acc: 0.1458  
448/50000 [..............................] - ETA: 5:20 - loss: 2.8842 - acc: 0.1406

...
...
...

49664/50000 [============================>.] - ETA: 1s - loss: 1.5160 - acc: 0.4611  
49728/50000 [============================>.] - ETA: 1s - loss: 1.5157 - acc: 0.4612  
49792/50000 [============================>.] - ETA: 1s - loss: 1.5153 - acc: 0.4614  
49856/50000 [============================>.] - ETA: 0s - loss: 1.5147 - acc: 0.4615  
49920/50000 [============================>.] - ETA: 0s - loss: 1.5144 - acc: 0.4617  
49984/50000 [============================>.] - ETA: 0s - loss: 1.5141 - acc: 0.4617  
50000/50000 [==============================] - 262s 5ms/step - loss: 1.5140 - acc: 0.4618 - val_loss: 1.0715 - val_acc: 0.6195

End of Epoch 1  
Tenga en cuenta que en la mayoría de los casos, desearía tener un conjunto de validación diferente del conjunto de pruebas, por lo que debe especificar un porcentaje de los datos de entrenamiento para usar como el conjunto de validación. En este caso, solo pasaremos los datos de prueba para asegurarnos de que los datos de prueba estén reservados y no entrenados. Solo tendremos datos de prueba en este ejemplo, para mantener las cosas simples.
Ahora podemos evaluar el modelo y ver cómo se realiza. Sólo tiene que llamar model.evaluate():
# Model evaluation
scores = model.evaluate(X_test, y_test, verbose=0)  
print("Accuracy: %.2f%%" % (scores[1]*100))  
Y nos saludan con el resultado:
Accuracy: 83.01%  
¡Y eso es! Ahora tenemos un reconocimiento de imagen entrenado CNN. No está mal para la primera ejecución, pero probablemente querrá jugar con la estructura y los parámetros del modelo para ver si no puede obtener un mejor rendimiento.

Conclusión

Ahora que ha implementado su primera red de reconocimiento de imágenes en Keras, sería una buena idea jugar con el modelo y ver cómo el cambio de sus parámetros afecta su rendimiento.
Esto le dará una idea de las mejores opciones para diferentes parámetros de modelo. También debe leer sobre las diferentes opciones de parámetros e hiper-parámetros mientras lo hace. Una vez que se sienta cómodo con estos, puede intentar implementar su propio clasificador de imágenes en un conjunto de datos diferente.

Acerca de: Programator

Somos Instinto Programador

0 comentarios:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Con tecnología de Blogger.