Tutorial de Keras
¿Qué es Keras?
Keras es una biblioteca de redes neuronales de código abierto escrita en Python que se ejecuta sobre Theano o Tensorflow. Está diseñado para ser modular, rápido y fácil de usar. Fue desarrollado por François Chollet, un ingeniero de Google. Keras no maneja computación de bajo nivel. En cambio, utiliza otra biblioteca para hacerlo, llamada “Backend.
Keras es un contenedor de API de alto nivel para API de bajo nivel, capaz de ejecutarse sobre TensorFlow, CNTK o Theano. La API de alto nivel de Keras maneja la forma en que creamos modelos, definimos capas o configuramos múltiples modelos de entrada y salida. En este nivel, Keras también compila nuestro modelo con funciones de pérdida y optimizador, proceso de entrenamiento con función de ajuste. Keras en Python no maneja API de bajo nivel, como hacer el gráfico computacional, hacer tensores u otras variables porque ha sido manejado por el motor "backend".
¿Qué es un back-end?
Backend es un término en Keras que realiza todos los cálculos de bajo nivel, como productos tensoriales, convoluciones y muchas otras cosas, con la ayuda de otras bibliotecas como Tensorflow o Theano. Entonces, el “motor backend” realizará el cálculo y desarrollo de los modelos. Tensorflow es el “motor backend” predeterminado pero podemos cambiarlo en la configuración.
Backend de Theano, Tensorflow y CNTK
Theano es un proyecto de código abierto desarrollado por el grupo MILA de la Universidad de Montreal, Quebec, Canadá. Fue el primer Framework ampliamente utilizado. es un Python Biblioteca que ayuda con matrices multidimensionales para operaciones matemáticas utilizando Numpy o Scipy. Theano puede utilizar GPU para realizar cálculos más rápidos y también puede crear automáticamente gráficos simbólicos para calcular gradientes. En su sitio web, Theano afirma que puede reconocer expresiones numéricamente inestables y calcularlas con algoritmos más estables, lo que resulta muy útil para nuestras expresiones inestables.
Por otro lado, Tensorflow es la estrella en ascenso en el marco de aprendizaje profundo. Desarrollada por el equipo Brain de Google, es la herramienta de aprendizaje profundo más popular. Con muchas características, los investigadores contribuyen a ayudar a desarrollar este marco para fines de aprendizaje profundo.
Otro motor backend para Keras es The Microsoft Kit de herramientas cognitivas o CNTK. Es un marco de aprendizaje profundo de código abierto desarrollado por Microsoft Equipo. Puede ejecutarse en varias GPU o en varias máquinas para entrenar modelos de aprendizaje profundo a gran escala. En algunos casos, se informó que CNTK era más rápido que otros marcos como Tensorflow o Theano. A continuación, en este tutorial de Keras CNN, compararemos los backends de Theano, TensorFlow y CNTK.
Comparando los backends
Necesitamos hacer un punto de referencia para conocer la comparación entre estos dos backends. Como puedes ver en El punto de referencia de Jeong-Yoon Lee, se compara el rendimiento de 3 backends diferentes en hardware diferente. Y el resultado es que Theano es más lento que el otro backend, según se informa. 50 equipos más lento, pero la precisión es cercana entre sí.
Otra prueba de referencia es realizado por Jasmeet Bhatia. Informó que Theano es más lento que Tensorflow para algunas pruebas. Pero la precisión general es casi la misma para todas las redes probadas.
Entonces, entre Theano, Tensorflow y CTK es obvio que TensorFlow es mejor que Theano. Con TensorFlow, el tiempo de cálculo es mucho más corto y CNN es mejor que los demás.
Siguiente en este Keras Python tutorial, aprenderemos sobre la diferencia entre Keras y TensorFlow (Keras y Tensorflow).
Keras y Tensorflow
Parámetros | Keras | Flujo tensor |
---|---|---|
Tipo | Envoltorio de API de alto nivel | API de bajo nivel |
Complejidad: | Fácil de usar si Python idioma | Necesita aprender la sintaxis del uso de algunas funciones de Tensorflow. |
Finalidad | Implementación rápida para crear modelos con capas estándar. | Le permite crear un gráfico computacional arbitrario o capas de modelo. |
Herramientas | Utiliza otra herramienta de depuración API como TFDBG | Puedes utilizar las herramientas de visualización de Tensorboard. |
Comunidad | Grandes comunidades activas | Grandes comunidades activas y recursos ampliamente compartidos |
Ventajas de Keras
Implementación rápida y fácil de entender
Keras crea muy rápidamente un modelo de red. Si desea hacer un modelo de red simple con unas pocas líneas, Python Keras puede ayudarte con eso. Mire el ejemplo de Keras a continuación:
from keras.models import Sequential from keras.layers import Dense, Activation model = Sequential() model.add(Dense(64, activation='relu', input_dim=50)) #input shape of 50 model.add(Dense(28, activation='relu')) #input shape of 50 model.add(Dense(10, activation='softmax'))
Gracias a la API amigable, podemos comprender fácilmente el proceso. Escribir el código con una función simple y sin necesidad de configurar múltiples parámetros.
Gran apoyo de la comunidad
Hay muchas comunidades de IA que utilizan Keras para su marco de aprendizaje profundo. Muchos de ellos publican sus códigos y tutoriales para el público en general.
Tener múltiples backends
Puede elegir Tensorflow, CNTK y Theano como backend con Keras. Puede elegir un backend diferente para diferentes proyectos según sus necesidades. Cada backend tiene su propia ventaja única.
Implementación de modelos sencilla y multiplataforma
Con una variedad de dispositivos y plataformas compatibles, puede implementar Keras en cualquier dispositivo como
- iOS con CoreML
- Android con Tensorflow Android,
- Navegador web compatible con .js
- motor de nube
- Frambuesa Pi
Compatibilidad con múltiples GPU
Puede entrenar Keras en una sola GPU o utilizar varias GPU a la vez. Porque Keras tiene soporte incorporado para el paralelismo de datos, por lo que puede procesar grandes volúmenes de datos y acelerar el tiempo necesario para entrenarlos.
Desventajas de Keras
No se puede manejar API de bajo nivel
Keras solo maneja API de alto nivel que se ejecuta sobre otro marco o motor backend como Tensorflow, Theano o CNTK. Por lo tanto, no es muy útil si desea crear su propia capa abstracta para fines de investigación porque Keras ya tiene capas preconfiguradas.
Instalación de Keras
En esta sección, analizaremos varios métodos disponibles para instalar Keras.
Instalación directa o entorno virtual
¿Cuál es mejor? ¿Instalación directa en el Python actual o utilizar un entorno virtual? Sugiero utilizar un entorno virtual si tienes muchos proyectos. ¿Quieres saber por qué? Esto se debe a que diferentes proyectos pueden usar una versión diferente de una biblioteca keras.
Por ejemplo, tengo un proyecto que necesita Python 3.5 usando OpenCV 3.3 con el backend Keras-Theano anterior, pero en el otro proyecto tengo que usar Keras con la última versión y un Tensorflow como backend. Python Soporte 3.6.6
No queremos que la biblioteca de Keras entre en conflicto entre sí, ¿verdad? Entonces usamos un entorno virtual para localizar el proyecto con un tipo específico de biblioteca o podemos usar otra plataforma como Cloud Service para hacer nuestro cálculo por nosotros como Amazon Servicio web.
Instalación de Keras en Amazon Servicio web (AWS)
Amazon Web Service es una plataforma que ofrece servicios y productos de Cloud Computing para investigadores o cualquier otro fin. AWS alquila su hardware, redes, bases de datos, etc. para que podamos usarlo directamente desde Internet. Uno de los servicios populares de AWS para fines de aprendizaje profundo es el Amazon Servicio de aprendizaje profundo de imágenes de máquina o DL
Para obtener instrucciones detalladas sobre cómo utilizar AWS, consulte este tutoriales
Nota sobre el AMI: Tendrás disponible el siguiente AMI
AWS Deep Learning AMI es un entorno virtual en el servicio AWS EC2 que ayuda a los investigadores o profesionales a trabajar con Deep Learning. DLAMI ofrece desde motores de CPU pequeños hasta motores de múltiples GPU de alta potencia con CUDA y cuDNN preconfigurados y viene con una variedad de marcos de aprendizaje profundo.
Si desea utilizarlo instantáneamente, debe elegir Deep Learning AMI porque viene preinstalado con marcos de trabajo de aprendizaje profundo populares.
Pero si desea probar un marco de aprendizaje profundo personalizado para la investigación, debe instalar la AMI base de aprendizaje profundo porque viene con bibliotecas fundamentales como CUDA, cuDNN, controladores de GPU y otras bibliotecas necesarias para ejecutar con su entorno de aprendizaje profundo.
Cómo instalar Keras en Amazon SageMaker
Amazon SageMaker es una plataforma de aprendizaje profundo que lo ayudará a capacitar e implementar una red de aprendizaje profundo con el mejor algoritmo.
Como principiante, este es, con diferencia, el método más sencillo para utilizar Keras. A continuación se muestra un proceso sobre cómo instalar Keras en Amazon Creador de sabios:
Paso 1) Abrir Amazon SageMaker
En el primer paso, abra el Amazon Sabio consola y haga clic en Crear instancia de cuaderno.
Paso 2) Ingrese los detalles
- Ingrese el nombre de su cuaderno.
- Cree un rol de IAM. Creará un rol AMI Amazon Rol de IAM en el formato de AmazonSageMaker-función de ejecución-AAAAMMDD|HHmmSS.
- Finalmente, elija Crear instancia de cuaderno. Después de unos momentos, Amazon Sagemaker lanza una instancia de cuaderno.
Nota: :Si desea acceder a los recursos desde su VPC, configure el acceso directo a Internet como habilitado. De lo contrario, esta instancia de notebook no tendrá acceso a Internet, por lo que será imposible entrenar o alojar modelos.
Paso 3) Inicie la instancia
Haga clic en Abrir para iniciar la instancia.
Paso 4) Comience a codificar
In Jupyter, Haga clic en Nuevo> conda_tensorflow_p36 y estará listo para codificar
Instalar Keras en Linux
Para habilitar Keras con Tensorflow como motor backend, primero debemos instalar Tensorflow. Ejecute este comando para instalar tensorflow con CPU (sin GPU)
pip install --upgrade tensorflow
Si desea habilitar la compatibilidad con GPU para tensorflow, puede usar este comando
pip install --upgrade tensorflow-gpu
vamos a registrarnos Python para ver si nuestra instalación es exitosa escribiendo
user@user:~$ python Python 3.6.4 (default, Mar 20 2018, 11:10:20) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tensorflow >>>
si no hay ningún mensaje de error, el proceso de instalación es exitoso
Instalar Keras
Después de instalar Tensorflow, comencemos a instalar keras. Escriba este comando en la terminal
pip install keras
Comenzará a instalar Keras y también todas sus dependencias. Deberías ver algo como esto:
¡Ahora tenemos Keras instalado en nuestro sistema!
Verificando
Antes de comenzar a usar Keras, debemos verificar si nuestro Keras usa Tensorflow como backend abriendo el archivo de configuración:
gedit ~/.keras/keras.json
Debería ver algo como esto
{ "floatx": "float32", "epsilon": 1e-07, "backend": "tensorflow", "image_data_format": "channels_last" }
Como puede ver, el "backend" usa tensorflow. Significa que keras está usando Tensorflow como backend como esperábamos.
y ahora ejecútelo en la terminal escribiendo
user@user:~$ python3 Python 3.6.4 (default, Mar 20 2018, 11:10:20) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import keras Using TensorFlow backend. >>>
Cómo instalar Keras en Windows
Antes de instalar Flujo tensor y Keras, deberíamos instalar Python, pip y virtualenv. Si ya instalaste estas bibliotecas, debes continuar con el siguiente paso; de lo contrario, haz lo siguiente:
Instale Python 3 descargando desde este enlace
Instale pip ejecutando este vídeo
Instale virtualenv con este comando
pip3 install –U pip virtualenv
Instale Microsoft Visual C++ Actualización redistribuible 2015 de 3
- Vaya al sitio de descarga de Visual Studio https://www.microsoft.com/en-us/download/details.aspx?id=53587
- Seleccione redistribuibles y herramientas de compilación
- Descargue e instale el Microsoft Visual C++ Actualización redistribuible 2015 de 3
Luego ejecuta este script
pip3 install virtualenv
Configurar entorno virtual
Esto se utiliza para aislar el sistema de trabajo con el sistema principal.
virtualenv –-system-site-packages –p python3 ./venv
Activa el entorno
.\venv\Scripts\activate
Después de preparar el entorno, la instalación de Tensorflow y Keras sigue siendo la misma que la de Linux. A continuación, en este tutorial de Aprendizaje profundo con Keras, aprenderemos sobre los fundamentos de Keras para el aprendizaje profundo.
Fundamentos de Keras para el aprendizaje profundo
La estructura principal en Keras es el Modelo que define el gráfico completo de una red. Puede agregar más capas a un modelo existente para crear un modelo personalizado que necesite para su proyecto.
Aquí se explica cómo crear un modelo secuencial y algunas capas de uso común en el aprendizaje profundo.
1. Modelo secuencial
from keras.models import Sequential from keras.layers import Dense, Activation,Conv2D,MaxPooling2D,Flatten,Dropout model = Sequential()
2. Capa convolucional
Este es un Keras Python Ejemplo de capa convolucional como capa de entrada con la forma de entrada de 320x320x3, con 48 filtros de tamaño 3×3 y usa ReLU como función de activación.
input_shape=(320,320,3) #this is the input shape of an image 320x320x3 model.add(Conv2D(48, (3, 3), activation='relu', input_shape= input_shape))
otro tipo es
model.add(Conv2D(48, (3, 3), activation='relu'))
3. Máx.Pooling Capa
Para reducir la resolución de la representación de entrada, use MaxPool2d y especifique el tamaño del kernel
model.add(MaxPooling2D(pool_size=(2, 2)))
4. Capa densa
agregar una capa completamente conectada con solo especificar el tamaño de salida
model.add(Dense(256, activation='relu'))
5. Capa de abandono
Agregar capa de abandono con 50% de probabilidad
model.add(Dropout(0.5))
Recopilar, capacitar y evaluar
Después de definir nuestro modelo, comencemos a entrenarlos. Primero es necesario compilar la red con la función de pérdida y la función optimizadora. Esto permitirá que la red cambie de peso y minimice la pérdida.
model.compile(loss='mean_squared_error', optimizer='adam')
Ahora, para comenzar a entrenar, use fit para alimentar los datos de entrenamiento y validación al modelo. Esto le permitirá entrenar la red en lotes y establecer las épocas.
model.fit(X_train, X_train, batch_size=32, epochs=10, validation_data=(x_val, y_val))
Nuestro último paso es evaluar el modelo con los datos de prueba.
score = model.evaluate(x_test, y_test, batch_size=32)
Intentemos usar regresión lineal simple.
import keras from keras.models import Sequential from keras.layers import Dense, Activation import numpy as np import matplotlib.pyplot as plt x = data = np.linspace(1,2,200) y = x*4 + np.random.randn(*x.shape) * 0.3 model = Sequential() model.add(Dense(1, input_dim=1, activation='linear')) model.compile(optimizer='sgd', loss='mse', metrics=['mse']) weights = model.layers[0].get_weights() w_init = weights[0][0][0] b_init = weights[1][0] print('Linear regression model is initialized with weights w: %.2f, b: %.2f' % (w_init, b_init)) model.fit(x,y, batch_size=1, epochs=30, shuffle=False) weights = model.layers[0].get_weights() w_final = weights[0][0][0] b_final = weights[1][0] print('Linear regression model is trained to have weight w: %.2f, b: %.2f' % (w_final, b_final)) predict = model.predict(data) plt.plot(data, predict, 'b', data , y, 'k.') plt.show()
Después de entrenar los datos, el resultado debería verse así
con el peso inicial
Linear regression model is initialized with weights w: 0.37, b: 0.00
y peso final
Linear regression model is trained to have weight w: 3.70, b: 0.61
Ajuste de modelos previamente entrenados en Keras y cómo usarlos
Por qué usamos Fine Tune Models y cuándo lo usamos
El ajuste fino es una tarea para modificar un modelo previamente entrenado de modo que los parámetros se adapten al nuevo modelo. Cuando queremos entrenar desde cero en un nuevo modelo, necesitamos una gran cantidad de datos para que la red pueda encontrar todos los parámetros. Pero en este caso, usaremos un modelo previamente entrenado para que los parámetros ya estén aprendidos y tengan un peso.
Por ejemplo, si queremos entrenar nuestro propio modelo Keras para resolver un problema de clasificación pero solo tenemos una pequeña cantidad de datos, entonces podemos resolverlo usando un Transferir aprendizaje + Método de ajuste fino.
Al utilizar una red y pesas previamente entrenadas, no necesitamos entrenar toda la red. Sólo necesitamos entrenar la última capa que se utiliza para resolver nuestra tarea, como lo llamamos método de ajuste fino.
Preparación del modelo de red
Para el modelo previamente entrenado, podemos cargar una variedad de modelos que Keras ya tiene en su biblioteca, como por ejemplo:
- VGG16
- OrigenV3
- Resnet
- red móvil
- Xception
- InicioResNetV2
Pero en este proceso, usaremos el modelo de red VGG16 e imageNet como nuestro peso para el modelo. Ajustaremos una red para clasificar 8 tipos diferentes de clases usando imágenes de Conjunto de datos de imágenes naturales de Kaggle
Arquitectura del modelo VGG16
Carga de nuestros datos en AWS S3 Bucket
Para nuestro proceso de entrenamiento, utilizaremos una imagen de imágenes naturales de 8 clases diferentes, como aviones, automóviles, gatos, perros, flores, frutas, motocicletas y personas. Primero, necesitamos cargar nuestros datos en Amazon Cubo S3.
Amazon Cubo S3
Paso 1) Después de iniciar sesión en su cuenta S3, creemos un depósito marcando Crear cubo
Paso 2) Ahora elija un nombre de depósito y su región según su cuenta. Asegúrese de que el nombre del depósito esté disponible. Después de ese clic Crear.
Paso 3) Como puedes ver, tu Bucket está listo para usar. Pero como puedes ver, el acceso no es público, es bueno para ti si quieres mantenerlo privado. Puede cambiar este depósito para acceso público en las Propiedades del depósito
Paso 4) Ahora comienzas a cargar tus datos de entrenamiento en tu Bucket. Aquí subiré el archivo tar.gz que consta de imágenes para el proceso de capacitación y prueba.
Paso 5) Ahora haga clic en su archivo y copie el Enlace para que podamos descargarlo.
Preparación de datos
Necesitamos generar nuestros datos de entrenamiento usando Keras ImageDataGenerator.
Primero debe descargar usando wget con el enlace a su archivo desde S3 Bucket.
!wget https://s3.us-east-2.amazonaws.com/naturalimages02/images.tar.gz !tar -xzf images.tar.gz
Después de descargar los datos, comencemos el proceso de capacitación.
from keras.preprocessing.image import ImageDataGenerator import numpy as np import matplotlib.pyplot as plt train_path = 'images/train/' test_path = 'images/test/' batch_size = 16 image_size = 224 num_class = 8 train_datagen = ImageDataGenerator(validation_split=0.3, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) train_generator = train_datagen.flow_from_directory( directory=train_path, target_size=(image_size,image_size), batch_size=batch_size, class_mode='categorical', color_mode='rgb', shuffle=True)
Los datos de imagenGenerator creará un dato X_training desde un directorio. El subdirectorio de ese directorio se utilizará como clase para cada objeto. La imagen se cargará con el modo de color RGB, con el modo de clase categórica para los datos de Y_training, con un tamaño de lote de 16. Finalmente, mezcle los datos.
Veamos nuestras imágenes aleatoriamente trazándolas con matplotlib
x_batch, y_batch = train_generator.next() fig=plt.figure() columns = 4 rows = 4 for i in range(1, columns*rows): num = np.random.randint(batch_size) image = x_batch[num].astype(np.int) fig.add_subplot(rows, columns, i) plt.imshow(image) plt.show()
Después de eso, creemos nuestro modelo de red desde VGG16 con peso previamente entrenado de imageNet. Congelaremos estas capas para que no se puedan entrenar para ayudarnos a reducir el tiempo de cálculo.
Creando nuestro modelo desde VGG16
import keras from keras.models import Model, load_model from keras.layers import Activation, Dropout, Flatten, Dense from keras.preprocessing.image import ImageDataGenerator from keras.applications.vgg16 import VGG16 #Load the VGG model base_model = VGG16(weights='imagenet', include_top=False, input_shape=(image_size, image_size, 3)) print(base_model.summary()) # Freeze the layers for layer in base_model.layers: layer.trainable = False # # Create the model model = keras.models.Sequential() # # Add the vgg convolutional base model model.add(base_model) # # Add new layers model.add(Flatten()) model.add(Dense(1024, activation='relu')) model.add(Dense(1024, activation='relu')) model.add(Dense(num_class, activation='softmax')) # # Show a summary of the model. Check the number of trainable parameters print(model.summary())
Como puede ver a continuación, el resumen de nuestro modelo de red. A partir de una entrada de capas VGG16, agregamos 2 capas completamente conectadas que extraerán 1024 características y una capa de salida que calculará las 8 clases con la activación softmax.
Layer (type) Output Shape Param # ================================================================= vgg16 (Model) (None, 7, 7, 512) 14714688 _________________________________________________________________ flatten_1 (Flatten) (None, 25088) 0 _________________________________________________________________ dense_1 (Dense) (None, 1024) 25691136 _________________________________________________________________ dense_2 (Dense) (None, 1024) 1049600 _________________________________________________________________ dense_3 (Dense) (None, 8) 8200 ================================================================= Total params: 41,463,624 Trainable params: 26,748,936 Non-trainable params: 14,714,688
Formación
# # Compile the model from keras.optimizers import SGD model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=1e-3), metrics=['accuracy']) # # Start the training process # model.fit(x_train, y_train, validation_split=0.30, batch_size=32, epochs=50, verbose=2) # # #save the model # model.save('catdog.h5') history = model.fit_generator( train_generator, steps_per_epoch=train_generator.n/batch_size, epochs=10) model.save('fine_tune.h5') # summarize history for accuracy import matplotlib.pyplot as plt plt.plot(history.history['loss']) plt.title('loss') plt.ylabel('loss') plt.xlabel('epoch') plt.legend(['loss'], loc='upper left') plt.show()
Resultados
Epoch 1/10 432/431 [==============================] - 53s 123ms/step - loss: 0.5524 - acc: 0.9474 Epoch 2/10 432/431 [==============================] - 52s 119ms/step - loss: 0.1571 - acc: 0.9831 Epoch 3/10 432/431 [==============================] - 51s 119ms/step - loss: 0.1087 - acc: 0.9871 Epoch 4/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0624 - acc: 0.9926 Epoch 5/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0591 - acc: 0.9938 Epoch 6/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0498 - acc: 0.9936 Epoch 7/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0403 - acc: 0.9958 Epoch 8/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0248 - acc: 0.9959 Epoch 9/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0466 - acc: 0.9942 Epoch 10/10 432/431 [==============================] - 52s 120ms/step - loss: 0.0338 - acc: 0.9947
Como puede ver, nuestras pérdidas se reducen significativamente y la precisión es casi del 100%. Para probar nuestro modelo, seleccionamos imágenes al azar en Internet y las colocamos en la carpeta de prueba con una clase diferente para probar.
Probando nuestro modelo
model = load_model('fine_tune.h5') test_datagen = ImageDataGenerator() train_generator = train_datagen.flow_from_directory( directory=train_path, target_size=(image_size,image_size), batch_size=batch_size, class_mode='categorical', color_mode='rgb', shuffle=True) test_generator = test_datagen.flow_from_directory( directory=test_path, target_size=(image_size, image_size), color_mode='rgb', shuffle=False, class_mode='categorical', batch_size=1) filenames = test_generator.filenames nb_samples = len(filenames) fig=plt.figure() columns = 4 rows = 4 for i in range(1, columns*rows -1): x_batch, y_batch = test_generator.next() name = model.predict(x_batch) name = np.argmax(name, axis=-1) true_name = y_batch true_name = np.argmax(true_name, axis=-1) label_map = (test_generator.class_indices) label_map = dict((v,k) for k,v in label_map.items()) #flip k,v predictions = [label_map[k] for k in name] true_value = [label_map[k] for k in true_name] image = x_batch[0].astype(np.int) fig.add_subplot(rows, columns, i) plt.title(str(predictions[0]) + ':' + str(true_value[0])) plt.imshow(image) plt.show()
¡Y nuestra prueba es la que se muestra a continuación! ¡Solo 1 imagen se predice incorrectamente en una prueba de 14 imágenes!
Red neuronal de reconocimiento facial con Keras
Por qué necesitamos reconocimiento
Necesitamos Reconocimiento para que nos resulte más fácil reconocer o identificar el rostro de una persona, el tipo de objetos, la edad estimada de una persona a partir de su rostro o incluso conocer las expresiones faciales de esa persona.
Tal vez te des cuenta de que cada vez que intentas marcar la cara de tu amigo en una foto, la función de Facebook lo ha hecho por ti, es decir, marcar la cara de tu amigo sin que tengas que marcarla primero. Se trata del Reconocimiento Facial que aplica Facebook para que nos resulte más fácil etiquetar amigos.
¿Entonces, cómo funciona? Cada vez que marcamos la cara de nuestro amigo, la IA de Facebook lo aprenderá e intentará predecirlo hasta obtener el resultado correcto. El mismo sistema que usaremos para realizar nuestro propio Reconocimiento Facial. Comencemos a hacer nuestro propio reconocimiento facial usando Deep Learning
modelo de red
Usaremos un modelo de red VGG16 pero con peso VGGFace.
Arquitectura del modelo VGG16
¿Qué es VGGFace? Es una implementación de Keras del reconocimiento facial profundo introducido por Parkhi, Omkar M. et al. “Deep Face Recognition”. BMVC (2015). El marco utiliza VGG16 como arquitectura de red.
Puede descargar VGGFace desde gitHub
from keras.applications.vgg16 import VGG16 from keras_vggface.vggface import VGGFace face_model = VGGFace(model='vgg16', weights='vggface', input_shape=(224,224,3)) face_model.summary()
Como puedes ver el resumen de la red.
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) (None, 224, 224, 3) 0 _________________________________________________________________ conv1_1 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ conv1_2 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ pool1 (MaxPooling2D) (None, 112, 112, 64) 0 _________________________________________________________________ conv2_1 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________ conv2_2 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________ pool2 (MaxPooling2D) (None, 56, 56, 128) 0 _________________________________________________________________ conv3_1 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ conv3_2 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ conv3_3 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ pool3 (MaxPooling2D) (None, 28, 28, 256) 0 _________________________________________________________________ conv4_1 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ conv4_2 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ conv4_3 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ pool4 (MaxPooling2D) (None, 14, 14, 512) 0 _________________________________________________________________ conv5_1 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ conv5_2 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ conv5_3 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ pool5 (MaxPooling2D) (None, 7, 7, 512) 0 _________________________________________________________________ flatten (Flatten) (None, 25088) 0 _________________________________________________________________ fc6 (Dense) (None, 4096) 102764544 _________________________________________________________________ fc6/relu (Activation) (None, 4096) 0 _________________________________________________________________ fc7 (Dense) (None, 4096) 16781312 _________________________________________________________________ fc7/relu (Activation) (None, 4096) 0 _________________________________________________________________ fc8 (Dense) (None, 2622) 10742334 _________________________________________________________________ fc8/softmax (Activation) (None, 2622) 0 ================================================================= Total params: 145,002,878 Trainable params: 145,002,878 Non-trainable params: 0 _________________________________________________________________ Traceback (most recent call last):
haremos un Transferir aprendizaje + Ajuste fino para agilizar el entrenamiento con pequeños conjuntos de datos. Primero, congelaremos las capas base para que no se puedan entrenar.
for layer in face_model.layers: layer.trainable = False
luego agregamos nuestra propia capa para reconocer nuestras caras de prueba. Agregaremos 2 capas completamente conectadas y una capa de salida con 5 personas para detectar.
from keras.models import Model, Sequential from keras.layers import Input, Convolution2D, ZeroPadding2D, MaxPooling2D, Flatten, Dense, Dropout, Activation person_count = 5 last_layer = face_model.get_layer('pool5').output x = Flatten(name='flatten')(last_layer) x = Dense(1024, activation='relu', name='fc6')(x) x = Dense(1024, activation='relu', name='fc7')(x) out = Dense(person_count, activation='softmax', name='fc8')(x) custom_face = Model(face_model.input, out)
Veamos nuestro resumen de red.
Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) (None, 224, 224, 3) 0 _________________________________________________________________ conv1_1 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ conv1_2 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ pool1 (MaxPooling2D) (None, 112, 112, 64) 0 _________________________________________________________________ conv2_1 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________ conv2_2 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________ pool2 (MaxPooling2D) (None, 56, 56, 128) 0 _________________________________________________________________ conv3_1 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ conv3_2 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ conv3_3 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ pool3 (MaxPooling2D) (None, 28, 28, 256) 0 _________________________________________________________________ conv4_1 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ conv4_2 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ conv4_3 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ pool4 (MaxPooling2D) (None, 14, 14, 512) 0 _________________________________________________________________ conv5_1 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ conv5_2 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ conv5_3 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ pool5 (MaxPooling2D) (None, 7, 7, 512) 0 _________________________________________________________________ flatten (Flatten) (None, 25088) 0 _________________________________________________________________ fc6 (Dense) (None, 1024) 25691136 _________________________________________________________________ fc7 (Dense) (None, 1024) 1049600 _________________________________________________________________ fc8 (Dense) (None, 5) 5125 ================================================================= Total params: 41,460,549 Trainable params: 26,745,861 Non-trainable params: 14,714,688
Como puede ver arriba, después de la capa pool5, se aplanará en un único vector de características que será utilizado por la capa densa para el reconocimiento final.
Preparando nuestras caras
Ahora preparemos nuestras caras. Hice un directorio formado por 5 personajes famosos.
- Jack Ma
- Jason Statham
- Johnny Depp
- Robert Downey Jr
- Rowan Atkinson
Cada carpeta contiene 10 fotografías, para cada proceso de formación y evaluación. Es una cantidad muy pequeña de datos pero ese es el desafío, ¿verdad?
Usaremos la ayuda de la herramienta Keras para ayudarnos a preparar los datos. Esta función se repetirá en la carpeta del conjunto de datos y luego la preparará para que pueda usarse en la capacitación.
from keras.preprocessing.image import ImageDataGenerator batch_size = 5 train_path = 'data/' eval_path = 'eval/' train_datagen = ImageDataGenerator(rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) valid_datagen = ImageDataGenerator(rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) train_generator = train_datagen.flow_from_directory( train_path, target_size=(image_size,image_size), batch_size=batch_size, class_mode='sparse', color_mode='rgb') valid_generator = valid_datagen.flow_from_directory( directory=eval_path, target_size=(224, 224), color_mode='rgb', batch_size=batch_size, class_mode='sparse', shuffle=True, )
Entrenando nuestro modelo
Comencemos nuestro proceso de capacitación compilando nuestra red con función de pérdida y optimizador. Aquí usamos sparse_categorical_crossentropy como nuestra función de pérdida, con la ayuda de SGD como nuestro optimizador de aprendizaje.
from keras.optimizers import SGD custom_face.compile(loss='sparse_categorical_crossentropy', optimizer=SGD(lr=1e-4, momentum=0.9), metrics=['accuracy']) history = custom_face.fit_generator( train_generator, validation_data=valid_generator, steps_per_epoch=49/batch_size, validation_steps=valid_generator.n, epochs=50) custom_face.evaluate_generator(generator=valid_generator) custom_face.save('vgg_face.h5') Epoch 25/50 10/9 [==============================] - 60s 6s/step - loss: 1.4882 - acc: 0.8998 - val_loss: 1.5659 - val_acc: 0.5851 Epoch 26/50 10/9 [==============================] - 59s 6s/step - loss: 1.4882 - acc: 0.8998 - val_loss: 1.5638 - val_acc: 0.5809 Epoch 27/50 10/9 [==============================] - 60s 6s/step - loss: 1.4779 - acc: 0.8597 - val_loss: 1.5613 - val_acc: 0.5477 Epoch 28/50 10/9 [==============================] - 60s 6s/step - loss: 1.4755 - acc: 0.9199 - val_loss: 1.5576 - val_acc: 0.5809 Epoch 29/50 10/9 [==============================] - 60s 6s/step - loss: 1.4794 - acc: 0.9153 - val_loss: 1.5531 - val_acc: 0.5892 Epoch 30/50 10/9 [==============================] - 60s 6s/step - loss: 1.4714 - acc: 0.8953 - val_loss: 1.5510 - val_acc: 0.6017 Epoch 31/50 10/9 [==============================] - 60s 6s/step - loss: 1.4552 - acc: 0.9199 - val_loss: 1.5509 - val_acc: 0.5809 Epoch 32/50 10/9 [==============================] - 60s 6s/step - loss: 1.4504 - acc: 0.9199 - val_loss: 1.5492 - val_acc: 0.5975 Epoch 33/50 10/9 [==============================] - 60s 6s/step - loss: 1.4497 - acc: 0.8998 - val_loss: 1.5490 - val_acc: 0.5851 Epoch 34/50 10/9 [==============================] - 60s 6s/step - loss: 1.4453 - acc: 0.9399 - val_loss: 1.5529 - val_acc: 0.5643 Epoch 35/50 10/9 [==============================] - 60s 6s/step - loss: 1.4399 - acc: 0.9599 - val_loss: 1.5451 - val_acc: 0.5768 Epoch 36/50 10/9 [==============================] - 60s 6s/step - loss: 1.4373 - acc: 0.8998 - val_loss: 1.5424 - val_acc: 0.5768 Epoch 37/50 10/9 [==============================] - 60s 6s/step - loss: 1.4231 - acc: 0.9199 - val_loss: 1.5389 - val_acc: 0.6183 Epoch 38/50 10/9 [==============================] - 59s 6s/step - loss: 1.4247 - acc: 0.9199 - val_loss: 1.5372 - val_acc: 0.5934 Epoch 39/50 10/9 [==============================] - 60s 6s/step - loss: 1.4153 - acc: 0.9399 - val_loss: 1.5406 - val_acc: 0.5560 Epoch 40/50 10/9 [==============================] - 60s 6s/step - loss: 1.4074 - acc: 0.9800 - val_loss: 1.5327 - val_acc: 0.6224 Epoch 41/50 10/9 [==============================] - 60s 6s/step - loss: 1.4023 - acc: 0.9800 - val_loss: 1.5305 - val_acc: 0.6100 Epoch 42/50 10/9 [==============================] - 59s 6s/step - loss: 1.3938 - acc: 0.9800 - val_loss: 1.5269 - val_acc: 0.5975 Epoch 43/50 10/9 [==============================] - 60s 6s/step - loss: 1.3897 - acc: 0.9599 - val_loss: 1.5234 - val_acc: 0.6432 Epoch 44/50 10/9 [==============================] - 60s 6s/step - loss: 1.3828 - acc: 0.9800 - val_loss: 1.5210 - val_acc: 0.6556 Epoch 45/50 10/9 [==============================] - 59s 6s/step - loss: 1.3848 - acc: 0.9599 - val_loss: 1.5234 - val_acc: 0.5975 Epoch 46/50 10/9 [==============================] - 60s 6s/step - loss: 1.3716 - acc: 0.9800 - val_loss: 1.5216 - val_acc: 0.6432 Epoch 47/50 10/9 [==============================] - 60s 6s/step - loss: 1.3721 - acc: 0.9800 - val_loss: 1.5195 - val_acc: 0.6266 Epoch 48/50 10/9 [==============================] - 60s 6s/step - loss: 1.3622 - acc: 0.9599 - val_loss: 1.5108 - val_acc: 0.6141 Epoch 49/50 10/9 [==============================] - 60s 6s/step - loss: 1.3452 - acc: 0.9399 - val_loss: 1.5140 - val_acc: 0.6432 Epoch 50/50 10/9 [==============================] - 60s 6s/step - loss: 1.3387 - acc: 0.9599 - val_loss: 1.5100 - val_acc: 0.6266
Como puede ver, nuestra precisión de validación es de hasta el 64%, este es un buen resultado para una pequeña cantidad de datos de entrenamiento. Podemos mejorar esto agregando más capas o agregando más imágenes de entrenamiento para que nuestro modelo pueda aprender más sobre las caras y lograr más precisión.
Probemos nuestro modelo con una imagen de prueba.
from keras.models import load_model from keras.preprocessing.image import load_img, save_img, img_to_array from keras_vggface.utils import preprocess_input test_img = image.load_img('test.jpg', target_size=(224, 224)) img_test = image.img_to_array(test_img) img_test = np.expand_dims(img_test, axis=0) img_test = utils.preprocess_input(img_test) predictions = model.predict(img_test) predicted_class=np.argmax(predictions,axis=1) labels = (train_generator.class_indices) labels = dict((v,k) for k,v in labels.items()) predictions = [labels[k] for k in predicted_class] print(predictions) ['RobertDJr']
Usando la imagen de Robert Downey Jr. como nuestra imagen de prueba, ¡muestra que la cara predicha es cierta!
Predicción usando Live Cam!
¿Qué tal si ponemos a prueba nuestra habilidad para implementarlo con una entrada de una cámara web? Usando OpenCV con la cascada Haar Face para encontrar nuestra cara y con la ayuda de nuestro modelo de red, podemos reconocer a la persona.
El primer paso es preparar tus rostros y los de tus amigos. ¡Cuantos más datos tengamos, mejor será el resultado!
Prepare y entrene su red como en el paso anterior. Una vez completado el entrenamiento, agregue esta línea para obtener la imagen de entrada de la cámara.
#Load trained model from keras.models import load_model from keras_vggface import utils import cv2 image_size = 224 device_id = 0 #camera_device id model = load_model('my faces.h5') #make labels according to your dataset folder labels = dict(fisrtname=0,secondname=1) #and so on print(labels) cascade_classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') camera = cv2.VideoCapture(device_id) while camera.isOpened(): ok, cam_frame = camera.read() if not ok: break gray_img=cv2.cvtColor(cam_frame, cv2.COLOR_BGR2GRAY) faces= cascade_classifier.detectMultiScale(gray_img, minNeighbors=5) for (x,y,w,h) in faces: cv2.rectangle(cam_frame,(x,y),(x+w,y+h),(255,255,0),2) roi_color = cam_frame [y:y+h, x:x+w] roi color = cv2.cvtColor(roi_color, cv2.COLOR_BGR2RGB) roi_color = cv2.resize(roi_color, (image_size, image_size)) image = roi_color.astype(np.float32, copy=False) image = np.expand_dims(image, axis=0) image = preprocess_input(image, version=1) # or version=2 preds = model.predict(image) predicted_class=np.argmax(preds,axis=1) labels = dict((v,k) for k,v in labels.items()) name = [labels[k] for k in predicted_class] cv2.putText(cam_frame,str(name), (x + 10, y + 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,255), 2) cv2.imshow('video image', cam_frame) key = cv2.waitKey(30) if key == 27: # press 'ESC' to quit break camera.release() cv2.destroyAllWindows()
¿Cuál es mejor? Keras o Tensorflow
Keras ofrece sencillez a la hora de escribir el guión. Podemos empezar a escribir y comprender directamente con Keras, ya que no es demasiado difícil de entender. Es más fácil de usar y de implementar, no es necesario crear muchas variables para ejecutar el modelo. Por lo tanto, no necesitamos comprender todos los detalles del proceso de backend.
Por otro lado, Tensorflow es el de operaciones de bajo nivel que ofrece flexibilidad y operaciones avanzadas si desea realizar un gráfico o modelo computacional arbitrario. Tensorflow también puede visualizar el proceso con la ayuda de TensorTablero y una herramienta de depuración especializada.
Por lo tanto, si desea comenzar a trabajar con aprendizaje profundo sin tanta complejidad, utilice Keras, ya que ofrece simplicidad y es más fácil de usar e implementar que Tensorflow. Pero si desea escribir su propio algoritmo en un proyecto o investigación de aprendizaje profundo, debería utilizar Tensorflow.
Resumen
Así que vamos a resumir todo lo que hemos discutido y hecho en este tutorial.
- Keras en una API de alto nivel que se utiliza para facilitar las redes de aprendizaje profundo con la ayuda del motor backend.
- Keras es fácil de usar y comprender con soporte de Python, por lo que se siente más natural que nunca. Es bueno para principiantes que quieran aprender sobre aprendizaje profundo y para investigadores que quieran una API fácil de usar.
- El proceso de instalación es sencillo y puede utilizar un entorno virtual o utilizar una plataforma externa como AWS.
- Keras también viene con varios tipos de modelos de red, por lo que nos facilita el uso del modelo disponible para entrenar previamente y ajustar nuestro propio modelo de red.
- Además, hay muchos tutoriales y artículos sobre el uso de Keras de códigos de comunidades de todo el mundo con fines de aprendizaje profundo.