Modelos y capas

En el aprendizaje de máquina, un modelo es una función con que se pueden aprender los parámetros que se 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. mediante la API de capas en el que construir un modelo de uso de capas.
  2. mediante la API Core con el OPS de nivel inferior, tales 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 usando la API Core.

Crear modelos con la API de capas

Hay dos maneras de crear un modelo utilizando el 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 más común de modelo es el Sequential modelo, que es una pila lineal de capas. Se puede crear un Sequential modelo pasando una lista de capas a la sequential() función:

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

O mediante el add() método:

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 en el modelo necesita un inputShape . Asegúrese de que se excluya el tamaño del lote cuando se facilite el inputShape . Por ejemplo, si va a alimentar a los tensores de modelo de la 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 a través de la tf.model() función. La diferencia clave entre tf.model() y tf.sequential() es que tf.model() le permite crear un gráfico arbitrario de capas, siempre y cuando no tienen ciclos.

Aquí es un fragmento de código que define el mismo modelo que anteriormente utilizando el tf.model() API:

// 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 con el fin de 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 ningún tipo de valores concretos.

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

apply() también se le puede dar un concreto Tensor , si pasa un concreto Tensor a ella:

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 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 y el modelo funcional son instancias de la LayersModel clase. Una de las principales ventajas de trabajar con un LayersModel es la validación: te obliga a especificar la forma de entrada y lo utilizará más adelante para validar su entrada. El LayersModel también hace inferencia forma automática como los flujos de datos 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

Llamar 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 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 null valores en las formas de salida de las capas: un recordatorio de que el modelo de espera la entrada tiene un tamaño de lote como la dimensión más exterior, que en este caso puede ser flexible debido a la null valor.

Publicación por entregas

Uno de los principales beneficios de utilizar un LayersModel sobre la API de bajo nivel 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.

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 el ahorro y la carga de guía para la memorización de diferentes medios (por ejemplo, el almacenamiento de archivos, IndexedDB , activará la 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 apply() método con un tensor de hormigón:

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 siempre tratar de utilizar la API de las capas primera, ya que es el modelo de la API Keras así adoptados por el 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 de 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 de la API Core son sólo funciones que tienen uno o más Tensors y devuelven un Tensor . El mismo modelo que se escribió anteriormente con la API central 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 señales a TensorFlow.js que estos tensores se pueden aprender. Se puede crear una Variable usando tf.variable () y pasando en una ya existente Tensor .

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, ver el modelo de formación guía de cómo entrenar a un modelo.