Modelos y capas

En el aprendizaje automático, un modelo es una función con parámetros que se pueden aprender que asigna una entrada a una salida. Los parámetros óptimos se obtienen entrenando el modelo con datos. Un modelo bien entrenado proporcionará un mapeo preciso desde la entrada hasta la salida deseada.

En TensorFlow.js hay dos formas de crear un modelo de aprendizaje automático:

  1. usando la API de capas donde construyes un modelo usando capas .
  2. utilizando la API principal con operaciones de nivel inferior como tf.matMul() , tf.add() , etc.

Primero, veremos la API de capas, que es una API de nivel superior para construir modelos. Luego, mostraremos cómo construir el mismo modelo utilizando la API central.

Creación de modelos con la API de capas

Hay dos formas de crear un modelo usando la API de capas: un modelo secuencial y un modelo funcional . Las siguientes dos secciones analizan cada tipo más de cerca.

El modelo secuencial

El tipo de modelo más común es el modelo Sequential , que es una pila lineal de capas. Puede crear un modelo Sequential pasando una lista de capas a la función sequential() :

const model = tf.sequential({
 layers: [
   tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
   tf.layers.dense({units: 10, activation: 'softmax'}),
 ]
});

O a través del método add() :

const model = tf.sequential();
model.add(tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}));
model.add(tf.layers.dense({units: 10, activation: 'softmax'}));

IMPORTANTE: La primera capa del modelo necesita una inputShape . Asegúrese de excluir el tamaño del lote al proporcionar el inputShape . Por ejemplo, si planea alimentar los tensores del modelo de forma [B, 784] , donde B puede ser de cualquier tamaño de lote, especifique inputShape como [784] al crear el modelo.

Puede acceder a las capas del modelo a través de model.layers y, más específicamente, model.inputLayers y model.outputLayers .

El modelo funcional

Otra forma de crear un LayersModel es a través de la función tf.model() . La diferencia clave entre tf.model() y tf.sequential() es que tf.model() le permite crear un gráfico arbitrario de capas, siempre que no tengan ciclos.

Aquí hay un fragmento de código que define el mismo modelo que el anterior usando la API tf.model() :

// Create an arbitrary graph of layers, by connecting them
// via the apply() method.
const input = tf.input({shape: [784]});
const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
const dense2 = tf.layers.dense({units: 10, activation: 'softmax'}).apply(dense1);
const model = tf.model({inputs: input, outputs: dense2});

Llamamos a apply() en cada capa para conectarlo a la salida de otra capa. El resultado de apply() en este caso es un SymbolicTensor , que actúa como un Tensor pero sin valores concretos.

Tenga en cuenta que, a diferencia del modelo secuencial, creamos un SymbolicTensor a través tf.input() en lugar de proporcionar una forma de inputShape a la primera capa.

apply() también puede darte un Tensor concreto, si le pasas un Tensor concreto:

const t = tf.tensor([-2, 1, 0, 5]);
const o = tf.layers.activation({activation: 'relu'}).apply(t);
o.print(); // [0, 1, 0, 5]

Esto puede ser útil al probar capas de forma aislada y ver su salida.

Al igual que en un modelo secuencial, puede acceder a las capas del modelo a través de model.layers y, más específicamente, model.inputLayers y model.outputLayers .

Validación

Tanto el modelo secuencial como el modelo funcional son instancias de la clase LayersModel . Uno de los principales beneficios de trabajar con LayersModel es la validación: lo obliga a especificar la forma de entrada y la usará más tarde para validar su entrada. LayersModel también realiza inferencias automáticas de formas a medida que los datos fluyen a través de las capas. Conocer la forma de antemano permite que el modelo cree automáticamente sus parámetros y puede decirle si dos capas consecutivas no son compatibles entre sí.

Resumen Modelo

Llame a model.summary() para imprimir un resumen útil del modelo, que incluye:

  • Nombre y tipo de todas las capas del modelo.
  • Forma de salida para cada capa.
  • Número de parámetros de peso de cada capa.
  • Si el modelo tiene una topología general (que se analiza a continuación), las entradas que recibe cada capa
  • El número total de parámetros entrenables y no entrenables del modelo.

Para el modelo que definimos anteriormente, obtenemos el siguiente resultado en la consola:

Capa (tipo) Forma de salida Parámetro #
dense_Dense1 (Denso) [nulo, 32] 25120
dense_Dense2 (Denso) [nulo, 10] 330
Parámetros totales: 25450
Parámetros entrenables: 25450
Parámetros no entrenables: 0

Tenga en cuenta los valores null en las formas de salida de las capas: un recordatorio de que el modelo espera que la entrada tenga un tamaño de lote como la dimensión más externa, que en este caso puede ser flexible debido al valor null .

Publicación por entregas

Uno de los principales beneficios de usar LayersModel sobre la API de nivel inferior es la capacidad de guardar y cargar un modelo. Un LayersModel sabe acerca de:

  • la arquitectura del modelo, lo que le permite volver a crear el modelo.
  • los pesos del modelo
  • la configuración de entrenamiento (pérdida, optimizador, métricas).
  • el estado del optimizador, lo que le permite reanudar el entrenamiento.

Para guardar o cargar un modelo es solo 1 línea de código:

const saveResult = await model.save('localstorage://my-model-1');
const model = await tf.loadLayersModel('localstorage://my-model-1');

El ejemplo anterior guarda el modelo en el almacenamiento local en el navegador. Consulte la model.save() documentation y la guía de guardado y carga para saber cómo guardar en diferentes medios (por ejemplo, almacenamiento de archivos, IndexedDB , desencadenar una descarga del navegador, etc.)

Capas personalizadas

Las capas son los componentes básicos de un modelo. Si su modelo está realizando un cálculo personalizado, puede definir una capa personalizada, que interactúa bien con el resto de las capas. A continuación, definimos una capa personalizada que calcula la suma de cuadrados:

class SquaredSumLayer extends tf.layers.Layer {
 constructor() {
   super({});
 }
 // In this case, the output is a scalar.
 computeOutputShape(inputShape) { return []; }

 // call() is where we do the computation.
 call(input, kwargs) { return input.square().sum();}

 // Every layer needs a unique name.
 getClassName() { return 'SquaredSum'; }
}

Para probarlo, podemos llamar al método apply() con un tensor concreto:

const t = tf.tensor([-2, 1, 0, 5]);
const o = new SquaredSumLayer().apply(t);
o.print(); // prints 30

IMPORTANTE: si agrega una capa personalizada, pierde la capacidad de serializar un modelo.

Creación de modelos con la API principal

Al comienzo de esta guía, mencionamos que hay dos formas de crear un modelo de aprendizaje automático en TensorFlow.js.

La regla general es siempre tratar de usar la API de capas primero, ya que está modelada según la bien adoptada API de Keras, que sigue las mejores prácticas y reduce la carga cognitiva . La API de capas también ofrece varias soluciones listas para usar, como inicialización de peso, serialización de modelos, capacitación en monitoreo, portabilidad y verificación de seguridad.

Es posible que desee utilizar la API principal siempre que:

  • Necesita máxima flexibilidad o control.
  • No necesita serialización o puede implementar su propia lógica de serialización.

Los modelos en Core API son solo funciones que toman uno o más Tensors y devuelven un Tensor . El mismo modelo que el anterior escrito usando la API Core se ve así:

// The weights and biases for the two dense layers.
const w1 = tf.variable(tf.randomNormal([784, 32]));
const b1 = tf.variable(tf.randomNormal([32]));
const w2 = tf.variable(tf.randomNormal([32, 10]));
const b2 = tf.variable(tf.randomNormal([10]));

function model(x) {
  return x.matMul(w1).add(b1).relu().matMul(w2).add(b2).softmax();
}

Tenga en cuenta que en Core API somos responsables de crear e inicializar los pesos del modelo. Cada peso está respaldado por una Variable que le indica a TensorFlow.js que estos tensores se pueden aprender. Puede crear una Variable usando tf.variable() y pasando un Tensor existente.

En esta guía, se ha familiarizado con las diferentes formas de crear un modelo utilizando las capas y la API principal. A continuación, consulte la guía de modelos de entrenamiento para saber cómo entrenar un modelo.