No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Entrenamiento y evaluación de modelo de clasificación de texto

19/24
Recursos

Aportes 6

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Hiperparámetros

EPOCHS = 6
TASA_APRENDIZAJE = 0.15
BATCH_TAMANO = 86

Optimizador

optimizer = torch.optim.Adam(modelo.parameters(), lr= TASA_APRENDIZAJE)

Aquí tienes un ejemplo completo de cómo puedes realizar el \*\*entrenamiento\*\* y la \*\*evaluación\*\* de un modelo de clasificación de texto utilizando PyTorch y TorchText, asumiendo que ya tienes los datos preparados y tokenizados. \### Paso 1: Preparación de los datos Para este ejemplo, asumiremos que ya has cargado el dataset (como \*\*DBpedia\*\*) y creado tu vocabulario. También vamos a usar un DataLoader para manejar los datos en mini-lotes. \### Paso 2: Definir el modelo El modelo que vamos a usar es una simple red neuronal con una capa de embeddings, una capa recurrente (GRU), y una capa completamente conectada para la clasificación. ```python import torch import torch.nn as nn import torch.optim as optim class TextClassificationModel(nn.Module): def \_\_init\_\_(self, vocab\_size, embed\_dim, num\_class): super(TextClassificationModel, self).\_\_init\_\_() self.embedding = nn.EmbeddingBag(vocab\_size, embed\_dim, sparse=True) self.fc = nn.Linear(embed\_dim, num\_class) self.init\_weights() def init\_weights(self): initrange = 0.5 self.embedding.weight.data.uniform\_(-initrange, initrange) self.fc.weight.data.uniform\_(-initrange, initrange) self.fc.bias.data.zero\_() def forward(self, text, offsets): embedded = self.embedding(text, offsets) return self.fc(embedded) ``` \### Paso 3: Entrenamiento del modelo \#### Función de entrenamiento ```python def train(dataloader, model, criterion, optimizer): model.train() total\_acc, total\_count = 0, 0 log\_interval = 500 for idx, (label, text, offsets) in enumerate(dataloader): optimizer.zero\_grad() predicted\_label = model(text, offsets) loss = criterion(predicted\_label, label) loss.backward() torch.nn.utils.clip\_grad\_norm\_(model.parameters(), 0.1) # Evitar gradientes explosivos optimizer.step() total\_acc += (predicted\_label.argmax(1) == label).sum().item() total\_count += label.size(0) if idx % log\_interval == 0 and idx > 0: print(f'Batch {idx}: Accuracy: {total\_acc/total\_count:.4f}') total\_acc, total\_count = 0, 0 ``` \### Paso 4: Evaluación del modelo \#### Función de evaluación Para evaluar el modelo, no aplicamos gradientes, y calculamos la precisión en el conjunto de prueba. ```python def evaluate(dataloader, model, criterion): model.eval() total\_acc, total\_count = 0, 0 with torch.no\_grad(): for label, text, offsets in dataloader: predicted\_label = model(text, offsets) loss = criterion(predicted\_label, label) total\_acc += (predicted\_label.argmax(1) == label).sum().item() total\_count += label.size(0) return total\_acc/total\_count ``` \### Paso 5: Entrenar y evaluar ```python VOCAB\_SIZE = len(vocab) # Tamaño del vocabulario EMBED\_DIM = 64 # Dimensión de los embeddings NUM\_CLASS = len(set(\[label for (label, text) in train\_iter])) # Número de clases model = TextClassificationModel(VOCAB\_SIZE, EMBED\_DIM, NUM\_CLASS).to(device) optimizer = optim.SGD(model.parameters(), lr=0.001) criterion = nn.CrossEntropyLoss() \# Entrenamiento for epoch in range(10): train(train\_dataloader, model, criterion, optimizer) acc = evaluate(test\_dataloader, model, criterion) print(f'Epoch {epoch+1}: Test Accuracy: {acc:.4f}') ``` \### Paso 6: Preparar los datos para DataLoader Antes de entrenar el modelo, es necesario definir un `DataLoader` que maneje cómo se cargarán los datos en mini-lotes. Aquí te dejo un ejemplo de cómo preparar los datos: ```python from torch.utils.data import DataLoader from torchtext.datasets import DBpedia from torchtext.data.utils import get\_tokenizer tokenizer = get\_tokenizer('basic\_english') def yield\_tokens(data\_iter): for \_, text in data\_iter: yield tokenizer(text) vocab = build\_vocab\_from\_iterator(yield\_tokens(train\_iter), specials=\["\<unk>"]) vocab.set\_default\_index(vocab\["\<unk>"]) def collate\_batch(batch): label\_list, text\_list, offsets = \[], \[], \[0] for (\_label, \_text) in batch: label\_list.append(int(\_label) - 1) processed\_text = torch.tensor(vocab(tokenizer(\_text)), dtype=torch.int64) text\_list.append(processed\_text) offsets.append(processed\_text.size(0)) label\_list = torch.tensor(label\_list, dtype=torch.int64) text\_list = torch.cat(text\_list) offsets = torch.tensor(offsets\[:-1]).cumsum(dim=0) return label\_list, text\_list, offsets train\_iter = DBpedia(split='train') test\_iter = DBpedia(split='test') train\_dataloader = DataLoader(train\_iter, batch\_size=8, shuffle=True, collate\_fn=collate\_batch) test\_dataloader = DataLoader(test\_iter, batch\_size=8, shuffle=True, collate\_fn=collate\_batch) ``` \### Conclusión Este es un flujo básico de cómo entrenar y evaluar un modelo de clasificación de texto con PyTorch. El modelo usa embeddings simples y una capa de clasificación, pero puedes mejorarlo añadiendo capas más complejas como LSTM o CNN. También puedes probar diferentes optimizadores, tasas de aprendizaje y técnicas de regularización para obtener mejores resultados.
tengo una pregunta, se crea y se inicializa una variable `major\_loss\_validation` pero en ningun momento veo que el valor de esa variable se modifique, pero aun asi siempre se compara contra el valor de esa variable para guardar el mejor modelo: if validacion\_loss < major\_loss\_validation: la pregunta es, no se deberia guardar el valor del mejor modelo en esa variable `major\_loss\_validation`?
Cambiando el optimizador a Adam solamente tuve un resultado prometedor ![](https://static.platzi.com/media/user_upload/image-eaf9e13f-5204-407f-9ab2-86bfb03fbda1.jpg)
Durante la ejecución del Entrenamiento y la validación me apareció el siguiente mensaje de error: ![](https://i.ibb.co/br1v3VT/image.png) La solución fue eliminar el sparse=True en: `self.embedding = nn.EmbeddingBag(vocab_size, embed_dim, sparse=True)` Luego de eso, me salió el siguiente error en la evaluación: ![](https://i.ibb.co/4719f7z/image.png) El cual ocurre porque en el video, en el código de la clase, para la función de entrenamiento se utilizó: `total_count += label.size(0)` Pero en la función de validación no se le pasó ningún parámetro, ergo: la solución es ponerle el 0.
Comparto el modelo usando LSTM:from torch import nnimport torch.nn.functional as F class ModeloClasificacionTexto(nn.Module):  def \_\_init\_\_(self, vocab\_size, embed\_dim, hidden\_size, num\_class):    super(ModeloClasificacionTexto, self).\_\_init\_\_()         # Capa de incrustación (embedding)    self.embedding = nn.EmbeddingBag(vocab\_size, embed\_dim)         # Capa LSTM    self.lstm = nn.LSTM(embed\_dim, hidden\_size)         # Capa de transformación    self.transformation = nn.Sequential(        nn.Linear(hidden\_size, hidden\_size),        nn.ReLU(),        nn.Linear(hidden\_size, hidden\_size)    )         # Capa de normalización por lotes (batch normalization)    self.bn1 = nn.BatchNorm1d(embed\_dim)         # Capa completamente conectada (fully connected)    self.fc = nn.Linear(embed\_dim, num\_class)   def forward(self, text, offsets):        # Incrustar el texto (embed the text)    embedded = self.embedding(text, offsets)         # Pasar el texto incrustado a través de la capa LSTM (pass the embedded text through the LSTM layer)    lstm\_out, \_ = self.lstm(embedded)         # Aplicar la transformación (apply the transformation)    # transformed\_out = self.transformation(lstm\_out\[:, -1, :])    transformed\_out = self.transformation(lstm\_out\[-1, :])         # Aplicar la normalización por lotes (apply batch normalization)    embedded\_norm = self.bn1(embedded)         # Aplicar la función de activación ReLU (apply the ReLU activation function)    embedded\_activated = F.relu(embedded\_norm)         # Devolver las probabilidades de clase (output the class probabilities)    return self.fc(embedded\_activated) ```python from torch import nn import torch.nn.functional as F class ModeloClasificacionTexto(nn.Module): def __init__(self, vocab_size, embed_dim, hidden_size, num_class): super(ModeloClasificacionTexto, self).__init__() # Capa de incrustación (embedding) self.embedding = nn.EmbeddingBag(vocab_size, embed_dim) # Capa LSTM self.lstm = nn.LSTM(embed_dim, hidden_size) # Capa de transformación self.transformation = nn.Sequential( nn.Linear(hidden_size, hidden_size), nn.ReLU(), nn.Linear(hidden_size, hidden_size) ) # Capa de normalización por lotes (batch normalization) self.bn1 = nn.BatchNorm1d(embed_dim) # Capa completamente conectada (fully connected) self.fc = nn.Linear(embed_dim, num_class) def forward(self, text, offsets): # Incrustar el texto (embed the text) embedded = self.embedding(text, offsets) # Pasar el texto incrustado a través de la capa LSTM (pass the embedded text through the LSTM layer) lstm_out, _ = self.lstm(embedded) # Aplicar la transformación (apply the transformation) # transformed_out = self.transformation(lstm_out[:, -1, :]) transformed_out = self.transformation(lstm_out[-1, :]) # Aplicar la normalización por lotes (apply batch normalization) embedded_norm = self.bn1(embedded) # Aplicar la función de activación ReLU (apply the ReLU activation function) embedded_activated = F.relu(embedded_norm) # Devolver las probabilidades de clase (output the class probabilities) return self.fc(embedded_activated) ```