Desafiando los Límites: Explorando Redes Neuronales Avanzadas

Redes Neuronales Avanzadas

En esta última entrega de nuestro viaje, nos adentraremos en el emocionante mundo de las Redes Neuronales Avanzadas. Exploraremos arquitecturas y técnicas que han llevado el aprendizaje profundo a nuevas alturas, permitiendo abordar problemas más complejos y lograr resultados más sorprendentes.

Conoceremos las Redes Neuronales Recurrentes (RNN) que son expertas en trabajar con secuencias de datos, ideales para tareas como el procesamiento de lenguaje natural y la predicción de series temporales. Además, nos sumergiremos en las Redes Neuronales Generativas (GAN), capaces de crear contenido nuevo y realista, desde imágenes hasta música.

  • Las redes neuronales avanzadas son modelos de aprendizaje profundo más complejos que las redes neuronales simples. Incorporan arquitecturas más elaboradas y algoritmos de entrenamiento más potentes.
  • Algunos ejemplos incluyen redes neuronales convolucionales (CNN), redes neuronales recurrentes (RNN), redes antagonistas generativas (GAN) y redes de memoria a largo/corto plazo (LSTM / GRU).
  • Las CNN son excelentes para tareas de visión por computadora como clasificación de imágenes. Las RNN son buenas para datos secuenciales como texto o audio. Las GAN se usan en generación de contenido como imágenes. Las LSTM/GRU capturan dependencias a largo plazo en secuencias.
  • Entrenar estas redes neuronales avanzadas requiere grandes conjuntos de datos, mucho poder de cómputo y técnicas como dropout o batch normalization para regularización.
  • Otras técnicas avanzadas incluyen attention mechanisms, representaciones distribuidas de palabras, embeddings continuos, transfer learning, etc.
  • Las aplicaciones van desde procesamiento de lenguaje natural, reconocimiento de voz y objetos, hasta la generación de texto e imágenes. Sigue siendo un área de investigación muy activa.

En fin, las redes neuronales avanzadas permiten modelos de IA más potentes y flexibles, impulsando avances en muchas áreas. Pero requieren mucho conocimiento y recursos para implementar y entrenar efectivamente.

Presentamos un ejemplo sencillo de una red neuronal que sustituye números por palabras, es decir a cada palabra la asocia con un número para poder trabajar de mejor manera:

import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# Datos de ejemplo
texts = [
    "Esta película es increíble, realmente la disfruté mucho.",
    "La trama era confusa y la actuación fue decepcionante.",
    "No puedo creer que perdí tiempo viendo esta película aburrida.",
    "La cinematografía y la banda sonora fueron excepcionales."
]
# Tokenización de texto
tokenizer = Tokenizer()
tokenizer.fit_on_texts(texts)
vocab_size = len(tokenizer.word_index) + 1  # tamaño del vocabulario

# Secuencias de palabras y etiquetas
sequences = tokenizer.texts_to_sequences(texts)
max_sequence_length = max(len(seq) for seq in sequences)  # longitud máxima de secuencia
train_sequences = pad_sequences(sequences, maxlen=max_sequence_length, padding='post')

# Resultado
print("Secuencias de palabras:")
print(train_sequences)

El resultado es:

Secuencias de palabras:
[[ 2  3  5  6  7  1  8  9  0  0]
 [ 1 10 11 12  4  1 13 14 15  0]
 [16 17 18 19 20 21 22  2  3 23]
 [ 1 24  4  1 25 26 27 28  0  0]]

Es decir, por cada palabra que encuentra en el arreglo texts, la sustituye por un valor numérico, bueno el modelo de entrenamiento queda así:

# Datos de ejemplo
texts = [
    "Esta película es increíble, realmente la disfruté mucho.",
    "La trama era confusa y la actuación fue decepcionante.",
    "La cinematografía y la banda sonora fueron excepcionales."]
 
test_texts = [
    "Esta película es increíble.",
    "No me gustó la trama de esta película.",
    "Increíble actuación, realmente disfruté la película."]
 
 Ejecutamos este código:

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense

# Creación del modelo
model_rnn = Sequential()
vocab_size = 10000  # por ejemplo, si hay 10,000 palabras únicas en tu conjunto de datos
embedding_dim = 50  # dimensión del espacio de representación de palabras
max_sequence_length = 100  # longitud máxima de las secuencias de palabras

# Capa de embedding para representar palabras como vectores densos
model_rnn.add(Embedding(input_dim=vocab_size, output_dim=embedding_dim, input_length=max_sequence_length))

# Capa LSTM con 100 unidades
model_rnn.add(LSTM(100))

# Capa completamente conectada con una neurona y activación sigmoide para clasificación binaria
model_rnn.add(Dense(1, activation='sigmoid'))

# Compilar el modelo
model_rnn.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

# Entrenar el modelo (en este caso, se asume que tienes datos de entrenamiento)
model_rnn.fit(train_sequences, train_labels, epochs=5, batch_size=64, validation_split=0.2)

# Hacer predicciones

test_texts = [
    "Esta película es increíble.",
    "No me gustó la trama de esta película.",
    "Increíble actuación, realmente disfruté la película."]

# Tokenización de texto utilizando el mismo tokenizer del conjunto de entrenamiento
test_sequences = tokenizer.texts_to_sequences(test_texts)
max_sequence_length = max(len(seq) for seq in test_sequences)  # longitud máxima de secuencia
test_sequences = pad_sequences(test_sequences, maxlen=max_sequence_length, padding='post')
test_sequences = pad_sequences(sequences, maxlen=100, padding='post')

predictions_rnn = model_rnn.predict(test_sequences)

for i, text in enumerate(test_texts):
    print(f"Texto: {text}")
    print(f"Predicción: {predictions_rnn[i][0].round()}")
    print()

El resultado es:

Epoch 1/5
1/1 [=] - 3s 3s/step - loss: 0.6512 - accuracy: 0.0000e+00 - val_loss: 0.4632 - val_accuracy: 0.0000e+00
Epoch 2/5
1/1 [=] - 0s 39ms/step - loss: 0.5620 - accuracy: 0.0000e+00 - val_loss: 0.2947 - val_accuracy: 0.0000e+00
Epoch 3/5
1/1 [=] - 0s 36ms/step - loss: 0.4661 - accuracy: 0.0000e+00 - val_loss: 0.0977 - val_accuracy: 0.0000e+00
Epoch 4/5
1/1 [=] - 0s 38ms/step - loss: 0.3545 - accuracy: 0.0000e+00 - val_loss: -0.1482 - val_accuracy: 0.0000e+00
Epoch 5/5
1/1 [=] - 0s 37ms/step - loss: 0.2155 - accuracy: 0.0000e+00 - val_loss: -0.4771 - val_accuracy: 0.0000e+00
1/1 [==============================] - 0s 357ms/step
Texto: Esta película es increíble.
Predicción: 1.0

Texto: No me gustó la trama de esta película.
Predicción: 1.0

Texto: Increíble actuación, realmente disfruté la película.
Predicción: 1.0

Por cada texto de entrada, tenemos una predicción similar de salida.

Otro ejemplo: Para generar una secuencia de palabras, es decir de un texto inicial añade dos palabras ya definidas pero de manera aleatoria:

import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers import Embedding, LSTM, Dense
from tensorflow.keras.models import Sequential
import numpy as np

# Ejemplo de datos
frases = [
    'Hola mundo feliz',
    'Hola mundo triste',
    'Hola mundo emocionante',
    'Este es un ejemplo de secuencia de palabras',
    'Este es otro ejemplo de secuencia']

# Preprocesamiento de datos
tokenizer = Tokenizer()
tokenizer.fit_on_texts(frases)
total_palabras = len(tokenizer.word_index) + 1

# Crear secuencias de entrada
input_sequences = []
for linea in frases:
    token_list = tokenizer.texts_to_sequences([linea])[0]
    for i in range(1, len(token_list)):
        n_gram_sequence = token_list[:i+1]
        input_sequences.append(n_gram_sequence)

# Rellenar secuencias
max_sequence_len = max([len(x) for x in input_sequences])
input_sequences = np.array(pad_sequences(input_sequences, 
                            maxlen=max_sequence_len, padding='pre'))

# Crear predictores y etiqueta
X, etiquetas = input_sequences[:,:-1],input_sequences[:,-1]
y = tf.keras.utils.to_categorical(etiquetas, num_classes=total_palabras)

# Crear el modelo RNN
modelo = Sequential()
modelo.add(Embedding(total_palabras, 100, input_length=max_sequence_len-1))
modelo.add(LSTM(150))
modelo.add(Dense(total_palabras, activation='softmax'))

modelo.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
modelo.summary()

# Entrenar el modelo
modelo.fit(X, y, epochs=100, verbose=1)

# Función para generar texto
def completar_oracion(seed_text, next_words=1):
    for _ in range(next_words):
        token_list = tokenizer.texts_to_sequences([seed_text])[0]
        token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')
        predicted = modelo.predict(token_list, verbose=0)
        predicted = np.argmax(predicted, axis=-1)# Obtener la clase con mayor probabilidad
        output_word = ""
        for word, index in tokenizer.word_index.items():
            if index == predicted:
                output_word = word
                break
        seed_text += " " + output_word
    return seed_text

# Probar el modelo
texto_inicial = 'Hola mundo'
texto_generado = completar_oracion(texto_inicial, next_words=2)
print(texto_generado)

El resultado es:

... Epoch 99/100
1/1 [==============================] - 0s 11ms/step - loss: 0.2859 - accuracy: 0.8333
Epoch 100/100
1/1 [==============================] - 0s 12ms/step - loss: 0.2849 - accuracy: 0.8333
Hola mundo feliz triste

Dependiendo del texto inicial el programa siempre añadirá dos palabras (next_words=2).



 

Comentarios

Entradas más populares de este blog

Perceptrón Simple (Not, AND, OR):

Descifrando la Magia del Perceptrón Multicapa: Desafíos XOR y la Elegancia de Backpropagation