Caffe2: creación de su propia red

En esta lección, aprenderá a definir un single layer neural network (NN)en Caffe2 y ejecutarlo en un conjunto de datos generado aleatoriamente. Escribiremos código para representar gráficamente la arquitectura de la red, imprimiremos 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"])

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 usando 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.