Conjuntos de datos de PyTorch

En las tareas de deep learning, la carga y el procesamiento de datos son una parte crucial.

PyTorch proporciona potentes herramientas de carga y procesamiento de datos, que incluyen principalmente:

  • torch.utils.data.Dataset: clase abstracta de dataset, que debe personalizarse e implementarse__len__(tamaño del dataset) y__getitem__(obtener muestras por índice).

  • torch.utils.data.TensorDataset: dataset basado en tensores, adecuado para manejar pares datos-etiqueta, con soporte directo para procesamiento por lotes e iteración.

  • torch.utils.data.DataLoader: iterador que envuelve un Dataset, proporciona funciones como procesamiento por lotes, barajado de datos y carga multihilo, lo que facilita la entrada de datos al entrenamiento del modelo.

  • torchvision.datasets.ImageFolder: carga datos de imágenes desde carpetas, cada subcarpeta representa una categoría, adecuado para tareas de clasificación de imágenes.

Datasets integrados de PyTorch

PyTorch proporciona muchos datasets de uso común a través del módulo torchvision.datasets, por ejemplo:

  • MNIST: dataset de imágenes de dígitos escritos a mano, utilizado para tareas de clasificación de imágenes.
  • CIFAR: dataset de imágenes en color de 32x32 que contiene 10 clases y 60000 imágenes, utilizado para tareas de clasificación de imágenes.
  • COCO: dataset de detección de objetos, segmentación y detección de puntos clave, un dataset a gran escala con más de 330k imágenes y 2.5M instancias de objetos.
  • ImageNet: contiene más de 14 millones de imágenes, utilizado para tareas como clasificación de imágenes y detección de objetos.
  • STL-10: dataset de imágenes en color de 96x96 que contiene 100k imágenes, utilizado para tareas de clasificación de imágenes.
  • Cityscapes: contiene 5000 imágenes de escenas de calles urbanas finamente anotadas, utilizado para tareas de segmentación semántica.
  • SQUAD: dataset para tareas de comprensión lectora automática.

Los datasets anteriores se pueden cargar mediante funciones del módulo torchvision.datasets, y también se pueden cargar otros datasets de forma personalizada.

torchvision y torchtext

  • torchvision: una biblioteca gráfica que proporciona APIs de procesamiento de datos de imágenes e interfaces de datasets, incluyendo funciones de carga de datasets y transformaciones de imagen comunes.
  • torchtext: kit de herramientas de procesamiento de lenguaje natural, proporciona herramientas para el procesamiento y modelado de datos de texto, incluyendo métodos de preprocesamiento y carga de datos.

torch.utils.data.Dataset

Dataset es la clase utilizada para la abstracción de datasets en PyTorch.

Un dataset personalizado debe heredar de torch.utils.data.Dataset y sobrescribir los siguientes dos métodos:

  • __len__: devuelve el tamaño del dataset.
  • __getitem__: obtiene una muestra de datos y su etiqueta según el índice.

Ejemplo

import torch
from torch.utils.data import Dataset

# Dataset personalizado
class MyDataset(Dataset):
    def __init__(self, data, labels):
        # Inicialización de datos
        self.data = data
        self.labels = labels

    def __len__(self):
        # Devuelve el tamaño del dataset
        return len(self.data)

    def __getitem__(self, idx):
        # Devuelve datos y etiquetas por índice
        sample = self.data[idx]
        label = self.labels[idx]
        return sample, label

# Generar datos de ejemplo
data = torch.randn(100, 5)  # 100 muestras, cada muestra tiene 5 características
labels = torch.randint(0, 2, (100,))  # 100 etiquetas, con valores 0 o 1

# Instanciar el dataset
dataset = MyDataset(data, labels)

# Probar el dataset
print("Tamaño del dataset:", len(dataset))
print("Muestra 0:", dataset[0])

El resultado de salida es el siguiente:

数据集大小: 100
第 0 个样本: (tensor([-0.2006,  0.7304, -1.3911, -0.4408,  1.1447]), tensor(0))

torch.utils.data.DataLoader

DataLoader es el cargador de datos proporcionado por PyTorch, utilizado para cargar datasets por lotes.

Proporciona las siguientes funciones:

  • Carga por lotes: mediante la configuración debatch_size。
  • Barajado de datos: mediante la configuración deshuffle=True。
  • Aceleración multihilo: mediante la configuración denum_workers。
  • Acceso por iteración: accede a los datos por lotes de forma conveniente.

Ejemplo

import torch
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

# Dataset personalizado
class MyDataset(Dataset):
    def __init__(self, data, labels):
        # Inicialización de datos
        self.data = data
        self.labels = labels

    def __len__(self):
        # Devuelve el tamaño del dataset
        return len(self.data)

    def __getitem__(self, idx):
        # Devuelve datos y etiquetas por índice
        sample = self.data[idx]
        label = self.labels[idx]
        return sample, label

# Generar datos de ejemplo
data = torch.randn(100, 5)  # 100 muestras, cada muestra tiene 5 características
labels = torch.randint(0, 2, (100,))  # 100 etiquetas, con valores 0 o 1

# Instanciar el dataset
dataset = MyDataset(data, labels)
# Instanciar DataLoader
dataloader = DataLoader(dataset, batch_size=10, shuffle=True, num_workers=0)

# Iterar sobre DataLoader
for batch_idx, (batch_data, batch_labels) in enumerate(dataloader):
    print(f"Lote {batch_idx + 1}")
    print("Datos:", batch_data)
    print("Etiquetas:", batch_labels)
    if batch_idx == 2:  # Solo se muestran los primeros 3 lotes
        break

El resultado de salida es el siguiente:

批次 1
数据: tensor([[ 0.4689,  0.6666, -1.0234,  0.8948,  0.4503],
        [ 0.0273, -0.4684, -0.7762,  0.7963,  0.2168],
        [ 1.0677, -0.3502, -0.9594, -1.1318, -0.2196],
        [-1.4989,  0.0267,  1.0405, -0.7284,  0.2335],
        [-0.5887, -0.4934,  1.6283,  1.4638,  0.0157],
        [-1.1047, -0.6550, -0.0381,  0.3617, -1.2792],
        [ 0.3592, -0.8264,  0.0231, -1.5508,  0.6833],
        [-0.6835,  0.6979,  0.9048, -0.4756,  0.3003],
        [ 1.1562, -0.4516, -1.2415,  0.2859,  0.5837],
        [ 0.7937,  1.5316, -0.6139,  0.7999,  0.5506]])
标签: tensor([0, 1, 1, 1, 1, 0, 1, 1, 0, 0])
批次 2
数据: tensor([[-0.0388, -0.3658,  0.8993, -1.5027,  1.0738],
        [-0.6182,  1.0684, -2.3049,  0.8338,  0.1363],
        [-0.5289,  0.1661, -0.0349,  0.2112,  1.4745],
        [-0.3304, -1.2114, -0.2982, -0.3006,  0.5252],
        [-1.4394, -0.3732,  1.0281,  0.5754,  1.0081],
        [ 0.8714, -0.1945, -0.2451, -0.2879, -2.0520],
        [ 0.0235,  0.4360,  0.1233,  0.0504,  0.5908],
        [ 0.5927,  0.1785, -0.9052, -0.9012,  0.8914],
        [ 0.4693,  0.5533, -0.1903,  0.0267,  0.4077],
        [-1.1683,  1.6699, -0.4846, -0.7404,  0.3370]])
标签: tensor([1, 1, 0, 1, 0, 1, 1, 0, 1, 1])
批次 3
数据: tensor([[ 0.2103, -0.7839,  1.4899,  2.2749, -0.7548],
        [-1.2836,  1.0025, -1.1162, -0.4261,  1.0690],
        [-0.7969,  1.0418, -0.7405,  0.8766,  0.2347],
        [-1.1071,  1.8560, -1.2979, -0.8364, -0.2925],
        [-1.0488,  0.4802, -0.6453,  0.2009,  0.5693],
        [ 0.8883,  0.4619, -0.2087,  0.2189, -0.3708],
        [-1.4578,  0.3629,  1.8282,  0.5353, -1.1783],
        [-1.2813,  0.5129, -0.4598, -0.2131, -1.2804],
        [ 1.7831,  1.1730, -0.2305, -0.6550,  0.1197],
        [-0.9384, -0.0483,  1.9626,  0.3342,  0.1700]])
标签: tensor([0, 0, 0, 1, 0, 1, 1, 1, 0, 1])

Usar datasets integrados

PyTorch proporciona varios datasets de uso común, almacenados en torchvision, especialmente adecuados para tareas de imágenes.

Cargar el dataset MNIST:

Ejemplo

import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

# Definir el preprocesamiento de datos
transform = transforms.Compose([
    transforms.ToTensor(),  # Convertir a tensor
    transforms.Normalize((0.5,), (0.5,))  # Normalización
])

# Cargar el dataset de entrenamiento
train_dataset = torchvision.datasets.MNIST(
    root='./data', train=True, transform=transform, download=True)

# Usar DataLoader para cargar datos
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

# Ver los datos de un lote
data_iter = iter(train_loader)
images, labels = next(data_iter)
print(f"Tamaño de las imágenes del lote: {images.shape}")  # La forma de salida es [batch_size, 1, 28, 28]
print(f"Etiquetas del lote: {labels}")

El resultado de salida es:

批次图像大小: torch.Size([32, 1, 28, 28])
批次标签: tensor([0, 4, 9, 8, 1, 3, 8, 1, 7, 2, 1, 1, 1, 2, 6, 3, 9, 7, 6, 9, 4, 9, 7, 1,
        3, 7, 3, 0, 7, 7, 6, 7])

Aplicación personalizada de Dataset y DataLoader

A continuación se muestra un ejemplo que utiliza un archivo CSV como fuente de datos y lee los datos mediante un Dataset y DataLoader personalizados.

El contenido del archivo CSV es el siguiente (descargarejemplo_pytorch_data.csv):

Ejemplo

import torch
import pandas as pd
from torch.utils.data import Dataset, DataLoader

# Dataset CSV personalizado
class CSVDataset(Dataset):
    def __init__(self, file_path):
        # Leer el archivo CSV
        self.data = pd.read_csv(file_path)

    def __len__(self):
        # Devuelve el tamaño del dataset
        return len(self.data)

    def __getitem__(self, idx):
        # Usar .iloc para indexar explícitamente por posición
        row = self.data.iloc[idx]
        # Separar las características y las etiquetas
        features = torch.tensor(row.iloc[:-1].to_numpy(), dtype=torch.float32)  # Características
        label = torch.tensor(row.iloc[-1], dtype=torch.float32)  # Etiquetas
        return features, label

# Instanciar el dataset y DataLoader
dataset = CSVDataset("ejemplo_pytorch_data.csv")
dataloader = DataLoader(dataset, batch_size=4, shuffle=True)

# Iterar sobre DataLoader
for features, label in dataloader:
    print("Características:", features)
    print("Etiquetas:", label)
    break

El resultado de salida es:

特征: tensor([[ 1.2000,  2.1000, -3.0000],
        [ 1.0000,  1.1000, -2.0000],
        [ 0.5000, -1.2000,  3.3000],
        [-0.3000,  0.8000,  1.2000]])
标签: tensor([1., 0., 1., 0.])
tianqixin@Mac-mini ejemplo-test % python3 test.py
特征: tensor([[ 1.5000,  2.2000, -1.1000],
        [ 2.1000, -3.3000,  0.0000],
        [-2.3000,  0.4000,  0.7000],
        [-0.3000,  0.8000,  1.2000]])
标签: tensor([0., 1., 0., 0.])
Otras extensiones