Unha lista de números é un vector (por exemplo, [2, 4, 6]).
Unha táboa con filas e columnas é unha matriz (por exemplo, unha táboa de 3x3 con números).
Un tensor é unha extensión disto, podendo ter calquera número de dimensións. Os tensores son como caixas organizadas con números, que se poden mover, transformar e operar neles.
Na Intelixencia Artificial, especialmente en redes neuronais, traballamos con enormes cantidades de datos, como imaxes, textos e números. Estes datos organízanse en forma de tensores para que os computadores poidan procesalos de maneira rápida e eficiente.
Por exemplo:
Unha imaxe pode representarse como un tensor onde cada píxel ten valores de cor (vermelho, verde e azul).
Un texto pode transformarse nun tensor onde cada palabra se representa con números.
Usamos tensores porque permiten manipular grandes cantidades de información usando matemáticas avanzadas e computación eficiente.
Proba a visualizar o tensor dunha imaxe
Con este programa executado en Colab, podes subir o arquivo dunha imaxe e visualizar o tensor no que se traduce para que unha máquina poda traballar con ela.
Proba a visualizar o tensor dun texto
Con este programa executado en Colab, podes subir o arquivo dun texto e visualizar o tensor no que se traduce para que unha máquina poda traballar con el.
Explicación das saídas "tipo"
Imaxe
Dimensións do tensor: torch.Size([1, 96, 96]). O tensor que representa a imaxe ten tres dimensións:
1: Indica que a imaxe ten unha soa canle, probablemente en escala de grises.
96: Indica que a imaxe ten 96 píxeles de altura.
96: Indica que a imaxe ten 96 píxeles de ancho.
O tensor describe unha imaxe de 96x96 en escala de grises.
Valores do tensor (Primeiros 10 números): tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]). Mostra os primeiros 10 valores numéricos do tensor.
Cada número representa a intensidade dun píxel da imaxe.
Neste caso, todos os valores son 0.0, o que significa que eses píxeles son completamente negros. A imaxe parece ter unha zona escura ao principio.
Todos os valores do tensor. Aquí ves os valores numéricos organizados como píxeles da imaxe. Cada número representa unha intensidade de cor entre 0.0 (negro) e 1.0 (branco).
Exemplos:
0.0000 → Píxel negro.
0.9608 → Píxel case branco.
0.5686 → Píxel de cor intermedia.
Este tensor é a representación matemática da imaxe, útil para procesamento en IA.
Texto
"Detectando a codificación do arquivo...". O programa está intentando descubrir en que formato está codificado o arquivo de texto. Se o texto usa UTF-8, poderá lerse sen problemas. Se UTF-8 non funciona, buscarase outra alternativa.
"⚠️ Erro con UTF-8, probando con 'latin-1' como alternativa...". O programa tentou ler o texto en UTF-8, pero atopou caracteres que non poden decodificarse correctamente. Como alternativa, usa latin-1, que permite ler case calquera texto sen erros, aínda que pode modificar algúns caracteres especiais.
"Convertendo cada caracter en números...". Cada letra, número ou símbolo do texto ten un código numérico ASCII. O programa está transformando cada caracter nun número para que poida ser procesado como un tensor.
Exemplo:
A letra "A" → 65
A letra "B" → 66
O espazo " " → 32
"Convertendo a lista de números nun tensor...". O texto xa foi convertido nunha lista de números. Agora esta lista transfórmase nun tensor, que é unha estrutura matemática usada en IA para procesamento eficiente.
"Dimensións do tensor: torch.Size([20389])". O tensor ten 20389 elementos, o que significa que o texto tiña 20389 caracteres. Isto indica que o documento era relativamente longo.
"Valores do tensor (Primeiros 10 números): tensor([80, 75, 3, 4, 20, 0, 0, 8, 0, 0], dtype=torch.int32)". O programa mostra os primeiros 10 números do tensor para que vexamos a transformación. Estes valores corresponden aos caracteres iniciais do arquivo de texto. Interpretación: O número 80 representa P, 75 representa K...
"Todos os valores do tensor..." Aquí podes ver a representación numérica completa do arquivo en forma de tensor. Como vemos na saída, aparecen números como 109, 105, 109, 101, 116, 121..., que parecen representar "mimetype", indicando que pode ser un arquivo binario e non un texto plano.
Código Python: Visualización do tensor dunha imaxe subida a colab
from google.colab import files # Permite subir arquivos desde o ordenador a Google Colab
from PIL import Image # Librería para abrir e manipular imaxes
import torch # Biblioteca de IA e computación numérica
import torchvision.transforms as transforms # Transformacións de imaxes para PyTorch
import matplotlib.pyplot as plt # Librería para visualizar gráficos e imaxes
# 1️ Subir a imaxe
print(" Subindo unha imaxe desde o teu ordenador...")
uploaded = files.upload() # Abre un diálogo para que o usuario seleccione un arquivo
# 2️ Obter o nome do arquivo subido
image_path = list(uploaded.keys())[0] # Gardamos o nome do arquivo subido
print(f" A túa imaxe '{image_path}' foi cargada correctamente!")
# 3️ Cargar e visualizar a imaxe
image = Image.open(image_path) # Abrimos a imaxe usando PIL
plt.imshow(image) # Mostramos a imaxe
plt.title(" Imaxe orixinal") # Poñemos un título á imaxe
plt.axis("off") # Eliminamos os eixos para mellor visualización
plt.show() # Mostramos a imaxe na saída de Colab
# 4️ Converter a imaxe nun tensor
print(" Convertendo a imaxe nun tensor...")
transform = transforms.ToTensor() # Transforma a imaxe nun tensor (numeros organizados en 3D)
tensor_image = transform(image) # Aplicamos a transformación
# 5️ Mostrar información do tensor
print(" Dimensións do tensor:", tensor_image.shape) # Mostra a forma do tensor (Canais, Alto, Ancho)
print(" Valores do tensor (Primeiros 10 números):", tensor_image.flatten()[:10]) # Mostra os primeiros valores do tensor
# 6️ Asegurarse de que se mostran todos os valores
torch.set_printoptions(profile="full") # Configuramos PyTorch para que non acurte os valores ao imprimir
# 7️ Imprimir todos os valores do tensor
print(" Todos os valores do tensor:")
print(tensor_image)
Código Python: visualización do tensor dun texto subido a colab
from google.colab import files # Librería para subir arquivos desde o ordenador a Google Colab
import torch # Biblioteca de IA e computación numérica
# 1 Subir un arquivo de texto
print(" Subindo un arquivo de texto desde o teu ordenador...")
uploaded = files.upload() # Abre un diálogo para seleccionar un arquivo de texto
# 2 Obter o nome do arquivo subido
file_path = list(uploaded.keys())[0] # Gardamos o nome do arquivo subido
print(f" O teu arquivo '{file_path}' foi cargado correctamente!")
import chardet # Librería para detectar codificacións de texto
# 3 Ler o contido do arquivo en modo binario
print(" Detectando a codificación do arquivo...")
with open(file_path, "rb") as f:
raw_data = f.read() # Lemos os datos en formato binario
# Tentamos decodificar o texto en UTF-8 primeiro
try:
text = raw_data.decode("utf-8")
print(" O texto foi decodificado correctamente en UTF-8.")
except UnicodeDecodeError:
print("⚠️ Erro con UTF-8, probando con 'latin-1' como alternativa...")
text = raw_data.decode("latin-1") # Decodificación alternativa en caso de erro
# 4 Converter o texto en números (codificación ASCII)
print(" Convertendo cada caracter en números...")
text_encoded = [ord(char) for char in text] # Cada caracter transfórmase no seu código numérico
# 5 Convertir a lista nun tensor de números
print(" Convertendo a lista de números nun tensor...")
text_tensor = torch.tensor(text_encoded, dtype=torch.int32) # Tensor de números enteros
# 6 Mostrar información do tensor
print(" Dimensións do tensor:", text_tensor.shape) # Indica o tamaño do tensor
print(" Valores do tensor (Primeiros 10 números):", text_tensor[:10]) # Mostra os primeiros números para facilitar a visualización
print(" Todos os valores do tensor:")
print(text_tensor) # Mostra todos os valores do tensor
Actividades de aprendizaxe
Actividade 1: Descargar e manipular dataset MNIST
◦ Obxectivo: Aprender a descargar e manipular o dataset mnist. ◦ Instrución: Descargar o dataset MNIST, visualizar as imaxes dato e separar 25 para probas posteriores.
O programa inclue explicacións detalladas nos comentarios para que comprendas cada paso.
Executandoo en Colab, podes probar a descargar o dataset, ver exemplos dos datos que contén e separar 25 imaxes para probas posteriores.
Non te preocupes por comprender o programa totalmente, só de entender o que fai.
MINST é o "Ola mundo" dos dataset. Contén imaxes de díxitos con características moi concretas. Se usamos outras para probas, adoitan dar problemas ou non predicirse correctamente, de aí que separemos no inicio, 25 imaxes que usa para validación e non "aprende" no adestramento.
Resultado esperado
Creación propia. Resultado da actividade(CC BY-SA)
Explicación dos métodos de Pytorch:
Este código emprega PyTorch e Torchvision para descargar, visualizar e gardar imaxes do dataset MNIST, un conxunto de datos de números escritos a man.
root="./data" → Indica o directorio onde se gardarán os datos.
train=True → Especifica que queremos as imaxes de adestramento.
transform=transforms.ToTensor() → Convirte as imaxes en tensores.
download=True → Se os datos non están gardados previamente, descárgaos automaticamente.
image = image.squeeze(0) * 255
Función: Elimina a dimensión innecesaria do tensor e escala os valores de 0-1 a 0-255.
Explicación:
squeeze(0) → Elimina a dimensión extra do tensor porque MNIST ten só unha canle (escala de grises).
* 255 → Convértese os valores de píxeles de 0-1 a 0-255, para que poidan ser gardados como imaxes reais.
(Proba: Comenta a liña * 255 e observa que ao gardar as imaxes, aparecen moito máis escuras porque os valores quedan entre 0-1.)
transform = transforms.ToTensor()
Función: Convirte as imaxes nun tensor de PyTorch, onde cada píxel terá valores entre 0.0 e 1.0.
Uso común: Axuda a preparar imaxes para redes neuronais.
(Proba: Substitúe transforms.ToTensor() por transforms.Normalize((0.5,), (0.5,)) e observa que os valores do tensor agora estarán centrados arredor de 0.)
Función: Convirte un tensor PyTorch nunha imaxe estándar en formato PIL.
Explicación:
.numpy() → Convirte o tensor nun array NumPy.
.astype("uint8") → Convértese os valores do tensor en enteros (0-255) para que poida ser gardado como imaxe.
( Proba: Garda a imaxe en formato .jpg en vez de .png cambiando image.save(f"mnist_digit_{label}_{i}.png") por image.save(f"mnist_digit_{label}_{i}.jpg").)
Posibles actividades adicionais:
Mostrar só os díxitos impares do dataset. Filtra e visualiza só os números 1, 3, 5, 7, 9.
Modificar a escala das imaxes gardadas. Cambia o tamaño das imaxes antes de gardalas.
image = image.resize((50, 50)) # Redimensiona a imaxe a 50x50 píxeles image.save(f"mnist_digit_{label}_{i}_resized.png")
Usar unha transformación diferente. Aplica un filtro de inversión ás imaxes antes de gardalas.
transform = transforms.Compose([ transforms.ToTensor(), transforms.Lambda(lambda x: 1 - x) # Invertemos os valores, os píxeles negros pasan a ser brancos ])
Código Python: Descarga, visualización e separación de 25 imaxes de proba en MNIST
'''Este programa descarga os datos de adestramento de MNIST e visualiza os 5 primeiros
logo os de validación e gárda os 25 primeiros coma imaxes png'''
import torchvision # Importa a biblioteca para traballar con visión por computador import torchvision.datasets as datasets # Biblioteca para descargar conxuntos de datos de visión por computador
import torchvision.transforms as transforms # Módulo para aplicar transformacións a imaxes
import torch # Biblioteca para traballar con tensores en intelixencia artificial
import matplotlib.pyplot as plt # Librería para visualizar imaxes e gráficos
from PIL import Image # Librería para manipular imaxes en formato PIL
# 1️ Descargar o dataset de adestramento MNIST
dataset = torchvision.datasets.MNIST(
root="./data", # Indica o directorio onde se almacenarán os datos descargados
train=True, # Especifica que queremos o conxunto de datos de adestramento (non o de test)
transform=transforms.ToTensor(), # Convértese cada imaxe nun tensor de PyTorch para facilitar o procesamento
download=True # Se os datos non están presentes, descárgaos automaticamente desde internet
)
# 2️ Mostrar unha mensaxe para indicar que a descarga completouse
print(" Descarga completada!")
# 3 Explorar os datos do dataset MNIST
print(f" Forma dos datos: {dataset.data.shape}")
# Mostra as dimensións do dataset -> (60000, 28, 28)
# Isto significa que temos 60.000 imaxes de números, cada unha de 28x28 píxeles
print(f" Etiquetas dispoñibles: {dataset.targets.unique()}")
# Mostra os valores das etiquetas (0-9)
# Estes son os números que pode recoñecer o modelo de IA
# 4 Visualizar algunhas imaxes do dataset de adestramento
fig, axes = plt.subplots(1, 5, figsize=(10, 3))
# Creamos unha figura con 5 subgráficos nunha fila
# figsize=(10,3) determina o tamaño do gráfico
for i in range(5): # Iteramos sobre as primeiras 5 imaxes
axes[i].imshow(dataset.data[i], cmap="gray")
# Mostramos a imaxe en escala de grises (cmap="gray")
axes[i].set_title(f"Etiqueta: {dataset.targets[i].item()}")
# Poñemos un título con o número que representa cada imaxe
axes[i].axis("off")
# Eliminamos os eixos para unha mellor visualización
plt.show() # Mostramos a figura coas imaxes
# 5 Descargar o dataset MNIST de proba (test)
mnist_val = datasets.MNIST(
root="./data", # Directorio onde se gardará o dataset
train=False, # Indica que queremos o conxunto de proba (non o de adestramento)
download=True, # Se o dataset non está na carpeta, descárgao automaticamente
transform=transforms.ToTensor() # Convértese a imaxe nun tensor de PyTorch (valores entre 0 e 1)
)
# 6 Gardar as primeiras 25 imaxes en formato PNG
for i in range(25):
image, label = mnist_val[i] # Obtén a imaxe e a etiqueta correspondente
image = image.squeeze(0) * 255 # Escala os valores de 0-1 a 0-255 (para converter en imaxe estándar)
# Converter o tensor a imaxe en formato PIL
image = Image.fromarray(image.numpy().astype("uint8"))
# Gardar a imaxe cun nome descritivo
image.save(f"mnist_digit_{label}_{i}.png")
# 7 Mostrar unha mensaxe para indicar que a descarga completouse
print(" Descarga de imaxes de proba completada!")
Actividade 2: Rede neuronal e adestramento
◦ Obxectivo: Aprender o funcionamento de Pytorch na creación de redes neuronais ◦ Instrución: Crear unha rede neuronal de 2 capas e adestrala para recoñecer díxitos 0-9 con MINST
O programa inclue explicacións detalladas nos comentarios para que comprendas cada paso.
Executandoo en Colab, podes probar a e visualizar a aprendizaxe da rede.
Non te preocupes por comprender o programa totalmente, só de entender o que fai.
Investiga cada parámetro que non coñezas.
Resultado esperado
Curva de perda (gráfica esquerda)
A gráfica ten o título "Curva de perda", e representa o valor da perda ao longo das iteracións.
O eixo X está etiquetado como "Iteracións", e vai de 0 a aproximadamente 4690.
O eixo Y representa "Valor da perda", cun rango entre 0.0 e 2.4.
A liña da gráfica comeza cunha perda alta, arredor de 2.4, e descende rapidamente nas primeiras iteracións.
A partir das primeiras centenas de iteracións, a perda continúa diminuíndo pero máis lentamente.
Na parte final da gráfica, a perda estabilízase arredor de 0.5, aínda con pequenas flutuacións.
A curva mostra que a perda diminúe ao longo das iteracións e que o modelo mellora progresivamente. Nos primeiros momentos hai unha caída rápida, pero despois a redución é máis gradual ata alcanzar a estabilización.
Curva de precisión (gráfica dereita)
A gráfica ten o título "Curva de precisión", e representa a precisión ao longo das épocas.
O eixo X indica "Épocas", e vai de 0 a 4.
O eixo Y mostra "Precisión", cun rango entre 0.74 e 0.90.
A liña da gráfica comeza cunha precisión de aproximadamente 0.74 na primeira época.
A precisión aumenta rapidamente na primeira época.
Nas seguintes épocas, a precisión segue aumentando pero máis lentamente ata alcanzar arredor de 0.90.
A precisión incrementa coas épocas e estabilízase arredor de 0.90, mostrando que o modelo mellora o seu rendemento progresivamente.
Explicación dos métodos de Pytorch:
Métodos de PyTorch utilizados no código
torch.nn.Module → Definir modelos de redes neuronais
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__() self.fc1 = nn.Linear(28*28, 128) # Capa oculta con 128 neuronas self.fc2 = nn.Linear(128, 10) # Capa de saída con 10 clases
def forward(self, x):
x = x.view(-1, 28*28) # Aplanar imaxes de 28x28 píxeles a un vector de 784 elementos x = torch.relu(self.fc1(x)) # Activación ReLU na primeira capa x = self.fc2(x) # Obtención da saída sen activación final (CrossEntropyLoss xa a aplica) return x
Define a arquitectura dun modelo simple con duas capas totalmente conectadas. Usa torch.relu() para introducir non linealidade na rede neuronal. O método forward() define como os datos pasan polo modelo.
nn.Linear(in_features, out_features) crea unha capa de neuronas, conectando todas as entradas con todas as saídas.Transforma os datos mediante multiplicacións de matrices e sumas de sesgos.
torch.nn.CrossEntropyLoss → Función de perda
criterion = nn.CrossEntropyLoss()
Calcular a diferencia entre as predicións do modelo e as etiquetas reais usando probabilidades softmax. É ideal para clasificación multiclase (como recoñecer números 0-9 en MNIST).
Actualiza os pesos do modelo despois de cada iteración para reducir a perda. Usa o método Gradiente Estocástico (SGD) para mellorar a precisión.
torch.argmax → Predición das clases
predictions = torch.argmax(outputs, dim=1)
Obten o índice da clase máis probable predita polo modelo. Se outputs é tensor([[0.1, 3.2, 1.5], [2.1, 0.3, 0.8]]), torch.argmax(outputs, dim=1) devolve [1, 0], indicando as clases predicidas.
torch.utils.data.DataLoader → Cargar datos en lotes
Carga os datos en lotes pequenos para evitar problemas de memoria. batch_size=64 divide os datos en lotes de 64 imaxes por iteración. shuffle=True mestura as imaxes para evitar que o modelo aprenda patróns estraños vendo sempre o mesmo díxito.
loss.backward() → Retropropagación
loss.backward()
Calcula os gradientes dos parámetros para actualizar os pesos do modelo. Permite mellorar as conexións entre as neuronas.
Posibles actividades adicionais:
Engade unha nova capa oculta con nn.Linear(128, 64) e observa o impacto na precisión.
Cambia nn.Linear(28*28, 128) por nn.Linear(28*28, 256) e observa se mellora o modelo.
Substitúe nn.CrossEntropyLoss() por nn.MSELoss() e observa como afecta o adestramento (MSE úsase máis en regresión que en clasificación).
Cambia optim.SGD(model.parameters(), lr=0.01) por optim.Adam(model.parameters(), lr=0.001) e compara a rapidez do adestramento.
Cambia torch.argmax(outputs, dim=1) por torch.softmax(outputs, dim=1) e observa os valores predicidos (dará probabilidades en vez de clases).
Cambia batch_size=64 por batch_size=256 e observa como afecta a rapidez do adestramento e ó número de iteracións.
Engade print(model.fc1.weight.grad) para ver como os gradientes cambian en cada iteración.
Aumenta o número de capas da rede e compara os resultados.
Visualiza algunhas imaxes mal clasificadas para entender os erros do modelo.
Usa outra función de activación como torch.sigmoid() en vez de torch.relu().
Código Python: Creación e adestramento dunha rede neuronal simple con Pytorch
import torch # Biblioteca para computación numérica e IA
import torch.nn as nn # Módulo de redes neuronais
import torch.optim as optim # Optimización para adestrar modelos
import torchvision # Biblioteca para manipular datos visuais
import torchvision.transforms as transforms # Transformacións de imaxe
import matplotlib.pyplot as plt # Librería para visualizar gráficos
# 1️ Cargar o dataset MNIST xa descargado en Colab
transform = transforms.Compose([
transforms.ToTensor(), # Convértese a imaxe nun tensor con valores entre 0 e 1
])
# Cargamos os datos de adestramento
train_dataset = torchvision.datasets.MNIST(root="./data", train=True, transform=transform, download=False)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
# Cargamos os datos de validación
test_dataset = torchvision.datasets.MNIST(root="./data", train=False, transform=transform, download=False)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
print("Datos cargados correctamente!")
# 2️ Definir a rede neuronal
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(28*28, 128) # Capa totalmente conectada con 128 neuronas
self.fc2 = nn.Linear(128, 10) # Saída con 10 neuronas (unha por cada díxito 0-9)
def forward(self, x):
x = x.view(-1, 28*28) # Aplanamos a imaxe de 28x28 a un vector de 784 elementos
x = torch.relu(self.fc1(x)) # Aplicamos a activación ReLU
x = self.fc2(x) # Última capa para obter as predicións
return x
# Crear o modelo
model = SimpleNN()
print(" Modelo creado:")
print(model)
# 3️ Definir a función de perda e o optimizador
criterion = nn.CrossEntropyLoss() # Función de perda para clasificación multiclase(temos 10 clases)
optimizer = optim.SGD(model.parameters(), lr=0.01) # Optimización con Gradiente Estocástico (SGD)
# 4️ Adestrar a rede neuronal
epochs = 5 # Número de épocas
losses = [] # Lista para gardar os valores da perda
accuracies = [] # Lista para gardar as precisións
print(" Comezando o adestramento...")
iteracions=0
for epoch in range(epochs):
correct = 0
total = 0
print(model.fc1.weight.grad) #para ver como os gradientes cambian en cada iteración.
for images, labels in train_loader: # Iterar sobre os datos de adestramento
iteracions+= 1 #Contar iteracións
optimizer.zero_grad() # Reiniciar gradientes
outputs = model(images) # Pasar as imaxes polo modelo
loss = criterion(outputs, labels) # Calcular a perda
loss.backward() # Retropropagar os erros
optimizer.step() # Actualizar os parámetros do modelo
losses.append(loss.item()) # Gardar a perda
# Calcular a precisión
predictions = torch.argmax(outputs, dim=1)
correct += (predictions == labels).sum().item()
total += labels.size(0)
accuracy = correct / total # Calcular precisión
accuracies.append(accuracy) # Gardar a precisión
print(f" Época {epoch+1}: Perda = {loss.item():.4f}, Precisión = {accuracy:.4f}")
print(f" Total de iteracións no adestramento: {iteracions}")
print(" Adestramento completado!")
# 5️ Visualizar as curvas de aprendizaxe
plt.figure(figsize=(10, 4))
# Gráfica da perda ao longo das épocas
plt.subplot(1, 2, 1)
plt.plot(losses, label="Perda")
plt.xlabel("Iteracións") # nº de iteracións=cantidade de datos/lotes de datos=6000/64=938 aprox
plt.ylabel("Valor da perda")
plt.title("Curva de perda")
plt.legend()
# Gráfica da precisión ao longo das épocas
plt.subplot(1, 2, 2)
plt.plot(accuracies, label="Precisión", marker='o')
plt.xlabel("Épocas")
plt.ylabel("Precisión")
plt.title("Curva de precisión")
plt.legend()
plt.show()
print("Gráficas de perda e precisión xeradas!")
Actividade 3: Proba do modelo
◦ Obxectivo: Comprender como o modelo predí o novo díxito. ◦ Instrución: Prepara as 25 imaxes de validación gardadas para predecir e proba o modelo.
O programa inclue explicacións detalladas nos comentarios para que comprendas cada paso.
Executandoo en Colab, podes probar a subir imaxes do conxunto de 25 que separaches e predicir co modelo que díxito é.
Non te preocupes por comprender o programa totalmente, só de entender o que fai.
Razona coas porcentaxes que saen:acerta ou non? Ten algo a imaxe que poda inducir a erro.
Resultado esperado
Creación propia. Resultado da actividade(CC BY-SA)
Explicación dos métodos de Pytorch:
Métodos de PyTorch utilizados
torchvision.transforms → Transformacións de imaxes
transform = transforms.Compose([ transforms.Resize((28, 28)), # Redimensiona a imaxe a 28x28 píxeles (tamaño estándar en MNIST) transforms.ToTensor(), # Convértese a imaxe nun tensor con valores entre 0 e 1 transforms.Normalize((0.5,), (0.5,)) # Normaliza os valores para mellorar a predición ]) image_tensor = transform(image).unsqueeze(0) # Engade unha dimensión de lote
transforms.Resize((28, 28)) → Redimensiona a imaxe para que se adapte ao modelo.
transforms.ToTensor() → Convértese cada píxel en valores entre 0.0 e 1.0.
transforms.Normalize((0.5,), (0.5,)) → Centra os valores arredor de 0 (máis eficiente para a rede neuronal).
.unsqueeze(0) → Engade unha dimensión de lote, facendo que a imaxe sexa válida para o modelo(quitarámola antes para gardala como png).
model.eval() → Poñer o modelo en modo de avaliación
model.eval()
Pon o modelo en modo de avaliación, desactivando capas como Dropout e BatchNorm.Evita que o modelo modifique parámetros durante a predición.
torch.no_grad() → Desactivar o cálculo de gradientes
with torch.no_grad(): output = model(image_tensor)
Evita o cálculo innecesario de gradientes, reducindo o uso de memoria e aumentando a eficiencia.Indicado para predicións, xa que non se realiza adestramento.
torch.softmax() → Obtención de probabilidades
probabilities = torch.softmax(output, dim=1)
Converte os valores da saída do modelo en probabilidades (entre 0 e 1).Facilita a interpretación dos resultados.
torch.topk() → Seleccionar as opcións máis probables
top3 = torch.topk(probabilities, 3)
Obten os 3 números máis probables predicidos polo modelo. Devolve tanto os valores coma as probabilidades asociadas.
Posibles actividades adicionais:
Cambia a normalización Normalize((0.5,), (0.5,)) por Normalize((0.2,), (0.2,)) e observa como cambia a saída.
Executa print(model.training) antes e despois de model.eval() para ver o cambio no estado do modelo.
Retira torch.no_grad() e observa o impacto no uso de memoria.
Mostra os valores antes e despois de aplicar softmax() para ver a diferenza.
Modifica topk(3) por topk(5) e observa a saída.
Código Python: Proba do modelo para recoñecer imaxes de díxitos a man do 0 ó 9
import torchvision.transforms as transforms # Biblioteca para transformar imaxes
from PIL import Image # Manipulación de imaxes en formato PIL
import matplotlib.pyplot as plt # Librería para visualizar imaxes
import torch # Biblioteca de computación numérica e intelixencia artificial
from google.colab import files # Permite subir arquivos en Google Colab
# 1️ Subir unha imaxe dun díxito
print(" Sube unha imaxe dun díxito (formato PNG ou JPG)...")
uploaded = files.upload() # Abre un diálogo para seleccionar a imaxe
# 2️ Obter o nome do ficheiro subido
filename = list(uploaded.keys())[0] # Gardamos o nome do ficheiro subido
print(f" Imaxe '{filename}' cargada correctamente!")
# 3️ Cargar a imaxe
image = Image.open(filename).convert("L") # Converte a imaxe a escala de grises
# 4️ Transformar a imaxe para a predición
print(" Transformando a imaxe para adaptala ao modelo MNIST...")
transform = transforms.Compose([
transforms.Resize((28, 28)), # Redimensionar a imaxe ao formato de MNIST (28x28 píxeles)
transforms.ToTensor(), # Converter a imaxe nun tensor
transforms.Normalize((0.5,), (0.5,)) # Normalizar os valores para mellor predición
])
image_tensor = transform(image).unsqueeze(0) # Engadimos unha dimensión de lote
print(" Imaxe transformada lista para predición!")
#5 Visualizar ambas imaxes
plt.figure(figsize=(10, 4)) # Define o tamaño da figura
plt.subplot(1, 2, 1) # Primeira imaxe
plt.imshow(image, cmap="gray")
plt.title(" Díxito subido")
plt.axis("off")
plt.subplot(1, 2, 2) # Segunda imaxe
plt.imshow(image_tensor.squeeze(0).squeeze(0), cmap="gray")
plt.title(" Díxito transformado")
plt.axis("off")
plt.show() # Mostrar ambas imaxes á vez na mesma fila
# 6 Predición co modelo adestrado
print(" Realizando a predición co modelo MNIST...")
model.eval() # Poñemos o modelo en modo avaliación (desactiva o adestramento)
with torch.no_grad(): # Desactivamos o cálculo de gradientes para a predición
output = model(image_tensor) # Predición do modelo
# 7 Obter os 3 díxitos máis probables
probabilities = torch.softmax(output, dim=1) # Aplicamos Softmax para obter probabilidades
top3 = torch.topk(probabilities, 3) # Obtemos os 3 valores máis altos
print(" Predicións do modelo:")
for i in range(3):
predicted_digit = top3.indices[0][i].item() # Díxito predicido
probability = top3.values[0][i].item() # Probabilidade asociada
print(f" Díxito: {predicted_digit}, Probabilidade: {probability*100:.4f} %")
print(" Predición completada!")