sábado, 4 de enero de 2020

Instalar Keras y TensorFlow. Sistema de reconocimiento de imágenes

Keras y TensorFlow


Keras es una biblioteca de redes neuronales de alto nivel que sirve como una capa de abstracción fácil de usar sobre la biblioteca TensorFlow. 

Creamos un environment del mismo nombre en anaconda.

Anaconda navigator


Casi todos los comandos los vamos a lanzar desde la consola de comandos de anaconda.

Como abrir el editor de comandos de anaconda

Una vez abierta la consola instalamos tensorflow siguiendo las instrucciones. Para instalar tensorFlow:  https://www.tensorflow.org/install/

Antes de nada, habilitamos el comando pip con: python –m pip install –V pip


Instalamos tensorflow con pip3 install –upgrade tensorflow


La versión 1,6 de tensorflow dio error, por lo que tuvimos que desinstalarla e instalar la versión 1.5

Pip unisntall tensorflow
Pip uninstall protobuf
Activate tensorflow
Pip install –ignore-installed –upgrade tensorflow

Desinstalar tensorflow 1.6 para instalar la versión 1.5


Instalamos la versión 1.5 Pip install tensorflow ==1.5
  
Instalar versión 1.5 de TensorFlow


Para comprobar que la instalación es correcta entramos en la consola de python 

Python
Import tensorflow as tf

Hello = tf.constant(‘Hello, Tensorflow!’)
Sess = tf.Session()
Print(sess.run(hello))

Y nos debe mostrar el mensaje Hello Tensorflow!.

Comprobar que TensoFlow está correctamente instalado


Una vez instalado tensorflow continuamos con la instalación de Keras.

Instalación de Keras Desde la consola de anaconda ponemos: 
pip install keras

Instalar Keras


Abrimos la consola de Python  e importamos Keras

Python
Import keras

Import Keras


Y salimos de la consola de python con quit()

Salir de la consola de Python

Ahora traemos del github (ver enlace más adelante) el programa clasify.py y lo alojamos en un directorio de nuestro equipo.

Llamamos al programa con python clasify.py [imagen] 
python classify.py --image_url 


Ejecutar un programa de IA

Nos muestra un editor de imágenes con la imagen indicada

Editor de imágenes de Python


Y otra pantalla con las etiquetas de la imagen

Etiquetado automático de imágenes


Para etiquetar una imagen alojada en nuestro equipo, nos colocamos en el directorio donde se encuentra y  hacemos:

Python classify.py –image [nombre_imagen]
Python classify.py –image African_Bush_Elephant.jpg

llamada a una imagen del equipo

Implementacion


Nuestro objetivo final es escribir un pequeño programa python con un argumento  que será la ruta a un archivo local o  una URL a una imagen. 

Prediction function

Para empezar, cargamos los módulos keras.preprocessing y keras.applications.resnet50  y el modelo ResNet50 

from keras.preprocessing import image
from keras.applications.resnet50 import ResNet50, preprocess_input, decode_predictions
model = ResNet50(weights='imagenet')
Then we can define a predict function:

def predict(model, img, target_size, top_n=3):
  """Run model prediction on image
  Args:
    model: keras model
    img: PIL format image
    target_size: (width, height) tuple
    top_n: # of top predictions to return
  Returns:
    list of predicted labels and their probabilities
  """
  if img.size != target_size:
    img = img.resize(target_size)
  x = image.img_to_array(img)
  x = np.expand_dims(x, axis=0)
  x = preprocess_input(x)
  preds = model.predict(x)
  return decode_predictions(preds, top=top_n)[0]

Para usar la arquitectura ResNet50, target_size debe ser igual a (224, 224). Muchas arquitecturas tienen un tamaño de entrada fijo y ResNet50 es de este tipo. Si quisiéramos, podríamos clasificar múltiples imágenes a la vez.

preprocess_input: 

Pone a cero nuestros datos de imagen utilizando los valores medios del canal del conjunto de datos de entrenamiento. Este es un paso extremadamente importante que, si se salta, hará que todas las probabilidades predichas sean incorrectas. Este centrado medio es lo que se llama normalización de datos, un concepto fundamental en el aprendizaje automático.

model.predict: 

ejecuta la inferencia en nuestro lote de datos y devuelve las predicciones

decode_predictions

Toma las etiquetas codificadas asociadas con model.predictand devuelve etiquetas legibles por humanos del conjunto ILSVRC de ImageNet.

El módulo keras.applications proporciona 4 arquitecturas listas para usar: ResNet50, InceptionV3, VGG16, VGG19, XCeption. Seleccionamos arbitrariamente ResNet50, pero somos libres de cambiarlo con cualquiera de las otras arquitecturas listas para usar. 

Mostrando las imagines y los gráficos

Podemos usar matplotlib para imprimir el resultado en un gráfico de barras horizontales de esta manera:

def plot_preds(image, preds):  
  """Displays image and the top-n predicted probabilities 
     in a bar graph  
  Args:    
    image: PIL image
    preds: list of predicted labels and their probabilities  
  """  
  #image
  plt.imshow(image)
  plt.axis('off')
  
  #bar graph
  plt.figure()  
  order = list(reversed(range(len(preds))))  
  bar_preds = [pr[2] for pr in preds]
  labels = (pr[1] for pr in preds)
  plt.barh(order, bar_preds, alpha=0.5)
  plt.yticks(order, labels)
  plt.xlabel('Probability')
  plt.xlim(0, 1.01)
  plt.tight_layout()
  plt.show()

Función principal 

Definimos la función principal de este modo:

if __name__=="__main__":
  a = argparse.ArgumentParser()
  a.add_argument("--image", help="path to image")
  a.add_argument("--image_url", help="url to image")
  args = a.parse_args()
if args.image is None and args.image_url is None:
    a.print_help()
    sys.exit(1)
if args.image is not None:
    img = Image.open(args.image)
    plot_preds(predict(model, img, target_size))
if args.image_url is not None:
    response = requests.get(args.image_url)
    img = Image.open(BytesIO(response.content))
    plot_preds(predict(model, img, target_size))

En esta línea le podemos deir el nº de etiquetas a generar

def predict(model, img, target_size, top_n=30)

Para etiquetar fotos del equipo, nos situamos en el directorio donde está la foto y ponemos: 

python classify.py –image African_Bush_elephant.jpg

Programa completo 

Una vez que unimos todo el código anterior, tendremos  el inicio de un sistema de reconocimiento de imágenes. El programa completo y las imágenes de ejemplo se pueden descargar  aquí.

import sys
import argparse
import numpy as np
from PIL import Image
import requests
from io import BytesIO
import matplotlib.pyplot as plt

from keras.preprocessing import image
from keras.applications.resnet50 import ResNet50, preprocess_input, decode_predictions

model = ResNet50(weights='imagenet')
target_size = (224, 224)

def predict(model, img, target_size, top_n=3):
  """Run model prediction on image
  Args:
    model: keras model
    img: PIL format image
    target_size: (w,h) tuple
    top_n: # of top predictions to return
  Returns:
    list of predicted labels and their probabilities
  """
  if img.size != target_size:
    img = img.resize(target_size)

  x = image.img_to_array(img)
  x = np.expand_dims(x, axis=0)
  x = preprocess_input(x)
  preds = model.predict(x)
  return decode_predictions(preds, top=top_n)[0]

def plot_preds(image, preds):
  """Displays image and the top-n predicted probabilities in a bar graph
  Args:
    image: PIL image
    preds: list of predicted labels and their probabilities
  """
  plt.imshow(image)
  plt.axis('off')

  plt.figure()
  order = list(reversed(range(len(preds))))
  bar_preds = [pr[2] for pr in preds]
  labels = (pr[1] for pr in preds)
  plt.barh(order, bar_preds, alpha=0.5)
  plt.yticks(order, labels)
  plt.xlabel('Probability')
  plt.xlim(0,1.01)
  plt.tight_layout()
  plt.show()

if __name__=="__main__":
  a = argparse.ArgumentParser()
  a.add_argument("--image", help="path to image")
  a.add_argument("--image_url", help="url to image")
  args = a.parse_args()

  if args.image is None and args.image_url is None:
    a.print_help()
    sys.exit(1)

  if args.image is not None:
    img = Image.open(args.image)
    preds = predict(model, img, target_size)
    plot_preds(img, preds)

  if args.image_url is not None:
    response = requests.get(args.image_url)
    img = Image.open(BytesIO(response.content))
    preds = predict(model, img, target_size)
    plot_preds(img, preds)



No hay comentarios:

Publicar un comentario