{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "Qjsf78ymkS0E" }, "source": [ "#
Taller de Aprendizaje Automático
\n", "##
Taller 9: *Natural Language Processing* (NLP)
" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "SUfgw7Siq3td" }, "source": [ "## Introducción" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "I4y3HbLOkOVD" }, "source": [ "La siguiente actividad propone el abordaje de un problema de procesamiento de lenguaje natural (NLP) utilizando herramientas de *embedding* y modelos RNN. El conjunto de datos que se utilizará es IMDb, el cual corresponde a un problema de clasificación donde se tienen 50000 criticas de películas (35000 de *train* y 15000 de *test*), y se quiere estimar si éstas son críticas positivas (1) o negativas (0). \n", "\n", "La propuesta consiste en entender y reproducir los pasos de la sección *Sentiment Analysis* para los datos **sin procesar**, agregando algunas variantes como mitigar el sobreajuste y entender la herramienta *embeddings*.\n", "\n", "En este Taller también se introduce la biblioteca *Streamlit*, utilizada para desarrollar prototipos de aplicaciones web de aprendizaje automático. Aquellos que así lo deseen, podrán generar de manera sencilla una aplicación web que clasifique las críticas proporcionadas por los usuarios." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "rY6vz2Ekj8ig" }, "source": [ "## Objetivos\n", "\n", "\n", "* Aplicar modelos basados en RNN a un problema de NLP.\n", "* Trabajar con embeddings para secuencias de texto, en particular embeddings preentrenados.\n", "* Utilizar herramientas para la visualización de embeddings.\n", "* (Opcional, no evaluado) Desarrollar una aplicación web que clasifique críticas proporcionadas por los usarios " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "common-destiny" }, "source": [ "## Formas de trabajo" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "xVgxoLgl1-KA" }, "source": [ "### Opción 1: Trabajar localmente\n", "Recomendamos esta opción solo si dispones de una GPU. Si no es el caso, sugerimos utilizar Colab." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "moral-gallery" }, "source": [ "Descargar los datos en su máquina personal y trabajar en su propio ambiente de desarrollo.\n", "\n", "`conda activate TAA-py310` \n", "`jupyter-notebook` " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "UfcTy55R2A7w" }, "source": [ "Los paquetes faltantes se pueden instalar desde el notebook haciendo: \n", "` !pip install paquete_faltante` " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "lined-sport" }, "source": [ "### Opción 2: Trabajar en *Colab*. " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "lined-candle" }, "source": [ "\n", " \n", "
\n", " Ejecutar en Google Colab\n", "
" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "expensive-jewel" }, "source": [ "Se puede trabajar en Google Colab. Para ello es necesario contar con una cuenta de **google drive** y ejecutar un notebook almacenado en dicha cuenta. De lo contrario, no se conservarán los cambios realizados en la sesión. En caso de ya contar con una cuenta, se puede abrir el notebook y luego ir a `Archivo-->Guardar una copia en drive`. " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "h8OOpzq91ITq" }, "source": [ "La siguiente celda realiza la configuración necesaria para obtener datos desde la plataforma Kaggle. Le solicitará que suba el archivo *kaggle.json* asociado a su cuenta." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:15.018423Z", "start_time": "2022-06-08T19:24:15.011294Z" }, "colab": { "base_uri": "https://localhost:8080/", "height": 89 }, "executionInfo": { "elapsed": 7753, "status": "ok", "timestamp": 1686090159474, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "LlKwJ6sKmhBt", "outputId": "b1411d1e-bd71-4bba-ccf9-8d85bafc84d5" }, "outputs": [], "source": [ "import warnings\n", "\n", "warnings.filterwarnings(\"ignore\")\n", "from google.colab import files\n", "\n", "# El siguiente archivo solicitado es para habilitar la API de Kaggle en el entorno que está trabajando.\n", "# Este archivo se descarga entrando a su perfíl de Kaggle, en la sección API, presionando donde dice: Create New API Token\n", "\n", "uploaded = files.upload()\n", "\n", "for fn in uploaded.keys():\n", " print(\n", " 'User uploaded file \"{name}\" with length {length} bytes'.format(\n", " name=fn, length=len(uploaded[fn])\n", " )\n", " )\n", "\n", "# Then move kaggle.json into the folder where the API expects to find it.\n", "!mkdir -p ~/.kaggle/ && mv kaggle.json ~/.kaggle/ && chmod 600 ~/.kaggle/kaggle.json" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "Xj1R6mm14u0t" }, "source": [ "# Parte 1: Análisis y preprocesamiento de datos\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "M44JXP4Z41BI" }, "source": [ "Se utilizará el conjunto de IMDb provisto por Kaggle. Se tienen 50000 criticas de películas que al igual que en el *Taller 2* se utilizarán 35000 para *train* y 15000 para *test*.\n", "\n", "* Ejecutar la siguiente celda para descargar el conjunto y verificar que los conjuntos tienen la cantidad de instancias esperadas. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.584675Z", "start_time": "2022-06-08T19:24:23.473981Z" }, "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 2596, "status": "ok", "timestamp": 1686090165028, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "CwAZeeqamXo2", "outputId": "50a59952-9d16-4cee-cf85-5b2fbf28f7f1" }, "outputs": [], "source": [ "# Descarga la base IMDb de Kaggle\n", "!kaggle datasets download -d lakshmi25npathi/imdb-dataset-of-50k-movie-reviews" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.601403Z", "start_time": "2022-06-08T19:24:23.590754Z" }, "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 4217, "status": "ok", "timestamp": 1686090169243, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "nj1ZMjmtn3cX", "outputId": "919edbfd-78d7-4a43-be42-54cbb2d79632" }, "outputs": [], "source": [ "import zipfile\n", "import pandas as pd\n", "import tensorflow as tf\n", "\n", "# Se descomprime el archivo descargado\n", "with zipfile.ZipFile(\"imdb-dataset-of-50k-movie-reviews.zip\", \"r\") as zip_ref:\n", " zip_ref.extractall(\"\")\n", "\n", "# Se levanta como pandas DataFrame\n", "data_file = \"IMDB Dataset.csv\"\n", "data = pd.read_csv(data_file)\n", "\n", "# Separación de Conjuntos\n", "N = 35000\n", "X_train = data.loc[: N - 1, \"review\"].values\n", "y_train = data.loc[: N - 1, \"sentiment\"].values == \"positive\"\n", "X_test = data.loc[N:, \"review\"].values\n", "y_test = data.loc[N:, \"sentiment\"].values == \"positive\"\n", "\n", "# Armado de los Tensorflow Datasets\n", "data_train = tf.data.Dataset.from_tensor_slices((X_train, y_train))\n", "data_test = tf.data.Dataset.from_tensor_slices((X_test, y_test))\n", "\n", "# Verificación\n", "print(\"Train Size:\", len(data_train), \"Test Size:\", len(data_test))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "rQpeE5zh8ZlC" }, "source": [ "* Del conjunto de entrenamiento visualizar tanto una review positiva como una negativa. Se sugiere ir a los Notebooks del *Capítulo 16*. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.608069Z", "start_time": "2022-06-08T19:24:20.153Z" }, "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 11, "status": "ok", "timestamp": 1685821204215, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "SMp1E9d27ro5", "outputId": "deecc372-69a2-4f95-bc16-51dc05877e8a" }, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "iYU0vZiD65J1" }, "source": [ "* Reservar unas 5000 críticas de los datos de entrenamiento para validación. Puede ser útil el uso del método *.skip()*. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.608859Z", "start_time": "2022-06-08T19:24:20.156Z" }, "executionInfo": { "elapsed": 8, "status": "ok", "timestamp": 1686084565823, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "D55BIKVp7M2K" }, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "zTQ3PHH338ys" }, "source": [ "* Prepare los batches para todos los conjuntos" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "executionInfo": { "elapsed": 7, "status": "ok", "timestamp": 1686084565823, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "GIFFRf6e4BmI" }, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "gEdt3JsjIjIS" }, "source": [ "* Keras proporciona una capa de `TextVectorization` para el preprocesamiento básico de texto. Explique el funcionamiento y adapte una capa para los datos de entrenemiento en cuestión. Se sugiere leer la sección asociada a esta capa en el *Capítulo 13* del libro. Utilice un tamaño de vocabulario de 10000 palabras. \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "LhvC46EhHf2K" }, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "xMkt4V3_4NGm" }, "source": [ "* Obtenga el diccionario de la capa `TextVectorization`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 10, "status": "ok", "timestamp": 1685993914944, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "Q-LMMrdwH4YP", "outputId": "7363491d-9d69-4340-ffcf-aa8813ad0889" }, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "TL0ayaj4C90z" }, "source": [ "* Siguiendo el ejemplo adjunto en la [documentación](https://www.tensorflow.org/api_docs/python/tf/keras/layers/TextVectorization) de la capa `TextVectorization`. Cree un modelo de keras que cuente únicamente con esta capa y observe el resultado de pasar una crítica cualquiera. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "UUSqc8-o4Xj2" }, "source": [ "* Utilizando esta capa ¿cuáles son los largos de secuencias para los primeros *batches*? ¿Es un problema a resolver que todos tengan largos distintos? ¿Por qué?." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 82326, "status": "ok", "timestamp": 1685803862353, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "RP2mCScC4Zz4", "outputId": "6ac94a21-02ae-4ef8-9623-7cd455f9b708" }, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "VNZlLb6v4OHS" }, "source": [ "# Parte 2: *Embedding*" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "ZmZeKwMu4dlD" }, "source": [ "* Cree y entrene el modelo que aparece al final de la sección *Sentiment Analysis* y previo a la sección *Masking* del *Capítulo 16* en la tercera edición del libro." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "kYunxz_uRruE" }, "source": [ "* Implemente el uso de *Masking* en el modelo que ya utilizó. ¿Por qué podría ser esto útil para el aprendizaje?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "Uz0ynw4zy1w5" }, "source": [ "* Observe que el modelo se sobreajusta a los datos. Utilice alguna técnica vista para regularizar." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "QqU7n4gMZc5X" }, "source": [ "* El modelo cuenta con una capa de entrada de *embedding* la cual abarca la mayoría de los parámetros entrenables. En este caso un *embedding* es un vector entrenable que representa una palabra en nuevo espacio cuyo tamaño es un hiperparámetro. La concatenación de estos vectores conforma la matriz de *embedding*, donde su cantidad de filas corresponde a la suma del tamaño del vocabulario y la cantidad de columnas a las dimensiones de los vectores (*embed_size*). Al igual que una matriz de pesos, ésta se inicializa de forma aleatoria, y actualiza sus valores para cada *step* de entrenamiento.\n", "\n", " * ¿Cuál es la ventaja de utilizar una capa de *embedding*? (Ver la sección *Encoding Categorical Features Using Embeddings* del *Capítulo 13* del libro.)\n", " * Visualizar una representación del espacio de *embedding* utilizando *Comet*. **Importante:** para evitar errores, modifique del diccionario el valor del espacio por ``. \n", "\n", " Para este último punto se recomienda seguir el siguiente ejemplo: [logging-embeddings](https://www.comet.ml/docs/user-interface/embeddings/#logging-embeddings). \n", "\n", "* Para su mejor modelo: visualizar a qué distancias se encuentran las palabras unas de otras tanto en la representación a baja dimensión como en el espacio de *embedding*. Sobre todo probar con adjetivos positivos (*wonderful*, *excellent*, etc.) y negativos (*ugly*, *boring*, etc.) comparando los resultados. ¿Qué logra observar?." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "PfSujuskbZog" }, "source": [ "# Parte 3: *Embedding Preentrenado*" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "g4y9GduFbiZD" }, "source": [ "Una de las técnicas para mejorar el desempeño en este tipo de problemas es utilizar *embeddings* ya entrenados. \n", "Siguiendo el ejemplo [Using pre-trained word embeddings](https://keras.io/examples/nlp/pretrained_word_embeddings/):" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "ACU7xlN8bqzP" }, "source": [ "* Descargar el *embedding* preentrenado [GloVE](https://nlp.stanford.edu/projects/glove/) que aparece en la sección *Load pre-trained word embeddings*. Deberan utilizar el `glove.6B.100d.txt` que consiste en embeddings de dimensión 100." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.618500Z", "start_time": "2022-06-08T19:24:20.229Z" }, "id": "R368yCtObhyk" }, "outputs": [], "source": [ "!wget https://nlp.stanford.edu/data/glove.6B.zip\n", "!unzip -q glove.6B.zip" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "z9ARmJXcbyhU" }, "source": [ "* Preparar la nueva matriz de *embedding*. ¿Cuántas palabras del conjunto de entrenamiento se encuentran en el vocabulario de GloVE? ¿Cuántas no?." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.619152Z", "start_time": "2022-06-08T19:24:20.231Z" }, "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 8639, "status": "ok", "timestamp": 1685808550596, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "7nfz9Ee1b0yP", "outputId": "2c2d46d5-ee0d-4f38-dded-6b25c816cf48" }, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "ipkjXoNecR2_" }, "source": [ "* Entrenar el modelo con la nueva matriz de *embedding* de manera que los valores de ésta se mantengan fijos (ver parámetro en la capa de *embedding*). Utilice masking. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "BwqxdPALEyJ4" }, "source": [ "* Partiendo del modelo con los pesos aprendidos anteriormente, haga los *embeddings* entrenables y observe cómo cambian las representaciones de las palabras. Puede ser útil modificar el *learning rate*." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "m0_RrsTZsaKM" }, "source": [ "* Comparar con los modelos anteriores en cuanto al desempeño, la cantidad de parámetros y el tiempo de entrenamiento.\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Respuesta: " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "Af_D4NTCsezj" }, "source": [ "* Visualizar cómo es el espacio de *embedding*. ¿Qué diferencias puede observar con respecto al anterior?\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "4tsZq6m2FMjv" }, "source": [ "Respuesta: " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "QnyfpJny_Eq-" }, "source": [ "# Parte 4: Mejoras en los Modelos" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "pcsXZdnYo-sl" }, "source": [ "Se sugieren algunas líneas que podrían mejorar los desempeños obtenidos en las partes anteriores: \n", "\n", "* Ampliar el tamaño del vocabulario utilizado durante el entrenamiento, junto con aumentar la complejidad del modelo.\n", "* Implementar una función de preprocesamiento de texto que realice tareas como eliminar las etiquetas HTML, eliminar números y llevar a cabo otras acciones relevantes.\n", "* Considerar la utilización de n-gramas y/o modificar el tokenizador utilizado. \n", "* Evaluar el cambio de las neuronas recurrentes de GRU a LSTM. \n", "\n", "Piense por qué tiene sentido explorar estas estrategias y pruebe alguna que considere relevante o proponga alguna otra que le parezca relevante. \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "90O_LXGExzWp" }, "source": [ "# Parte 5: Desarrollo de una aplicación web (Opcional)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "FAIXZ-_DNeN7" }, "source": [ "En esta parte veremos cómo generar una aplicación web sencilla que permita mostrar el funcionamiento de un modelo que hayamos entrenado. Para ello utilizaremos la biblioteca [Streamlit](https://streamlit.io/)." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2022-06-07T13:41:26.128144Z", "start_time": "2022-06-07T13:41:26.119600Z" }, "id": "Oz7kKyFaF6uQ" }, "source": [ "## Streamlit\n", "Streamlit es una biblioteca de código abierto escrita en Python que permite crear y compartir aplicaciones web que usan algoritmos de aprendizaje automático. En la [documentación](https://docs.streamlit.io/) encontrará información sobre cómo instalar y crear aplicaciones utilizando la biblioteca. El flujo de trabajo básico consta de los siguientes pasos: \n", "\n", "1. Instalación \n", "2. Desarrollo de la aplicación \n", "3. Desplieque de la aplicación" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2022-06-07T13:42:20.285367Z", "start_time": "2022-06-07T13:42:20.280067Z" }, "heading_collapsed": true, "id": "G_y-rIEzF6uQ" }, "source": [ "### Instalación\n", "En la mayoría de los casos, la biblioteca debería quedar instalada luego de crear un ambiente virtual (por ejemplo de conda) y hacer: \n", "\n", "`pip install streamlit` \n", "\n", "Puede verificar que la instalación sea correcta haciendo: \n", "\n", "`streamlit hello`\n", "\n", "Puede ver los detalles de instalación en https://docs.streamlit.io/library/get-started/installation" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2022-06-07T13:43:13.534243Z", "start_time": "2022-06-07T13:43:13.529929Z" }, "id": "ACy7SerfF6uR" }, "source": [ "### Desarrollo de la aplicación \n", "\n", "Se sugiere desarrollar la aplicación partiendo de un ejemplo que clasifica críticas de cine utilizando un modelo entrenado con las técnicas vistas en el Taller 2. Dicho ejemplo puede verse en funcionamiento [acá](https://share.streamlit.io/taa-fing/taa-2022/main/apps/movie_review_app/movie_review_app.py). La siguiente celda descarga el código fuente y lo descomprime. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.630093Z", "start_time": "2022-06-08T19:24:20.258Z" }, "id": "6s5kTwpCF6uR" }, "outputs": [], "source": [ "!wget iie.fing.edu.uy/~carbajal/movie_review/apps.zip\n", "!unzip apps.zip" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "MDw4xQQ_F6uR" }, "source": [ "Copie el archivo *movie_review_app.py*, modifique el nombre, y realice las siguientes modificaciones (además de las de diseño que crea conveniente): \n", "\n", "**Cambio de Modelo:** Para hacer inferencia fuera de este *Notebook* será necesario contar con el modelo entrenado. El modelo se puede guardar con alguna de las técnicas vistas en el curso. Se sugiere utilizar el *Callback* **ModelCheckpoint**. " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "pYAdJltN6iWw" }, "source": [ "**Modificación del pipeline de inferencia:** El objetivo es generar una función que a partir de una única reseña prediga si la reseña es *positiva*(1) o *negativa*(0). Para ello se brinda una función a completar " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.632348Z", "start_time": "2022-06-08T19:24:20.263Z" }, "id": "wWkkHf_67KPS" }, "outputs": [], "source": [ "# Pipeline funtion to make inference\n", "def pipeline_inference(review, model):\n", " \"\"\"\n", " Función que prepara una review aislada y hace inferencia con el modelo.\n", "\n", " Entradas:\n", " review: String con la review a hacer inferencia\n", " model: Modelo entrenado con el que se realiza inferencia\n", "\n", " Salida:\n", "\n", " pred: Predicción del modelo\n", "\n", " \"\"\"\n", "\n", " # ...\n", "\n", " return pred" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "a_2uml4vSIvi" }, "source": [ "* Las siguientes celdas prueban la función. Verifique que funciona correctamente." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.633515Z", "start_time": "2022-06-08T19:24:20.265Z" }, "id": "qN9RStj0DQD_" }, "outputs": [], "source": [ "# Load model\n", "checkpoint_filepath = \"/content/...\"\n", "\n", "model_loaded = keras.models.load_model(checkpoint_filepath)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.634730Z", "start_time": "2022-06-08T19:24:20.266Z" }, "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 4, "status": "ok", "timestamp": 1685822396086, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "ePLSyMO1BMuX", "outputId": "663b9125-3272-47b8-9384-6ba92df7629d" }, "outputs": [], "source": [ "review = \"This movie is really boring. I do not recommend it.\"\n", "\n", "pred = pipeline_inference(review, model_loaded)\n", "\n", "pred" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2022-06-08T19:24:23.636273Z", "start_time": "2022-06-08T19:24:20.268Z" }, "colab": { "base_uri": "https://localhost:8080/" }, "executionInfo": { "elapsed": 494, "status": "ok", "timestamp": 1685822405417, "user": { "displayName": "Emiliano Acevedo", "userId": "17654465047341541848" }, "user_tz": 180 }, "id": "WmV5G1WRTDpi", "outputId": "494a99ef-3ead-4bc1-ec70-e56bac4ccc55" }, "outputs": [], "source": [ "review = \"This movie is wonderful. I love it.\"\n", "\n", "pred = pipeline_inference(review, model_loaded)\n", "\n", "pred" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "bE1B8l8vF6uT" }, "source": [ "### Correr la aplicación localmente" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "IbsE4S8VF6uT" }, "source": [ "Una vez realizadas las modificaciones en el archivo principal, cree un directorio donde guardar los archivos de su aplicación. Guarde allí el modelo, el archivo tipo numpy con las palabras y su archivo principal (Ej. *movie_review_app.py*)." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "_Xm1pGUmbV6_" }, "source": [ "* Una vez modificado el código, puede probarlo localmente. Para ello ejecute el siguiente comando, sustituyendo *movie_review_app.py* por el nombre de su archivo principal.\n", "\n", "\n", "`!streamlit run apps/movie_review_app/movie_review_app.py` \n", "\n", "* Si en vez de localmente, está corriendo el notebook en Colab, ejecute: \n", "\n", "`!streamlit run apps/movie_review_app/movie_review_app.py & npx localtunnel --port 80` " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "IIsigqf7F6uU" }, "source": [ "### Despliegue de la aplicación" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "jKXAqZA4uAYA" }, "source": [ "Una vez que la app fue desarrollada es posible compartirla para que otros puedan probarla. Para ello es necesario: \n", "\n", "1. Contar con una cuenta de [Streamlit Cloud](https://docs.streamlit.io/streamlit-cloud/get-started#sign-up-for-streamlit-cloud) y un repositorio de GitHub donde almacenar el código. \n", "2. Subir al repositorio el código y los datos necesarios para correrlo. \n", "3. [Conectar la cuenta de Streamlit Cloud con la del repositorio](https://docs.streamlit.io/streamlit-cloud/get-started#connect-your-github-account). \n", "4. [Publicar la app](https://docs.streamlit.io/streamlit-cloud/get-started/deploy-an-app)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "id": "rN0y6d6rvO_u" }, "source": [ "*Comentario:* Puede que sea necesario agregar en el repositorio un archivo *requirements.txt* donde deba especificar las liberías utilizas en el archivo *main.py*. " ] } ], "metadata": { "accelerator": "GPU", "colab": { "collapsed_sections": [ "rY6vz2Ekj8ig", "VNZlLb6v4OHS", "PfSujuskbZog", "QnyfpJny_Eq-", "90O_LXGExzWp" ], "provenance": [] }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false }, "widgets": { "application/vnd.jupyter.widget-state+json": { "072849505bab4fea82ee4abb72307163": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "136f851ae67e40fca045beea37324393": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "205d0bff45604ee29595e512a41da75c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_d07d3f63f00747fdb004a1cd30600ca3", "placeholder": "​", "style": "IPY_MODEL_bac0544265d1411a8a81ec21208598d0", "value": "Map: 100%" } }, "206b7539c3874812963d6ece92da47cf": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2d8f13663d9d49e2a359ea77bb4cdc0a": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_ef8db48fc56742de8d1fc132ff966110", "max": 20000, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_136f851ae67e40fca045beea37324393", "value": 20000 } }, "2db06fcc2c8d4744b8a1757c0423576b": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "313ddd7614f947518978eee4ee716ec9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_59e5c2331b9a45cfb61b20545ceb51f7", "placeholder": "​", "style": "IPY_MODEL_9c07e6229c464695ae371a0a92da69f5", "value": " 20000/20000 [00:22<00:00, 908.39 examples/s]" } }, "39a65803e4194d84b0f7da28afb027c9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_205d0bff45604ee29595e512a41da75c", "IPY_MODEL_5fcd057c6d084914a14f50c46807a506", "IPY_MODEL_8249976d220d4502bcf60c485cd8e117" ], "layout": "IPY_MODEL_74bfc9b8c9244d9282887fa48f42d50b" } }, "3f490155f92a483d97b9f555621ac3e1": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "59e5c2331b9a45cfb61b20545ceb51f7": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5fcd057c6d084914a14f50c46807a506": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_dd96438bbc784332af1fbcda62c11383", "max": 15001, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_f608b13137cb4fc1bf99b925b5b8964f", "value": 15001 } }, "6418a9f5d7864482822eff7d950a90a0": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": "hidden", "width": null } }, "6a9077adcf4f40e29552c51d74b7ffd8": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "74bfc9b8c9244d9282887fa48f42d50b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": "hidden", "width": null } }, "7988f3c22f1d43f7be54550ed7842bbe": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "7b1cd8372db446a1bacbfe3162a965c0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_ba36b5edf9bc466488ec22066407045f", "placeholder": "​", "style": "IPY_MODEL_2db06fcc2c8d4744b8a1757c0423576b", "value": "Map: 100%" } }, "8249976d220d4502bcf60c485cd8e117": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_072849505bab4fea82ee4abb72307163", "placeholder": "​", "style": "IPY_MODEL_7988f3c22f1d43f7be54550ed7842bbe", "value": " 15001/15001 [00:11<00:00, 1294.30 examples/s]" } }, "8f434769c7a74b49a7bb52a4876793f4": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_af8a8ec465c245698baf5c597f8823a2", "placeholder": "​", "style": "IPY_MODEL_6a9077adcf4f40e29552c51d74b7ffd8", "value": "Map: 100%" } }, "9c07e6229c464695ae371a0a92da69f5": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "9ddb988363ee4389b769ecf082f5a045": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "a574435c6de34f2285ba3037f52804b1": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_3f490155f92a483d97b9f555621ac3e1", "placeholder": "​", "style": "IPY_MODEL_cf895c08f92340efa242c1ebf3655b8e", "value": " 5000/5000 [00:03<00:00, 1510.34 examples/s]" } }, "a953d9971e9c443bb3cd3366ba06d478": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_7b1cd8372db446a1bacbfe3162a965c0", "IPY_MODEL_2d8f13663d9d49e2a359ea77bb4cdc0a", "IPY_MODEL_313ddd7614f947518978eee4ee716ec9" ], "layout": "IPY_MODEL_e4187e118f294d25a2faad1cbeec9924" } }, "af8a8ec465c245698baf5c597f8823a2": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "ba36b5edf9bc466488ec22066407045f": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "bac0544265d1411a8a81ec21208598d0": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "bfe3d62706f7429f90a15a0c7c1e41ab": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_206b7539c3874812963d6ece92da47cf", "max": 5000, "min": 0, "orientation": "horizontal", "style": "IPY_MODEL_9ddb988363ee4389b769ecf082f5a045", "value": 5000 } }, "cf895c08f92340efa242c1ebf3655b8e": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "d07d3f63f00747fdb004a1cd30600ca3": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "dd8a7fe1d581424c977aeb0ce3942074": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_8f434769c7a74b49a7bb52a4876793f4", "IPY_MODEL_bfe3d62706f7429f90a15a0c7c1e41ab", "IPY_MODEL_a574435c6de34f2285ba3037f52804b1" ], "layout": "IPY_MODEL_6418a9f5d7864482822eff7d950a90a0" } }, "dd96438bbc784332af1fbcda62c11383": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e4187e118f294d25a2faad1cbeec9924": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": "hidden", "width": null } }, "ef8db48fc56742de8d1fc132ff966110": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f608b13137cb4fc1bf99b925b5b8964f": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } } } } }, "nbformat": 4, "nbformat_minor": 0 }