En aquest tema, aprendrem com crear un bucle d'entrenament per a una xarxa neuronal utilitzant PyTorch. El bucle d'entrenament és una part fonamental del procés d'aprenentatge automàtic, ja que és on la xarxa neuronal ajusta els seus pesos per minimitzar la funció de pèrdua.

Objectius

  • Entendre la importància del bucle d'entrenament.
  • Aprendre a implementar un bucle d'entrenament bàsic en PyTorch.
  • Comprendre com monitoritzar el rendiment del model durant l'entrenament.

Conceptes Clau

  1. Dades d'Entrenament: Les dades utilitzades per entrenar el model.
  2. Funció de Pèrdua: Una mesura de com de bé el model està fent les seves prediccions.
  3. Optimitzador: Un algoritme que ajusta els pesos del model per minimitzar la funció de pèrdua.
  4. Època: Una passada completa per tot el conjunt de dades d'entrenament.
  5. Batch: Un subconjunt de les dades d'entrenament utilitzat per actualitzar els pesos del model en cada iteració.

Implementació del Bucle d'Entrenament

Pas 1: Preparar les Dades

Abans de començar l'entrenament, necessitem carregar i preprocessar les dades. Utilitzarem el conjunt de dades MNIST com a exemple.

import torch
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

# Transformacions per normalitzar les dades
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])

# Carregar el conjunt de dades MNIST
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)

Pas 2: Definir el Model

Definim una xarxa neuronal simple per a la classificació de dígits.

import torch.nn as nn
import torch.nn.functional as F

class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(28*28, 128)
        self.fc2 = nn.Linear(128, 64)
        self.fc3 = nn.Linear(64, 10)

    def forward(self, x):
        x = x.view(-1, 28*28)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

model = SimpleNN()

Pas 3: Definir la Funció de Pèrdua i l'Optimitzador

Utilitzarem la funció de pèrdua CrossEntropyLoss i l'optimitzador Adam.

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

Pas 4: Implementar el Bucle d'Entrenament

Ara implementem el bucle d'entrenament. En cada època, passarem per totes les dades d'entrenament, calcularem la pèrdua, farem la retropropagació i actualitzarem els pesos del model.

num_epochs = 5

for epoch in range(num_epochs):
    running_loss = 0.0
    for images, labels in train_loader:
        # Zero the parameter gradients
        optimizer.zero_grad()
        
        # Forward pass
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # Backward pass and optimization
        loss.backward()
        optimizer.step()
        
        running_loss += loss.item()
    
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}')

Explicació del Codi

  1. Zero the parameter gradients: Abans de cada pas d'optimització, cal posar a zero els gradients acumulats dels paràmetres del model.
  2. Forward pass: Passar les dades d'entrada a través del model per obtenir les prediccions.
  3. Loss calculation: Calcular la pèrdua comparant les prediccions amb les etiquetes reals.
  4. Backward pass: Calcular els gradients de la pèrdua respecte als paràmetres del model.
  5. Optimizer step: Actualitzar els paràmetres del model utilitzant els gradients calculats.

Exercici Pràctic

Implementa un bucle d'entrenament per a una xarxa neuronal que classifiqui imatges del conjunt de dades CIFAR-10. Utilitza una xarxa neuronal convolucional (CNN) i monitoritza la pèrdua durant l'entrenament.

Solució

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms

# Transformacions per normalitzar les dades
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

# Carregar el conjunt de dades CIFAR-10
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)

# Definir la xarxa neuronal convolucional
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, 3, 1)
        self.conv2 = nn.Conv2d(16, 32, 3, 1)
        self.fc1 = nn.Linear(32*6*6, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2, 2)
        x = x.view(-1, 32*6*6)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

model = SimpleCNN()

# Definir la funció de pèrdua i l'optimitzador
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Bucle d'entrenament
num_epochs = 10

for epoch in range(num_epochs):
    running_loss = 0.0
    for images, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}')

Conclusió

En aquesta secció, hem après a implementar un bucle d'entrenament bàsic en PyTorch. Hem vist com carregar i preprocessar les dades, definir un model, una funció de pèrdua i un optimitzador, i com utilitzar-los per entrenar el model. Aquest és un pas fonamental en el desenvolupament de models d'aprenentatge automàtic i és important comprendre bé cada part del procés. En el següent tema, explorarem com validar i provar el nostre model per assegurar-nos que generalitza bé a dades no vistes.

© Copyright 2024. Tots els drets reservats