Caffe2 - Guía rápida

En los últimos años, Deep Learning se ha convertido en una gran tendencia en Machine Learning. Se ha aplicado con éxito para resolver problemas previamente insolubles en Vision, Speech Recognition and Natural Language Processing(PNL). Hay muchos más dominios en los que se está aplicando el Deep Learning y ha demostrado su utilidad.

Caffe (Convolutional Architecture for Fast Feature Embedding) es un marco de aprendizaje profundo desarrollado en Berkeley Vision and Learning Center (BVLC). El proyecto Caffe fue creado por Yangqing Jia durante su Ph.D. en la Universidad de California - Berkeley. Caffe ofrece una forma sencilla de experimentar con el aprendizaje profundo. Está escrito en C ++ y proporciona enlaces paraPython y Matlab.

Es compatible con muchos tipos diferentes de arquitecturas de aprendizaje profundo, como CNN (Red neuronal convolucional), LSTM(Memoria a corto plazo) y FC (Completamente conectado). Es compatible con GPU y, por lo tanto, es ideal para entornos de producción que involucran redes neuronales profundas. También es compatible con bibliotecas de kernel basadas en CPU comoNVIDIA, Biblioteca CUDA Deep Neural Network (cuDNN) e Intel Math Kernel Library (Intel MKL).

En abril de 2017, la empresa de servicios de redes sociales con sede en EE. UU. Facebook anunció Caffe2, que ahora incluye RNN (redes neuronales recurrentes) y en marzo de 2018, Caffe2 se fusionó con PyTorch. Los creadores de Caffe2 y los miembros de la comunidad han creado modelos para resolver varios problemas. Estos modelos están disponibles para el público como modelos previamente entrenados. Caffe2 ayuda a los creadores a utilizar estos modelos y a crear su propia red para realizar predicciones sobre el conjunto de datos.

Antes de entrar en los detalles de Caffe2, comprendamos la diferencia entre machine learning y deep learning. Esto es necesario para comprender cómo se crean y utilizan los modelos en Caffe2.

Aprendizaje automático frente a aprendizaje profundo

En cualquier algoritmo de aprendizaje automático, ya sea tradicional o de aprendizaje profundo, la selección de características en el conjunto de datos juega un papel extremadamente importante para obtener la precisión de predicción deseada. En las técnicas tradicionales de aprendizaje automático,feature selectionse realiza principalmente mediante inspección humana, juicio y conocimiento de dominio profundo. A veces, puede buscar ayuda de algunos algoritmos probados para la selección de funciones.

El flujo de aprendizaje automático tradicional se muestra en la siguiente figura:

En el aprendizaje profundo, la selección de funciones es automática y es parte del propio algoritmo de aprendizaje profundo. Esto se muestra en la siguiente figura:

En algoritmos de aprendizaje profundo, feature engineeringse hace automáticamente. Generalmente, la ingeniería de características requiere mucho tiempo y requiere una buena experiencia en el dominio. Para implementar la extracción automática de características, los algoritmos de aprendizaje profundo generalmente solicitan una gran cantidad de datos, por lo que si solo tiene miles y decenas de miles de puntos de datos, la técnica de aprendizaje profundo puede no brindarle resultados satisfactorios.

Con datos más grandes, los algoritmos de aprendizaje profundo producen mejores resultados en comparación con los algoritmos ML tradicionales con la ventaja adicional de que hay menos o ninguna ingeniería de funciones.

Ahora, ya que tiene algunas ideas sobre el aprendizaje profundo, permítanos obtener una descripción general de lo que es Caffe.

Entrenando una CNN

Aprendamos el proceso de entrenamiento de una CNN para clasificar imágenes. El proceso consta de los siguientes pasos:

  • Data Preparation- En este paso, recortamos en el centro las imágenes y las redimensionamos para que todas las imágenes para entrenamiento y prueba tengan el mismo tamaño. Esto generalmente se hace ejecutando una pequeña secuencia de comandos de Python en los datos de la imagen.

  • Model Definition- En este paso, definimos una arquitectura CNN. La configuración se almacena en.pb (protobuf)archivo. En la siguiente figura se muestra una arquitectura típica de CNN.

  • Solver Definition- Definimos el archivo de configuración del solucionador. Solver realiza la optimización del modelo.

  • Model Training- Usamos la utilidad Caffe incorporada para entrenar el modelo. El entrenamiento puede llevar una cantidad considerable de tiempo y uso de CPU. Una vez que se completa la capacitación, Caffe almacena el modelo en un archivo, que luego se puede usar en los datos de prueba y la implementación final para las predicciones.

Novedades de Caffe2

En Caffe2, encontrará muchos modelos pre-entrenados listos para usar y también aprovechar las contribuciones de la comunidad de nuevos modelos y algoritmos con bastante frecuencia. Los modelos que cree se pueden escalar fácilmente utilizando la potencia de la GPU en la nube y también se pueden reducir al uso de masas en dispositivos móviles con sus bibliotecas multiplataforma.

Las mejoras realizadas en Caffe2 sobre Caffe se pueden resumir de la siguiente manera:

  • Despliegue móvil
  • Nuevo soporte de hardware
  • Soporte para capacitación distribuida a gran escala
  • Computación cuantificada
  • Prueba de estrés en Facebook

Demostración de modelo previamente entrenado

El sitio del Berkeley Vision and Learning Center (BVLC) ofrece demostraciones de sus redes previamente capacitadas. Una red de este tipo para la clasificación de imágenes está disponible en el enlace adjunto.https://caffe2.ai/docs/learn-more#null__caffe-neural-network-for-image-classification y se muestra en la captura de pantalla a continuación.

En la captura de pantalla, la imagen de un perro está clasificada y etiquetada con su precisión de predicción. También dice que tomó solo0.068 secondspara clasificar la imagen. Puede probar una imagen de su elección especificando la URL de la imagen o subiendo la imagen en las opciones que se encuentran en la parte inferior de la pantalla.

Ahora que tiene suficientes conocimientos sobre las capacidades de Caffe2, es hora de experimentar Caffe2 por su cuenta. Para usar los modelos previamente entrenados o para desarrollar sus modelos en su propio código Python, primero debe instalar Caffe2 en su máquina.

En la página de instalación del sitio Caffe2 que está disponible en el enlace https://caffe2.ai/docs/getting-started.html Verá lo siguiente para seleccionar su plataforma y tipo de instalación.

Como puede ver en la captura de pantalla anterior, Caffe2 admite varias plataformas populares, incluidas las móviles.

Ahora, entenderemos los pasos para MacOS installation en el que se prueban todos los proyectos de este tutorial.

Instalación de MacOS

La instalación puede ser de cuatro tipos como se indica a continuación:

  • Binarios prediseñados
  • Construir a partir de la fuente
  • Imágenes de Docker
  • Cloud

Dependiendo de su preferencia, seleccione cualquiera de los anteriores como su tipo de instalación. Las instrucciones que se dan aquí corresponden al sitio de instalación de Caffe2 parapre-built binaries. Utiliza Anaconda paraJupyter environment. Ejecute el siguiente comando en el indicador de su consola

pip install torch_nightly -f 
https://download.pytorch.org/whl/nightly/cpu/torch_nightly.html

Además de lo anterior, necesitará algunas bibliotecas de terceros, que se instalan mediante los siguientes comandos:

conda install -c anaconda setuptools
conda install -c conda-forge graphviz  
conda install -c conda-forge hypothesis
conda install -c conda-forge ipython
conda install -c conda-forge jupyter
conda install -c conda-forge matplotlib
conda install -c anaconda notebook
conda install -c anaconda pydot
conda install -c conda-forge python-nvd3
conda install -c anaconda pyyaml
conda install -c anaconda requests
conda install -c anaconda scikit-image
conda install -c anaconda scipy

Algunos de los tutoriales del sitio web de Caffe2 también requieren la instalación de zeromq, que se instala con el siguiente comando:

conda install -c anaconda zeromq

Instalación de Windows / Linux

Ejecute el siguiente comando en el indicador de su consola:

conda install -c pytorch pytorch-nightly-cpu

Como debe haber notado, necesitaría Anaconda para usar la instalación anterior. Deberá instalar los paquetes adicionales como se especifica en elMacOS installation.

Prueba de instalación

Para probar su instalación, a continuación se proporciona una pequeña secuencia de comandos de Python, que puede cortar y pegar en su proyecto Juypter y ejecutar.

from caffe2.python import workspace
import numpy as np
print ("Creating random data")
data = np.random.rand(3, 2)
print(data)
print ("Adding data to workspace ...")
workspace.FeedBlob("mydata", data)
print ("Retrieving data from workspace")
mydata = workspace.FetchBlob("mydata")
print(mydata)

Cuando ejecute el código anterior, debería ver el siguiente resultado:

Creating random data
[[0.06152718 0.86448082]
[0.36409966 0.52786113]
[0.65780886 0.67101053]]
Adding data to workspace ...
Retrieving data from workspace
[[0.06152718 0.86448082]
[0.36409966 0.52786113]
[0.65780886 0.67101053]]

La captura de pantalla de la página de prueba de instalación se muestra aquí para su referencia rápida:

Ahora que ha instalado Caffe2 en su máquina, proceda a instalar las aplicaciones del tutorial.

Instalación del tutorial

Descargue la fuente de los tutoriales usando el siguiente comando en su consola:

git clone --recursive https://github.com/caffe2/tutorials caffe2_tutorials

Una vez completada la descarga, encontrará varios proyectos de Python en el caffe2_tutorialscarpeta en su directorio de instalación. La captura de pantalla de esta carpeta se proporciona para su rápida lectura.

/Users/yourusername/caffe2_tutorials

Puede abrir algunos de estos tutoriales para ver qué Caffe2 codeparece. Los siguientes dos proyectos descritos en este tutorial se basan en gran medida en los ejemplos que se muestran arriba.

Ahora es el momento de hacer nuestra propia codificación en Python. Entendamos cómo utilizar un modelo previamente entrenado de Caffe2. Más adelante, aprenderá a crear su propia red neuronal trivial para entrenar en su propio conjunto de datos.

Antes de que aprenda a usar un modelo previamente entrenado en su aplicación Python, primero verifiquemos que los modelos estén instalados en su máquina y que sean accesibles a través del código Python.

Cuando instala Caffe2, los modelos entrenados previamente se copian en la carpeta de instalación. En la máquina con instalación de Anaconda, estos modelos están disponibles en la siguiente carpeta.

anaconda3/lib/python3.7/site-packages/caffe2/python/models

Consulte la carpeta de instalación en su máquina para ver la presencia de estos modelos. Puede intentar cargar estos modelos desde la carpeta de instalación con el siguiente script corto de Python:

CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
print(INIT_NET)
print(PREDICT_NET)

Cuando el script se ejecute correctamente, verá el siguiente resultado:

/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/init_net.pb
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/predict_net.pb

Esto confirma que el squeezenet El módulo está instalado en su máquina y es accesible a su código.

Ahora, está listo para escribir su propio código Python para la clasificación de imágenes usando Caffe2 squeezenet módulo pre-entrenado.

En esta lección, aprenderá a utilizar un modelo previamente entrenado para detectar objetos en una imagen determinada. Usarássqueezenet Módulo pre-entrenado que detecta y clasifica los objetos en una imagen dada con gran precisión.

Abra una nueva Juypter notebook y siga los pasos para desarrollar esta aplicación de clasificación de imágenes.

Importación de bibliotecas

Primero, importamos los paquetes requeridos usando el siguiente código:

from caffe2.proto import caffe2_pb2
from caffe2.python import core, workspace, models
import numpy as np
import skimage.io
import skimage.transform
from matplotlib import pyplot
import os
import urllib.request as urllib2
import operator

A continuación, configuramos algunos variables -

INPUT_IMAGE_SIZE = 227
mean = 128

Obviamente, las imágenes utilizadas para el entrenamiento serán de varios tamaños. Todas estas imágenes deben convertirse a un tamaño fijo para un entrenamiento preciso. Asimismo, las imágenes de prueba y la imagen que se quiere predecir en el entorno de producción también deben convertirse al tamaño, el mismo que se utilizó durante el entrenamiento. Por lo tanto, creamos una variable llamada arribaINPUT_IMAGE_SIZE tener valor 227. Por lo tanto, convertiremos todas nuestras imágenes al tamaño227x227 antes de usarlo en nuestro clasificador.

También declaramos una variable llamada mean tener valor 128, que se utiliza más adelante para mejorar los resultados de la clasificación.

A continuación, desarrollaremos dos funciones para procesar la imagen.

Procesamiento de imágenes

El procesamiento de imágenes consta de dos pasos. El primero es cambiar el tamaño de la imagen y el segundo es recortar la imagen de forma centralizada. Para estos dos pasos, escribiremos dos funciones para cambiar el tamaño y recortar.

Cambio de tamaño de imagen

Primero, escribiremos una función para cambiar el tamaño de la imagen. Como se dijo anteriormente, cambiaremos el tamaño de la imagen para227x227. Así que definamos la funciónresize como sigue -

def resize(img, input_height, input_width):

Obtenemos la relación de aspecto de la imagen dividiendo el ancho por el alto.

original_aspect = img.shape[1]/float(img.shape[0])

Si la relación de aspecto es superior a 1, indica que la imagen es amplia, es decir que está en modo paisaje. Ahora ajustamos la altura de la imagen y devolvemos la imagen redimensionada usando el siguiente código:

if(original_aspect>1):
   new_height = int(original_aspect * input_height)
   return skimage.transform.resize(img, (input_width,
   new_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)

Si la relación de aspecto es less than 1, indica el portrait mode. Ahora ajustamos el ancho usando el siguiente código:

if(original_aspect<1):
   new_width = int(input_width/original_aspect)
   return skimage.transform.resize(img, (new_width,
   input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)

Si la relación de aspecto es igual a 1, no realizamos ningún ajuste de altura / ancho.

if(original_aspect == 1):
   return skimage.transform.resize(img, (input_width,
   input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)

El código de función completo se proporciona a continuación para su referencia rápida:

def resize(img, input_height, input_width):
   original_aspect = img.shape[1]/float(img.shape[0])
   if(original_aspect>1):
      new_height = int(original_aspect * input_height)
      return skimage.transform.resize(img, (input_width,
	   new_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
   if(original_aspect<1):
         new_width = int(input_width/original_aspect)
         return skimage.transform.resize(img, (new_width,
         input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)
   if(original_aspect == 1):
         return skimage.transform.resize(img, (input_width,
         input_height), mode='constant', anti_aliasing=True, anti_aliasing_sigma=None)

Ahora escribiremos una función para recortar la imagen alrededor de su centro.

Recorte de imágenes

Declaramos el crop_image funciona de la siguiente manera:

def crop_image(img,cropx,cropy):

Extraemos las dimensiones de la imagen usando la siguiente declaración:

y,x,c = img.shape

Creamos un nuevo punto de partida para la imagen usando las siguientes dos líneas de código:

startx = x//2-(cropx//2)
starty = y//2-(cropy//2)

Finalmente, devolvemos la imagen recortada creando un objeto de imagen con las nuevas dimensiones -

return img[starty:starty+cropy,startx:startx+cropx]

El código de función completo se proporciona a continuación para su referencia rápida:

def crop_image(img,cropx,cropy):
   y,x,c = img.shape
   startx = x//2-(cropx//2)
   starty = y//2-(cropy//2)
   return img[starty:starty+cropy,startx:startx+cropx]

Ahora, escribiremos código para probar estas funciones.

Procesando imagen

En primer lugar, copie un archivo de imagen en images subcarpeta dentro del directorio de su proyecto. tree.jpgEl archivo se copia en el proyecto. El siguiente código de Python carga la imagen y la muestra en la consola:

img = skimage.img_as_float(skimage.io.imread("images/tree.jpg")).astype(np.float32)
print("Original Image Shape: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Original image')

La salida es la siguiente:

Tenga en cuenta que el tamaño de la imagen original es 600 x 960. Necesitamos cambiar el tamaño de esto a nuestra especificación de227 x 227. Llamando a nuestro definido anteriormenteresizela función hace este trabajo.

img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after resizing: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Resized image')

La salida es la que se muestra a continuación:

Tenga en cuenta que ahora el tamaño de la imagen es 227 x 363. Necesitamos recortar esto para227 x 227para la alimentación final de nuestro algoritmo. Llamamos a la función de cultivo previamente definida para este propósito.

img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after cropping: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Center Cropped')

A continuación se menciona la salida del código:

En este punto, la imagen es de tamaño 227 x 227y está listo para su posterior procesamiento. Ahora intercambiamos los ejes de la imagen para extraer los tres colores en tres zonas diferentes.

img = img.swapaxes(1, 2).swapaxes(0, 1)
print("CHW Image Shape: " , img.shape)

A continuación se muestra la salida:

CHW Image Shape: (3, 227, 227)

Tenga en cuenta que el último eje ahora se ha convertido en la primera dimensión de la matriz. Ahora trazaremos los tres canales usando el siguiente código:

pyplot.figure()
for i in range(3):
   pyplot.subplot(1, 3, i+1)
   pyplot.imshow(img[i])
   pyplot.axis('off')
   pyplot.title('RGB channel %d' % (i+1))

La salida se indica a continuación:

Finalmente, realizamos un procesamiento adicional en la imagen, como convertir Red Green Blue a Blue Green Red (RGB to BGR), eliminando la media para obtener mejores resultados y agregando el eje de tamaño de lote utilizando las siguientes tres líneas de código:

# convert RGB --> BGR
img = img[(2, 1, 0), :, :]
# remove mean
img = img * 255 - mean
# add batch size axis
img = img[np.newaxis, :, :, :].astype(np.float32)

En este punto, su imagen está en NCHW formaty está listo para ingresar a nuestra red. A continuación, cargaremos nuestros archivos de modelo previamente entrenados y alimentaremos la imagen de arriba para la predicción.

Predicción de objetos en imagen procesada

Primero configuramos los caminos para el init y predict redes definidas en los modelos pre-entrenados de Caffe.

Establecer rutas de archivo de modelo

Recuerde de nuestra discusión anterior, todos los modelos entrenados previamente se instalan en el modelscarpeta. Configuramos la ruta a esta carpeta de la siguiente manera:

CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")

Preparamos el camino hacia el init_net archivo protobuf del squeezenet modelo de la siguiente manera -

INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')

Asimismo, configuramos el camino hacia el predict_net protobuf de la siguiente manera:

PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')

Imprimimos las dos rutas con fines de diagnóstico:

print(INIT_NET)
print(PREDICT_NET)

El código anterior junto con el resultado se proporciona aquí para su referencia rápida:

CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
print(INIT_NET)
print(PREDICT_NET)

La salida se menciona a continuación:

/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/init_net.pb
/anaconda3/lib/python3.7/site-packages/caffe2/python/models/squeezenet/predict_net.pb

A continuación, crearemos un predictor.

Creando Predictor

Leemos los archivos del modelo usando las siguientes dos declaraciones:

with open(INIT_NET, "rb") as f:
   init_net = f.read()
with open(PREDICT_NET, "rb") as f:
   predict_net = f.read()

El predictor se crea pasando punteros a los dos archivos como parámetros al Predictor función.

p = workspace.Predictor(init_net, predict_net)

los pobject es el predictor, que se utiliza para predecir los objetos en cualquier imagen dada. Tenga en cuenta que cada imagen de entrada debe estar en formato NCHW como lo hemos hecho anteriormente a nuestrotree.jpg archivo.

Predicción de objetos

Predecir los objetos en una imagen dada es trivial, simplemente ejecutando una sola línea de comando. Nosotros llamamosrun método en el predictor objeto para la detección de un objeto en una imagen determinada.

results = p.run({'data': img})

Los resultados de la predicción ahora están disponibles en el results objeto, que convertimos en una matriz para nuestra legibilidad.

results = np.asarray(results)

Imprima las dimensiones de la matriz para su comprensión utilizando la siguiente declaración:

print("results shape: ", results.shape)

La salida es la que se muestra a continuación:

results shape: (1, 1, 1000, 1, 1)

Ahora eliminaremos el eje innecesario:

preds = np.squeeze(results)

La predicación más alta ahora se puede recuperar tomando el max valor en el preds formación.

curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1))
print("Prediction: ", curr_pred)
print("Confidence: ", curr_conf)

La salida es la siguiente:

Prediction: 984
Confidence: 0.89235985

Como ve, el modelo ha predicho un objeto con un valor de índice 984 con 89%confianza. El índice de 984 no tiene mucho sentido para nosotros para comprender qué tipo de objeto se detecta. Necesitamos obtener el nombre en cadena para el objeto usando su valor de índice. El tipo de objetos que reconoce el modelo junto con sus valores de índice correspondientes están disponibles en un repositorio de github.

Ahora, veremos cómo recuperar el nombre de nuestro objeto que tiene un valor de índice de 984.

Resultado de cadena de caracteres

Creamos un objeto URL en el repositorio de github de la siguiente manera:

codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac0
71eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes"

Leemos el contenido de la URL -

response = urllib2.urlopen(codes)

La respuesta contendrá una lista de todos los códigos y sus descripciones. A continuación se muestran algunas líneas de la respuesta para que comprenda lo que contiene:

5: 'electric ray, crampfish, numbfish, torpedo',
6: 'stingray',
7: 'cock',
8: 'hen',
9: 'ostrich, Struthio camelus',
10: 'brambling, Fringilla montifringilla',

Ahora iteramos toda la matriz para localizar nuestro código deseado de 984 usando un for bucle de la siguiente manera:

for line in response:
   mystring = line.decode('ascii')
   code, result = mystring.partition(":")[::2]
   code = code.strip()
   result = result.replace("'", "")
   if (code == str(curr_pred)):
      name = result.split(",")[0][1:]
      print("Model predicts", name, "with", curr_conf, "confidence")

Cuando ejecute el código, verá el siguiente resultado:

Model predicts rapeseed with 0.89235985 confidence

Ahora puede probar el modelo en otra imagen.

Predecir una imagen diferente

Para predecir otra imagen, simplemente copie el archivo de imagen en el imagescarpeta del directorio de su proyecto. Este es el directorio en el que nuestro anteriortree.jpgel archivo está almacenado. Cambie el nombre del archivo de imagen en el código. Solo se requiere un cambio como se muestra a continuación

img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32)

La imagen original y el resultado de la predicción se muestran a continuación:

La salida se menciona a continuación:

Model predicts pretzel with 0.99999976 confidence

Como puede ver, el modelo previamente entrenado es capaz de detectar objetos en una imagen dada con gran precisión.

Fuente completa

La fuente completa del código anterior que utiliza un modelo previamente entrenado para la detección de objetos en una imagen determinada se menciona aquí para su referencia rápida:

def crop_image(img,cropx,cropy):
   y,x,c = img.shape
   startx = x//2-(cropx//2)
   starty = y//2-(cropy//2)
   return img[starty:starty+cropy,startx:startx+cropx]
img = skimage.img_as_float(skimage.io.imread("images/pretzel.jpg")).astype(np.float32)
print("Original Image Shape: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Original image')
img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after resizing: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Resized image')
img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE)
print("Image Shape after cropping: " , img.shape)
pyplot.figure()
pyplot.imshow(img)
pyplot.title('Center Cropped')
img = img.swapaxes(1, 2).swapaxes(0, 1)
print("CHW Image Shape: " , img.shape)
pyplot.figure()
for i in range(3):
pyplot.subplot(1, 3, i+1)
pyplot.imshow(img[i])
pyplot.axis('off')
pyplot.title('RGB channel %d' % (i+1))
# convert RGB --> BGR
img = img[(2, 1, 0), :, :]
# remove mean
img = img * 255 - mean
# add batch size axis
img = img[np.newaxis, :, :, :].astype(np.float32)
CAFFE_MODELS = os.path.expanduser("/anaconda3/lib/python3.7/site-packages/caffe2/python/models")
INIT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'init_net.pb')
PREDICT_NET = os.path.join(CAFFE_MODELS, 'squeezenet', 'predict_net.pb')
print(INIT_NET)
print(PREDICT_NET)
with open(INIT_NET, "rb") as f:
   init_net = f.read()
with open(PREDICT_NET, "rb") as f:
   predict_net = f.read()
p = workspace.Predictor(init_net, predict_net)
results = p.run({'data': img})
results = np.asarray(results)
print("results shape: ", results.shape)
preds = np.squeeze(results)
curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1))
print("Prediction: ", curr_pred)
print("Confidence: ", curr_conf)
codes = "https://gist.githubusercontent.com/aaronmarkham/cd3a6b6ac071eca6f7b4a6e40e6038aa/raw/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b/alexnet_codes"
response = urllib2.urlopen(codes)
for line in response:
   mystring = line.decode('ascii')
   code, result = mystring.partition(":")[::2]
   code = code.strip()
   result = result.replace("'", "")
   if (code == str(curr_pred)):
      name = result.split(",")[0][1:]
      print("Model predicts", name, "with", curr_conf, "confidence")

En ese momento, sabrá cómo utilizar un modelo previamente entrenado para realizar predicciones en su conjunto de datos.

Lo que sigue es aprender a definir su neural network (NN) arquitecturas en Caffe2y capacítelos en su conjunto de datos. Ahora aprenderemos cómo crear un NN trivial de una sola capa.

En esta lección, aprenderá a definir un single layer neural network (NN)en Caffe2 y ejecútelo en un conjunto de datos generado aleatoriamente. Escribiremos código para representar gráficamente la arquitectura de la red, imprimir los valores de entrada, salida, pesos y sesgo. Para comprender esta lección, debe estar familiarizado conneural network architectures, es terms y mathematics utilizado en ellos.

Red de arquitectura

Consideremos que queremos construir un NN de una sola capa como se muestra en la siguiente figura:

Matemáticamente, esta red está representada por el siguiente código Python:

Y = X * W^T + b

Dónde X, W, b son tensores y Yes la salida. Llenaremos los tres tensores con algunos datos aleatorios, ejecutaremos la red y examinaremos elYsalida. Para definir la red y los tensores, Caffe2 proporciona variosOperator funciones.

Operadores Caffe2

En Caffe2, Operatores la unidad básica de cálculo. El Caffe2Operator se representa como sigue.

Caffe2 proporciona una lista exhaustiva de operadores. Para la red que estamos diseñando actualmente, usaremos el operador llamado FC, que calcula el resultado de pasar un vector de entradaX en una red completamente conectada con una matriz de peso bidimensional W y un vector de sesgo unidimensional b. En otras palabras, calcula la siguiente ecuación matemática

Y = X * W^T + b

Dónde X tiene dimensiones (M x k), W tiene dimensiones (n x k) y b es (1 x n). La salidaY será de dimensión (M x n), dónde M es el tamaño del lote.

Para los vectores X y W, usaremos el GaussianFilloperador para crear algunos datos aleatorios. Para generar valores de sesgob, usaremos ConstantFill operador.

Ahora procederemos a definir nuestra red.

Creando Red

En primer lugar, importe los paquetes necesarios:

from caffe2.python import core, workspace

A continuación, defina la red llamando core.Net como sigue -

net = core.Net("SingleLayerFC")

El nombre de la red se especifica como SingleLayerFC. En este punto, se crea el objeto de red llamado net. Hasta ahora no contiene capas.

Creando tensores

Ahora crearemos los tres vectores requeridos por nuestra red. Primero, crearemos el tensor X llamandoGaussianFill operador de la siguiente manera:

X = net.GaussianFill([], ["X"], mean=0.0, std=1.0, shape=[2, 3], run_once=0)

los X el vector tiene dimensiones 2 x 3 con el valor medio de los datos de 0,0 y la desviación estándar de 1.0.

Asimismo, creamos W tensor de la siguiente manera -

W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)

los W el vector es de tamaño 5 x 3.

Finalmente, creamos sesgo b matriz de tamaño 5.

b = net.ConstantFill([], ["b"], shape=[5,], value=1.0, run_once=0)

Ahora viene la parte más importante del código y eso es definir la red en sí.

Definición de red

Definimos la red en la siguiente declaración de Python:

Y = X.FC([W, b], ["Y"])

Nosotros llamamos FC operador en los datos de entrada X. Los pesos se especifican enWy sesgo en b. La salida esY. Alternativamente, puede crear la red utilizando la siguiente declaración de Python, que es más detallada.

Y = net.FC([X, W, b], ["Y"])

En este punto, simplemente se crea la red. Hasta que ejecutemos la red al menos una vez, no contendrá ningún dato. Antes de ejecutar la red, examinaremos su arquitectura.

Arquitectura de red de impresión

Caffe2 define la arquitectura de red en un archivo JSON, que se puede examinar llamando al método Proto en el archivo creado. net objeto.

print (net.Proto())

Esto produce la siguiente salida:

name: "SingleLayerFC"
op {
   output: "X"
   name: ""
   type: "GaussianFill"
   arg {
      name: "mean"
      f: 0.0
   }
   arg {
      name: "std"
      f: 1.0
   }
   arg {
      name: "shape"
      ints: 2
      ints: 3
   }
   arg {
      name: "run_once"
      i: 0
   }
}
op {
   output: "W"
   name: ""
   type: "GaussianFill"
   arg {
      name: "mean"
      f: 0.0
   }
   arg {
      name: "std"
      f: 1.0
   }
   arg {
      name: "shape"
      ints: 5
      ints: 3
   }
   arg {
      name: "run_once"
      i: 0
   }
}
op {
   output: "b"
   name: ""
   type: "ConstantFill"
   arg {
      name: "shape"
      ints: 5
   }
   arg {
      name: "value"
      f: 1.0
   }
   arg {
      name: "run_once"
      i: 0
   }
}
op {
   input: "X"
   input: "W"
   input: "b"
   output: "Y"
   name: ""
   type: "FC"
}

Como puede ver en la lista anterior, primero define los operadores X, W y b. Examinemos la definición deWcomo ejemplo. El tipo deW se especifica como GausianFill. losmean se define como flotar 0.0, la desviación estándar se define como flotante 1.0, y el shape es 5 x 3.

op {
   output: "W"
   name: "" type: "GaussianFill"
   arg {
      name: "mean" 
	   f: 0.0
   }
   arg { 
      name: "std" 
      f: 1.0
   }
   arg { 
      name: "shape" 
      ints: 5 
      ints: 3
   }
   ...
}

Examine las definiciones de X y bpara su propia comprensión. Finalmente, veamos la definición de nuestra red de una sola capa, que se reproduce aquí.

op {
   input: "X"
   input: "W"
   input: "b"
   output: "Y"
   name: ""
   type: "FC"
}

Aquí, el tipo de red es FC (Totalmente conectado) con X, W, b como entradas y Yes la salida. Esta definición de red es demasiado detallada y, para redes grandes, resultará tedioso examinar su contenido. Afortunadamente, Caffe2 proporciona una representación gráfica de las redes creadas.

Representación gráfica de red

Para obtener la representación gráfica de la red, ejecute el siguiente fragmento de código, que es esencialmente solo dos líneas de código Python.

from caffe2.python import net_drawer
from IPython import display
graph = net_drawer.GetPydotGraph(net, rankdir="LR")
display.Image(graph.create_png(), width=800)

Cuando ejecute el código, verá el siguiente resultado:

Para redes grandes, la representación gráfica se vuelve extremadamente útil para visualizar y depurar errores de definición de red.

Finalmente, ha llegado el momento de ejecutar la red.

Ejecución de la red

Ejecuta la red llamando al RunNetOnce método en el workspace objeto -

workspace.RunNetOnce(net)

Después de que la red se ejecute una vez, se crearán todos nuestros datos que se generan al azar, se alimentarán a la red y se creará la salida. Los tensores que se crean después de ejecutar la red se denominanblobsen Caffe2. El espacio de trabajo consta deblobsusted crea y almacena en la memoria. Esto es bastante similar a Matlab.

Después de ejecutar la red, puede examinar el blobs que contiene el espacio de trabajo utilizando lo siguiente print mando

print("Blobs in the workspace: {}".format(workspace.Blobs()))

Verá la siguiente salida:

Blobs in the workspace: ['W', 'X', 'Y', 'b']

Tenga en cuenta que el espacio de trabajo consta de tres blobs de entrada: X, W y b. También contiene el blob de salida llamadoY. Examinemos ahora el contenido de estos blobs.

for name in workspace.Blobs():
   print("{}:\n{}".format(name, workspace.FetchBlob(name)))

Verá la siguiente salida:

W:
[[ 1.0426593 0.15479846 0.25635982]
[-2.2461145 1.4581774 0.16827184]
[-0.12009818 0.30771437 0.00791338]
[ 1.2274994 -0.903331 -0.68799865]
[ 0.30834186 -0.53060573 0.88776857]]
X:
[[ 1.6588869e+00 1.5279824e+00 1.1889904e+00]
[ 6.7048723e-01 -9.7490678e-04 2.5114202e-01]]
Y:
[[ 3.2709925 -0.297907 1.2803618 0.837985 1.7562964]
[ 1.7633215 -0.4651525 0.9211631 1.6511179 1.4302125]]
b:
[1. 1. 1. 1. 1.]

Tenga en cuenta que los datos en su máquina o, de hecho, en cada ejecución de la red serían diferentes ya que todas las entradas se crean al azar. Ahora ha definido con éxito una red y la ha ejecutado en su computadora.

En la lección anterior, aprendió a crear una red trivial y aprendió cómo ejecutarla y examinar su salida. El proceso para crear redes complejas es similar al proceso descrito anteriormente. Caffe2 proporciona un gran conjunto de operadores para crear arquitecturas complejas. Le recomendamos que examine la documentación de Caffe2 para obtener una lista de operadores. Después de estudiar el propósito de varios operadores, estaría en condiciones de crear redes complejas y capacitarlos. Para entrenar la red, Caffe2 proporciona variospredefined computation units- esos son los operadores. Deberá seleccionar los operadores adecuados para capacitar a su red para el tipo de problema que está tratando de resolver.

Una vez que una red está entrenada a su satisfacción, puede almacenarla en un archivo de modelo similar a los archivos de modelo entrenados previamente que utilizó anteriormente. Estos modelos entrenados se pueden contribuir al repositorio de Caffe2 para beneficio de otros usuarios. O simplemente puede poner el modelo entrenado para su propio uso de producción privado.

Resumen

Caffe2, que es un marco de aprendizaje profundo, le permite experimentar con varios tipos de redes neuronales para predecir sus datos. El sitio de Caffe2 proporciona muchos modelos previamente entrenados. Aprendió a usar uno de los modelos entrenados previamente para clasificar objetos en una imagen determinada. También aprendió a definir una arquitectura de red neuronal de su elección. Estas redes personalizadas se pueden entrenar utilizando muchos operadores predefinidos en Caffe. Un modelo entrenado se almacena en un archivo que se puede llevar a un entorno de producción.