No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de TensorFlow.js

Curso de TensorFlow.js

Alejandro Santamaria

Alejandro Santamaria

Utilizando un modelo de regresión lineal

17/21
Recursos

¿Cómo podemos guardar un modelo entrenado?

Después de entrenar un modelo, es fundamental asegurarnos de que podemos guardarlo correctamente para futuros usos. La modificación del HTML para incluir un botón que permita guardar el modelo es un paso sencillo pero crucial.

  1. Creación del botón de guardado: Se debe crear un input type button en el HTML que llamará a una función específica encargada de esta tarea.
  2. Función para guardar el modelo:
    • Es importante que esta función sea asíncrona debido a la potencial cantidad de datos que se necesitan guardar.
    • Al ejecutarla, almacenará el modelo en una ubicación especificada, como la carpeta de downloads, descargándolo automáticamente a su computadora.

¿Cómo detener el entrenamiento de un modelo?

Durante el proceso de entrenamiento, especialmente en modelos grandes, puede ser útil detener el entrenamiento manualmente. Este manejo permite optimizar recursos y evaluar el modelo en el momento más oportuno.

  • Condición para detener el modelo:
    • Establecer un callback que actúe al finalizar cada ciclo de entrenamiento (epoch).
    • Agregar un botón en la interfaz que permita, con un simple clic, detener el proceso.
let stopTraining = false;

// Código para el callback
function revisarEntrenamiento(epochs) {
    if (stopTraining) {
        // Detener entrenamiento
    }
}

¿Cómo cargar un modelo previamente guardado?

Cargar un modelo nos permite continuar el análisis y obtener predicciones sin necesidad de entrenarlo nuevamente.

  • Campo de archivo input:
    • Se deben crear campos de entrada para cargar los archivos JSON (que contiene la topología del modelo) y binarios (contiene los pesos del modelo).
  • Función de carga del modelo:
    • Realizar la carga de los archivos especificados utilizando los inputs proporcionados.
    • Implementar TF.loadLayersModel que coordina esta acción de carga.

¿Cómo desplegar las predicciones del modelo?

Con el modelo ya cargado, se puede iniciar el proceso para mostrar predicciones.

  • Formato de datos:
    • Toma los datos del modelo original y realiza un proceso conocido como desnormalización.
    • Convertir estos datos en un formato comprensible para entonces ejecutar una gráfica de predicciones.
function realizarPredicciones() {
    const preds = model.predict(tensorDatosEntrada);
    const datosDesnormalizados = desnormalizarDatos(preds);
    actualizarGrafica(datosDesnormalizados);
}

// Función de desnormalización
function desnormalizarDatos(tensor) {
    // Operaciones matemáticas para revertir la normalización
}

En resumen, entender cómo guardar, detener, cargar y desplegar predicciones en modelos de regresión es vital para maximizar el uso de nuestras redes neuronales. Al integrar correctamente estas funciones en tu flujo de trabajo, tendrás un control total sobre el proceso de aprendizaje máquina. ¡No te desanimes si al principio parece complicado! Con práctica, obtener el máximo provecho de tus modelos será cada vez más sencillo.

Aportes 6

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

hasta el momento el archivo index.html quedaria asi

<!DOCTYPE html>

<html lang="es">
<head>
    <meta charset="UTF-8">
            
    <title> Modelo Regresion </title>

    <!-- Importar TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js"></script>
    <!-- Importar tfjs-vis  Visualizacion-->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tfjs-vis.umd.min.js"></script>
 
</head>

<body>
    <br>
    JSON File <input type="file" id="upload-json" /><br>
    Binary File <input type="file" id="upload-weights" /><br>
    <input type="button" value="Cargar Modelo" onclick="cargarModelo();" /> <br>

    <input type="button" value="Detener Entrenamiento" onclick="stopTraining=true;">
    <input type="button" value="Guardar Modelo" onclick="guardarModelo();" /> <br>
    <input type="button" value="Curva de Inferencia" onclick="verCurvaInferencia();" /> <br>

    <!-- Importar el archivo principal -->
    <script src="script.js"></script>
</body>
</html>

y el archivo script.js, que debe estar en la misma carpeta de index.html

/*

{
  "IngresoPromedioZona": 79545.45857,
	"EdadPromedioZona": 5.682861322,
	"NumeroDeCuartosPromedio": 7.009188143,
	"NumeroRecamarasPromedio": 4.09,
	"PoblacionZona": 23086.8005,
	"Precio": 1059033.558,
	"Direccion": "No disponible"
}

*/

var stopTraining;

async function getData() {
    const datosCasasR = await fetch('https://static.platzi.com/media/public/uploads/datos-entrenamiento_15cd99ce-3561-494e-8f56-9492d4e86438.json');  
    const datosCasas = await datosCasasR.json();  
    const datosLimpios = datosCasas.map(casa => ({
      precio: casa.Precio,
      cuartos: casa.NumeroDeCuartosPromedio
    }))
    .filter(casa => (casa.precio != null && casa.cuartos != null));
    
    return datosLimpios;
  }

  //mostrar curva de inferencia()
async function verCurvaInferencia(){
  var data = await getData();
  var tensorData = await convertirDatosATensores(data);

  const { entradasMax, entradasMin, etiquetasMin, etiquetasMax} = tensorData;

  const [xs, preds] = tf.tidy(() => {
    const xs = tf.linspace(0,1,100);
    const preds = modelo.predict(xs.reshape([100,1]));

    const desnormX = xs
      .mul(entradasMax.sub(entradasMin))
      .add(entradasMin)
    
      const desnormY = preds
      .mul(etiquetasMax.sub(etiquetasMin))
      .add(etiquetasMin)

      return [desnormX.dataSync(), desnormY.dataSync()];

  });

  const puntosPrediccion = Array.from(xs).map((val, i) => {
    return {x: val, y: preds[i]}
  });

  const puntosOriginales = data.map(d => ({
    x: d.cuartos, y: d.precio,
  }));

  tfvis.render.scatterplot(
    { name: 'Prediccion vs Originales' },
    { values: [puntosOriginales, puntosPrediccion], series: ['originales','predicciones']},
    {
      xLabel: 'Cuartos',
      yLabel: 'Precio',
      height: 300
    }
  );

}
  
async function cargarModelo(){
  const uploadJSONInput = document.getElementById('upload-json');
  const uploadWeightsInput = document.getElementById('upload-weights');

  modelo = await tf.loadLayersModel(tf.io.browserFiles(
    [uploadJSONInput.files[0], uploadWeightsInput.files[0]]
  ));
  console.log("Modelo Cargado");
}

  function visualizarDatos(data){
    const valores = data.map(d => ({
      x: d.cuartos,
      y: d.precio,
    }));
  
    tfvis.render.scatterplot(
      {name: 'Cuartos vs Precio'},
      {values: valores}, 
      {
        xLabel: 'Cuartos',
        yLabel: 'Precio',
        height: 300
      }
    );
  }

function crearModelo(){
  const modelo = tf.sequential(); 
    
  // agregar capa oculta que va a recibir 1 dato
  modelo.add(tf.layers.dense({ inputShape: [1], units: 1, useBias: true }));
  
  // agregar una capa de salida que va a tener 1 sola unidad
  modelo.add(tf.layers.dense({ units: 1, useBias: true }));

  return modelo;
}

const optimizador = tf.train.adam()
const funcion_perdida = tf.losses.meanSquaredError;
const metricas = ['mse'];

async function entrenarModelo(model, inputs, labels) {
  // Prepare the model for training.  
  model.compile({
    optimizer: optimizador,
    loss: funcion_perdida,
    metrics: metricas,
  });
  
  const surface = { name: 'show.history live', tab: 'Training' };
  const tamanioBatch = 28;
  const epochs = 50;
  const history = [];
  
  return await model.fit(inputs, labels, {
    tamanioBatch,
    epochs,
    shuffle: true,
    callbacks: {
      onEpochEnd: (epoch, log) => {
        history.push(log);
        tfvis.show.history(surface, history,  ['loss', 'mse']);

        if(stopTraining){
          modelo.stopTraining = true;
        }
      }
    }
  });
}

async function guardarModelo(){
    const saveResult = await modelo.save('downloads://modelo-regresion');

}

function convertirDatosATensores(data){
  return tf.tidy(() => {
    tf.util.shuffle(data);

    const entradas = data.map(d => d.cuartos)
    const etiquetas = data.map(d => d.precio);

    const tensorEntradas = tf.tensor2d(entradas, [entradas.length, 1]);
    const tensorEtiquetas = tf.tensor2d(etiquetas, [etiquetas.length, 1]);

    
    const entradasMax = tensorEntradas.max();
    const entradasMin = tensorEntradas.min();  
    const etiquetasMax = tensorEtiquetas.max();
    const etiquetasMin = tensorEtiquetas.min();

    // (dato -min) / (max-min)
    const entradasNormalizadas = tensorEntradas.sub(entradasMin).div(entradasMax.sub(entradasMin));
    const etiquetasNormalizadas = tensorEtiquetas.sub(etiquetasMin).div(etiquetasMax.sub(etiquetasMin));
  
      return {
        entradas: entradasNormalizadas,
        etiquetas: etiquetasNormalizadas,
        // Return the min/max bounds so we can use them later.
        entradasMax,
        entradasMin,
        etiquetasMax,
        etiquetasMin,
      }

  });
}

var modelo;
async function run() {

    const data = await getData();

    visualizarDatos(data);

    modelo = crearModelo();

    const tensorData = convertirDatosATensores(data);
    const {entradas, etiquetas} = tensorData;

    await entrenarModelo(modelo, entradas, etiquetas);
    
}


run();



Liso mi implementaciuon del modelo de regrecion lineal.

Mi implementación

Se acepta feedback 😄

Recordatorio

  • normalizacion:
    (dato - min) / (max-min) = 1
  • desnormalización:
    dato = (max - min) + min

Os dejo el codigo para quien tenga curiosidad de como sería desde node.js. No espereis obtener los graficos super chulos. Eso sí, teneis que tener instalado ‘@tensorflow/tfjs-node’; las otras dos librerias ya vienen por defecto con node.js.

const tf = require('@tensorflow/tfjs-node');
const fetch = require('node-fetch');
const https = require('https');
const httpsAgent = new https.Agent({
    rejectUnauthorized: false,
});


async function getData() {
    const datosCasasR = await fetch('https://static.platzi.com/media/public/uploads/datos-entrenamiento_15cd99ce-3561-494e-8f56-9492d4e86438.json', {
        agent: httpsAgent
    });
    const datosCasas = await datosCasasR.json();

    var datosLimpios = datosCasas.map(casa => ({
        precio: casa.Precio,
        cuartos: casa.NumeroDeCuartosPromedio
    }));
    datosLimpios = datosLimpios.filter(casa => (
        (casa.precio != null && casa.cuartos != null)
    ))

    return datosLimpios;

};

function convertirDatosATensores(data) {
    return tf.tidy(() => {
        tf.util.shuffle(data);

        const entradas = data.map(d => d.cuartos)
        const etiquetas = data.map(d => d.precio);

        const tensorEntradas = tf.tensor2d(entradas, [entradas.length, 1]);
        const tensorEtiquetas = tf.tensor2d(etiquetas, [etiquetas.length, 1]);


        const entradasMax = tensorEntradas.max();
        const entradasMin = tensorEntradas.min();
        const etiquetasMax = tensorEtiquetas.max();
        const etiquetasMin = tensorEtiquetas.min();

        // (dato -min) / (max-min)
        const entradasNormalizadas = tensorEntradas.sub(entradasMin).div(entradasMax.sub(entradasMin));
        const etiquetasNormalizadas = tensorEtiquetas.sub(etiquetasMin).div(etiquetasMax.sub(etiquetasMin));

        return {
            entradas: entradasNormalizadas,
            etiquetas: etiquetasNormalizadas,
            // Return the min/max bounds so we can use them later.
            entradasMax,
            entradasMin,
            etiquetasMax,
            etiquetasMin,
        }

    });
}


function crearModelo() {
    const modelo = tf.sequential();

    // agregar capa oculta que va a recibir 1 dato
    modelo.add(tf.layers.dense({ inputShape: [1], units: 1, useBias: true }));

    // agregar una capa de salida que va a tener 1 sola unidad
    modelo.add(tf.layers.dense({ units: 1, useBias: true }));

    return modelo;
};

//const optimizador = tf.AdamOptimizer();
//const funcion_perdida = tf.losses.meanSquaredError();
//const metricas = ['mse'];

async function entrenarModelo(model, inputs, labels) {
    // Prepare the model for training.
    model.compile({
        optimizer: 'Adam',
        loss: 'meanSquaredError',
        metrics: ['mse','accuracy'],
    });

    const surface = { name: 'show.history live', tab: 'Training' };
    const tamanioBatch = 28;
    const epochs = 50;
    const history = [];

    

    

    return await model.fit(inputs,labels,{
        batchSize: 28,
        epochs: 10,
        callbacks: {onEpochEnd: async (epoch, logs)=>{
            console.log('Metricas',logs);
            await tf.nextFrame();
        }}       

    });

  



}

var modelo;
async function run() {
    const data = await getData();
    //console.log(data);
    //await crearModelo().summary();
    modelo = crearModelo();

    const tensorData = convertirDatosATensores(data);
    const { entradas, etiquetas } = tensorData;

    await entrenarModelo(modelo, entradas, etiquetas);

    await modelo.save('file://my-model');

}
run();