El uso de LSTM (Long Short-Term Memory) para la clasificación de texto y análisis de sentimientos es una aplicación popular en el campo del procesamiento del lenguaje natural (NLP). Aquí hay un resumen de cómo se utiliza LSTM en este contexto:
Preprocesamiento de texto: Antes de alimentar el texto a un modelo LSTM, es necesario realizar tareas de preprocesamiento como tokenización, eliminación de stop words, y lematización o derivación para estandarizar y limpiar los datos.
Representación del texto: El texto se convierte en vectores numéricos que pueden ser entendidos por el modelo LSTM. Esto puede hacerse utilizando técnicas como el one-hot encoding, word embeddings (como Word2Vec o GloVe), o técnicas más avanzadas como el uso de modelos de lenguaje pre-entrenados como BERT o GPT.
Construcción del modelo LSTM: Se crea un modelo LSTM que toma como entrada la representación numérica del texto. El modelo LSTM se entrena utilizando un conjunto de datos etiquetados para aprender a clasificar el texto en diferentes categorías o para realizar análisis de sentimientos.
Entrenamiento del modelo: Durante el entrenamiento, el modelo LSTM ajusta los pesos de sus conexiones internas para minimizar una función de pérdida, como la entropía cruzada, en función de los datos de entrenamiento. Esto implica propagar hacia atrás el error a través del tiempo utilizando el algoritmo de retropropagación a lo largo de las diferentes etapas temporales de la secuencia de texto.
Evaluación del modelo: Una vez entrenado, el modelo LSTM se evalúa utilizando un conjunto de datos de prueba para medir su desempeño en la clasificación de texto o en el análisis de sentimientos. Las métricas comunes de evaluación incluyen la precisión, la recuperación, la puntuación F1 y la matriz de confusión.
Predicción y despliegue: Una vez que el modelo ha sido entrenado y evaluado, puede ser utilizado para realizar predicciones en nuevos datos de texto y desplegado en producción para automatizar tareas de clasificación de texto o análisis de sentimientos en tiempo real.
El uso de LSTM para la clasificación de texto y análisis de sentimientos implica la construcción y entrenamiento de modelos LSTM que pueden aprender a comprender y clasificar el texto en diferentes categorías o para evaluar la polaridad de los sentimientos expresados en el texto.
import re
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
import keras
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score
import math
import nltk
import seaborn as sns
import matplotlib.pyplot as plt
data = pd.read_csv('https://raw.githubusercontent.com/marsgr6/ml-online/main/data/IMDB_Dataset.csv')
data.head()
| review | sentiment | |
|---|---|---|
| 0 | One of the other reviewers has mentioned that ... | positive |
| 1 | A wonderful little production. <br /><br />The... | positive |
| 2 | I thought this was a wonderful way to spend ti... | positive |
| 3 | Basically there's a family where a little boy ... | negative |
| 4 | Petter Mattei's "Love in the Time of Money" is... | positive |
El preprocesamiento de eliminación de caracteres no alfanuméricos y conversión a minúsculas es una parte importante del procesamiento de texto antes de alimentar los datos a un modelo LSTM u otro modelo de procesamiento del lenguaje natural (NLP). Aquí está el detalle de este proceso:
Eliminación de caracteres no alfanuméricos: Este paso implica eliminar todos los caracteres que no son letras o números del texto. Estos caracteres pueden incluir signos de puntuación, símbolos especiales, caracteres de control, etc. La eliminación de estos caracteres ayuda a limpiar el texto y a reducir la complejidad, lo que facilita el procesamiento posterior.
Conversión a minúsculas: Después de eliminar los caracteres no alfanuméricos, el texto se convierte completamente a minúsculas. Esto es importante para estandarizar el texto y evitar que el modelo LSTM considere las mismas palabras con diferentes casos como distintas, lo que podría reducir la efectividad del modelo.
Ejemplo práctico:
Supongamos que tenemos el siguiente texto de ejemplo:
"¡Hola! Este es un ejemplo de texto con signos de puntuación, números (123), y símbolos especiales."
Después del preprocesamiento de eliminación de caracteres no alfanuméricos y conversión a minúsculas, el texto se vería así:
"hola este es un ejemplo de texto con signos de puntuacion numeros 123 y simbolos especiales"
Como puedes ver, se eliminaron todos los caracteres no alfanuméricos y el texto se convirtió a minúsculas.
Este proceso de preprocesamiento es fundamental para limpiar y estandarizar el texto antes de utilizarlo en modelos de procesamiento del lenguaje natural como LSTM, lo que ayuda a mejorar la calidad de las predicciones y la eficacia del modelo.
def remove_html_markup(s):
tag = False
quote = False
out = ""
for c in s:
if c == '<' and not quote:
tag = True
elif c == '>' and not quote:
tag = False
elif (c == '"' or c == "'") and tag:
quote = not quote
elif not tag:
out = out + c
return out
def remove_tags(text):
result = remove_html_markup(text) #remove HTML tags
result = re.sub('https://.*','',result) #remove URLs
result = re.sub(r'\W+', ' ', result) #remove non-alphanumeric characters
result = result.lower()
return result
data['review'] = data['review'].apply(lambda cw : remove_tags(cw))
data.head()
| review | sentiment | |
|---|---|---|
| 0 | one of the other reviewers has mentioned that ... | positive |
| 1 | a wonderful little production the filming tech... | positive |
| 2 | i thought this was a wonderful way to spend ti... | positive |
| 3 | basically there s a family where a little boy ... | negative |
| 4 | petter mattei s love in the time of money is a... | positive |
data['review'][1]
'a wonderful little production the filming technique is very unassuming very old time bbc fashion and gives a comforting and sometimes discomforting sense of realism to the entire piece the actors are extremely well chosen michael sheen not only has got all the polari but he has all the voices down pat too you can truly see the seamless editing guided by the references to williams diary entries not only is it well worth the watching but it is a terrificly written and performed piece a masterful production about one of the great master s of comedy and his life the realism really comes home with the little things the fantasy of the guard which rather than use the traditional dream techniques remains solid then disappears it plays on our knowledge and our senses particularly with the scenes concerning orton and halliwell and the sets particularly of their flat with halliwell s murals decorating every surface are terribly well done '
La eliminación de stop words es otro paso importante en el preprocesamiento de texto antes de alimentar los datos a un modelo LSTM u otro modelo de procesamiento del lenguaje natural (NLP). Las stop words son palabras comunes que tienen poco o ningún significado en la comprensión del texto y que generalmente se eliminan porque no aportan información relevante para el análisis. Aquí está el detalle de este proceso:
Definición de stop words: Las stop words son palabras que se consideran irrelevantes para el análisis de texto debido a su alta frecuencia de aparición en el lenguaje natural. Ejemplos comunes de stop words incluyen "el", "la", "de", "y", "a", "en", "con", entre otras.
Identificación de stop words: Antes de eliminar las stop words, es necesario tener una lista de palabras consideradas como stop words en el idioma del texto que se está procesando. Estas listas suelen estar disponibles en bibliotecas de procesamiento de texto en varios idiomas, como NLTK (Natural Language Toolkit) para Python.
Eliminación de stop words: Una vez que se ha identificado la lista de stop words, estas palabras se eliminan del texto durante el preprocesamiento. Esto se hace comparando cada palabra del texto con la lista de stop words y eliminando aquellas que coincidan. Es importante tener en cuenta que la eliminación de stop words puede afectar la coherencia y la semántica del texto, por lo que es importante evaluar el impacto de esta técnica en el contexto específico de cada aplicación.
Ejemplo práctico:
Supongamos que tenemos el siguiente texto de ejemplo:
"Este es un ejemplo de texto con palabras comunes como 'el', 'la', 'de', 'y', 'a', 'en', que pueden ser eliminadas como stop words."
Después del preprocesamiento de eliminación de stop words, el texto se vería así:
"Este ejemplo texto palabras comunes 'el', 'la', 'de', 'y', 'a', 'en', eliminadas stop words."
Como puedes ver, las stop words como "es", "un", "con", "que", etc., han sido eliminadas del texto.
La eliminación de stop words es una técnica importante en el preprocesamiento de texto que ayuda a mejorar la calidad del análisis de texto y a reducir el ruido en los datos antes de alimentarlos a un modelo de procesamiento del lenguaje natural como LSTM.
nltk.download('stopwords')
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
data['review'] = data['review'].apply(lambda x: ' '.join([word for word in x.split() if word not in (stop_words)]))
data.head()
[nltk_data] Downloading package stopwords to /root/nltk_data... [nltk_data] Unzipping corpora/stopwords.zip.
| review | sentiment | |
|---|---|---|
| 0 | one reviewers mentioned watching 1 oz episode ... | positive |
| 1 | wonderful little production filming technique ... | positive |
| 2 | thought wonderful way spend time hot summer we... | positive |
| 3 | basically family little boy jake thinks zombie... | negative |
| 4 | petter mattei love time money visually stunnin... | positive |
La lematización es un proceso lingüístico que consiste en reducir las palabras a su forma base o raíz, conocida como lema. A diferencia del stemming, que también busca reducir las palabras a su forma base, la lematización tiene en cuenta la morfología y el contexto gramatical de las palabras para obtener una forma más precisa y significativa.
En la lematización, las palabras se convierten a su forma canónica o de diccionario, lo que facilita su análisis y comprensión en tareas de procesamiento del lenguaje natural (NLP). Por ejemplo, las palabras "corriendo", "corre", "corrió" se lematizarían todas como "correr", ya que comparten la misma forma base.
La lematización puede ayudar a reducir la variabilidad de las palabras en un texto y mejorar la coherencia y precisión del análisis. Es especialmente útil en aplicaciones de NLP como la clasificación de texto, el análisis de sentimientos y la recuperación de información, donde la comprensión precisa del texto es fundamental.
En el preprocesamiento de texto antes de alimentar los datos a un modelo LSTM u otro modelo de NLP, la lematización a menudo se realiza junto con otras técnicas como la tokenización, la eliminación de stop words y la conversión a minúsculas para estandarizar y limpiar los datos de texto antes del análisis. Las bibliotecas de procesamiento de texto como NLTK (Natural Language Toolkit) en Python proporcionan funciones y herramientas para realizar la lematización de manera eficiente.
nltk.download('wordnet')
w_tokenizer = nltk.tokenize.WhitespaceTokenizer()
lemmatizer = nltk.stem.WordNetLemmatizer()
def lemmatize_text(text):
st = ""
for w in w_tokenizer.tokenize(text):
st = st + lemmatizer.lemmatize(w) + " "
return st
data['review'] = data.review.apply(lemmatize_text)
data['review'][1]
[nltk_data] Downloading package wordnet to /root/nltk_data...
'wonderful little production filming technique unassuming old time bbc fashion give comforting sometimes discomforting sense realism entire piece actor extremely well chosen michael sheen got polari voice pat truly see seamless editing guided reference williams diary entry well worth watching terrificly written performed piece masterful production one great master comedy life realism really come home little thing fantasy guard rather use traditional dream technique remains solid disappears play knowledge sens particularly scene concerning orton halliwell set particularly flat halliwell mural decorating every surface terribly well done '
El dataset IMDb (Internet Movie Database) para análisis de reviews positivos y negativos es un conjunto de datos ampliamente utilizado en el campo del procesamiento del lenguaje natural (NLP) y el aprendizaje automático. Este conjunto de datos contiene críticas de películas recopiladas del sitio web IMDb, donde cada crítica está etiquetada como positiva o negativa según la opinión del crítico sobre la película.
Aquí hay una descripción general del dataset IMDb:
Origen de los datos: Las críticas de películas se recopilan del sitio web IMDb, que es una de las bases de datos más grandes y populares de películas en línea. IMDb permite a los usuarios escribir y publicar críticas de películas para compartir sus opiniones con otros usuarios.
Contenido del dataset: El dataset IMDb contiene un gran número de críticas de películas en texto sin procesar. Cada crítica está asociada con una etiqueta que indica si la opinión expresada en la crítica es positiva o negativa. Las etiquetas suelen ser binarias, donde "1" representa una crítica positiva y "0" representa una crítica negativa.
Tamaño del dataset: El tamaño del dataset puede variar, pero típicamente contiene decenas de miles o incluso cientos de miles de críticas de películas.
Uso en el análisis de sentimientos: El dataset IMDb es comúnmente utilizado para tareas de análisis de sentimientos, donde el objetivo es clasificar las críticas de películas como positivas o negativas basadas en su contenido textual. Esta tarea es un ejemplo de clasificación binaria en el procesamiento del lenguaje natural.
Aplicaciones: El dataset IMDb se utiliza en una variedad de aplicaciones, incluyendo la construcción y evaluación de modelos de aprendizaje automático para análisis de sentimientos, la investigación académica en el campo del procesamiento del lenguaje natural, y el desarrollo de sistemas de recomendación de películas basados en opiniones de usuarios.
El dataset IMDb es una importante fuente de datos para la investigación y el desarrollo de modelos de análisis de sentimientos en el campo del procesamiento del lenguaje natural, y ha sido fundamental en el avance de la comprensión computacional de las opiniones expresadas en texto en línea.
ax = data['sentiment'].value_counts().plot(kind='barh',
figsize=(8,6),
title="Classes")
ax.set_ylabel("Sentiment")
ax.set_xlabel("Frequency")
Text(0.5, 0, 'Frequency')
reviews = data['review'].values
labels = data['sentiment'].values
encoder = LabelEncoder()
encoded_labels = encoder.fit_transform(labels)
train_sentences, test_sentences, train_labels, test_labels = train_test_split(reviews, encoded_labels, stratify = encoded_labels)
El proceso de tokenización, truncamiento y padding es una parte fundamental del preprocesamiento de texto en el campo del procesamiento del lenguaje natural (NLP), especialmente cuando se trabaja con modelos como LSTM para tareas como la clasificación de texto o el análisis de sentimientos. Aquí está una descripción detallada de cada paso:
Tokenización: El tokenizer es una herramienta que se utiliza para convertir el texto en secuencias de tokens o palabras. Cada palabra en el texto se asigna a un identificador único (índice) y se representa como un número entero. Esto es importante porque los modelos de aprendizaje automático, como los modelos LSTM, requieren que los datos de entrada sean numéricos.
Truncamiento: En el procesamiento de texto, es común que las secuencias de palabras tengan longitudes diferentes. Sin embargo, para alimentar los datos a un modelo LSTM, es necesario que todas las secuencias tengan la misma longitud. El truncamiento es el proceso de cortar o eliminar palabras de las secuencias más largas para que todas tengan la misma longitud.
Padding: Después del truncamiento, algunas secuencias pueden ser más cortas que otras y es necesario agregar tokens especiales llamados "tokens de relleno" (padding tokens) para igualar la longitud de todas las secuencias. Estos tokens de relleno generalmente tienen un valor de cero o se representan como vectores de ceros.
El proceso de tokenización, truncamiento y padding garantiza que todas las secuencias de palabras tengan la misma longitud, lo que facilita el procesamiento por parte de modelos de aprendizaje automático como LSTM. Esto es crucial para garantizar que los datos de entrada sean consistentes y compatibles con la arquitectura del modelo. Las bibliotecas de procesamiento de texto como TensorFlow y Keras en Python proporcionan herramientas y funciones para realizar estos pasos de manera eficiente.
# Hyperparameters of the model
vocab_size = 3000 # choose based on statistics
oov_tok = ''
embedding_dim = 100
max_length = 200 # choose based on statistics, for example 150 to 200
padding_type='post'
trunc_type='post'
# tokenize sentences
tokenizer = Tokenizer(num_words = vocab_size, oov_token=oov_tok)
tokenizer.fit_on_texts(train_sentences)
word_index = tokenizer.word_index
# convert train dataset to sequence and pad sequences
train_sequences = tokenizer.texts_to_sequences(train_sentences)
train_padded = pad_sequences(train_sequences, padding='post', maxlen=max_length)
# convert Test dataset to sequence and pad sequences
test_sequences = tokenizer.texts_to_sequences(test_sentences)
test_padded = pad_sequences(test_sequences, padding='post', maxlen=max_length)
len(train_sequences[0]), len(train_padded[0])
(87, 200)
np.array(train_padded).max()
2999
train_padded[0]
array([ 1, 55, 79, 2075, 851, 312, 522, 1395, 58, 2808, 1,
623, 1, 416, 851, 386, 651, 229, 1, 454, 1395, 807,
905, 1218, 661, 404, 10, 79, 2075, 851, 1, 3, 1987,
1, 2032, 1015, 1, 1338, 1, 389, 316, 55, 2021, 925,
15, 1, 1, 1, 1300, 1, 105, 72, 383, 308, 357,
1, 2394, 12, 143, 58, 1, 1, 4, 120, 1395, 79,
2075, 851, 58, 1002, 851, 651, 229, 12, 429, 269, 1301,
1, 1, 1, 1, 1, 1, 1, 1748, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0], dtype=int32)
Este código en Python utiliza la biblioteca Keras para construir, compilar y resumir un modelo de red neuronal recurrente (RNN) con capas bidireccionales de LSTM para un problema de clasificación binaria.
Aquí está el detalle de cada parte del código:
Inicialización del modelo:
model = keras.Sequential([
keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length),
keras.layers.Bidirectional(keras.layers.LSTM(64)),
keras.layers.Dense(24, activation='relu'),
keras.layers.Dense(1, activation='sigmoid')
])
Sequential) de Keras, que es una secuencia lineal de capas.Embedding) que convierte las secuencias de números enteros (representación de las palabras) en vectores densos de longitud embedding_dim. El parámetro vocab_size especifica el tamaño del vocabulario y input_length especifica la longitud máxima de las secuencias de entrada.Bidirectional(LSTM(64))) con 64 unidades LSTM en cada dirección.Dense) con 24 neuronas y activación ReLU.Dense) con una sola neurona y activación sigmoide, que produce una salida binaria para la clasificación.Compilación del modelo:
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
loss) como entropía cruzada binaria, el optimizador (optimizer) como Adam y la métrica (metrics) de evaluación como precisión (accuracy).Resumen del modelo:
model.summary()
Binary Crossentropy es una función de pérdida comúnmente utilizada en problemas de clasificación binaria en el campo del aprendizaje automático y la inteligencia artificial. Esta función de pérdida se utiliza para evaluar la discrepancia entre las etiquetas verdaderas y las predicciones de un modelo en problemas donde se tienen dos clases mutuamente excluyentes (por ejemplo, positivo/negativo, sí/no, 1/0).
La fórmula matemática de la Binary Crossentropy es:
$$ \text{Binary Crossentropy} = -\frac{1}{N} \sum_{i=1}^{N} (y_i \cdot \log(\hat{y}_i) + (1 - y_i) \cdot \log(1 - \hat{y}_i)) $$Donde:
La Binary Crossentropy mide la diferencia entre las probabilidades predichas por el modelo ($\hat{y}_i $) y las etiquetas verdaderas ($ y_i $). Penaliza más fuertemente las discrepancias en las predicciones incorrectas, es decir, cuando el modelo predice una clase diferente a la etiqueta verdadera. Se optimiza minimizando esta función de pérdida durante el entrenamiento del modelo.
En resumen, la Binary Crossentropy es una medida de la discrepancia entre las probabilidades predichas por un modelo de clasificación binaria y las etiquetas verdaderas, y se utiliza como función de pérdida para entrenar el modelo y actualizar sus pesos durante el proceso de optimización.
Este código define un modelo de red neuronal recurrente bidireccional con capas LSTM para un problema de clasificación binaria, lo compila con una función de pérdida y un optimizador específicos, y muestra un resumen de su arquitectura.
# model initialization
model = keras.Sequential([
keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length),
keras.layers.Bidirectional(keras.layers.LSTM(64)),
keras.layers.Dense(24, activation='relu'),
keras.layers.Dense(1, activation='sigmoid')
])
# compile model
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
# model summary
model.summary()
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding (Embedding) (None, 200, 100) 300000
bidirectional (Bidirection (None, 128) 84480
al)
dense_5 (Dense) (None, 24) 3096
dense_6 (Dense) (None, 1) 25
=================================================================
Total params: 387601 (1.48 MB)
Trainable params: 387601 (1.48 MB)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________
num_epochs = 10
history = model.fit(train_padded, train_labels,
epochs=num_epochs, verbose=1,
validation_split=0.1)
Epoch 1/10 1055/1055 [==============================] - 287s 268ms/step - loss: 0.3887 - accuracy: 0.8250 - val_loss: 0.3064 - val_accuracy: 0.8680 Epoch 2/10 1055/1055 [==============================] - 263s 249ms/step - loss: 0.2755 - accuracy: 0.8906 - val_loss: 0.3474 - val_accuracy: 0.8605 Epoch 3/10 1055/1055 [==============================] - 262s 249ms/step - loss: 0.2421 - accuracy: 0.9045 - val_loss: 0.2889 - val_accuracy: 0.8848 Epoch 4/10 1055/1055 [==============================] - 265s 251ms/step - loss: 0.2126 - accuracy: 0.9168 - val_loss: 0.2847 - val_accuracy: 0.8717 Epoch 5/10 1055/1055 [==============================] - 262s 248ms/step - loss: 0.1797 - accuracy: 0.9310 - val_loss: 0.3336 - val_accuracy: 0.8696 Epoch 6/10 1055/1055 [==============================] - 265s 251ms/step - loss: 0.1551 - accuracy: 0.9428 - val_loss: 0.3280 - val_accuracy: 0.8760 Epoch 7/10 1055/1055 [==============================] - 266s 253ms/step - loss: 0.1267 - accuracy: 0.9560 - val_loss: 0.3721 - val_accuracy: 0.8677 Epoch 8/10 1055/1055 [==============================] - 274s 260ms/step - loss: 0.1134 - accuracy: 0.9616 - val_loss: 0.4403 - val_accuracy: 0.8661 Epoch 9/10 1055/1055 [==============================] - 260s 247ms/step - loss: 0.0982 - accuracy: 0.9667 - val_loss: 0.5065 - val_accuracy: 0.8637 Epoch 10/10 1055/1055 [==============================] - 263s 249ms/step - loss: 0.0834 - accuracy: 0.9721 - val_loss: 0.5201 - val_accuracy: 0.8688
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
#plt.ylim([0.5, 1])
plt.legend(loc='lower right')
<matplotlib.legend.Legend at 0x7ad146400eb0>
prediction = model.predict(test_padded)
# Get labels based on probability 1 if p>= 0.5 else 0
pred_labels = []
for i in prediction:
if i >= 0.5:
pred_labels.append(1)
else:
pred_labels.append(0)
print("Accuracy of prediction on test set : ", accuracy_score(test_labels, pred_labels))
391/391 [==============================] - 26s 63ms/step Accuracy of prediction on test set : 0.8664
from sklearn.metrics import confusion_matrix, classification_report
labels_classes = ["negative", "positive"]
cm = pd.DataFrame(confusion_matrix(test_labels, pred_labels, labels=[0, 1]),
columns=labels_classes,
index=labels_classes)
sns.heatmap(cm, square=True, annot=True, fmt='d', cbar=False)
plt.xlabel('True label')
plt.ylabel('Predicted label')
print(classification_report(test_labels, pred_labels))
precision recall f1-score support
0 0.87 0.86 0.87 6250
1 0.86 0.87 0.87 6250
accuracy 0.87 12500
macro avg 0.87 0.87 0.87 12500
weighted avg 0.87 0.87 0.87 12500
Este código en Python define un modelo de red neuronal recurrente (RNN) utilizando la biblioteca Keras para resolver un problema de clasificación binaria. Aquí está la descripción de cada parte del modelo:
Capa de Embedding:
keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length): Esta es la primera capa del modelo. Se utiliza para convertir las secuencias de números enteros (representación de palabras) en vectores densos de longitud embedding_dim. El parámetro vocab_size especifica el tamaño del vocabulario, embedding_dim especifica la dimensión de los vectores de embedding y input_length especifica la longitud máxima de las secuencias de entrada.Capa Bidireccional de LSTM:
keras.layers.Bidirectional(keras.layers.LSTM(64, return_sequences=True)): Esta es una capa bidireccional de LSTM (Long Short-Term Memory) con 64 unidades LSTM en cada dirección. La opción return_sequences=True indica que la capa devolverá secuencias en lugar de un único vector de salida.Capa Bidireccional de LSTM:
keras.layers.Bidirectional(keras.layers.LSTM(32)): Otra capa bidireccional de LSTM con 32 unidades LSTM en cada dirección. Esta capa no especifica return_sequences, por lo que su salida será un único vector en lugar de secuencias.Capa Densa:
keras.layers.Dense(64, activation='relu'): Una capa densa con 64 neuronas y función de activación ReLU. Esta capa realiza la extracción de características de las representaciones de las secuencias generadas por las capas LSTM.Capa de Dropout:
keras.layers.Dropout(0.5): Una capa de dropout que apaga aleatoriamente el 50% de las neuronas durante el entrenamiento para evitar el sobreajuste.Capa de Salida:
keras.layers.Dense(1, activation='sigmoid'): Una capa densa de salida con una sola neurona y función de activación sigmoide. Esta capa produce una salida binaria que representa la probabilidad de pertenencia a la clase positiva en un problema de clasificación binaria.Este modelo utiliza dos capas bidireccionales de LSTM para procesar secuencias de texto, seguidas de capas densas para la extracción de características y una capa de salida para la clasificación binaria. La capa de dropout se utiliza para regularizar el modelo y evitar el sobreajuste durante el entrenamiento.
Dropout es una técnica de regularización utilizada en redes neuronales para evitar el sobreajuste durante el entrenamiento. El sobreajuste ocurre cuando el modelo se adapta demasiado a los datos de entrenamiento y no generaliza bien a datos nuevos, lo que resulta en un rendimiento deficiente en datos de prueba o en situaciones del mundo real.
La idea detrás de Dropout es apagar aleatoriamente (eliminar temporalmente) un porcentaje de las neuronas durante cada paso de entrenamiento. Esto significa que las neuronas seleccionadas no contribuirán a la propagación hacia adelante ni a la retropropagación en esa iteración específica del entrenamiento. Como resultado, el modelo no puede depender demasiado de ninguna neurona específica o de una combinación particular de neuronas para realizar predicciones.
El efecto de Dropout es similar a entrenar una gran cantidad de redes neuronales más pequeñas y luego combinarlas en un solo modelo. Esto obliga a cada neurona a aprender características útiles de los datos de entrada de manera más independiente y robusta, lo que conduce a una representación más generalizable de los datos. Además, Dropout también ayuda a reducir la dependencia entre las neuronas, lo que hace que el modelo sea más resistente a los patrones de ruido en los datos.
En cuanto a la regularización, es un término más amplio que se refiere a técnicas utilizadas para prevenir el sobreajuste en modelos de aprendizaje automático. Dropout es una forma específica de regularización que se enfoca en las neuronas individuales en una red neuronal. Otras técnicas de regularización incluyen la penalización L1 y L2 (también conocida como regularización de peso), la eliminación de características, la reducción de dimensionalidad y la utilización de arquitecturas de modelo más simples.
Dropout es una técnica de regularización eficaz que ayuda a mejorar la generalización de los modelos de redes neuronales al prevenir el sobreajuste durante el entrenamiento. Se logra apagando aleatoriamente una fracción de las neuronas durante cada paso de entrenamiento, lo que fomenta una representación más robusta y generalizable de los datos.
model = keras.Sequential([
keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length),
keras.layers.Bidirectional(keras.layers.LSTM(64, return_sequences=True)),
keras.layers.Bidirectional(keras.layers.LSTM(32)),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(1, activation='sigmoid')
])
# compile model
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
# model summary
model.summary()
Model: "sequential_4"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, 200, 100) 300000
bidirectional_1 (Bidirecti (None, 200, 128) 84480
onal)
bidirectional_2 (Bidirecti (None, 64) 41216
onal)
dense_7 (Dense) (None, 64) 4160
dropout (Dropout) (None, 64) 0
dense_8 (Dense) (None, 1) 65
=================================================================
Total params: 429921 (1.64 MB)
Trainable params: 429921 (1.64 MB)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________
num_epochs = 10
history = model.fit(train_padded, train_labels,
epochs=num_epochs, verbose=1,
validation_split=0.1)
Epoch 1/10 1055/1055 [==============================] - 496s 462ms/step - loss: 0.5126 - accuracy: 0.7566 - val_loss: 0.4434 - val_accuracy: 0.7864 Epoch 2/10 1055/1055 [==============================] - 484s 458ms/step - loss: 0.3792 - accuracy: 0.8481 - val_loss: 0.2928 - val_accuracy: 0.8851 Epoch 3/10 1055/1055 [==============================] - 477s 453ms/step - loss: 0.3185 - accuracy: 0.8701 - val_loss: 0.2991 - val_accuracy: 0.8723 Epoch 4/10 1055/1055 [==============================] - 482s 457ms/step - loss: 0.2716 - accuracy: 0.8943 - val_loss: 0.2759 - val_accuracy: 0.8859 Epoch 5/10 1055/1055 [==============================] - 487s 462ms/step - loss: 0.2458 - accuracy: 0.9074 - val_loss: 0.2862 - val_accuracy: 0.8848 Epoch 6/10 1055/1055 [==============================] - 482s 457ms/step - loss: 0.2228 - accuracy: 0.9162 - val_loss: 0.3005 - val_accuracy: 0.8803 Epoch 7/10 1055/1055 [==============================] - 474s 450ms/step - loss: 0.2020 - accuracy: 0.9259 - val_loss: 0.2959 - val_accuracy: 0.8827 Epoch 8/10 1055/1055 [==============================] - 468s 443ms/step - loss: 0.1866 - accuracy: 0.9326 - val_loss: 0.3102 - val_accuracy: 0.8795 Epoch 9/10 1055/1055 [==============================] - 473s 448ms/step - loss: 0.1653 - accuracy: 0.9413 - val_loss: 0.3460 - val_accuracy: 0.8717 Epoch 10/10 1055/1055 [==============================] - 470s 445ms/step - loss: 0.1459 - accuracy: 0.9505 - val_loss: 0.3381 - val_accuracy: 0.8760
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
#plt.ylim([0.5, 1])
plt.legend(loc='lower right')
<matplotlib.legend.Legend at 0x7ad13aede7a0>
prediction = model.predict(test_padded)
# Get labels based on probability 1 if p>= 0.5 else 0
pred_labels = []
for i in prediction:
if i >= 0.5:
pred_labels.append(1)
else:
pred_labels.append(0)
print("Accuracy of prediction on test set : ", accuracy_score(test_labels, pred_labels))
labels_classes = ["negative", "positive"]
cm = pd.DataFrame(confusion_matrix(test_labels, pred_labels, labels=[0, 1]),
columns=labels_classes,
index=labels_classes)
sns.heatmap(cm, square=True, annot=True, fmt='d', cbar=False)
plt.xlabel('True label')
plt.ylabel('Predicted label')
print(classification_report(test_labels, pred_labels))
391/391 [==============================] - 43s 104ms/step
Accuracy of prediction on test set : 0.87168
precision recall f1-score support
0 0.87 0.88 0.87 6250
1 0.88 0.87 0.87 6250
accuracy 0.87 12500
macro avg 0.87 0.87 0.87 12500
weighted avg 0.87 0.87 0.87 12500
# update and restart session
!pip install --upgrade tensorflow
!pip install --upgrade keras
Requirement already satisfied: tensorflow in /usr/local/lib/python3.10/dist-packages (2.15.0)
Collecting tensorflow
Downloading tensorflow-2.15.0.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (475.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 475.2/475.2 MB 2.4 MB/s eta 0:00:00
Requirement already satisfied: absl-py>=1.0.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.4.0)
Requirement already satisfied: astunparse>=1.6.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.6.3)
Requirement already satisfied: flatbuffers>=23.5.26 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (23.5.26)
Requirement already satisfied: gast!=0.5.0,!=0.5.1,!=0.5.2,>=0.2.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.5.4)
Requirement already satisfied: google-pasta>=0.1.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.2.0)
Requirement already satisfied: h5py>=2.9.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.9.0)
Requirement already satisfied: libclang>=13.0.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (16.0.6)
Requirement already satisfied: ml-dtypes~=0.2.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.2.0)
Requirement already satisfied: numpy<2.0.0,>=1.23.5 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.25.2)
Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.3.0)
Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from tensorflow) (23.2)
Requirement already satisfied: protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.20.3 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (3.20.3)
Requirement already satisfied: setuptools in /usr/local/lib/python3.10/dist-packages (from tensorflow) (67.7.2)
Requirement already satisfied: six>=1.12.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.16.0)
Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.4.0)
Requirement already satisfied: typing-extensions>=3.6.6 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (4.10.0)
Requirement already satisfied: wrapt<1.15,>=1.11.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.14.1)
Requirement already satisfied: tensorflow-io-gcs-filesystem>=0.23.1 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (0.36.0)
Requirement already satisfied: grpcio<2.0,>=1.24.3 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (1.62.0)
Requirement already satisfied: tensorboard<2.16,>=2.15 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.15.2)
Requirement already satisfied: tensorflow-estimator<2.16,>=2.15.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.15.0)
Requirement already satisfied: keras<2.16,>=2.15.0 in /usr/local/lib/python3.10/dist-packages (from tensorflow) (2.15.0)
Requirement already satisfied: wheel<1.0,>=0.23.0 in /usr/local/lib/python3.10/dist-packages (from astunparse>=1.6.0->tensorflow) (0.42.0)
Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.16,>=2.15->tensorflow) (2.27.0)
Requirement already satisfied: google-auth-oauthlib<2,>=0.5 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.16,>=2.15->tensorflow) (1.2.0)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.16,>=2.15->tensorflow) (3.5.2)
Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.16,>=2.15->tensorflow) (2.31.0)
Requirement already satisfied: tensorboard-data-server<0.8.0,>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.16,>=2.15->tensorflow) (0.7.2)
Requirement already satisfied: werkzeug>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from tensorboard<2.16,>=2.15->tensorflow) (3.0.1)
Requirement already satisfied: cachetools<6.0,>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.16,>=2.15->tensorflow) (5.3.3)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.16,>=2.15->tensorflow) (0.3.0)
Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.10/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.16,>=2.15->tensorflow) (4.9)
Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.10/dist-packages (from google-auth-oauthlib<2,>=0.5->tensorboard<2.16,>=2.15->tensorflow) (1.3.1)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorboard<2.16,>=2.15->tensorflow) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorboard<2.16,>=2.15->tensorflow) (3.6)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorboard<2.16,>=2.15->tensorflow) (2.0.7)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2.21.0->tensorboard<2.16,>=2.15->tensorflow) (2024.2.2)
Requirement already satisfied: MarkupSafe>=2.1.1 in /usr/local/lib/python3.10/dist-packages (from werkzeug>=1.0.1->tensorboard<2.16,>=2.15->tensorflow) (2.1.5)
Requirement already satisfied: pyasn1<0.6.0,>=0.4.6 in /usr/local/lib/python3.10/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard<2.16,>=2.15->tensorflow) (0.5.1)
Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.10/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<2,>=0.5->tensorboard<2.16,>=2.15->tensorflow) (3.2.2)
Installing collected packages: tensorflow
Attempting uninstall: tensorflow
Found existing installation: tensorflow 2.15.0
Uninstalling tensorflow-2.15.0:
Successfully uninstalled tensorflow-2.15.0
Successfully installed tensorflow-2.15.0.post1
Requirement already satisfied: keras in /usr/local/lib/python3.10/dist-packages (2.15.0)
Collecting keras
Downloading keras-3.0.5-py3-none-any.whl (1.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.0/1.0 MB 7.0 MB/s eta 0:00:00
Requirement already satisfied: absl-py in /usr/local/lib/python3.10/dist-packages (from keras) (1.4.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from keras) (1.25.2)
Requirement already satisfied: rich in /usr/local/lib/python3.10/dist-packages (from keras) (13.7.0)
Collecting namex (from keras)
Downloading namex-0.0.7-py3-none-any.whl (5.8 kB)
Requirement already satisfied: h5py in /usr/local/lib/python3.10/dist-packages (from keras) (3.9.0)
Requirement already satisfied: dm-tree in /usr/local/lib/python3.10/dist-packages (from keras) (0.1.8)
Requirement already satisfied: ml-dtypes in /usr/local/lib/python3.10/dist-packages (from keras) (0.2.0)
Requirement already satisfied: markdown-it-py>=2.2.0 in /usr/local/lib/python3.10/dist-packages (from rich->keras) (3.0.0)
Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.10/dist-packages (from rich->keras) (2.16.1)
Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.10/dist-packages (from markdown-it-py>=2.2.0->rich->keras) (0.1.2)
Installing collected packages: namex, keras
Attempting uninstall: keras
Found existing installation: keras 2.15.0
Uninstalling keras-2.15.0:
Successfully uninstalled keras-2.15.0
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
tensorflow 2.15.0.post1 requires keras<2.16,>=2.15.0, but you have keras 3.0.5 which is incompatible.
Successfully installed keras-3.0.5 namex-0.0.7
Un modelo Transformer es una arquitectura de red neuronal desarrollada por Google que revolucionó el campo del procesamiento del lenguaje natural (NLP). A diferencia de las arquitecturas recurrentes tradicionales como LSTM y GRU, los modelos Transformer utilizan una arquitectura completamente basada en atención y no tienen componentes recurrentes, lo que les permite manejar de manera más efectiva las dependencias a largo plazo en secuencias de texto.
Aquí hay una descripción básica de cómo funciona un modelo Transformer:
Capas de Codificador y Decodificador: Un modelo Transformer consta de un codificador y un decodificador, cada uno compuesto por múltiples capas.
Autoatención (Self-Attention): La autoatención es la piedra angular del modelo Transformer. Permite que el modelo procese las palabras en paralelo en lugar de secuencialmente, lo que lo hace más rápido y eficiente. En la autoatención, cada palabra en una secuencia interactúa con todas las demás palabras en la misma secuencia, y el modelo asigna pesos a estas interacciones para calcular una representación de atención ponderada para cada palabra.
Capas de Feed-Forward: Después de la autoatención, la representación de cada palabra pasa a través de una capa de feed-forward (totalmente conectada) para realizar transformaciones adicionales.
Conexiones Residuales y Normalización por Capas: Cada capa en un modelo Transformer tiene conexiones residuales y normalización por capas, lo que ayuda a mitigar el problema de desvanecimiento del gradiente durante el entrenamiento.
Apilamiento de Capas: Un modelo Transformer puede tener múltiples capas de codificador y decodificador apiladas una sobre otra. Esto permite que el modelo aprenda representaciones más complejas y de mayor nivel de abstracción.
El uso de un modelo Transformer para clasificación de texto implica entrenar el modelo con un gran corpus de texto etiquetado y luego utilizarlo para predecir las etiquetas de clasificación para nuevos textos. Durante el entrenamiento, el modelo ajusta sus parámetros para minimizar una función de pérdida que mide la discrepancia entre las etiquetas verdaderas y las predicciones del modelo. Una vez entrenado, el modelo puede realizar clasificaciones precisas en textos no vistos.
Algunas implementaciones populares de modelos Transformer incluyen BERT (Bidirectional Encoder Representations from Transformers), GPT (Generative Pre-trained Transformer) y T5 (Text-To-Text Transfer Transformer). Estos modelos se han utilizado con éxito en una amplia variedad de tareas de NLP, incluyendo clasificación de texto, traducción automática, generación de texto y más.

La atención de producto punto escalado (Scaled Dot-Product Attention) es un componente fundamental en los modelos Transformer utilizados en el procesamiento del lenguaje natural (NLP). Proporciona una forma de calcular la atención entre las diferentes partes de una secuencia de entrada de manera eficiente y efectiva. Aquí está una descripción de cómo funciona:
Donde $ d_k $ es la dimensión de las consultas y las claves.
Escalado: Antes de calcular el producto punto, se escala el resultado dividiéndolo por la raíz cuadrada de la dimensión de las claves. Esto ayuda a estabilizar los gradientes durante el entrenamiento y controla la magnitud de los valores resultantes de la atención.
Aplicación a los Valores: Una vez que se calculan los pesos de atención, se aplican a los valores correspondientes para obtener la salida de la atención. Es decir, para una consulta $ q_i $, la salida $ o_i $ se calcula como la suma ponderada de los valores $ v_j $ con los pesos de atención correspondientes:
La atención de producto punto escalado permite al modelo aprender a enfocarse en partes específicas de la secuencia de entrada, dependiendo de la relevancia de las claves con respecto a las consultas. Esto hace que los modelos Transformer sean especialmente eficaces para tareas de procesamiento del lenguaje natural, donde la atención precisa y contextual es crucial para comprender y generar texto de manera efectiva.
La atención multi-cabeza (Multi-Head Attention) es una extensión de la atención de producto punto escalado utilizada en los modelos Transformer en el procesamiento del lenguaje natural (NLP). Permite que el modelo atienda simultáneamente a diferentes partes de la secuencia de entrada desde diferentes perspectivas, lo que ayuda a capturar relaciones complejas y a mejorar el rendimiento del modelo. Aquí está una descripción de cómo funciona:
División de las Representaciones: En lugar de calcular la atención con una sola cabeza (o perspectiva), la atención multi-cabeza divide la representación de las consultas, claves y valores en múltiples cabezas. Esto se hace mediante la proyección lineal de las representaciones originales en $ h $ conjuntos de representaciones más pequeñas, donde $ h $ es el número de cabezas.
Atención Independiente: Para cada cabeza, se calcula la atención de producto punto escalado independientemente. Es decir, para cada cabeza, se realizan los mismos pasos de cálculo de atención que en la atención de producto punto escalado, pero utilizando las representaciones proyectadas correspondientes.
Concatenación y Proyección: Después de calcular la atención para cada cabeza, las salidas de atención de todas las cabezas se concatenan y se proyectan linealmente nuevamente en el espacio de representación original. Esto permite que el modelo combine información de múltiples perspectivas en una representación integrada.
La atención multi-cabeza permite que el modelo aprenda a enfocarse en diferentes partes de la secuencia de entrada desde diferentes perspectivas, lo que puede ser útil para capturar relaciones complejas y modelar dependencias a diferentes escalas. Esto hace que los modelos Transformer sean especialmente eficaces para tareas de procesamiento del lenguaje natural, donde la comprensión contextual y la atención precisa son cruciales.

import keras
from keras import ops
from keras import layers
Este código implementa dos clases en Python utilizando la biblioteca Keras que se utilizan para construir y preprocesar datos para un modelo de Transformer. Aquí hay una descripción de cada clase:
Clase TransformerBlock:
__init__, se definen las capas que componen el bloque, incluyendo una capa de atención multi-cabeza (layers.MultiHeadAttention) y una capa FFN (keras.Sequential). También se definen capas de normalización por lotes (layers.LayerNormalization) y capas de dropout (layers.Dropout) para regularizar el modelo.call, se realiza la propagación hacia adelante a través del bloque. Primero, se aplica la capa de atención multi-cabeza a las entradas. Luego, se aplica dropout a la salida de la atención y se agrega a las entradas originales antes de aplicar la normalización por lotes. A continuación, se aplica la capa FFN a la salida de la normalización por lotes, seguida de dropout y una vez más, se agrega a la salida de la normalización por lotes.Clase TokenAndPositionEmbedding:
__init__, se definen dos capas de embedding: una para los tokens (layers.Embedding) y otra para las posiciones (layers.Embedding). Estas capas se utilizan para mapear los índices de tokens y posiciones a vectores de embedding.call, se calculan los embeddings de tokens y posiciones y se suman para obtener la representación final de entrada. Los embeddings de posición se generan utilizando una capa de embedding de posiciones, mientras que los embeddings de tokens se obtienen utilizando una capa de embedding de tokens.Además de estas clases, el código también carga y preprocesa datos utilizando el conjunto de datos IMDb. Carga las revisiones de películas IMDb y las etiquetas correspondientes, y luego las rellena y trunca para que todas tengan la misma longitud antes de utilizarlas para entrenar un modelo de Transformer.
class TransformerBlock(layers.Layer):
def __init__(self, embed_dim, num_heads, ff_dim, rate=0.1):
super().__init__()
self.att = layers.MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim)
self.ffn = keras.Sequential(
[layers.Dense(ff_dim, activation="relu"), layers.Dense(embed_dim),]
)
self.layernorm1 = layers.LayerNormalization(epsilon=1e-6)
self.layernorm2 = layers.LayerNormalization(epsilon=1e-6)
self.dropout1 = layers.Dropout(rate)
self.dropout2 = layers.Dropout(rate)
def call(self, inputs):
attn_output = self.att(inputs, inputs)
attn_output = self.dropout1(attn_output)
out1 = self.layernorm1(inputs + attn_output)
ffn_output = self.ffn(out1)
ffn_output = self.dropout2(ffn_output)
return self.layernorm2(out1 + ffn_output)
class TokenAndPositionEmbedding(layers.Layer):
def __init__(self, maxlen, vocab_size, embed_dim):
super().__init__()
self.token_emb = layers.Embedding(input_dim=vocab_size, output_dim=embed_dim)
self.pos_emb = layers.Embedding(input_dim=maxlen, output_dim=embed_dim)
def call(self, x):
maxlen = ops.shape(x)[-1]
positions = ops.arange(start=0, stop=maxlen, step=1)
positions = self.pos_emb(positions)
x = self.token_emb(x)
return x + positions
vocab_size = 20000 # Only consider the top 20k words
maxlen = 200 # Only consider the first 200 words of each movie review
(x_train, y_train), (x_val, y_val) = keras.datasets.imdb.load_data(num_words=vocab_size)
print(len(x_train), "Training sequences")
print(len(x_val), "Validation sequences")
x_train = keras.utils.pad_sequences(x_train, maxlen=maxlen)
x_val = keras.utils.pad_sequences(x_val, maxlen=maxlen)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb.npz 17464789/17464789 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step 25000 Training sequences 25000 Validation sequences
Aquí está una descripción de cada parte del código a continuación:
Parámetros del Modelo:
embed_dim = 32: Tamaño de embedding para cada token.num_heads = 2: Número de cabezas de atención.ff_dim = 32: Tamaño de la capa oculta en la red feed forward dentro del Transformer.Definición de la Entrada:
inputs = layers.Input(shape=(maxlen,)): Se define la capa de entrada del modelo con la forma (maxlen,), donde maxlen es la longitud máxima de las secuencias de entrada.Capa de Embedding y de Transformer:
embedding_layer = TokenAndPositionEmbedding(maxlen, vocab_size, embed_dim): Se crea la capa de embedding utilizando la clase TokenAndPositionEmbedding.x = embedding_layer(inputs): Se aplica la capa de embedding a las entradas.transformer_block = TransformerBlock(embed_dim, num_heads, ff_dim): Se crea un bloque Transformer utilizando la clase TransformerBlock.x = transformer_block(x): Se aplica el bloque Transformer a las salidas de la capa de embedding.Capa de Global Average Pooling:
x = layers.GlobalAveragePooling1D()(x): Se aplica una capa de pooling promedio global para reducir la dimensionalidad de las salidas del Transformer.Capas de Dropout y Densas:
x = layers.Dropout(0.1)(x): Se aplica dropout para regularizar las salidas del pooling promedio global.x = layers.Dense(20, activation="relu")(x): Se aplica una capa densa con activación ReLU.x = layers.Dropout(0.1)(x): Se aplica dropout adicional.outputs = layers.Dense(2, activation="softmax")(x): Se aplica una capa densa con activación softmax para producir las salidas del modelo. En este caso, el modelo está diseñado para clasificar textos en dos clases, por lo que la salida es un vector de probabilidad de longitud 2.Compilación del Modelo:
model = keras.Model(inputs=inputs, outputs=outputs): Se crea el modelo Keras especificando las entradas y salidas.Este código define un modelo de clasificación de texto utilizando un Transformer en Keras, que consta de una capa de embedding, un bloque Transformer, capas de pooling, capas densas y capas de dropout para la regularización. El modelo está diseñado para clasificar textos en dos clases utilizando la función de activación softmax en la capa de salida.
embed_dim = 32 # Embedding size for each token
num_heads = 2 # Number of attention heads
ff_dim = 32 # Hidden layer size in feed forward network inside transformer
inputs = layers.Input(shape=(maxlen,))
embedding_layer = TokenAndPositionEmbedding(maxlen, vocab_size, embed_dim)
x = embedding_layer(inputs)
transformer_block = TransformerBlock(embed_dim, num_heads, ff_dim)
x = transformer_block(x)
x = layers.GlobalAveragePooling1D()(x)
x = layers.Dropout(0.1)(x)
x = layers.Dense(20, activation="relu")(x)
x = layers.Dropout(0.1)(x)
outputs = layers.Dense(2, activation="softmax")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
history = model.fit(
x_train, y_train, batch_size=32, epochs=2, validation_data=(x_val, y_val)
)
Epoch 1/2 782/782 ━━━━━━━━━━━━━━━━━━━━ 125s 154ms/step - accuracy: 0.7216 - loss: 0.5120 - val_accuracy: 0.8812 - val_loss: 0.2828 Epoch 2/2 782/782 ━━━━━━━━━━━━━━━━━━━━ 114s 146ms/step - accuracy: 0.9310 - loss: 0.1872 - val_accuracy: 0.8676 - val_loss: 0.3153
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
#plt.ylim([0.5, 1])
plt.legend(loc='lower right')
<matplotlib.legend.Legend at 0x7ed83667bf10>
prediction = model.predict(x_val)
782/782 ━━━━━━━━━━━━━━━━━━━━ 35s 44ms/step
import numpy as np
prediction[0], np.argmax(prediction[0])
(array([0.6780869 , 0.32191303], dtype=float32), 0)
import pandas as pd
import seaborn as sns
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score
# Get labels based on probability 1 if p>= 0.5 else 0
pred_labels = []
for pred_i in prediction:
pred_labels.append(np.argmax(pred_i))
print("Accuracy of prediction on test set : ", accuracy_score(y_val, pred_labels))
labels_classes = ["negative", "positive"]
cm = pd.DataFrame(confusion_matrix(y_val, pred_labels, labels=[0, 1]),
columns=labels_classes,
index=labels_classes)
sns.heatmap(cm, square=True, annot=True, fmt='d', cbar=False)
plt.xlabel('True label')
plt.ylabel('Predicted label')
print(classification_report(y_val, pred_labels))
Accuracy of prediction on test set : 0.86756
precision recall f1-score support
0 0.91 0.82 0.86 12500
1 0.84 0.92 0.87 12500
accuracy 0.87 25000
macro avg 0.87 0.87 0.87 25000
weighted avg 0.87 0.87 0.87 25000
Un autoencoder es un tipo de red neuronal que se utiliza para aprender representaciones eficientes de datos de entrada, con el objetivo principal de reconstruir los datos de salida lo más fielmente posible. Funciona en dos etapas: la etapa de codificación (o compresión) y la etapa de decodificación (o reconstrucción). Aquí está una explicación detallada de cómo funciona:
Etapa de Codificación:
Etapa de Decodificación:
Función de Pérdida:
Aplicaciones:
Un autoencoder es una red neuronal que aprende a comprimir y luego reconstruir los datos de entrada, capturando las características más importantes de los datos originales en un espacio de características de dimensionalidad menor. Esto permite la reducción de dimensionalidad y la generación de representaciones útiles para una variedad de aplicaciones de aprendizaje automático.

La arquitectura de un autoencoder consta de un codificador que comprime los datos de entrada en un código latente y un decodificador que reconstruye los datos de entrada a partir de este código latente. Juntos, el codificador y el decodificador aprenden a representar y reconstruir eficientemente los datos de entrada, lo que permite la reducción de dimensionalidad y la generación de representaciones útiles para diversas aplicaciones.
Un autoencoder puede tener varias capas tanto en el codificador como en el decodificador. La profundidad de la arquitectura del autoencoder puede variar dependiendo de la complejidad de los datos y la tarea que se esté abordando. Aquí hay una descripción de cómo podrían ser varias capas en cada parte del autoencoder:
Codificador (Encoder):
Decodificador (Decoder):
La profundidad de las capas en el codificador y el decodificador puede variar según la complejidad de los datos y la capacidad del autoencoder para aprender representaciones útiles y reconstruir con precisión los datos de entrada. Una arquitectura más profunda puede capturar relaciones más complejas entre las características de los datos y generar representaciones más precisas, pero también puede aumentar la complejidad computacional y el riesgo de sobreajuste. Por lo tanto, el diseño de la arquitectura del autoencoder debe equilibrar la complejidad del modelo con el rendimiento y la generalización deseada.

El uso de autoencoders para la detección de anomalías es una técnica de aprendizaje no supervisado que se basa en la capacidad de los autoencoders para aprender y reconstruir patrones normales en los datos de entrada. Aquí hay un resumen del proceso:
Entrenamiento del Autoencoder:
Evaluación del Error de Reconstrucción:
Detección de Anomalías:
Aplicaciones:
En resumen, los autoencoders pueden detectar anomalías al aprender a reconstruir datos normales y luego identificar muestras con un alto error de reconstrucción como anomalías potenciales. Esta técnica puede ser efectiva para identificar patrones anómalos en una variedad de conjuntos de datos no estructurados o semi-estructurados.
!pip install pyod
WARNING: Ignoring invalid distribution -ensorflow (/usr/local/lib/python3.10/dist-packages) Collecting pyod Downloading pyod-1.1.3.tar.gz (160 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 160.5/160.5 kB 3.4 MB/s eta 0:00:00 Preparing metadata (setup.py) ... done Requirement already satisfied: joblib in /usr/local/lib/python3.10/dist-packages (from pyod) (1.3.2) Requirement already satisfied: matplotlib in /usr/local/lib/python3.10/dist-packages (from pyod) (3.7.1) Requirement already satisfied: numpy>=1.19 in /usr/local/lib/python3.10/dist-packages (from pyod) (1.25.2) Requirement already satisfied: numba>=0.51 in /usr/local/lib/python3.10/dist-packages (from pyod) (0.58.1) Requirement already satisfied: scipy>=1.5.1 in /usr/local/lib/python3.10/dist-packages (from pyod) (1.11.4) Requirement already satisfied: scikit_learn>=0.22.0 in /usr/local/lib/python3.10/dist-packages (from pyod) (1.2.2) Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from pyod) (1.16.0) Requirement already satisfied: llvmlite<0.42,>=0.41.0dev0 in /usr/local/lib/python3.10/dist-packages (from numba>=0.51->pyod) (0.41.1) Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.10/dist-packages (from scikit_learn>=0.22.0->pyod) (3.3.0) Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->pyod) (1.2.0) Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib->pyod) (0.12.1) Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->pyod) (4.49.0) Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->pyod) (1.4.5) Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->pyod) (23.2) Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->pyod) (9.4.0) Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->pyod) (3.1.1) Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/dist-packages (from matplotlib->pyod) (2.8.2) Building wheels for collected packages: pyod Building wheel for pyod (setup.py) ... done Created wheel for pyod: filename=pyod-1.1.3-py3-none-any.whl size=190251 sha256=a8abbb1f21e56f4b38201cfd154f5b2b6d3f76ee64b3f927e19eb1fe68b24d1c Stored in directory: /root/.cache/pip/wheels/05/f8/db/124d43bec122d6ec0ab3713fadfe25ebed8af52ec561682b4e Successfully built pyod WARNING: Ignoring invalid distribution -ensorflow (/usr/local/lib/python3.10/dist-packages) Installing collected packages: pyod Successfully installed pyod-1.1.3
import numpy as np
import pandas as pd
from pyod.models.auto_encoder import AutoEncoder
from pyod.utils.data import generate_data
contamination = 0.1 # percentage of outliers
n_train = 500 # number of training points
n_test = 500 # number of testing points
n_features = 25 # Number of features
X_train, X_test, y_train, y_test = generate_data(
n_train=n_train, n_test=n_test,
n_features=n_features,
contamination=contamination,random_state=1234)
X_train = pd.DataFrame(X_train)
X_test = pd.DataFrame(X_test)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_train = pd.DataFrame(X_train)
X_test = scaler.transform(X_test)
X_test = pd.DataFrame(X_test)
model = AutoEncoder(hidden_neurons =[25, 2, 2, 25])
model.fit(X_train)
/usr/local/lib/python3.10/dist-packages/keras/src/layers/core/dense.py:85: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ │ dense_4 (Dense) │ (None, 25) │ 650 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout_5 (Dropout) │ (None, 25) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_5 (Dense) │ (None, 25) │ 650 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout_6 (Dropout) │ (None, 25) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_6 (Dense) │ (None, 25) │ 650 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout_7 (Dropout) │ (None, 25) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_7 (Dense) │ (None, 2) │ 52 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout_8 (Dropout) │ (None, 2) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_8 (Dense) │ (None, 2) │ 6 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout_9 (Dropout) │ (None, 2) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_9 (Dense) │ (None, 25) │ 75 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout_10 (Dropout) │ (None, 25) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_10 (Dense) │ (None, 25) │ 650 │ └──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 2,733 (10.68 KB)
Trainable params: 2,733 (10.68 KB)
Non-trainable params: 0 (0.00 B)
None Epoch 1/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 4s 34ms/step - loss: 87.0458 - val_loss: 70.3867 Epoch 2/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 62.6538 - val_loss: 52.7862 Epoch 3/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 49.6187 - val_loss: 43.8291 Epoch 4/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 41.9889 - val_loss: 38.1159 Epoch 5/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 35.6882 - val_loss: 34.3978 Epoch 6/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 17ms/step - loss: 35.7181 - val_loss: 31.3997 Epoch 7/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 32.1487 - val_loss: 29.0643 Epoch 8/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 30.6444 - val_loss: 26.9976 Epoch 9/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 27.6644 - val_loss: 25.0470 Epoch 10/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 24.8786 - val_loss: 23.3432 Epoch 11/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 23.2740 - val_loss: 21.6498 Epoch 12/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 21.8342 - val_loss: 20.0883 Epoch 13/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 15ms/step - loss: 20.5590 - val_loss: 18.6671 Epoch 14/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 18.3322 - val_loss: 17.4904 Epoch 15/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 17.2797 - val_loss: 16.4273 Epoch 16/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - loss: 15.9336 - val_loss: 15.5321 Epoch 17/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 17ms/step - loss: 15.4915 - val_loss: 14.7106 Epoch 18/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - loss: 14.4795 - val_loss: 13.9479 Epoch 19/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 13.3558 - val_loss: 13.3935 Epoch 20/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 15ms/step - loss: 12.7461 - val_loss: 12.7608 Epoch 21/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 16ms/step - loss: 12.3183 - val_loss: 12.2236 Epoch 22/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 17ms/step - loss: 11.6420 - val_loss: 11.7257 Epoch 23/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 22ms/step - loss: 11.5250 - val_loss: 11.2534 Epoch 24/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 17ms/step - loss: 10.9871 - val_loss: 10.8088 Epoch 25/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 13ms/step - loss: 10.4904 - val_loss: 10.4516 Epoch 26/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 15ms/step - loss: 10.0301 - val_loss: 10.0775 Epoch 27/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 9.6807 - val_loss: 9.7246 Epoch 28/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 9.0506 - val_loss: 9.4065 Epoch 29/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 15ms/step - loss: 8.8459 - val_loss: 9.1090 Epoch 30/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 8.4654 - val_loss: 8.8516 Epoch 31/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 8.5114 - val_loss: 8.5685 Epoch 32/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 7.9165 - val_loss: 8.3254 Epoch 33/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 7.7586 - val_loss: 8.1076 Epoch 34/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 7.6997 - val_loss: 7.8839 Epoch 35/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 7ms/step - loss: 7.2835 - val_loss: 7.7018 Epoch 36/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 7.1927 - val_loss: 7.5088 Epoch 37/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 6.7762 - val_loss: 7.3333 Epoch 38/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 6.7115 - val_loss: 7.1452 Epoch 39/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 6.6706 - val_loss: 6.9847 Epoch 40/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 6.4787 - val_loss: 6.8311 Epoch 41/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 6.4621 - val_loss: 6.6890 Epoch 42/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 6.1422 - val_loss: 6.5540 Epoch 43/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 7ms/step - loss: 6.0211 - val_loss: 6.4297 Epoch 44/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 5.7419 - val_loss: 6.2978 Epoch 45/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 5.6925 - val_loss: 6.1742 Epoch 46/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 5.6467 - val_loss: 6.0641 Epoch 47/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step - loss: 5.6321 - val_loss: 5.9603 Epoch 48/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - loss: 5.6807 - val_loss: 5.8596 Epoch 49/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 5.3204 - val_loss: 5.7627 Epoch 50/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 5.3782 - val_loss: 5.6636 Epoch 51/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 5.1794 - val_loss: 5.5721 Epoch 52/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 5.2472 - val_loss: 5.4873 Epoch 53/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 5.1257 - val_loss: 5.4062 Epoch 54/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 4.9663 - val_loss: 5.3323 Epoch 55/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 4.9177 - val_loss: 5.2596 Epoch 56/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - loss: 4.7869 - val_loss: 5.1856 Epoch 57/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 14ms/step - loss: 4.7353 - val_loss: 5.1211 Epoch 58/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 4.6177 - val_loss: 5.0589 Epoch 59/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 4.5873 - val_loss: 4.9941 Epoch 60/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 4.4950 - val_loss: 4.9244 Epoch 61/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 17ms/step - loss: 4.5267 - val_loss: 4.8629 Epoch 62/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 16ms/step - loss: 4.3055 - val_loss: 4.8091 Epoch 63/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 4.5133 - val_loss: 4.7551 Epoch 64/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 4.4142 - val_loss: 4.7032 Epoch 65/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 4.2257 - val_loss: 4.6529 Epoch 66/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 4.1111 - val_loss: 4.6059 Epoch 67/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 17ms/step - loss: 4.1409 - val_loss: 4.5545 Epoch 68/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 15ms/step - loss: 4.1417 - val_loss: 4.5020 Epoch 69/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 32ms/step - loss: 4.1515 - val_loss: 4.4606 Epoch 70/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - loss: 3.9356 - val_loss: 4.4187 Epoch 71/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 16ms/step - loss: 3.8345 - val_loss: 4.3821 Epoch 72/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 3.8633 - val_loss: 4.3401 Epoch 73/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 16ms/step - loss: 3.8845 - val_loss: 4.2918 Epoch 74/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - loss: 4.0386 - val_loss: 4.2553 Epoch 75/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 3.8380 - val_loss: 4.2170 Epoch 76/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 3.9213 - val_loss: 4.1808 Epoch 77/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 3.6855 - val_loss: 4.1435 Epoch 78/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 3.6738 - val_loss: 4.1089 Epoch 79/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 3.7924 - val_loss: 4.0741 Epoch 80/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 3.6632 - val_loss: 4.0421 Epoch 81/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 7ms/step - loss: 3.7908 - val_loss: 4.0065 Epoch 82/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 3.5555 - val_loss: 3.9764 Epoch 83/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 3.4941 - val_loss: 3.9509 Epoch 84/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 3.4754 - val_loss: 3.9195 Epoch 85/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 3.5537 - val_loss: 3.8922 Epoch 86/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 3.5582 - val_loss: 3.8620 Epoch 87/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 3.4268 - val_loss: 3.8383 Epoch 88/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 17ms/step - loss: 3.5541 - val_loss: 3.8098 Epoch 89/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 13ms/step - loss: 3.3937 - val_loss: 3.7838 Epoch 90/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 12ms/step - loss: 3.2044 - val_loss: 3.7596 Epoch 91/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 3.4640 - val_loss: 3.7335 Epoch 92/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 3.2518 - val_loss: 3.7112 Epoch 93/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 17ms/step - loss: 3.0943 - val_loss: 3.6892 Epoch 94/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - loss: 3.1338 - val_loss: 3.6660 Epoch 95/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 3.1792 - val_loss: 3.6403 Epoch 96/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step - loss: 3.1220 - val_loss: 3.6185 Epoch 97/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 10ms/step - loss: 3.1912 - val_loss: 3.5971 Epoch 98/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 11ms/step - loss: 3.2970 - val_loss: 3.5753 Epoch 99/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 3.2579 - val_loss: 3.5537 Epoch 100/100 15/15 ━━━━━━━━━━━━━━━━━━━━ 0s 9ms/step - loss: 3.0050 - val_loss: 3.5350 16/16 ━━━━━━━━━━━━━━━━━━━━ 1s 27ms/step
AutoEncoder(batch_size=32, contamination=0.1, dropout_rate=0.2, epochs=100,
hidden_activation='relu', hidden_neurons=[25, 2, 2, 25],
l2_regularizer=0.1,
loss=<function mean_squared_error at 0x7ed840b8edd0>,
optimizer='adam', output_activation='sigmoid', preprocessing=True,
random_state=None, validation_size=0.1, verbose=1)
# Get the outlier scores for the train data
y_train_scores = model.decision_scores_
# Predict the anomaly scores
y_test_scores = model.decision_function(X_test) # outlier scores
y_test_scores = pd.Series(y_test_scores)
# Plot it!
import matplotlib.pyplot as plt
plt.hist(y_test_scores, bins='auto')
plt.title("Histogram for Model Anomaly Scores")
plt.show()
16/16 ━━━━━━━━━━━━━━━━━━━━ 0s 7ms/step
df_test = X_test.copy()
df_test['score'] = y_test_scores
df_test['cluster'] = np.where(df_test['score'] < 4, 0, 1)
from sklearn.decomposition import PCA
import seaborn as sns
pca = PCA(2)
pca.fit(X_train)
x_pca = pca.transform(X_test)
x_pca = pd.DataFrame(x_pca)
x_pca.columns=['PC1','PC2']
# Plot
plt.figure(figsize=(8,4))
plt.subplot(1,2,1)
sns.scatterplot(x=x_pca.PC1, y=x_pca.PC2, hue=pd.Categorical(df_test['cluster']), alpha=1)
plt.title('Scatter plot with outliers')
plt.subplot(1,2,2)
sns.scatterplot(x=X_test[0], y=X_test[1], hue=pd.Categorical(df_test['cluster']), alpha=1)
plt.title('Scatter plot with outliers')
Text(0.5, 1.0, 'Scatter plot with outliers')
Las Generative Adversarial Networks (GANs), o Redes Generativas Adversarias en español, son un tipo de modelo de aprendizaje profundo que consta de dos redes neuronales: el generador y el discriminador. El propósito principal de una GAN es generar datos nuevos que sean similares a un conjunto de datos de entrenamiento dado.
Aquí hay una descripción de cómo funcionan las GANs:
Generador (Generator):
Discriminador (Discriminator):
Proceso de Entrenamiento:
Aplicaciones:
En resumen, las GANs son una técnica poderosa para generar datos sintéticos realistas que son indistinguibles de los datos reales, y se utilizan en una amplia variedad de aplicaciones creativas y prácticas en el campo del aprendizaje profundo.
Una red generativa adversarial (GAN) tiene dos partes:
El generador aprende a generar datos plausibles. Las instancias generadas se convierten en ejemplos de entrenamiento negativos para el discriminador.
El discriminador aprende a distinguir los datos falsos del generador de los datos reales. El discriminador penaliza al generador por producir resultados implausibles.
Cuando comienza el entrenamiento, el generador produce datos obviamente falsos, y el discriminador aprende rápidamente a distinguir que son falsos:
A medida que avanza el entrenamiento, el generador se acerca a producir resultados que pueden engañar al discriminador:
Finalmente, si el entrenamiento del generador va bien, el discriminador empeora en distinguir entre lo real y lo falso. Comienza a clasificar datos falsos como reales, y su precisión disminuye.
Aquí hay una imagen de todo el sistema:
Tanto el generador como el discriminador son redes neuronales. La salida del generador está conectada directamente a la entrada del discriminador. A través de la retropropagación, la clasificación del discriminador proporciona una señal que el generador utiliza para actualizar sus pesos.
El discriminador en una GAN es simplemente un clasificador. Intenta distinguir entre datos reales y los datos creados por el generador. Puede usar cualquier arquitectura de red apropiada para el tipo de datos que está clasificando.
Datos de Entrenamiento del Discriminador
Los datos de entrenamiento del discriminador provienen de dos fuentes:
En la figura, las dos cajas "Muestra (Sample)" representan estas dos fuentes de datos que alimentan al discriminador. Durante el entrenamiento del discriminador, el generador no se entrena. Sus pesos permanecen constantes mientras produce ejemplos para que el discriminador se entrene.
Entrenamiento del Discriminador
El discriminador se conecta a dos funciones de pérdida. Durante el entrenamiento del discriminador, este ignora la pérdida del generador y solo utiliza la pérdida del discriminador. Utilizamos la pérdida del generador durante el entrenamiento del generador, como se describe en la siguiente sección.
Durante el entrenamiento del discriminador
La parte del generador en una GAN aprende a crear datos falsos incorporando retroalimentación del discriminador. Aprende a hacer que el discriminador clasifique su salida como real.
El entrenamiento del generador requiere una integración más estrecha entre el generador y el discriminador que lo que requiere el entrenamiento del discriminador. La parte de la GAN que entrena al generador incluye:
Entrada Aleatoria
Las redes neuronales necesitan alguna forma de entrada. Normalmente ingresamos datos que queremos manipular, como una instancia que queremos clasificar o sobre la cual hacer una predicción. Pero ¿qué usamos como entrada para una red que genera instancias de datos completamente nuevas?
En su forma más básica, una GAN toma ruido aleatorio como su entrada. Luego, el generador transforma este ruido en una salida significativa. Al introducir ruido, podemos hacer que la GAN produzca una amplia variedad de datos, muestreando de diferentes lugares en la distribución objetivo.
Los experimentos sugieren que la distribución del ruido no importa mucho, por lo que podemos elegir algo fácil de muestrear, como una distribución uniforme. Por conveniencia, el espacio del cual se muestrea el ruido suele ser de menor dimensión que la dimensionalidad del espacio de salida.
Nota: Algunas GAN utilizan una entrada no aleatoria para dar forma a la salida. Consulte Variaciones de GAN.
Uso del Discriminador para Entrenar al Generador
Para entrenar una red neuronal, alteramos los pesos de la red para reducir el error o la pérdida de su salida. Sin embargo, en nuestra GAN, el generador no está directamente conectado a la pérdida que estamos tratando de afectar. El generador alimenta a la red del discriminador, y el discriminador produce la salida que estamos tratando de afectar. La pérdida del generador penaliza al generador por producir una muestra que la red del discriminador clasifica como falsa.
Este segmento adicional de la red debe incluirse en la retropropagación. La retropropagación ajusta cada peso en la dirección correcta al calcular el impacto del peso en la salida, es decir, cómo cambiaría la salida si cambiara el peso. Pero el impacto de un peso del generador depende del impacto de los pesos del discriminador en los que se alimenta. Por lo tanto, la retropropagación comienza en la salida y fluye hacia atrás a través del discriminador hacia el generador.
Al mismo tiempo, no queremos que el discriminador cambie durante el entrenamiento del generador. Intentar alcanzar un objetivo móvil haría que un problema difícil fuera aún más difícil para el generador.
Por lo tanto, entrenamos al generador con el siguiente procedimiento:
Esta es una iteración del entrenamiento del generador. En la próxima sección veremos cómo equilibrar el entrenamiento tanto del generador como del discriminador.
Debido a que una GAN contiene dos redes entrenadas de forma separada, su algoritmo de entrenamiento debe abordar dos complicaciones:
Entrenamiento Alternante
El entrenamiento de una GAN procede en períodos alternantes:
Mantenemos el generador constante durante la fase de entrenamiento del discriminador. A medida que el entrenamiento del discriminador intenta descifrar cómo distinguir entre datos reales y falsos, debe aprender a reconocer las fallas del generador. Este es un problema diferente para un generador completamente entrenado que para un generador no entrenado que produce una salida aleatoria.
De manera similar, mantenemos el discriminador constante durante la fase de entrenamiento del generador. De lo contrario, el generador estaría tratando de alcanzar un objetivo móvil y podría nunca converger.
Es este vaivén lo que permite a las GAN abordar problemas generativos que de otro modo serían intratables. Obtenemos un punto de apoyo en el difícil problema generativo al comenzar con un problema de clasificación mucho más simple. Por otro lado, si no puedes entrenar un clasificador para distinguir entre datos reales y generados incluso para la salida inicial aleatoria del generador, no puedes comenzar el entrenamiento de la GAN.
A medida que el generador mejora con el entrenamiento, el rendimiento del discriminador empeora porque el discriminador no puede distinguir fácilmente entre real y falso. Si el generador tiene éxito perfectamente, entonces el discriminador tiene una precisión del 50%. En efecto, el discriminador lanza una moneda al aire para hacer su predicción.
Esta progresión plantea un problema para la convergencia de la GAN en su conjunto: la retroalimentación del discriminador se vuelve menos significativa con el tiempo. Si la GAN continúa entrenando más allá del punto en que el discriminador está dando retroalimentación completamente aleatoria, entonces el generador comienza a entrenar con retroalimentación basura, y su propia calidad puede colapsar.
Para una GAN, la convergencia a menudo es un estado fugaz, en lugar de estable.
Las GAN intentan replicar una distribución de probabilidad. Por lo tanto, deben usar funciones de pérdida que reflejen la distancia entre la distribución de los datos generados por la GAN y la distribución de los datos reales.
¿Cómo se captura la diferencia entre dos distribuciones en las funciones de pérdida de GAN? Esta pregunta es un área de investigación activa, y se han propuesto muchos enfoques. Aquí abordaremos dos funciones de pérdida comunes de GAN, ambas implementadas en TF-GAN:
TF-GAN implementa muchas otras funciones de pérdida también.
¿Una o dos funciones de pérdida?
Una GAN puede tener dos funciones de pérdida: una para el entrenamiento del generador y otra para el entrenamiento del discriminador. ¿Cómo pueden dos funciones de pérdida trabajar juntas para reflejar una medida de distancia entre distribuciones de probabilidad?
En los esquemas de pérdida que veremos aquí, las pérdidas del generador y del discriminador se derivan de una sola medida de distancia entre distribuciones de probabilidad. En ambos esquemas, sin embargo, el generador solo puede afectar un término en la medida de distancia: el término que refleja la distribución de los datos falsos. Por lo tanto, durante el entrenamiento del generador, eliminamos el otro término, que refleja la distribución de los datos reales.
Las pérdidas del generador y del discriminador se ven diferentes al final, aunque se derivan de una sola fórmula.
Pérdida Minimax
En el artículo que introdujo las GAN, el generador intenta minimizar la siguiente función mientras que el discriminador intenta maximizarla:
En esta función:
La fórmula se deriva de la entropía cruzada entre las distribuciones reales y generadas.
El generador no puede afectar directamente el término $log(D(x))$ en la función, por lo que, para el generador, minimizar la pérdida es equivalente a minimizar $log(1 - D(G(z)))$.
En TF-GAN, vea minimax_discriminator_loss y minimax_generator_loss para una implementación de esta función de pérdida.
Pérdida Minimax Modificada
El artículo original de GAN señala que la función de pérdida minimax anterior puede hacer que la GAN se quede atascada en las primeras etapas del entrenamiento de GAN cuando el trabajo del discriminador es muy fácil. Por lo tanto, el artículo sugiere modificar la pérdida del generador para que el generador intente maximizar $log D(G(z))$.
En TF-GAN, vea modified_generator_loss para una implementación de esta modificación.
Pérdida de Wasserstein
Por defecto, TF-GAN utiliza la pérdida de Wasserstein.
Esta función de pérdida depende de una modificación del esquema de GAN (llamado "Wasserstein GAN" o "WGAN") en el que el discriminador en realidad no clasifica las instancias. Para cada instancia, produce un número. Este número no tiene que ser menor que uno o mayor que cero, por lo que no podemos usar 0.5 como un umbral para decidir si una instancia es real o falsa. El entrenamiento del discriminador solo intenta hacer que la salida sea más grande para las instancias reales que para las falsas.
Dado que realmente no puede discriminar entre real y falso, al discriminador de WGAN se le llama "crítico" en lugar de "discriminador". Esta distinción tiene importancia teórica, pero para fines prácticos podemos tratarlo como un reconocimiento de que las entradas a las funciones de pérdida no tienen que ser probabilidades.
Las funciones de pérdida en sí son engañosamente simples:
Pérdida del Crítico: $D(x) - D(G(z))$
El discriminador intenta maximizar esta función. En otras palabras, intenta maximizar la diferencia entre su salida en instancias reales y su salida en instancias falsas.
Pérdida del Generador: $D(G(z))$
El generador intenta maximizar esta función. En otras palabras, intenta maximizar la salida del discriminador para sus instancias falsas.
En estas funciones:
En TF-GAN, consulte wasserstein_generator_loss y wasserstein_discriminator_loss para implementaciones.
Requisitos
La justificación teórica para la GAN de Wasserstein (o WGAN) requiere que los pesos en toda la GAN se recorten para que permanezcan dentro de un rango limitado.
Beneficios
Las GAN de Wasserstein son menos propensas a quedarse atascadas que las GAN basadas en minimax, y evitan problemas con los gradientes que desaparecen. La distancia de transporte también tiene la ventaja de ser una métrica real: una medida de distancia en un espacio de distribuciones de probabilidad. La entropía cruzada no es una métrica en este sentido.
Las GAN (Redes Generativas Adversarias) se pueden utilizar para la ampliación de datos o data augmentation de diversas maneras. Aquí hay algunos enfoques comunes:
Generación de Datos Realistas: La GAN puede generar datos sintéticos que se parezcan a los datos reales en el conjunto de datos original. Por ejemplo, si tienes un conjunto de imágenes de rostros humanos, una GAN puede generar nuevas imágenes de rostros humanos que sean casi indistinguibles de las imágenes reales. Estos datos generados pueden utilizarse para aumentar el tamaño del conjunto de datos original y mejorar la diversidad y representatividad de los datos.
Aumento de la Variedad: La GAN puede generar muestras que cubran partes del espacio de características que pueden estar subrepresentadas en el conjunto de datos original. Esto puede ayudar a mejorar la robustez y generalización del modelo entrenado con el conjunto de datos aumentado.
Generación de Datos de Etiquetas Frías: En problemas de clasificación con etiquetas frías o con un número limitado de ejemplos por clase, una GAN puede generar ejemplos adicionales para clases menos representadas. Esto ayuda a equilibrar la distribución de clases en el conjunto de datos, lo que puede mejorar el rendimiento del modelo en la clasificación de esas clases menos comunes.
Aumento de Datos con Información Adicional: Si se tienen características adicionales o metadatos junto con los datos originales, una GAN puede generar datos sintéticos que conserven estas características adicionales. Por ejemplo, si se tienen imágenes médicas junto con información sobre la edad y el sexo del paciente, una GAN puede generar nuevas imágenes médicas que estén vinculadas a combinaciones específicas de edad y sexo.
Las GAN pueden ser una herramienta poderosa para aumentar conjuntos de datos, mejorar la diversidad y la calidad de los datos, y ayudar a abordar problemas de desequilibrio de clases en el aprendizaje automático y la visión por computadora. Sin embargo, es importante tener en cuenta que el uso de datos generados debe hacerse con precaución y validarse cuidadosamente para garantizar que mejoren realmente el rendimiento del modelo en lugar de introducir sesgos o errores.
El data augmentation, o ampliación de datos, puede ser especialmente útil en problemas de clasificación desbalanceados, donde hay una diferencia significativa en la cantidad de muestras disponibles para cada clase. Aquí hay algunas formas en que el data augmentation puede abordar este problema:
Generación de Muestras para Clases Minoritarias: En problemas desbalanceados, las clases minoritarias pueden tener menos ejemplos de entrenamiento, lo que puede llevar a un rendimiento deficiente del modelo en estas clases. El data augmentation puede generar muestras sintéticas para las clases minoritarias, lo que aumenta su representación en el conjunto de datos. Esto ayuda a equilibrar la distribución de clases y mejora la capacidad del modelo para aprender de manera efectiva sobre las clases menos comunes.
Aumento de la Variabilidad Intraclase: Incluso en clases con un número suficiente de ejemplos, el data augmentation puede mejorar la variabilidad intraclase. Por ejemplo, en problemas de reconocimiento de objetos, se pueden aplicar transformaciones como rotaciones, traslaciones y cambios de escala a las imágenes de entrenamiento existentes para generar nuevas muestras. Esto ayuda al modelo a capturar mejor la variabilidad de los datos y a generalizar de manera más efectiva a nuevas instancias.
Generación de Muestras con Etiquetas Frías: Si el conjunto de datos desbalanceado también tiene etiquetas frías o clases poco representadas, el data augmentation puede generar ejemplos adicionales para estas clases. Esto puede mejorar la capacidad del modelo para clasificar correctamente las clases menos comunes.
Aumento de la Diversidad de Muestras: El data augmentation puede introducir una mayor diversidad de muestras en el conjunto de datos, lo que puede ayudar al modelo a capturar mejor las relaciones subyacentes entre las características y las etiquetas. Por ejemplo, en el procesamiento de texto, se pueden aplicar técnicas como la eliminación de palabras, la sustitución de sinónimos y la inserción de palabras para generar nuevas variantes de las muestras de texto existentes.
En general, el data augmentation puede mejorar significativamente el rendimiento de los modelos en problemas desbalanceados al aumentar la representación de clases minoritarias, aumentar la variabilidad de los datos y mejorar la capacidad del modelo para generalizar a nuevas instancias. Sin embargo, es importante tener en cuenta que el data augmentation debe aplicarse de manera cuidadosa y controlada para evitar la introducción de sesgos o distorsiones no deseadas en los datos.
Equilibrar los datos es importante en el aprendizaje automático por varias razones:
Mejora el rendimiento del modelo: En problemas de clasificación desbalanceados, donde una clase tiene muchas más muestras que otras, los modelos de aprendizaje automático pueden sesgarse hacia la clase mayoritaria y tener dificultades para clasificar correctamente las clases minoritarias. Al equilibrar los datos, el modelo puede aprender de manera más equitativa de todas las clases y, por lo tanto, mejorar su capacidad para clasificar con precisión todas las clases.
Reducción del sesgo del modelo: Los modelos de aprendizaje automático pueden aprender a predecir la clase mayoritaria con alta precisión, incluso si no es la clase de interés. Esto puede ocurrir si el modelo se entrena en un conjunto de datos desbalanceado. Al equilibrar los datos, se reduce el sesgo del modelo hacia la clase mayoritaria y se fomenta una clasificación más equitativa de todas las clases.
Mejora la generalización: Un modelo entrenado en un conjunto de datos desbalanceado puede tener dificultades para generalizar a datos no vistos, especialmente en las clases minoritarias. Al equilibrar los datos, se mejora la capacidad del modelo para generalizar a nuevas instancias y a clases subrepresentadas.
Mitiga el impacto del sesgo en la evaluación del modelo: Al evaluar el rendimiento del modelo en un conjunto de datos desbalanceado, las métricas de evaluación pueden verse sesgadas hacia la clase mayoritaria. Al equilibrar los datos, se mitiga este sesgo y se obtienen métricas de evaluación más equitativas y representativas del rendimiento del modelo en todas las clases.
En resumen, el equilibrio de los datos es importante para garantizar que los modelos de aprendizaje automático sean justos, precisos y generalizables en problemas de clasificación desbalanceados. Esto ayuda a evitar el sesgo del modelo y mejora su capacidad para realizar predicciones precisas en todas las clases del problema.
El conjunto de datos de detección de fraudes en tarjetas de crédito es un conjunto de datos ampliamente utilizado en el campo de la detección de fraudes financieros. Contiene transacciones de tarjetas de crédito realizadas por titulares de tarjetas europeos durante un período de dos días en septiembre de 2013. El conjunto de datos está altamente desbalanceado, ya que solo el 0.172% de las transacciones son fraudes.
Aquí hay una descripción detallada del conjunto de datos:
Número de instancias: El conjunto de datos consta de 284,807 transacciones de tarjetas de crédito. Cada transacción está representada por un conjunto de características y una etiqueta binaria que indica si la transacción es fraudulenta (1) o legítima (0).
Características: Las características incluyen información básica de la transacción, como el monto de la transacción, el tiempo desde la primera transacción en segundos, y los componentes principales obtenidos mediante un análisis de componentes principales (PCA) para proteger la privacidad de los datos del cliente. Estas características PCA se derivan de las características originales, que no se proporcionan debido a problemas de privacidad y seguridad.
Variable de destino: La variable de destino es binaria y representa si una transacción es fraudulenta (1) o legítima (0).
Desbalanceo de clases: Como se mencionó anteriormente, el conjunto de datos está altamente desbalanceado, con una gran mayoría de transacciones legítimas y solo una pequeña fracción de transacciones fraudulentas.
Problema de aprendizaje: El objetivo del conjunto de datos es predecir si una transacción de tarjeta de crédito es fraudulenta o legítima basándose en las características proporcionadas.
Este conjunto de datos es un desafío interesante para los modelos de detección de fraudes debido a su desbalance de clases y su gran cantidad de características. Los investigadores y profesionales del aprendizaje automático utilizan este conjunto de datos para desarrollar y probar algoritmos de detección de fraudes, así como para evaluar la efectividad de diferentes técnicas de manejo de datos desbalanceados.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from google.colab import drive
drive.mount('/content/drive')
df = pd.read_csv('/content/drive/MyDrive/creditcard.csv')
df = df.dropna()
df.shape
Mounted at /content/drive
(284807, 31)
ratio_ones = df.Class.mean()
ratio_zeros = (len(df) - df.Class.sum())/len(df)
plt.bar('Regular transactions', height=ratio_zeros, label='Not Fraud')
plt.bar('Fraud transactions', height=ratio_ones, label='Fraud')
plt.xlabel("Target")
plt.ylabel('Percentage of total')
plt.text(-0.10, 0.5, "{0:.3f} %".format(ratio_zeros*100), fontsize=12)
plt.text(0.95, 0.1, "{0:.3f} %".format(ratio_ones*100), fontsize=12)
plt.legend()
plt.tight_layout()
from sklearn.model_selection import train_test_split
# Separate features and target variable
X = df.drop('Class', axis=1)
y = df['Class']
# Splitting data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2,
stratify=y)
train_df = pd.concat([X_train, y_train], axis=1)
from keras.layers import Dense, Input
from keras.models import Sequential, Model
from keras.optimizers import Adam
import tensorflow.keras.backend as K
import tensorflow as tf
# Load the dataset (fraud and non-fraud data)
fraud_data = train_df[train_df['Class'] == 1].drop('Class', axis=1).values
non_fraud_data = train_df[train_df['Class'] == 0].drop('Class', axis=1).values
np.unique(train_df['Class'], return_counts=True)
(array([0, 1]), array([227451, 394]))
# Calculate the number of synthetic fraud samples to generate
num_real_fraud = len(fraud_data)
num_synthetic_samples = len(non_fraud_data) - num_real_fraud
print("# of non-fraud: ", len(non_fraud_data))
print("# of Real Fraud:", num_real_fraud)
print("# of Synthetic Fraud required:", num_synthetic_samples)
# of non-fraud: 227451 # of Real Fraud: 394 # of Synthetic Fraud required: 227057
# Define the generator network
def build_generator(latent_dim, output_dim):
model = Sequential()
model.add(Dense(64, input_shape=(latent_dim,)))
model.add(Dense(128, activation='sigmoid'))
model.add(Dense(output_dim, activation='sigmoid'))
return model
# Define the discriminator network
def build_discriminator(input_dim):
model = Sequential()
model.add(Input((input_dim,)))
model.add(Dense(128, activation='sigmoid'))
model.add(Dense(1, activation='sigmoid'))
return model
# Dimensionality of the input noise for the generator
latent_dim = 512
# Build generator and discriminator models
generator = build_generator(latent_dim, fraud_data.shape[1])
discriminator = build_discriminator(fraud_data.shape[1])
/usr/local/lib/python3.10/dist-packages/keras/src/layers/core/dense.py:85: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs)
from keras.metrics import Precision, Recall
# Compile the discriminator model
discriminator.compile(optimizer=Adam(learning_rate=0.0002, beta_1=0.5), loss='binary_crossentropy', metrics=[Precision(), Recall()])
def generator_loss_log_d(y_true, y_pred):
return -K.mean(K.log(y_pred + K.epsilon()))
# GAN model combining generator and discriminator
def build_gan(generator, discriminator):
discriminator.trainable = False
model = Sequential()
model.add(generator)
model.add(discriminator)
model.compile(optimizer=Adam(learning_rate=0.0002, beta_1=0.5), loss=generator_loss_log_d)
return model
# Build and compile the GAN model
gan = build_gan(generator, discriminator)
# Compile the discriminator model
from keras.metrics import Precision, Recall
discriminator.compile(optimizer=Adam(learning_rate=0.0002, beta_1=0.5), loss='binary_crossentropy', metrics=[Precision(), Recall()])
# Set hyperparameters
epochs = 10000
batch_size = 32
# Training loop for the GANs
for epoch in range(epochs):
# Train discriminator (freeze generator)
discriminator.trainable = True
generator.trainable = False
# Random sampling from the real fraud data
real_fraud_samples = fraud_data[np.random.randint(0, num_real_fraud, batch_size)]
# Generate fake fraud samples using the generator
noise = np.random.normal(0, 1, size=(batch_size, latent_dim))
fake_fraud_samples = generator.predict(noise)
# Create labels for real and fake fraud samples
real_labels = np.ones((batch_size, 1))
fake_labels = np.zeros((batch_size, 1))
# Train the discriminator on real and fake fraud samples
d_loss_real = discriminator.train_on_batch(real_fraud_samples, real_labels)
d_loss_fake = discriminator.train_on_batch(fake_fraud_samples, fake_labels)
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# Train generator (freeze discriminator)
discriminator.trainable = False
generator.trainable = True
# Generate synthetic fraud samples and create labels for training the generator
noise = np.random.normal(0, 1, size=(batch_size, latent_dim))
valid_labels = np.ones((batch_size, 1))
# Train the generator to generate samples that "fool" the discriminator
g_loss = gan.train_on_batch(noise, valid_labels)
# Print the progress
if epoch % 100 == 0:
print(f"Epoch: {epoch} - D Loss: {d_loss} - G Loss: {g_loss}")
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 129ms/step Epoch: 0 - D Loss: [1.3800555 0. 0. ] - G Loss: 1.4951822757720947 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step
WARNING:tensorflow:5 out of the last 5 calls to <function TensorFlowTrainer.make_train_function.<locals>.one_step_on_iterator at 0x79a58b55e8c0> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for more details. WARNING:tensorflow:6 out of the last 6 calls to <function TensorFlowTrainer.make_train_function.<locals>.one_step_on_iterator at 0x79a588c82050> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for more details.
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 94ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 82ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 45ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 50ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 62ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 39ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 65ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 56ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 39ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 84ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step Epoch: 100 - D Loss: [0.72154146 0. 0. ] - G Loss: 1.906126856803894 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 44ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step Epoch: 200 - D Loss: [0.5506754 1. 0.32680348] - G Loss: 2.0540003776550293 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 44ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 61ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 52ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step Epoch: 300 - D Loss: [0.43937165 1. 0.5490033 ] - G Loss: 2.2031617164611816 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 42ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 43ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step Epoch: 400 - D Loss: [0.36371142 1. 0.65952307] - G Loss: 2.3655104637145996 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 42ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 43ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 43ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step Epoch: 500 - D Loss: [0.3093707 1. 0.72642213] - G Loss: 2.528599739074707 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step Epoch: 600 - D Loss: [0.26882875 1. 0.7711626 ] - G Loss: 2.6870267391204834 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 41ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 39ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 47ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 48ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step Epoch: 700 - D Loss: [0.23759857 1. 0.8033613 ] - G Loss: 2.838341236114502 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 48ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step Epoch: 800 - D Loss: [0.21270803 1. 0.8276373 ] - G Loss: 2.982362747192383 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 60ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 42ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step Epoch: 900 - D Loss: [0.19247948 1. 0.8465247 ] - G Loss: 3.118964672088623 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 35ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 28s 28s/step Epoch: 1000 - D Loss: [0.17579758 1. 0.86141986] - G Loss: 3.2474238872528076 1/1 ━━━━━━━━━━━━━━━━━━━━ 65s 65s/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 81ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 44ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 34ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 40ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 36ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 32ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 46ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step 1/1 ━━━━━━━━━━━━━━━━━━━━ 151s 151s/step
# After training, use the generator to create synthetic fraud data
noise = np.random.normal(0, 1, size=(num_synthetic_samples, latent_dim))
synthetic_fraud_data = generator.predict(noise)
X_train.shape, synthetic_fraud_data.shape
# Convert the result to a Pandas DataFrame format
fake_df = pd.DataFrame(synthetic_fraud_data, columns=df.drop(columns='Class').columns)
fake_df["Class"] = 1
fake_data_512.csv: https://drive.google.com/file/d/1KZd9CPQxYZJN6hPG2mIZmpcaiV4TgppS/view?usp=share_linkfake_df = pd.read_csv("/content/drive/MyDrive/fake_data_512.csv")
# Now, combine the synthetic DataFrame with the train DataFrame to create the working dataframe
wdf = pd.concat([train_df, fake_df], axis=0)
# Resetting the index of the new DataFrame
wdf.reset_index(drop=True, inplace=True)
wdf.shape, train_df.shape
((454902, 31), (227845, 31))
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report,confusion_matrix
X, y = train_df.drop(columns="Class"), train_df.Class
# Create a Random Forest Classifier with default parameters
clf = RandomForestClassifier(n_estimators=50, random_state=42)
# Train the model
clf.fit(X, y)
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))
confusion_matrix(y_test, y_pred)
precision recall f1-score support
0 1.00 1.00 1.00 56864
1 0.99 0.79 0.88 98
accuracy 1.00 56962
macro avg 0.99 0.89 0.94 56962
weighted avg 1.00 1.00 1.00 56962
array([[56863, 1],
[ 21, 77]])
# Trian with augmented data
X, y = wdf.drop(columns="Class"), wdf.Class
# Create a Random Forest Classifier with default parameters
clf = RandomForestClassifier(n_estimators=50, random_state=42)
# Train the model
clf.fit(X, y)
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))
confusion_matrix(y_test, y_pred)
precision recall f1-score support
0 1.00 1.00 1.00 56864
1 0.97 0.80 0.88 98
accuracy 1.00 56962
macro avg 0.99 0.90 0.94 56962
weighted avg 1.00 1.00 1.00 56962
array([[56862, 2],
[ 20, 78]])
El aprendizaje por transferencia (transfer learning en inglés) es una técnica de aprendizaje automático que aprovecha el conocimiento adquirido durante el entrenamiento de un modelo en un dominio fuente para mejorar el rendimiento en un dominio de destino relacionado pero diferente. En lugar de entrenar un modelo desde cero en un conjunto de datos específico, se utiliza un modelo previamente entrenado en un dominio similar como punto de partida y se ajustan sus parámetros para adaptarlo al nuevo problema.
El proceso de transferencia de conocimiento generalmente implica las siguientes etapas:
Pre-entrenamiento en el dominio fuente: Se entrena un modelo en un conjunto de datos grande y diverso relacionado con el problema de destino. Esto puede ser un conjunto de datos público o privado, y el modelo se entrena para resolver una tarea relacionada.
Selección del modelo base: Se elige un modelo pre-entrenado que sea relevante para el problema de destino. Estos modelos pueden ser arquitecturas de redes neuronales profundas como VGG, ResNet, Inception, etc., que se han entrenado en conjuntos de datos masivos como ImageNet.
Ajuste fino en el dominio de destino: Se adapta el modelo pre-entrenado al nuevo conjunto de datos de destino. Esto implica descongelar algunas capas del modelo y re-entrenarlas en el conjunto de datos de destino, mientras que otras capas pueden permanecer congeladas o tener una tasa de aprendizaje más baja.
Evaluación y ajuste: Se evalúa el rendimiento del modelo ajustado en el conjunto de datos de destino y se realizan ajustes adicionales si es necesario. Esto puede incluir la selección de hiperparámetros, la adición de capas adicionales, o la modificación de la arquitectura del modelo.
El aprendizaje por transferencia es especialmente útil cuando se tienen conjuntos de datos de destino pequeños o se carece de recursos computacionales para entrenar modelos desde cero. También puede ayudar a mejorar el rendimiento del modelo en dominios específicos donde se dispone de conjuntos de datos de referencia grandes y pre-entrenados. Esta técnica se utiliza ampliamente en áreas como el procesamiento de imágenes, el procesamiento de lenguaje natural y la visión por computadora.