Traitement et chargement des données PyTorch
Dans PyTorch, le traitement et le chargement des données constituent une étape cruciale du processus d'entraînement en apprentissage profond.
Pour gérer efficacement les données, PyTorch fournit des outils puissants, notammenttorch.utils.data.Datasetettorch.utils.data.DataLoader, qui nous aident à gérer des tâches telles que les jeux de données, le chargement par lots et l'augmentation des données.
Introduction au traitement et au chargement des données avec PyTorch :
- Jeu de données personnalisé: En héritant de
torch.utils.data.Datasetpour charger votre propre jeu de données. - DataLoader:
DataLoaderCharger les données par lots, prendre en charge le chargement multithread et le mélange des données. - Prétraitement et augmentation des données: Utilisez
torchvision.transformspour effectuer des opérations courantes de prétraitement et d'augmentation d'images, améliorant la capacité de généralisation du modèle. - Chargement de jeux de données standard:
torchvision.datasetsfournit de nombreux jeux de données courants, ce qui simplifie le processus de chargement des données. - Sources de données multiples: En combinant plusieurs
Datasetinstances pour gérer des données provenant de différentes sources.
Jeu de données personnalisé
torch.utils.data.Datasetest une classe abstraite qui vous permet de créer des jeux de données à partir de vos propres sources de données.
Nous devons hériter de cette classe et implémenter les deux méthodes suivantes :
__len__(self): Renvoie le nombre d'échantillons dans le jeu de données.__getitem__(self, idx): Renvoie un échantillon par index.
Supposons que nous ayons un simple fichier CSV ou des données sous forme de liste ; nous pouvons créer notre propre jeu de données en héritant de la classe Dataset.
Exemple
from torch.utils.data import Dataset
# Classe de jeu de données personnalisée
class MyDataset(Dataset):
def __init__(self, X_data, Y_data):
"""
Initialise le jeu de données ; X_data et Y_data sont deux listes ou tableaux
X_data: caractéristiques d'entrée
Y_data: étiquettes cibles
"""
self.X_data = X_data
self.Y_data = Y_data
def __len__(self):
"""Renvoie la taille du jeu de données"""
return len(self.X_data)
def __getitem__(self, idx):
"""Renvoie les données à l'index spécifié"""
x = torch.tensor(self.X_data[idx], dtype=torch.float32) # Convertir en tenseur
y = torch.tensor(self.Y_data[idx], dtype=torch.float32)
return x, y
# Exemple de données
X_data = [[1, 2], [3, 4], [5, 6], [7, 8]] # Caractéristiques d'entrée
Y_data = [1, 0, 1, 0] # Étiquettes cibles
# Créer une instance de jeu de données
dataset = MyDataset(X_data, Y_data)
Chargement des données avec DataLoader
DataLoader est un outil important fourni par PyTorch, utilisé pour charger des données à partir d'un Dataset par lots.
DataLoader nous permet de lire les données par lots et d'effectuer un chargement multi-thread, améliorant ainsi l'efficacité de l'entraînement.
Exemple
# Créer une instance DataLoader ; batch_size définit le nombre d'échantillons chargés à chaque fois
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
# Afficher les données chargées
for epoch in range(1):
for batch_idx, (inputs, labels) in enumerate(dataloader):
print(f'Lot {batch_idx + 1}:')
print(f'Entrées: {inputs}')
print(f'Étiquettes: {labels}')
batch_size: Le nombre d'échantillons chargés à chaque fois.shuffle: Indique s'il faut mélanger les données ; généralement, les données doivent être mélangées pendant l'entraînement.drop_last: Si le nombre d'échantillons dans le jeu de données ne peut pas être divisé uniformément parbatch_size, lorsqu'il est défini surTrue, supprime le dernier lot incomplet.
Sortie :
Batch 1: Inputs: tensor([[3., 4.], [1., 2.]]) Labels: tensor([0., 1.]) Batch 2: Inputs: tensor([[7., 8.], [5., 6.]]) Labels: tensor([0., 1.])
Dans chaque boucle, DataLoader renvoie un lot de données, incluant les caractéristiques d'entrée (inputs) et les étiquettes cibles (labels).
Prétraitement et augmentation des données
Le prétraitement et l'augmentation des données sont cruciaux pour améliorer les performances du modèle.
PyTorch fournit le module torchvision.transforms pour effectuer des opérations courantes de prétraitement et d'augmentation d'images, telles que la rotation, le recadrage, la normalisation, etc.
Opérations courantes de prétraitement d'images :
Exemple
from PIL import Image
# Définir le pipeline de prétraitement des données
transform = transforms.Compose([
transforms.Resize((128, 128)), # Redimensionner l'image à 128x128
transforms.ToTensor(), # Convertir l'image en tenseur
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # Normaliser
])
# Charger l'image
image = Image.open('image.jpg')
# Appliquer le prétraitement
image_tensor = transform(image)
print(image_tensor.shape) # Afficher la forme du tenseur
transforms.Compose(): Combine plusieurs opérations de transformation entre elles.transforms.Resize(): Redimensionne l'image.transforms.ToTensor(): Convertit l'image en un tenseur PyTorch, avec des valeurs normalisées dans la[0, 1]plage.transforms.Normalize(): Normalise les données d'image ; la normalisation est généralement requise lors de l'utilisation de modèles pré-entraînés.
Augmentation des données d'image
Les techniques d'augmentation des données augmentent la diversité des données en appliquant des transformations aléatoires aux données d'entraînement, ce qui aide le modèle à mieux généraliser. Par exemple, des retournements aléatoires, des rotations, des recadrages, etc.
Exemple
transforms.RandomHorizontalFlip(), # Retournement horizontal aléatoire
transforms.RandomRotation(30), # Rotation aléatoire de 30 degrés
transforms.RandomResizedCrop(128), # Recadrage et redimensionnement aléatoires vers 128x128
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
Ces méthodes d'augmentation de données peuvent être combinées à l'aide de transforms.Compose() pour garantir que chaque image subit différentes transformations pendant l'entraînement.
Chargement des jeux de données d'images
Pour les jeux de données d'images, torchvision.datasets fournit de nombreux jeux de données courants (tels que CIFAR-10, ImageNet, MNIST, etc.) ainsi que des outils pour charger des données d'images.
Chargement du jeu de données MNIST :
Exemple
import torchvision.transforms as transforms
# Définir les opérations de prétraitement
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)) # Normaliser l'image en niveaux de gris
])
# Télécharger et charger le jeu de données MNIST
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
# Créer un DataLoader
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
# Parcourir les données d'entraînement
for inputs, labels in train_loader:
print(inputs.shape) # Forme des données d'entrée pour chaque lot
print(labels.shape) # Forme des étiquettes pour chaque lot
datasets.MNIST()téléchargera et chargera automatiquement le jeu de données MNIST.transformLe paramètre nous permet de prétraiter les données.train=Trueettrain=Falsereprésentent respectivement l'ensemble d'entraînement et l'ensemble de test.
Utilisation de plusieurs sources de données (jeu de données multi-sources)
Si votre jeu de données se compose de plusieurs fichiers ou de plusieurs sources (par exemple, plusieurs dossiers d'images), vous pouvez personnaliser le chargement de plusieurs sources de données en héritant de la classe Dataset.
PyTorch fournit des classes telles que ConcatDataset et ChainDataset pour concaténer plusieurs jeux de données.
Par exemple, supposons que nous ayons des données provenant de plusieurs dossiers d'images ; nous pouvons les fusionner en un seul jeu de données :
Exemple
# Supposons que dataset1 et dataset2 soient deux objets Dataset
combined_dataset = ConcatDataset([dataset1, dataset2])
combined_loader = DataLoader(combined_dataset, batch_size=64, shuffle=True)