es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo dividir en train_loader y test_loader usando PyTorch?

Tengo un proyecto que utiliza PyTorch y no tengo conocimientos sobre ello.

Tengo un archivo CSV con 7 columnas, la última es la etiqueta mientras que las primeras 6 son características.

Mi proyecto indica dividir los datos aleatoriamente en un cargador de entrenamiento y un cargador de prueba. He creado las etiquetas, pero estoy seguro de que son incorrectas.

Mi código se ve así:

import torch
import torch.utils.data as data
import torch.utils.data.dataset as dataset
import numpy as np
import pickle
from sklearn.preprocessing import MinMaxScaler, StandardScaler

class NavDataset(dataset.Dataset):
    def __init__(self):
        self.data = np.genfromtxt('saved/training_data.csv', delimiter=',')
        self.x = self.data[:, 0:5]
        self.y = self.data[:, [6]]

    # puede ser útil para equilibrar la distribución de los datos recogidos
    def normalize_and_scale(self):
        # normalizar datos y guardar escalador para inferencia
        self.scaler = MinMaxScaler()
        self.normalized_data = self.scaler.fit_transform(self.data)  # ajusta y transforma
        # guardar para normalizar en inferencia
        pickle.dump(self.scaler, open("saved/scaler.pkl", "wb"))

    def __len__(self):
        return len(self.y)

    # para este ejemplo, getitem() debe devolver un diccionario con entradas {'input': x, 'label': y}
    # x e y deben ser de tipo float32
    def __getitem__(self, idx):
        if not isinstance(idx, int):
            idx = idx.item()

        y = self.y[idx]
        x = self.x[idx]
        sample = {'input': x, 'label': y}
        return sample

class DataLoaders():
    def __init__(self, batch_size):
        self.nav_dataset = NavDataset()

        # dividir aleatoriamente el conjunto de datos en dos data.DataLoaders, train_loader y test_loader
        self.train_loader, self.test_loader = torch.utils.data.random_split(self.nav_dataset, [int(len(self.nav_dataset) * 0.8), int(len(self.nav_dataset) * 0.2)])
        # cargadores de datos que se iterarán, no se pueden modificar
        self.train_loader = torch.utils.data.DataLoader(self.train_loader, batch_size=batch_size, shuffle=True)
        self.test_loader = torch.utils.data.DataLoader(self.test_loader, batch_size=batch_size, shuffle=True)

def main():
    batch_size = 16
    data_loaders = DataLoaders(batch_size)
    # tenga en cuenta que así es como se iterarán los cargadores de datos y no se pueden modificar
    for idx, sample in enumerate(data_loaders.train_loader):
        _, _ = sample['input'], sample['label']
    for idx, sample in enumerate(data_loaders.test_loader):
        _, _ = sample['input'], sample['label']

if __name__ == 'main':
    main()

No entiendo cómo crear los cargadores de datos de entrenamiento y prueba y dividir el conjunto de datos. ¿Alguna ayuda para resolverlo?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para dividir el conjunto de datos en train_loader y test_loader, se puede utilizar la función train_test_split de la librería sklearn. Aquí se muestra un ejemplo de cómo puede modificar su código para lograr esto:

    import torch
    import torch.utils.data as data
    import torch.utils.data.dataset as dataset
    import numpy as np
    import pickle
    from sklearn.preprocessing import MinMaxScaler, StandardScaler
    from sklearn.model_selection import train_test_split
    
    
    class Nav_Dataset(dataset.Dataset):
        def __init__(self):
            self.data = np.genfromtxt('saved/training_data.csv', delimiter=',')
            self.x = self.data[:, 0:5]
            self.y = self.data[:, [6]]
            self.scaler = MinMaxScaler()
            self.normalized_data = self.scaler.fit_transform(self.data)
            pickle.dump(self.scaler, open("saved/scaler.pkl", "wb"))
    
        def __len__(self):
            return len(self.y)
    
        def __getitem__(self, idx):
            if not isinstance(idx, int):
                idx = idx.item()
            y = self.y[idx]
            x = self.x[idx]
            sample = {'input': x, 'label': y}
            return sample
    
    
    class Data_Loaders():
        def __init__(self, batch_size):
            self.nav_dataset = Nav_Dataset()
            x_train, x_test, y_train, y_test = train_test_split(self.nav_dataset.normalized_data[:,:6], 
                                                                self.nav_dataset.normalized_data[:,6], 
                                                                test_size=0.2, 
                                                                random_state=42)
            # crear datasets de train y test con los datos divididos
            self.train_dataset = dataset.TensorDataset(torch.Tensor(x_train), torch.Tensor(y_train))
            self.test_dataset = dataset.TensorDataset(torch.Tensor(x_test), torch.Tensor(y_test))
            # crear dataloaders de train y test
            self.train_loader = data.DataLoader(self.train_dataset, batch_size=batch_size, shuffle=True)
            self.test_loader = data.DataLoader(self.test_dataset, batch_size=batch_size, shuffle=True)
    
    
    def main():
        batch_size = 16
        data_loaders = Data_Loaders(batch_size)
        for idx, sample in enumerate(data_loaders.train_loader):
            _, _ = sample['input'], sample['label']
        for idx, sample in enumerate(data_loaders.test_loader):
            _, _ = sample['input'], sample['label']
    
    
    if __name__ == '__main__':
        main()
    

    En este código modificado, la función train_test_split divide los datos en un 80% para el conjunto de entrenamiento y un 20% para el conjunto de prueba. Los datos normalizados se dividen en x_train, x_test, y_train e y_test. Luego, se crean dos nuevos conjuntos de datos (train_dataset y test_dataset) utilizando los datos divididos, y se crean los correspondientes dataloaders (train_loader y test_loader) utilizando estos conjuntos de datos.

    Tenga en cuenta que el parámetro shuffle se establece en True para ambos dataloaders, lo que significa que los lotes se mezclarán aleatoriamente después de cada época. Esto puede ayudar a prevenir el sobreajuste y mejorar la generalización.

Comments are closed.