Path: blob/master/site/es-419/hub/tutorials/tf2_text_classification.ipynb
25118 views
Copyright 2019 The TensorFlow Hub Authors.
Licensed under the Apache License, Version 2.0 (the "License");
Clasificación de textos con revisiones de películas
En este bloc de notas se clasifican reseñas de películas como positiva o negativa a partir del texto de la reseña. Este es un ejemplo de clasificación binaria (o de dos clases), un tipo de problema de aprendizaje automático importante y ampliamente aplicable.
Usaremo los conjuntos de datos de IMDB que contiene el texto de 50 000 reseñas de películas del Conjunto de datos de películas de Internet. Se divide en 25 000 reseñas para entrenamiento y 25 000 reseñas para prueba. Los conjuntos de entrenamiento y prueba están equilibrados, lo que significa que contienen la misma cantidad de reseñas positivas y negativas.
En este bloc de notas se usa tf.keras, una API de alto nivel para generar y entrenar modelos en TensorFlow, y TensorFlow Hub, una biblioteca y plataforma para aprendizaje por transferencia. Si desea obtener un tutorial más avanzado sobre clasificación de textos con tf.keras
, consulte la Guía de clasificación de textos de MLCC.
Más modelos
Aquí puede encontrar modelos más expresivos o de mayor rendimiento que puede usar para generar la incorporación de texto.
Preparación
Descargar el conjunto de datos de IMDB
El conjunto de datos de IMDB está disponible en conjuntos de datos de TensorFlow. El siguiente código sirve para descargar el conjunto de datos de IMDB en su computadora (o en el tiempo de ejecución de Colab):
Explorar los datos
Tomémonos un momento para comprender el formato de los datos. Cada ejemplo es una frase que representa la reseña de película y una etiqueta correspondiente. La frase no se preprocesa de ninguna manera. La etiqueta es un valor de número entero que puede ser 0 o 1, donde 0 corresponde a una reseña negativa y 1 corresponde a una reseña positiva.
Imprimamos los primeros 10 ejemplos.
Imprimamos también las primeras 10 etiquetas.
Generar el modelo
La red neuronal se crea apilando capas, lo que implica tomar tres decisiones principales en términos de arquitectura:
¿Cómo se representará el texto?
¿Cuántas capas se usarán en el modelo?
¿Cuántas unidades ocultas se usarán para cada capa?
En este ejemplo, los datos de entrada están compuestos por oraciones. Las etiquetas que se deben predecir son 0 o 1.
Una forma de representar el texto es convertir las oraciones en vectores incorporados. Podemos usar una incorporación de texto preentrenada como la primera capa, lo que nos dará dos ventajas:
No hay que preocuparse por el preprocesamiento del texto.
Podemos sacar provecho del aprendizaje por transferencia.
Para este ejemplo usaremos un modelo de TensorFlow Hub llamado google/nnlm-en-dim50/2.
Hay otros dos modelos para probar en este tutorial:
google/nnlm-en-dim50-with-normalization/2: igual que google/nnlm-en-dim50/2, pero con normalización de texto adicional para eliminar la puntuación. Esto puede ayudar a obtener una mejor cobertura de las incorporaciones de tokens en el vocabulario en el texto de entrada.
google/nnlm-en-dim128-with-normalization/2: un modelo más grande con una dimensión de incorporación de 128 en lugar del modelo más pequeño de 50.
Primero crearemos una capa de Keras que use un modelo de TensorFlow Hub para incorporar las oraciones y la probaremos en un par de ejemplos de entrada. Observe como la forma de salida de las incorporaciones que se producen es la requerida: (num_examples, embedding_dimension)
.
Ahora vamos a generar un modelo completo:
Las capas se apilan secuencialmente para generar el clasificador:
La primera capa es una capa de TensorFlow Hub. Esta capa usa un modelo guardado preentrenado para asignar una oración a su vector de incorporación. El modelo que estamos usando (google/nnlm-en-dim50/2) divide la oración en tokens, incorpora cada token y luego combina la incorporación. Las dimensiones resultantes son:
(num_examples, embedding_dimension)
.Este vector de salida de longitud fija se canaliza a través de una capa (
Dense
) completamente conectada con 16 unidades ocultas.La última capa está densamente conectada con un único nodo de salida. Esto genera logits: las probabilidades logarítmicas de la clase verdadera, según el modelo.
Unidades ocultas
El modelo anterior tiene dos capas intermedias u "ocultas" entre la entrada y la salida. La cantidad de salidas (unidades, nodos o neuronas) es la dimensión del espacio de representación para la capa. En otras palabras, la cantidad de libertad que se le permite a la capa cuando aprende una representación interna.
Si un modelo tiene más unidades ocultas (un espacio de representación de alta dimensionalidad) o más capas, la red puede aprender representaciones más complejas. Sin embargo, la red se vuelve computacionalmente más costosa y puede derivar en patrones indeseados de aprendizaje; patrones que mejoran el rendimiento de los datos de entrenamiento pero no de los datos de prueba. A esto se lo denomina "sobreajuste" (overfitting) y lo veremos más adelante.
Función de pérdida y optimizador
Un modelo necesita una función de pérdida y un optimizador para el entrenamiento. Dado que este es un problema de clasificación binaria y el modelo genera una probabilidad (una capa de una sola unidad con una activación sigmoide), usaremos la función de pérdida binary_crossentropy
.
Esta no es la única opción para una función de pérdida, usted podría, por ejemplo, elegir mean_squared_error
. Pero, por lo general, binary_crossentropy
es mejor para trabajar con probabilidades; mide la "distancia" entre las distribuciones de probabilidad o, en nuestro caso, entre la distribución real y las predicciones.
Más adelante, cuando exploremos los problemas de regresión (por ejemplo, para predecir el precio de una vivienda), veremos cómo usar otra función de pérdida conocida como error cuadrático medio.
Ahora, configure el modelo para usar un optimizador y una función de pérdida:
Crear un conjunto de validación
Durante el entrenamiento, nos conviene comprobar la exactitud del modelo con datos que no haya visto antes. Crea un conjunto de validación. Para crearlo separamos 10 000 ejemplos de los datos de entrenamiento originales. (¿Por qué no usamos el conjunto de prueba ahora? Nuestro objetivo es desarrollar y ajustar el modelo usando solamente los datos de entrenamiento y después, usar los datos de prueba una sola vez para evaluar la precisión).
Entrenar el modelo
Entrene el modelo durante 40 épocas en minilotes de 512 muestras. Es decir, 40 iteraciones sobre todas las muestras en los tensores x_train
y y_train
. Durante el entrenamiento, monitoree la pérdida y la precisión del modelo en las 10 000 muestras del conjunto de validación:
Evaluar el modelo
Veamos el desempeño del modelo. Nos devolverá dos valores; la pérdida (un número que representa nuestro error, los valores bajos son mejores) y la precisión.
Este enfoque, relativamente sencillo, alcanza una precisión de aproximadamente un 87 %. Con enfoques más avanzados, el modelo debería acercarse al 95 %.
Crear un gráfico de precisión y pérdida a lo largo del tiempo
model.fit()
devuelve un objeto History
que contiene un diccionario con todo lo que ocurrió durante el entrenamiento:
Hay cuatro entradas: una por cada métrica que se monitoreó durante el entrenamiento y la validación. Podemos usarlas para trazar la pérdida y validación del entrenamiento, para compararlas. Podemos hacer lo mismo con la precisión de entrenamiento y validación:
En este gráfico, los puntos representan la pérdida y la precisión del entrenamiento y las líneas continuas reflejan la pérdida y la precisión de la validación.
Como puede ver, la pérdida del entrenamiento se reduce época tras época y la precisión del entrenamiento aumenta a medida que pasan las épocas. Esto es lo que suele pasar cuando se usa una optimización con descenso de gradiente, debe reducir al mínimo la cantidad deseada en cada iteración.
Esto no es lo que sucede en el caso de la pérdida y la precisión de la validación, al parecer llegan a su punto máximo después de aproximadamente veinte épocas. Este es un ejemplo de sobreajuste: el modelo funciona mejor con los datos de entrenamiento que con los datos que no ha visto anteriormente. Pasado este punto, el modelo se sobreoptimiza y aprende representaciones específicas de los datos de entrenamiento que no se generalizan a los datos de prueba.
Para este caso particular, podríamos evitar el sobreajuste con tan solo detener el entrenamiento después de aproximadamente veinte épocas. Más adelante verá cómo hacer esto automáticamente con una retrollamada.