TensorFlow.js: Crea un sistema de detección de spam y comentarios

1. Antes de comenzar

Durante la última década, las aplicaciones web se han vuelto cada vez más sociales e interactivas, con la compatibilidad con contenido multimedia, comentarios y mucho más en tiempo real gracias a posiblemente decenas de miles de personas que se encuentran en un sitio web moderadamente popular.

Esto también les brindó una oportunidad a los generadores de spam para que abusen de esos sistemas y asocien contenido menos salado con los artículos, los videos y las publicaciones que crearon otros usuarios con el fin de obtener más visibilidad.

Los métodos más antiguos de detección de spam, como la lista de palabras bloqueadas, se pueden omitir con facilidad y simplemente no son compatibles con los bots de spam avanzados, que evolucionan continuamente en su complejidad. Actualmente, puedes usar los modelos de aprendizaje automático que se entrenaron para detectar este tipo de spam.

Tradicionalmente, ejecutar un modelo de aprendizaje automático para prefiltrar los comentarios se habría realizado en el servidor, pero con TensorFlow.js ahora se puede ejecutar modelos de aprendizaje automático en el navegador del cliente mediante JavaScript. Puedes detener el spam incluso antes de que toque el backend, lo que podría ahorrar recursos costosos del servidor.

Como seguramente ya saben, el aprendizaje automático es una palabra de moda en la actualidad, ya que involucra a casi todas las industrias, pero ¿cómo puede dar sus primeros pasos para usar estas funciones como desarrollador web?

En este codelab, aprenderás a compilar una app web a partir de un lienzo en blanco que soluciona el problema real del spam en comentarios, mediante el procesamiento de lenguaje natural (el arte de comprender el lenguaje humano con una computadora). Muchos desarrolladores web encontrarán este problema mientras trabajan en una de las crecientes aplicaciones web que existen en la actualidad, y este codelab te permitirá abordar esos problemas de manera eficiente.

Requisitos previos

Este codelab se escribió para desarrolladores web que recién comienzan al aprendizaje automático y que buscan comenzar a usar modelos previamente entrenados con TensorFlow.js.

Para este lab, se asume que tiene conocimientos de HTML5, CSS y JavaScript.

Qué aprenderá

Realizará lo siguiente:

  • Obtén más información sobre qué es TensorFlow.js y qué modelos existen para el procesamiento de lenguaje natural.
  • Cree una página web simple de HTML, CSS y JS para un videoblog ficticio con una sección de comentarios en tiempo real.
  • Usa TensorFlow.js a fin de cargar un modelo de aprendizaje automático previamente entrenado y capaz de predecir si una oración ingresada puede ser spam o no y, de ser así, advertirle al usuario que se retuvo su comentario para la moderación.
  • Codifica las oraciones de comentarios de una manera que pueda usar el modelo de aprendizaje automático para clasificarlas.
  • Interpreta el resultado del modelo de aprendizaje automático para decidir si quieres marcar o no el comentario automáticamente. Esta UX hipotética se puede reutilizar en cualquier sitio web en el que estés trabajando y se adaptará a cualquier caso de uso del cliente, ya sea un blog normal, un foro o alguna forma de CMS, como Drupal.

Muy buena. ¿Es difícil hacerlo? No. ¡Comencemos!

Requisitos

  • Si lo prefieres, puedes usar una cuenta de Glitch.com, o bien usar un entorno de publicación web con el que te sientas cómodo editando y funcionando.

2. ¿Qué es TensorFlow.js?

1aee0ede85885520.png

TensorFlow.js es una biblioteca de aprendizaje automático de código abierto que puede ejecutarse en cualquier lugar donde JavaScript pueda. Se basa en la biblioteca original de TensorFlow escrita en Python y tiene como objetivo volver a crear esta experiencia para desarrolladores y este conjunto de API para el ecosistema de JavaScript.

¿Dónde se puede usar?

Dada la portabilidad de JavaScript, ahora puedes escribir en 1 lenguaje y realizar aprendizaje automático en todas las siguientes plataformas con facilidad:

  • Del cliente en el navegador web con JavaScript convencional
  • En el lado del servidor o incluso en dispositivos de IoT, como Raspberry Pi, mediante Node.js
  • Apps de escritorio con Electron
  • Apps nativas para dispositivos móviles que usan React Native

TensorFlow.js también admite múltiples backends dentro de cada uno de estos entornos (los entornos reales basados en hardware que puede ejecutar, por ejemplo, la CPU o WebGL). En este contexto, un "backend" no significa un entorno del servidor; por ejemplo, el backend para la ejecución podría ser el cliente en WebGL para garantizar la compatibilidad y para que todo funcione rápidamente. Actualmente, TensorFlow.js es compatible con lo siguiente:

  • Ejecución de WebGL en la tarjeta gráfica del dispositivo (GPU): esta es la forma más rápida de ejecutar modelos más grandes (de más de 3 MB) con aceleración de GPU.
  • Ejecución de Web Assembly (WASM) en CPU: Para mejorar el rendimiento de CPU en todos los dispositivos, incluidos los teléfonos de generación anterior, por ejemplo. Esto es más adecuado para modelos más pequeños (de menos de 3 MB) que, en realidad, pueden ejecutarse más rápido en la CPU con WASM que con WebGL debido a la sobrecarga de subir contenido a un procesador de gráficos.
  • Ejecución de CPU: El resguardo no debe estar disponible en ninguno de los otros entornos. Este es el más lento de los tres, pero siempre está ahí para ti.

Nota: Puedes forzar uno de estos backends si sabes en qué dispositivo se ejecutará o puedes permitir que TensorFlow.js decida por ti si lo haces. no lo especifiques.

Superpoderes del cliente

Ejecutar TensorFlow.js en el navegador web de la máquina cliente puede generar varios beneficios que vale la pena considerar.

Privacidad

Puedes entrenar y clasificar datos en la máquina cliente sin necesidad de enviar datos a un servidor web de terceros. En ocasiones, es posible que este sea un requisito para cumplir con leyes locales, como el GDPR, por ejemplo, cuando se procesen datos que el usuario desee conservar en sus equipos y no se envíen a terceros.

Velocidad

Dado que no tiene que enviar datos a un servidor remoto, la inferencia (el acto de clasificar los datos) puede ser más rápida. Aún mejor, tienes acceso directo a los sensores del dispositivo, como la cámara, el micrófono, el GPS, el acelerómetro y más, si el usuario te otorga acceso.

Alcance y escala

Con un solo clic, cualquier persona en el mundo podrá hacer clic en un vínculo que le envíes, abrir la página web en su navegador y utilizar lo que hayas creado. No necesita una configuración compleja del servidor en Linux con controladores CUDA y mucho más solo para usar el sistema de aprendizaje automático.

Costo

Que no haya servidores significa que lo único que debes pagar es una CDN para alojar tus archivos HTML, CSS, JS y de modelo. El costo de una CDN es mucho más económico que mantener un servidor (posiblemente con una tarjeta gráfica adjunta) en ejecución las 24 horas, todos los días.

Características del servidor

Cuando aprovechas la implementación de Node.js en Node.js, puedes habilitar las siguientes funciones.

Compatibilidad completa con CUDA

En el servidor, para la aceleración de tarjetas gráficas, debes instalar los controladores de NVIDIA CUDA para permitir que TensorFlow funcione con la tarjeta gráfica (a diferencia en el navegador que usa WebGL; no se requiere instalación). Sin embargo, con la compatibilidad total con CUDA, puede aprovechar al máximo las capacidades de nivel inferior de la tarjeta gráfica, lo que acelera los entrenamientos e inferencias. El rendimiento se encuentra al mismo nivel que la implementación de Python para TensorFlow, ya que ambos comparten el mismo backend de C++.

Tamaño del modelo

Para modelos de vanguardia a partir de la investigación, es posible que trabajes con modelos muy grandes, tal vez gigabytes de tamaño. Actualmente, no se pueden ejecutar estos modelos en el navegador web debido a las limitaciones de uso de memoria por pestaña del navegador. Para ejecutar estos modelos más grandes, puedes usar Node.js en tu propio servidor con las especificaciones de hardware que necesitas para ejecutar ese modelo de manera eficiente.

IOT

Node.js es compatible con computadoras de placa única populares, como Raspberry Pi, lo que, a su vez, te permite ejecutar modelos de TensorFlow.js en esos dispositivos.

Velocidad

Node.js está escrito en JavaScript, lo que significa que se beneficia de una compilación oportuna. Esto significa que, a menudo, es posible que observe mejoras en el rendimiento cuando utilice Node.js, ya que se optimizará en el tiempo de ejecución, en especial para el procesamiento previo que realice. Se puede observar un excelente ejemplo de esto en este caso de éxito, que muestra cómo Hugging Face usó Node.js a fin de obtener el doble de rendimiento para su modelo de procesamiento de lenguaje natural.

Ahora que comprendes los conceptos básicos de TensorFlow.js, dónde se puede ejecutar y algunos de sus beneficios, podemos comenzar a usarlo de forma útil.

3. Modelos previamente entrenados

¿Por qué querría usar un modelo previamente entrenado?

Comenzar con un modelo popular previamente entrenado tiene varios beneficios si se adapta al caso de uso deseado:

  1. No necesitas recopilar datos de entrenamiento por tu cuenta. Preparar los datos en el formato correcto y etiquetarlos de modo que un sistema de aprendizaje automático pueda usarlos para aprender puede consumir mucho tiempo y ser costoso.
  2. La capacidad de prototipar una idea rápidamente con una reducción de costos y de tiempo
    No tiene sentido "reinventar la rueda" cuando un modelo previamente entrenado puede ser suficiente para hacer lo que necesitas, lo que te permite concentrarte en usar el conocimiento que brinda el modelo a fin de implementar tus ideas creativas. ,
  3. Uso de una investigación de última generación. Los modelos previamente entrenados a menudo se basan en investigaciones populares, lo que te proporciona exposición a esos modelos y, al mismo tiempo, comprende su rendimiento en el mundo real.
  4. Facilidad de uso y mucha documentación. Debido a la popularidad de esos modelos.
  5. Capacidades de aprendizaje por transferencia Algunos modelos previamente entrenados ofrecen capacidades de aprendizaje por transferencia, que es, básicamente, la práctica de transferir información aprendida de una tarea de aprendizaje automático a otro ejemplo similar. Por ejemplo, un modelo que se entrenó originalmente para reconocer gatos puede volver a entrenarse para que reconozca perros, si le dio datos de entrenamiento nuevos. Esto será más rápido, ya que no comenzará con un lienzo en blanco. El modelo puede aplicar lo que ya aprendió a reconocer gatos para luego reconocer algo nuevo: los perros tienen ojos y oídos después de todo, así que, si ya sabe cómo encontrar esos atributos, ya estamos a medio camino. Vuelve a entrenar el modelo con tus propios datos de una manera mucho más rápida.

Un modelo de detección de comentarios spam spam entrenado previamente

Usarás la arquitectura del modelo de incorporación de palabras promedio para tus necesidades de detección de comentarios spam. Sin embargo, si intentas usar un modelo no entrenado, no será mejor que la casualidad de adivinar si las oraciones son spam.

Para que el modelo sea útil, debe entrenarse con datos personalizados, en este caso, para permitirle aprender el aspecto de los comentarios spam y los que no lo son. A partir de ese aprendizaje, habrá más probabilidades de clasificarlo correctamente en el futuro.

Afortunadamente, alguien ya entrenó esta arquitectura de modelo exacta para esta tarea de clasificación de comentarios spam, por lo que puedes usarla como punto de partida. Es posible que encuentre otros modelos previamente entrenados que usan la misma arquitectura de modelo para llevar a cabo diferentes acciones, como detectar en qué idioma se escribió un comentario o predecir si los datos del formulario de contacto del sitio web se deben enrutar automáticamente a un determinado equipo de la empresa según el texto escrito. p. ej., ventas (consultas de productos) o ingeniería (error técnico o comentarios). Con datos de entrenamiento suficientes, un modelo como este puede aprender a clasificar ese texto en cada caso para darle superpoderes a tu aplicación web y mejorar la eficiencia de tu organización.

En un codelab futuro, aprenderás a usar Model Maker para volver a entrenar este modelo de comentarios spam entrenado previamente y mejorar aún más su rendimiento en tus propios datos de comentarios. Por ahora, usarás el modelo de detección de comentarios spam existente como punto de partida para que la app web inicial funcione como un primer prototipo.

Este modelo de detección de spam previamente entrenado de comentarios se publicó en un sitio web conocido como TF Hub, un repositorio de modelos de aprendizaje automático mantenido por Google, en el que los ingenieros de AA pueden publicar sus modelos prediseñados para muchos casos de uso comunes. (como texto, visión, sonido y más para casos de uso específicos dentro de cada una de esas categorías). Descarga los archivos de modelo por ahora para usarlos en la app web más adelante en este codelab.

Haz clic en el botón de descarga del modelo JS, como se muestra a continuación:

ab65deff89b3d939.png

4. Configura el código

Requisitos

Comencemos a programar.

Creamos una plantilla estándar de Glitch.com para Node.js Express desde la que puedes clonar simplemente como estado base para este codelab con un solo clic.

En Glitch, haz clic en el botón "remix this" para bifurcarlo y crear un nuevo conjunto de archivos que puedes editar.

Este esqueleto muy simple nos proporciona los siguientes archivos en la carpeta www:

  1. Página HTML (index.html)
  2. Hoja de estilo (style.css)
  3. Archivo para escribir nuestro código JavaScript (script.js)

Para tu comodidad, también agregamos en el archivo HTML una importación para la biblioteca de TensorFlow.js que se ve de la siguiente manera:

index.html

<!-- Import TensorFlow.js library -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js" type="text/javascript"></script>

Luego, entregaremos esta carpeta www a través de un servidor Node Express sencillo a través de package.json y server.js

5. Anuncio HTML de la aplicación

¿Cuál es tu punto de partida?

Todos los prototipos requieren una estructura básica de HTML en la que puedes renderizar tus resultados. Configurar ahora. Agregarás:

  • Un título para la página
  • Texto descriptivo
  • Un video de marcador de posición que representa la entrada de blog de video
  • Un área para ver y escribir comentarios

Abre index.html y pega el código existente con lo siguiente para configurar las funciones anteriores:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>My Pretend Video Blog</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Import the webpage's stylesheet -->
    <link rel="stylesheet" href="/style.css">
  </head>
  <body>
    <header>
      <h1>MooTube</h1>
      <a id="login" href="#">Login</a>
    </header>

    <h2>Check out the TensorFlow.js rap for the show and tell!</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur ipsum quam, tincidunt et tempor in, pulvinar vel urna. Nunc eget erat pulvinar, lacinia nisl in, rhoncus est. Morbi molestie vestibulum nunc. Integer non ipsum dolor. Curabitur condimentum sem eget odio dapibus, nec bibendum augue ultricies. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Sed iaculis ut ligula sed tempor. Phasellus ac dictum felis. Integer arcu dui, facilisis sit amet placerat sagittis, blandit sit amet risus.</p>

    <iframe width="100%" height="500" src="https://www.youtube.com/embed/RhVs7ijB17c" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

    <section id="comments" class="comments">
      <div id="comment" class="comment" contenteditable></div>
      <button id="post" type="button">Comment</button>

      <ul id="commentsList">
        <li>
          <span class="username">NotASpammer</span>
          <span class="timestamp">3/18/2021, 6:52:16 PM</span>
          <p>I am not a spammer, I am a good boy.</p>
        </li>
        <li>
          <span class="username">SomeUser</span>
          <span class="timestamp">2/11/2021, 3:10:00 PM</span>
          <p>Wow, I love this video, so many amazing demos!</p>
        </li>
      </ul>
    </section>

    <!-- Import TensorFlow.js library -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js" type="text/javascript"></script>

    <!-- Import the page's JavaScript to do some stuff -->
    <script type="module" src="/script.js"></script>
  </body>
</html>

Desglose

Desglosemos algunos de los códigos HTML anteriores para destacar algunos de los elementos clave que agregó.

  • Agregaste una etiqueta <h1> para el título de la página junto con una etiqueta <a> para el botón de acceso, todo incluido en <header>. Luego, agregaste un <h2> para el título del artículo y una etiqueta <p> para la descripción del video. No hay nada especial.
  • Agregaste una etiqueta iframe que incorpora un video de YouTube arbitrario. Por ahora, se usa el poderoso rap de TensorFlow.js como marcador de posición. Sin embargo, puedes colocar cualquier video que desees con solo cambiar la URL del iframe. De hecho, en un sitio web de producción, el backend renderizaría todos estos valores de manera dinámica, según la página que se esté viendo.
  • Por último, agregaste un section con un ID y una clase de "comments", que contiene una div editable para escribir comentarios nuevos junto con un button a fin de enviar el nuevo comentario que deseas agregar junto con un sin ordenar. lista de comentarios. Tienes el nombre de usuario y la hora de publicación dentro de una etiqueta span dentro de cada elemento de la lista y, por último, el comentario en una etiqueta p. Por el momento, 2 comentarios de ejemplo están codificados como marcadores de posición.

Si obtienes una vista previa del resultado en este momento, debería verse de la siguiente manera:

73c8338334d5b251.png

Se ve bastante pésimo, así que es hora de agregar un poco de estilo...

6. Agr. estilo

Valores predeterminados del elemento

Primero, agrega estilos para los elementos HTML que acabas de agregar a fin de asegurarte de que se rendericen correctamente.

Comience por aplicar el restablecimiento de CSS para tener un punto de partida de comentarios en todos los navegadores y SO. Reemplaza los contenidos de la style.css con lo siguiente:

estilo.css

/* http://meyerweb.com/eric/tools/css/reset/
   v2.0 | 20110126
   License: none (public domain)
*/
a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}

Luego, agrega información a la CSS para darle vida a la interfaz de usuario.

Agrega lo siguiente al final de style.css debajo del código de restablecimiento de CSS que agregaste antes:

estilo.css

/* CSS files add styling rules to your content */
body {
  background: #212121;
  color: #fff;
  font-family: helvetica, arial, sans-serif;
}

header {
  background: linear-gradient(0deg, rgba(7,7,7,1) 0%, rgba(7,7,7,1) 85%, rgba(55,52,54,1) 100%);
  min-height: 30px;
  overflow: hidden;
}

h1 {
  color: #f0821b;
  font-size: 24pt;
  padding: 15px 25px;
  display: inline-block;
  float: left;
}

h2, p, section, iframe {
  background: #212121;
  padding: 10px 25px;
}

h2 {
  font-size: 16pt;
  padding-top: 25px;
}

p {
  color: #cdcdcd;
}

iframe {
  display: block;
  padding: 15px 0;
}

header a, button {
  color: #222;
  padding: 7px;
  min-width: 100px;
  background: rgb(240, 130, 30);
  border-radius: 3px;
  border: 1px solid #3d3d3d;
  text-transform: uppercase;
  font-weight: bold;
  cursor: pointer;
  transition: background 300ms ease-in-out;
}

header a {
  background: #efefef;
  float: right;
  margin: 15px 25px;
  text-decoration: none;
  text-align: center;
}

button:focus, button:hover, header a:hover {
  background: rgb(260, 150, 50);
}

.comment {
  background: #212121;
  border: none;
  border-bottom: 1px solid #888;
  color: #fff;
  min-height: 25px;
  display: block;
  padding: 5px;
}

.comments button {
  float: right;
  margin: 5px 0;
}

.comments button, .comment {
  transition: opacity 500ms ease-in-out;
}

.comments ul {
  clear: both;
  margin-top: 60px;
}

.comments ul li {
  margin-top: 5px;
  padding: 10px;
  transition: background 500ms ease-in-out;
}

.comments ul li * {
  background: transparent;
}

.comments ul li:nth-child(1) {
  background: #313131;
}

.comments ul li:hover {
  background: rgb(70, 60, 10);
}

.username, .timestamp {
  font-size: 80%;
  margin-right: 5px;
}

.username {
  font-weight: bold;
}

.processing {
  opacity: 0.3;
  filter: grayscale(1);
}

.comments ul li.spam {
  background-color: #d32f2f;
}

.comments ul li.spam::after {
  content: "⚠";
  margin: -17px 2px;
  zoom: 3;
  float: right;
}

¡Genial! ¡Eso es todo lo que necesitas! Si sobrescribes correctamente tus estilos con los 2 códigos anteriores, la vista previa en vivo debería verse así:

b86be8e2f6e7456.png

De forma predeterminada, el encantador modo nocturno y las encantadoras transiciones de CSS para efectos de desplazamiento en elementos clave Se ve bien. Ahora integra alguna lógica de comportamiento con JavaScript.

7. JavaScript: Control de DOM y controladores de eventos

Haz referencia a elementos DOM clave

Primero, asegúrate de poder acceder a las partes clave de la página que necesitarás manipular o a las que podrás acceder más adelante en el código, además de definir algunas constantes de clase de CSS para el estilo.

Para comenzar, reemplaza el contenido de script.js por las siguientes constantes:

script.js

const POST_COMMENT_BTN = document.getElementById('post');
const COMMENT_TEXT = document.getElementById('comment');
const COMMENTS_LIST = document.getElementById('commentsList');
// CSS styling class to indicate comment is being processed when
// posting to provide visual feedback to users.
const PROCESSING_CLASS = 'processing';

// Store username of logged in user. Right now you have no auth
// so default to Anonymous until known.
var currentUserName = 'Anonymous';

Administra la publicación de comentarios

A continuación, agrega un objeto de escucha de eventos y una función de control a POST_COMMENT_BTN para que pueda tomar el texto del comentario escrito y establecer una clase de CSS a fin de indicar que comenzó el procesamiento. Tenga en cuenta que verifica que no haya hecho clic en el botón en caso de que ya se esté procesando.

secuencia de comandos.js

/**
 * Function to handle the processing of submitted comments.
 **/
function handleCommentPost() {
  // Only continue if you are not already processing the comment.
  if (! POST_COMMENT_BTN.classList.contains(PROCESSING_CLASS)) {
    POST_COMMENT_BTN.classList.add(PROCESSING_CLASS);
    COMMENT_TEXT.classList.add(PROCESSING_CLASS);
    let currentComment = COMMENT_TEXT.innerText;
    console.log(currentComment);

    // TODO: Fill out the rest of this function later.
  }
}

POST_COMMENT_BTN.addEventListener('click', handleCommentPost);

¡Genial! Si actualizas la página web y tratas de publicar un comentario, ahora deberías ver el botón de comentarios y el texto en escala de grises. En la consola, deberías ver el comentario impreso de la siguiente manera:

827b5f3d09afbb21.png

Ahora que tienes un esqueleto básico de HTML, CSS y JS, es hora de volver a centrar tu atención en el modelo de aprendizaje automático para que puedas integrarlo a la hermosa página web.

8. Entregar el modelo de aprendizaje automático

Ya casi estás listo para cargar el modelo. Sin embargo, antes de hacerlo, debes subir los archivos del modelo descargados anteriormente en el codelab a tu sitio web para que se alojen y puedan usarse dentro del código.

Primero, si aún no lo hiciste, descomprime los archivos que descargaste para el modelo al comienzo de este codelab. Debería ver un directorio con los siguientes archivos:

5634d536ef8be9ca.png

¿Qué tienes aquí?

  • model.json: Este es uno de los archivos que componen el modelo entrenado de TensorFlow.js. En realidad, harás referencia a este archivo específico más adelante en tu código de TensorFlow.js.
  • group1-shard1of1.bin: Este es un archivo binario que contiene las ponderaciones preparadas (básicamente, un número de números que aprendió a realizar su tarea de clasificación) bien del modelo de TensorFlow.js, y deberá alojarse en algún lugar de tu servidor para la descarga.
  • vocab: Este archivo extraño sin extensión es algo de Model Maker que muestra cómo codificar palabras en las oraciones para que el modelo comprenda cómo se usan. Profundizaremos más en este tema en la siguiente sección.
  • labels.txt: Simplemente contiene los nombres de clase resultantes que el modelo predecirá. Para este modelo, si abres este archivo en tu editor de texto, solo tiene una lista de las etiquetas "false" y "true", lo que indica "no es spam" o "spam" como su resultado de predicción.

Aloja los archivos del modelo de TensorFlow.js

Primero, coloca model.json y los archivos *.bin que se generaron a un servidor web para que puedas acceder a ellos a través de la página web.

Sube archivos a Glitch

  1. Haz clic en la carpeta assets en el panel de la izquierda de tu proyecto de Glitch.
  2. Haga clic en Subir un elemento y seleccione group1-shard1of1.bin para subirlo a esta carpeta. Ahora, debería verse así:

25a2251c7f165184.png

  1. ¡Genial! Ahora, haz lo mismo con el archivo model.json. 2 archivos deberían estar en tu carpeta assets de la siguiente manera:

51a6dbd5d3097ffc.png

  1. Haz clic en el archivo group1-shard1of1.bin que acabas de subir. Podrás copiar la URL en su ubicación. Copia esta ruta de acceso como se muestra a continuación:

92ded8d46442c404.png

  1. Ahora, en la parte inferior izquierda de la pantalla, haz clic en Herramientas > Terminal. Espera a que se cargue la ventana de la terminal. Una vez que se haya cargado, escribe lo siguiente y luego presiona Intro para cambiar el directorio a la carpeta www:

terminal:

cd www
  1. Luego, usa wget para descargar los 2 archivos subidos. Para ello, reemplaza las URL que se indican más abajo por las URL que generaste para los archivos de la carpeta assets de Glitch (verifica la carpeta de elementos de la URL personalizada de cada archivo). ). Ten en cuenta que el espacio entre las dos URL y que deberás usar es diferente a las que se muestran a continuación, pero serán similares:

terminal

wget https://cdn.glitch.com/1cb82939-a5dd-42a2-9db9-0c42cab7e407%2Fmodel.json?v=1616111344958 https://cdn.glitch.com/1cb82939-a5dd-42a2-9db9-0c42cab7e407%2Fgroup1-shard1of1.bin?v=1616017964562

Muy bien, ahora creaste una copia de los archivos subidos a la carpeta www. Sin embargo, en este momento se descargaron con nombres extraños.

  1. Escribe ls en la terminal y presiona Intro. Verá un resultado similar al que se detalla a continuación:

9cc90f1d053f517f.png

  1. Con el comando mv, puedes cambiar los nombres de los archivos. Escribe lo siguiente en la consola y presiona <xyz>Intro</quick> o <quick>return</quick>, después de cada línea:

terminal:

mv *group1-shard1of1.bin* group1-shard1of1.bin
mv *model.json* model.json
  1. Por último, para actualizar el proyecto de Glitch, escribe refresh en la terminal y presiona <xyz>Intro</quick>:

terminal:

refresh
  1. Después de actualizar, deberías ver model.json y group1-shard1of1.bin en la carpeta www de la interfaz de usuario:

50dd98c0a8f3e629.png

¡Genial! Ya está listo para usar los archivos de modelo subidos con algún código real en el navegador.

9. Carga y usa el modelo alojado de TensorFlow.js

Ahora, puede probar la carga del modelo de TensorFlow.js que se subió con algunos datos para verificar si funciona.

En este momento, los datos de entrada de ejemplo que verá a continuación se verán bastante misteriosos (un arreglo de números), y cómo se generaron se explicarán en la siguiente sección. Solo velo como una matriz de números por ahora. En esta etapa, es importante probar que el modelo nos brinda una respuesta sin errores.

Agrega el siguiente código al final del archivo script.js y asegúrate de reemplazar el valor de string MODEL_JSON_URL por la ruta del archivo model.json que generaste cuando subiste el archivo a la carpeta de elementos de Glitch. el paso anterior. (Recuerda que puedes hacer clic en el archivo de la carpeta assets de Glitch para encontrar su URL).

Lee los comentarios del nuevo código para comprender lo que hace cada línea:

secuencia de comandos.js

// Set the URL below to the path of the model.json file you uploaded.
const MODEL_JSON_URL = 'model.json';
// Set the minimum confidence for spam comments to be flagged.
// Remember this is a number from 0 to 1, representing a percentage
// So here 0.75 == 75% sure it is spam.
const SPAM_THRESHOLD = 0.75;

// Create a variable to store the loaded model once it is ready so
// you can use it elsewhere in the program later.
var model = undefined;

/**
 * Asynchronous function to load the TFJS model and then use it to
 * predict if an input is spam or not spam.
 */
async function loadAndPredict(inputTensor) {
  // Load the model.json and binary files you hosted. Note this is
  // an asynchronous operation so you use the await keyword
  if (model === undefined) {
    model = await tf.loadLayersModel(MODEL_JSON_URL);
  }

  // Once model has loaded you can call model.predict and pass to it
  // an input in the form of a Tensor. You can then store the result.
  var results = await model.predict(inputTensor);

  // Print the result to the console for us to inspect.
  results.print();

  // TODO: Add extra logic here later to do something useful
}

loadAndPredict(tf.tensor([[1,3,12,18,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]));

Si el proyecto está configurado correctamente, ahora deberías ver algo como lo siguiente impreso en tu ventana de la consola, cuando usas el modelo que cargaste para predecir un resultado de la entrada que se le pasó:

e72acc17383bec33.png

En la consola, verás 2 números impresos:

  1. 0,9996011
  2. 0,0003989

Si bien esto puede parecer críptico, estas cifras en realidad representan las probabilidades de que el modelo considere que la clasificación es para la entrada que le diste. Pero ¿qué representan?

Si abres el archivo labels.txt de los archivos de modelos descargados que tienes en tu máquina local, verás que también tiene 2 campos:

  1. Falso
  2. Verdadero

Por lo tanto, en este caso, el modelo dice que es99.96011% Asegúrate (que se muestra en el objeto del resultado como 0.9996011) de que la entrada que le proporcionaste (que era[1,3,12,18,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] fueNO es spam (p. ej., Falso).

Ten en cuenta que false fue la primera etiqueta en labels.txt y se representa con el primer resultado de la impresión de la consola. Así sabrás con qué se relaciona la predicción de salida.

Muy bien. Ahora sabes cómo interpretar el resultado, pero ¿qué fue esa gran cantidad de números proporcionados como entrada y cómo conviertes las oraciones en este formato para que las use el modelo? Para ello, debes aprender sobre la asignación de tokens y tensores. Sigue leyendo para conocer todos los detalles.

10. Asignación de token y tensores

Asignación de token

Por lo tanto, los modelos de aprendizaje automático solo pueden aceptar una gran cantidad de números como entradas. ¿Por qué? Básicamente, se debe a que un modelo de aprendizaje automático es básicamente un conjunto de operaciones matemáticas en cadena, por lo que si le pasas algo que no es un número, tendrá dificultades para lidiar con él. Ahora, la pregunta es cómo convertir las oraciones en números para usarlas con el modelo que cargó.

Bueno, el proceso exacto difiere de un modelo a otro, pero, para este, hay un archivo más en los archivos de modelo que descargaste, llamado vocab,, y esta es la clave para codificar los datos.

Abre vocab en un editor de texto local en tu máquina y verás lo siguiente:

81e8bca3fbf62429.png

En esencia, esta es una tabla de consulta sobre cómo convertir palabras significativas que el modelo aprendió en números que puede comprender. También hay algunos casos especiales en la parte superior del archivo <PAD>, <START> y <UNKNOWN>:

  • <PAD>: Es la abreviatura de "padding". Resulta que a los modelos de aprendizaje automático les gusta tener una cantidad fija de entradas, sin importar la extensión de una oración. El modelo que se usa espera que siempre haya 20 números para la entrada (que definió el creador del modelo y se puede cambiar si vuelves a entrenar el modelo). Por lo tanto, si tienes una frase como "Me gusta el video", deberían llenar los espacios restantes del arreglo con 0, que representen el token <PAD>. Si la oración tiene más de 20 palabras, debes dividirla para que se ajuste a este requisito y, en su lugar, realiza varias clasificaciones en varias oraciones más pequeñas.
  • <START>: Este es siempre el primer token para indicar el inicio de la oración. Notarás en la entrada de ejemplo de los pasos anteriores que el arreglo de números comenzó con un “1”, esto representaba el token de <START>.
  • <UNKNOWN> - Como habrás supuesto, si la palabra no existe en esta búsqueda de palabras, simplemente usas el token <UNKNOWN> (representado por un "2") como número.

Para todas las demás palabras, existe en la búsqueda y tiene un número especial asociado, por lo que deberá usarse o, en ese caso, se usará el número de token <UNKNOWN>.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Take another look at the input used in the prior code you ran:

[1,3,12,18,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

Con esto, ahora puedes ver que fue una oración con 4 palabras, ya que el resto son tokens <START> o <PAD>, y que hay 20 números en el array. Muy bien, comenzando a entender un poco más.

La oración que escribí para esta versión fue "Me encanta mi perro". En la captura de pantalla anterior, puede ver que "I" se convirtió al número "3", que es correcto. Si buscas las otras palabras, también encontrarás los números correspondientes.

Tensors

Hay un último obstáculo antes de que el modelo de AA acepte tu entrada numérica. Deben convertir el array de números en algo conocido como un Tensor. Y, como ya habrás adivinado, TensorFlow se llama así por estas cosas: básicamente el Flow de los tensores.

¿Qué es un Tensor?

La definición oficial de TensorFlow.org dice lo siguiente:

"Los tensores son arreglos multidimensionales con un tipo uniforme. Todos los tensores son inmutables: nunca se pueden actualizar los contenidos de los tensores, solo se crea uno nuevo”.

En palabras simples, es simplemente un lujoso nombre matemático para un arreglo de cualquier dimensión que tenga algunas otras funciones compiladas en el objeto Tensor que nos resulten útiles como desarrolladores de aprendizaje automático. Sin embargo, se debe tener en cuenta que los tensores solo almacenan datos de 1 tipo, p. ej., todos los números enteros o todos los números de punto flotante, y una vez creados, nunca pueden cambiar el contenido de un Tensor, por lo que puedes considerarlo como un cuadro de almacenamiento permanente para números.

No te preocupes demasiado por esto por ahora. Por lo menos, piensa que es un mecanismo de almacenamiento multidimensional de modelos de aprendizaje automático con el que podrás trabajar hasta que te sumerjas con un buen libro como este. Es muy recomendable si deseas obtener más información sobre los tensores. y cómo usarlas.

Cómo combinar todo: Tensores y codificación de codificación

¿Cómo usas ese archivo vocab en el código? Muy buena pregunta.

Como desarrollador de JS, este archivo por sí solo es bastante inútil. Sería mucho mejor si este fuera un objeto de JavaScript que simplemente pudiera importar y usar. Se puede ver cómo sería bastante fácil convertir los datos de este archivo a un formato más similar al siguiente:

// Special cases. Export as constants.
export const PAD =  0;
export const START = 1;
export const UNKNOWN = 2;

// Export a lookup object.
export const LOOKUP = {
  "i": 3,
  "check": 4,
  "video": 5,
  "song": 6,
  "com": 7,
  "please": 8,
  "like": 9
  // and all the other words...
}

Con tu editor de texto favorito, puedes transformar fácilmente el archivo vocab para que tenga ese formato, con algo de búsqueda y reemplazo. Sin embargo, también puede usar esta herramienta prediseñada para facilitar este proceso.

Si realizas este trabajo con anticipación y guardas el archivo vocab en el formato correcto, no es necesario que realices esta conversión y que se analice cada carga de página, lo que es un desperdicio de recursos de CPU. Aún mejor, los objetos de JavaScript tienen las siguientes propiedades:

"El nombre de una propiedad de objeto puede ser cualquier string de JavaScript válida o cualquier acción que se pueda convertir en una string, incluida la string vacía. Sin embargo, solo se puede acceder a cualquier nombre de propiedad que no sea un identificador válido de JavaScript (por ejemplo, un nombre de propiedad que tenga un espacio o un guion, o que comience con un número) con la notación con corchetes.

Por lo tanto, siempre que uses la notación con corchetes, puedes crear una tabla de búsqueda bastante eficiente a través de esta transformación simple.

Convierte a un formato más útil

Convierte tu archivo de vocabulario al formato que se indica más arriba, ya sea manualmente a través del editor de texto o usa esta herramienta aquí. Guarda el resultado resultante como dictionary.js en tu carpeta www.

En Glitch, puedes crear un archivo nuevo en esta ubicación y pegar el resultado de tu conversión para guardarlo como se muestra a continuación:

c80f68535c92baf.gif

Una vez que tengas un archivo dictionary.js guardado en el formato descrito anteriormente, ahora puedes anteponer el siguiente código a la parte superior de script.js para importar el módulo dictionary.js que acabas de escribir. Aquí, también defines una ENCODING_LENGTH constante adicional para que sepas cuánto se debe agregar más adelante en el código, junto con una función tokenize que usarás para convertir un array de palabras en un tensor adecuado que se pueda usar como una entrada al modelo.

Consulta los comentarios en el siguiente código para obtener más detalles sobre lo que hace cada línea:

secuencia de comandos.js

import * as DICTIONARY from '/dictionary.js';

// The number of input elements the ML Model is expecting.
const ENCODING_LENGTH = 20;

/**
 * Function that takes an array of words, converts words to tokens,
 * and then returns a Tensor representation of the tokenization that
 * can be used as input to the machine learning model.
 */
function tokenize(wordArray) {
  // Always start with the START token.
  let returnArray = [DICTIONARY.START];

  // Loop through the words in the sentence you want to encode.
  // If word is found in dictionary, add that number else
  // you add the UNKNOWN token.
  for (var i = 0; i < wordArray.length; i++) {
    let encoding = DICTIONARY.LOOKUP[wordArray[i]];
    returnArray.push(encoding === undefined ? DICTIONARY.UNKNOWN : encoding);
  }

  // Finally if the number of words was < the minimum encoding length
  // minus 1 (due to the start token), fill the rest with PAD tokens.
  while (i < ENCODING_LENGTH - 1) {
    returnArray.push(DICTIONARY.PAD);
    i++;
  }

  // Log the result to see what you made.
  console.log([returnArray]);

  // Convert to a TensorFlow Tensor and return that.
  return tf.tensor([returnArray]);
}

Genial. Ahora, vuelve a la función handleCommentPost() y reemplázala por esta nueva versión.

Consulta el código de los comentarios de lo que agregaste:

secuencia de comandos.js

/**
 * Function to handle the processing of submitted comments.
 **/
function handleCommentPost() {
  // Only continue if you are not already processing the comment.
  if (! POST_COMMENT_BTN.classList.contains(PROCESSING_CLASS)) {
    // Set styles to show processing in case it takes a long time.
    POST_COMMENT_BTN.classList.add(PROCESSING_CLASS);
    COMMENT_TEXT.classList.add(PROCESSING_CLASS);

    // Grab the comment text from DOM.
    let currentComment = COMMENT_TEXT.innerText;
    // Convert sentence to lower case which ML Model expects
    // Strip all characters that are not alphanumeric or spaces
    // Then split on spaces to create a word array.
    let lowercaseSentenceArray = currentComment.toLowerCase().replace(/[^\w\s]/g, ' ').split(' ');

    // Create a list item DOM element in memory.
    let li = document.createElement('li');

    // Remember loadAndPredict is asynchronous so you use the then
    // keyword to await a result before continuing.
    loadAndPredict(tokenize(lowercaseSentenceArray), li).then(function() {
      // Reset class styles ready for the next comment.
      POST_COMMENT_BTN.classList.remove(PROCESSING_CLASS);
      COMMENT_TEXT.classList.remove(PROCESSING_CLASS);

      let p = document.createElement('p');
      p.innerText = COMMENT_TEXT.innerText;

      let spanName = document.createElement('span');
      spanName.setAttribute('class', 'username');
      spanName.innerText = currentUserName;

      let spanDate = document.createElement('span');
      spanDate.setAttribute('class', 'timestamp');
      let curDate = new Date();
      spanDate.innerText = curDate.toLocaleString();

      li.appendChild(spanName);
      li.appendChild(spanDate);
      li.appendChild(p);
      COMMENTS_LIST.prepend(li);

      // Reset comment text.
      COMMENT_TEXT.innerText = '';
    });
  }
}

Por último, actualiza la función loadAndPredict() para establecer un estilo si se detecta un comentario como spam.

Por ahora, solo cambiarás el estilo, pero podrás retener el comentario en una cola de moderación o evitar que se envíe.

secuencia de comandos.js

/**
 * Asynchronous function to load the TFJS model and then use it to
 * predict if an input is spam or not spam.
 */
async function loadAndPredict(inputTensor, domComment) {
  // Load the model.json and binary files you hosted. Note this is
  // an asynchronous operation so you use the await keyword
  if (model === undefined) {
    model = await tf.loadLayersModel(MODEL_JSON_URL);
  }

  // Once model has loaded you can call model.predict and pass to it
  // an input in the form of a Tensor. You can then store the result.
  var results = await model.predict(inputTensor);

  // Print the result to the console for us to inspect.
  results.print();

  results.data().then((dataArray)=>{
    if (dataArray[1] > SPAM_THRESHOLD) {
      domComment.classList.add('spam');
    }
  })
}

11. Actualizaciones en tiempo real: Node.js y WebSockets

Ahora tienes un frontend que funciona con la detección de spam. La pieza final del rompecabezas es el uso de Node.js con WebSockets para la comunicación en tiempo real y la actualización en tiempo real de los comentarios agregados que no son spam.

socket.io

socket.io es una de las maneras más populares (en el momento de la escritura) de usar WebSockets con Node.js. Ahora, dile a Glitch que quieres incluir la biblioteca de socket.io en la compilación. Para ello, edita package.json en el directorio de nivel superior (en la carpeta superior de la carpeta www) a fin de incluir socket.io como una de las dependencias. ,

. JSON

{
  "name": "tfjs-with-backend",
  "version": "0.0.1",
  "description": "A TFJS front end with thin Node.js backend",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.17.1",
    "socket.io": "^4.0.1"
  },
  "engines": {
    "node": "12.x"
  }
}

¡Genial! Luego, actualiza index.html dentro de la carpeta www para incluir la biblioteca socket.io.

Solo tienes que colocar esta línea de código por encima de la importación de la etiqueta de secuencia de comandos HTML para script.js cerca del final del archivo index.html:

index.html

<script src="/socket.io/socket.io.js"></script>

Ahora debería tener 3 etiquetas de secuencia de comandos en su archivo index.html:

  • la primera importa la biblioteca de TensorFlow.js
  • la segunda importación de socket.io que acaba de agregar
  • y la última debe importar el código script.js.

A continuación, edita server.js para configurar socket.io dentro del nodo y crear un backend simple a fin de retransmitir los mensajes recibidos a todos los clientes conectados.

Consulta los comentarios de código más abajo para ver una explicación de lo que hace el código Node.js:

server.js

const http = require('http');
const express = require("express");
const app = express();
const server = http.createServer(app);

// Require socket.io and then make it use the http server above.
// This allows us to expose correct socket.io library JS for use
// in the client side JS.
var io = require('socket.io')(server);

// Serve all the files in 'www'.
app.use(express.static("www"));

// If no file specified in a request, default to index.html
app.get("/", (request, response) => {
  response.sendFile(__dirname + "/www/index.html");
});

// Handle socket.io client connect event.
io.on('connect', socket => {
  console.log('Client connected');

  // If you wanted you could emit existing comments from some DB
  // to client to render upon connect.
  // socket.emit('storedComments', commentObjectArray);

  // Listen for "comment" event from a connected client.
  socket.on('comment', (data) => {
    // Relay this comment data to all other connected clients
    // upon receiving.
    socket.broadcast.emit('remoteComment', data);
  });
});

// Start the web server.
const listener = server.listen(process.env.PORT, () => {
  console.log("Your app is listening on port " + listener.address().port);
});

¡Genial! Ahora tiene un servidor web que detecta eventos socket.io. Concretamente, tienes un evento comment cuando un nuevo comentario proviene de un cliente y el servidor emite eventos remoteComment que el código del cliente escuchará para procesar un comentario remoto. Por último, lo último que debe hacer es agregar la lógica de socket.io al código del cliente para emitir y controlar estos eventos.

Primero, agrega el siguiente código al final de script.js para conectarte al servidor de socket.io y detectar o controlar los eventos remotos comentario recibidos:

secuencia de comandos.js

// Connect to Socket.io on the Node.js backend.
var socket = io.connect();

function handleRemoteComments(data) {
  // Render a new comment to DOM from a remote client.
  let li = document.createElement('li');
  let p = document.createElement('p');
  p.innerText = data.comment;

  let spanName = document.createElement('span');
  spanName.setAttribute('class', 'username');
  spanName.innerText = data.username;

  let spanDate = document.createElement('span');
  spanDate.setAttribute('class', 'timestamp');
  spanDate.innerText = data.timestamp;

  li.appendChild(spanName);
  li.appendChild(spanDate);
  li.appendChild(p);

  COMMENTS_LIST.prepend(li);
}

// Add event listener to receive remote comments that passed
// spam check.
socket.on('remoteComment', handleRemoteComments);

Por último, agrega código a la función loadAndPredict para emitir un evento socket.io si un comentario no es spam. Esto te permite actualizar a los otros clientes conectados con este comentario nuevo, ya que el contenido de este mensaje se retransmitirá a través del código server.js que escribiste anteriormente.

Simplemente reemplaza tu función loadAndPredict existente por el siguiente código que agrega una sentencia else a la verificación final de spam. Si el comentario no es spam, llama a socket.emit() para enviar todos los datos de comentarios:

secuencia de comandos.js

/**
 * Asynchronous function to load the TFJS model and then use it to
 * predict if an input is spam or not spam. The 2nd parameter
 * allows us to specify the DOM element list item you are currently
 * classifying so you can change it+s style if it is spam!
 */
async function loadAndPredict(inputTensor, domComment) {
  // Load the model.json and binary files you hosted. Note this is
  // an asynchronous operation so you use the await keyword
  if (model === undefined) {
    model = await tf.loadLayersModel(MODEL_JSON_URL);
  }

  // Once model has loaded you can call model.predict and pass to it
  // an input in the form of a Tensor. You can then store the result.
  var results = await model.predict(inputTensor);

  // Print the result to the console for us to inspect.
  results.print();

  results.data().then((dataArray)=>{
    if (dataArray[1] > SPAM_THRESHOLD) {
      domComment.classList.add('spam');
    } else {
      // Emit socket.io comment event for server to handle containing
      // all the comment data you would need to render the comment on
      // a remote client's front end.
      socket.emit('comment', {
        username: currentUserName,
        timestamp: domComment.querySelectorAll('span')[1].innerText,
        comment: domComment.querySelectorAll('p')[0].innerText
      });
    }
  })
}

Bien hecho. Si seguiste la acción correctamente, ahora deberías poder abrir 2 instancias de tu página de index.html.

Cuando publicas comentarios que no son spam, deberías verlos renderizados en el otro cliente casi al instante. Si el comentario es spam, simplemente nunca se enviará y, en su lugar, se marcará como spam en el frontend que lo generó solo de la siguiente manera:

ee0f13398ea4e91e.gif

12. Felicitaciones

¡Felicitaciones! Ya comenzaste a usar el aprendizaje automático con TensorFlow.js en el navegador web para detectar una aplicación real y detectar comentarios spam.

Pruébalo y pruébalo en varios comentarios. Es posible que notes algunas fallas. También notará que, si ingresa una oración de más de 20 palabras, en este momento fallará, ya que el modelo espera 20 palabras como entrada.

En ese caso, es posible que debas dividir las oraciones largas en grupos de 20 palabras y, luego, tener en cuenta la probabilidad de spam de cada oración secundaria para determinar si se muestran o no. Lo dejaremos como una tarea adicional opcional con la que podría experimentar, ya que existen muchos enfoques que puede adoptar para este fin.

En el siguiente codelab, te mostraremos cómo volver a entrenar este modelo con tus datos de comentarios personalizados para casos extremos que no detecta actualmente, o incluso para cambiar la expectativa de entrada del modelo a fin de que pueda controlar oraciones que tiene más de 20 palabras y, luego, los exporta y usa con TensorFlow.js.

Si por algún motivo tienes problemas, compara tu código con esta versión completa disponible aquí y comprueba si te perdiste algo.

Resumen

En este codelab, lograste lo siguiente:

  1. Aprendió qué es TensorFlow.js y qué modelos existen para el procesamiento de lenguaje natural.
  2. Creaste un sitio web ficticio que permite comentarios en tiempo real para un sitio web de ejemplo.
  3. Se cargó un modelo de aprendizaje automático previamente entrenado apto para la detección de spam en comentarios a través de TensorFlow.js en la página web.
  4. Aprendimos a codificar oraciones para usarlas con el modelo de aprendizaje automático cargado y a encapsular esa codificación en un tensor.
  5. Se interpretó el resultado del modelo de aprendizaje automático para decidir si desea dejar en espera de revisión el comentario y, de lo contrario, enviarlo al servidor para retransmitirlo a otros clientes conectados en tiempo real.

Próximos pasos

Ahora que tienes una base de trabajo desde la cual comenzar, ¿qué ideas creativas se te ocurren para extender este código estándar de modelo de aprendizaje automático a un caso de uso real en el que podrías estar trabajando?

Comparte tus creaciones con nosotros

También puedes ampliar fácilmente lo que creaste hoy para otros casos de uso creativo. Te recomendamos pensar de manera creativa y seguir hackeando.

Recuerda etiquetarnos en redes sociales con el hashtag #MadeWithTFJS para tener la oportunidad de que se incluya tu proyecto en el blog de TensorFlow o, incluso, en eventos futuros. Nos encantaría ver tus creaciones.

Más codelabs de TensorFlow.js para aprender más

Sitios web que puedes revisar