Cómo programar una red neuronal en Python con PyTorch para transformar grados Fahrenheit a Celsius
Aprende a utilizar Python y PyTorch y a entrenar una red neuronal para convertir grados Fahrenheit a Celsius
Un saludo a las 752 personas que van a recibir este post hoy lunes 27 de febrero. Hoy os traigo lo que os prometí la semana pasada, nuestra primera red neuronal programada en Python y usando PyTorch. Este post lo podéis encontrar también en GoogleCloab, una plataforma para que vosotros mismos podáis ejecutar el código a la vez que vais entendiendo todo. Allí encontraréis el código y su salida junto con algo de texto, pero más escueto que aquí, por lo que os recomiendo que lo vayáis leyendo a la par. Os dejo el enlace aquí.
Este código utiliza una red neuronal para predecir la temperatura en grados Celsius a partir de la temperatura en grados Fahrenheit.
En la primera parte del código se importan las librerías numpy
y matplotlib.pyplot
. numpy
es una librería de Python para el manejo de matrices y cálculos numéricos, mientras que matplotlib.pyplot
es una librería para la visualización de datos.
import numpy as np
import matplotlib.pyplot as plt
A continuación, se crea un conjunto de datos de entrenamiento que consiste en un rango de temperaturas en grados Fahrenheit (-450 a 500) y sus correspondientes temperaturas en grados Celsius, calculadas utilizando la fórmula de conversión de Fahrenheit a Celsius.
# Crear un conjunto de datos de entrenamiento
fahrenheit = np.linspace(-450, 500, 100000)
celsius = [(x - 32) * 5 / 9 for x in fahrenheit]
Después, se cambia la forma de los datos de entrenamiento para que puedan ser utilizados en la red neuronal. Se utiliza la función reshape
de numpy
para cambiar la forma de los datos de entrenamiento a un arreglo de una columna.
# Cambiar la forma de los datos de entrenamiento
fahrenheit = fahrenheit.reshape(-1, 1)
celsius = np.array(celsius).reshape(-1, 1)
Luego, se define la clase FahrenheitToCelsius
, que es la red neuronal. La clase hereda de nn.Module
, que es una clase base para todas las redes neuronales de PyTorch. Dentro de la clase se definen las capas de la red neuronal utilizando la clase nn.Linear
, que representa una capa lineal de la red neuronal. También se define el método forward
de la red neuronal, que es el método que se llama para realizar la predicción a partir de los datos de entrada.
import torch.nn as nn
import torch.nn.functional as F
class FahrenheitToCelsius(nn.Module):
def __init__(self, lr):
super().__init__()
self.fc1 = nn.Linear(1, 3)
self.fc2 = nn.Linear(3,7)
self.fc3 = nn.Linear(7,3)
self.fc4 = nn.Linear(3,1)
self.lr = lr
def forward(self, x):
x = self.fc1(x)
x = self.fc2(x)
x = self.fc3(x)
x = self.fc4(x)
return x
A continuación, se importa la librería torch
y se utiliza la función DataLoader
de la librería torch.utils.data
para crear un objeto DataLoader que se encargará de cargar los datos de entrenamiento en la red neuronal en lotes de tamaño batch_size
. También se define la función de pérdida nn.MSELoss
, que es la función de pérdida de regresión cuadrática media, y se define el optimizador torch.optim.SGD
, que es el optimizador de descenso de gradiente estocástico.
import torch
from torch.utils.data import DataLoader, TensorDataset
# Crear un objeto DataLoader
batch_size = 64
train_data = TensorDataset(torch.Tensor(fahrenheit), torch.Tensor(celsius))
train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True)
# Definir la función de pérdida
criterion = nn.MSELoss()
# Definir el optimizador
learning_rate = 0.000001
model = FahrenheitToCelsius(lr=learning_rate)
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
Después, se entrena la red neuronal utilizando un bucle for
. En cada iteración del bucle, se ajustan los pesos de la red neuronal utilizando los datos de entrenamiento en lotes, se calcula la pérdida utilizando la función de pérdida, se retropropaga el error utilizando el método backward
, y se actualizan los pesos de la red neuronal utilizando el optimizador. Además, se almacena la pérdida en cada iteración en una lista llamada loss_tracker
.
En cada décima iteración del bucle de entrenamiento, se imprime el valor de la pérdida actual y se utiliza la red neuronal para hacer una predicción de las temperaturas en grados Celsius a partir de las temperaturas en grados Fahrenheit. Los resultados de la predicción se visualizan utilizando matplotlib.pyplot
, donde los puntos azules representan la predicción de la red neuronal y los puntos rojos representan los datos de entrenamiento.
# Entrenar la red neuronal
num_epochs = 50
for epoch in range(num_epochs):
loss_tracker = []
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
loss_tracker.append(loss.item())
if (epoch % 1 == 0):
epoch_loss = sum(loss_tracker)/len(loss_tracker)
print(f"Epoch {epoch+1}/{num_epochs}. Loss: {epoch_loss}")
if (epoch % 10 == 0):
with torch.no_grad():
fahrenheit_plot = fahrenheit_plot.reshape(-1, 1)
celsius_pred = model(torch.Tensor(fahrenheit_plot))
plt.plot(celsius_plot,fahrenheit_plot, c='b')
plt.scatter(celsius_pred,fahrenheit_plot, c='r')
plt.title(f"Inferencia en la época {epoch+1}")
plt.xlabel("Celsius")
plt.ylabel("Fahrenheit")
plt.show()
Una vez que la red neuronal está entrenada, podemos inferir en ella para realizar predicciones del modelo.
fahrenheit = torch.tensor([77.0])
celsius_prediction = model(fahrenheit)
celsius_calculation = (fahrenheit - 32) * 5 / 9
El último post “Cómo crear tu primera red neuronal sin programar.” le llegó a 752 personas, de las cuales lo abrieron un 35% de las personas, en total el post se abrió 485 veces, recibiendo nueve likes.
Como siempre os digo, si tenéis alguna duda o pensáis que hay algo incorrecto podéis hablarme a través de Twitter o correo electrónico. También me gustaría que si os ha gustado le dierais al botón de like, para saber que temas os gustan más y enfocar las newsletter de una forma u otra.