Modelos y capas

En el aprendizaje automático, un modelo es una función con parámetros que se pueden aprender y 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. usando 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 crear modelos. Luego, mostraremos cómo construir el mismo modelo usando la API principal.

Creando modelos con la API de capas

Hay dos formas de crear un modelo utilizando Layers API: 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 mediante el 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 inputShape . Por ejemplo, si planea alimentar el modelo con tensores de forma [B, 784] , donde B puede ser 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 mediante la función tf.model() . La diferencia clave entre tf.model() y tf.sequential() es que tf.model() te 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 apply() en cada capa para conectarla a la salida de otra capa. El resultado de apply() en este caso es un SymbolicTensor , que actúa como un Tensor pero sin ningún valor concreto.

Tenga en cuenta que, a diferencia del modelo secuencial, creamos un SymbolicTensor mediante tf.input() en lugar de proporcionar un 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 resultar útil al probar capas de forma aislada y ver su resultado.

Al igual que en un modelo secuencial, puedes 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: te obliga a especificar la forma de entrada y la usarás más tarde para validar tu 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 indicarle si dos capas consecutivas no son compatibles entre sí.

Resumen Modelo

Llame 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 #
denso_Dense1 (denso) [nulo,32] 25120
denso_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 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, permitiéndole recrear el modelo.
  • los pesos del modelo
  • la configuración del entrenamiento (pérdida, optimizador, métricas).
  • el estado del optimizador, permitiéndole 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 del navegador. Consulte la model.save() documentation y la guía para guardar y cargar para saber cómo guardar en diferentes medios (por ejemplo, almacenamiento de archivos, IndexedDB , activar una descarga del navegador, etc.)

Capas personalizadas

Las capas son los componentes básicos de un modelo. Si su modelo realiza 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.

Creando modelos con la API Core

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 intentar siempre utilizar primero la API de capas, ya que está modelada a partir de la bien adoptada API de Keras, que sigue las mejores prácticas y reduce la carga cognitiva . La API de Layers 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 la 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 escrito anteriormente usando Core API 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 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 Layers y Core API. A continuación, consulte la guía de modelos de entrenamiento para saber cómo entrenar un modelo.