Fundamentos de PyTorch. Optimización

Esta entrada es parte del curso de Deep learning con PyTorch.

En posts pasados hemos visto los tensores en PyTorch y el módulo de redes neuronales nn.module. En este vamos a ver todo el proceso de entrenamiento de una red neuronal: creación del modelo, procesamiento de la entrada a través del modelo, computar la pérdida y actualizar los parámetros del modelo usando descenso por gradiente en función de la pérdida.

Primero, importamos las principales librerías, incluida torch.autograd para optimización, y definimos los parámetros del modelo. In [0]:

import torch
import torch.nn as nn
from torch.utils.data import Dataset
import torchvision.datasets as dsets
import torchvision.transforms as transforms
from torch.autograd import Variable


input_size    = 10
output_size    = 1   
hidden_size   = 50   
train_size= 5000
batch_size=10    
num_epochs    = 10     
learning_rate = 1e-3 
random=0

Creamos la secuencia de entrenamiento. Calculamos el número de secuencias de tamaño batch_size que contendrá la secuencia de entrenamiento. Creamos la secuencia de entrenamiento usando torch.normal y la salida, que en función del parámetro random, será una combinación lineal de la entrada o una salida aleatoria. In [0]:

len=int(train_size/batch_size)

input=torch.normal(0, 1, size=(train_size, input_size))
input=input/input.max()

linear1=nn.Linear(input_size, output_size)

if random==0:
  with torch.no_grad():
      label=linear1(input)
else:
      label=torch.normal(0, 1, size=(train_size, output_size))
      label=label/label.max()

Definimos el modelo, extendiendo la clase nn.Module. El modelo tiene una capa lineal, una ReLu y otra capa lineal, para poder hacer predicciones. Creamos una instancia del modelo con el tamaño la entrada, capas intermedias y salida indicados. In [0]:

class Net(nn.Module):
    def __init__(self, input_size, hidden_size, num_classes):
        super(Net, self).__init__()                    
        self.fc1 = nn.Linear(input_size, hidden_size)  
        self.relu1 = nn.ReLU()                          
        self.fc2 = nn.Linear(hidden_size, output_size) 
    
    def forward(self, x):                              
        out = self.fc1(x)
        out = self.relu1(out)
        out = self.fc2(out)
        return out


net = Net(input_size, hidden_size, output_size)

Vamos a proceder con el entrenamiento del modelo. Creamos una instancia de la función de pérdidas torch.nn.L1Loss(), que calcula la desviación absoluta media entre dos tensores. Usamos el paquete torch.optim que implementa varios algoritmos de optimización, creando una instancia del algoritmo adam, especificando los parámetros a optimizar y la learning rate.

Creamos el blucle de entrenamiento, donde para cada epoch (secuencia completa de entrenamiento), para cada batch de la entrada, borra los gradientes de los parámetros, selecciona la secuencia de entrada y salida, procesa la entrada con el modelo y la compara con la salida para calcular el error con loss = criterion(output, label1). Una vez calculado el error, se computa el gradiente de los parámetros con loss.backward() y se actualizan los parámetros usando este gradiente con optimizer.step()

In [0]:

criterion = nn.L1Loss()
optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)

for epoch in range(num_epochs):
    for i in range(len):      
        optimizer.zero_grad()
        input1=input[i*batch_size:(i+1)*batch_size]
        label1=label[i*batch_size:(i+1)*batch_size]                             
        output = net(input1)                             
        loss = criterion(output, label1)                 
        loss.backward()                                   
        optimizer.step()                                  
        
        if (i==0) or ((i+1) % 100 == 0):                              
            print('Epoch [%d/%d], Step [%d/%d], Loss: %.4f'
                 %(epoch+1, num_epochs, i+1, len, loss.data))

In [0]:

Por último, a título ilustrativo, creamos una secuencia de entrada-salida, procesamos la entrada con el modelo y lo comparamos con la salida esperada.

In [8]:

input11=torch.normal(0, 1, size=(10,))
input11=input11/input11.max()
label11=linear1(input11)
print(label11)
output11=net(input11)
print(output11)
print(criterion(output11, label11))
tensor([-0.1933], grad_fn=<AddBackward0>)
tensor([-0.1913], grad_fn=<AddBackward0>)
tensor(0.0021, grad_fn=<MeanBackward0>)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Orgullosamente ofrecido por WordPress | Tema: Baskerville 2 por Anders Noren.

Subir ↑

A %d blogueros les gusta esto: