PyTorch: Der Versuch, einen gemeinsamen Datensatz mit unterschiedlichen Transformationen zu erstellen, führt dazu, dass Python

Python-Programme
Anonymous
 PyTorch: Der Versuch, einen gemeinsamen Datensatz mit unterschiedlichen Transformationen zu erstellen, führt dazu, dass

Post by Anonymous »

Ich bin sehr neu bei PyTorch und versuche, einen Datensatz zu erstellen, für den einer bestimmten Stichprobe sowohl unmaskierte als auch maskierte Daten zugeordnet sind. Mit anderen Worten, das erste Datenelement ist nur das Originalmuster und auf das zweite Datenelement wird eine Transformation angewendet, die einige der Einträge maskiert.
Ich habe eine benutzerdefinierte JointDataset-Klasse erstellt, die dann zur Verwendung im Training an DataLoader übergeben wird. Ich habe unten ein MWE eingefügt, das aus einem Tutorial stammt, dem ich gefolgt bin und auf dem ich aufgebaut habe. Ein Problem, das ich habe und das ich anscheinend nicht beheben kann, ist, dass beim Entpacken der beiden Datensätze mit dem Datenlader die unmaskierten und maskierten Daten identisch sind. Ich konnte dies auf die Tatsache eingrenzen, dass train_set und val_set irgendwie mit ihren maskierten Gegenstücken überschrieben werden, wenn die data.Subset-Routine aufgerufen wird, um sie unter Verwendung der ursprünglichen Indizes zu erstellen. Kann ich irgendwie erklären, warum das passiert und wie ich dafür sorgen kann, dass dieses MWE das gewünschte Ergebnis liefert?

Code: Select all

# standard libraries
import sys
import numpy as np
from typing import Callable

# PyTorch data loading
import torch
import torch.utils.data as data
from torchvision import transforms

# custom masking function which masks an element of the sample with probability 0.25
def add_masking(sample):
noisy_sample = sample
prob = 0.25
for i in range(sample.shape[0]):
if (np.random.uniform(0.0, 1.0) < prob):
noisy_sample[i] = -1.0
return noisy_sample

# very basic custom dataset
class MyDataset(data.Dataset):
def __init__(self, array: np.array, transform: Callable = None):
self.data = array
self.transform = transform

def __len__(self):
return self.data.shape[1]

def __getitem__(self, idx):
# idx sample is located in the idx column of the data
sample = self.data[:,idx]
if self.transform:
sample = self.transform(sample)
return sample

# generate dataset
num_examples = 100
num_features = 10
X = np.random.rand(num_features, num_examples)
train_dataset = MyDataset(array=X, transform=None)

# split dataset into training and validation
train_set, val_set = data.random_split(train_dataset, [80, 20], generator=torch.Generator().manual_seed(42))
train_indices = train_set.indices
val_indices = val_set.indices

# mask dataset and split it according to the split described by train_indices and val_indices
train_masked_dataset = MyDataset(array=X, transform=transforms.Lambda(lambda x: add_masking(x)))
# these calls seem to replace val_set and train_set with the masked data...
train_masked_set = data.Subset(train_masked_dataset, train_indices)
val_masked_set = data.Subset(train_masked_dataset, val_indices)

# concatenate masked and unmasked data
class JointDataset(data.Dataset):
def __init__(self, dataset1, dataset2):
self.dataset1 = dataset1
self.dataset2 = dataset2
assert len(self.dataset1) == len(self.dataset2)

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

def __getitem__(self, index):
data1 = self.dataset1[index]
data2 = self.dataset2[index]
return data1, data2

# combine unmasked and masked data
train_set_combined = JointDataset(train_set, train_masked_set)
val_set_combined = JointDataset(val_set, val_masked_set)

# define data loaders
def numpy_collate(batch):
if isinstance(batch[0], np.ndarray):
return np.stack(batch)
elif isinstance(batch[0], (tuple,list)):
transposed = zip(*batch)
return [numpy_collate(samples) for samples in transposed]
else:
return np.array(batch)

train_loader = data.DataLoader(train_set_combined, batch_size=16, shuffle=True, drop_last=True, pin_memory=True, num_workers=32, collate_fn=numpy_collate, persistent_workers=True)
val_loader = data.DataLoader(val_set_combined, batch_size=16, shuffle=False, drop_last=False, num_workers=32, collate_fn=numpy_collate)

data_iter = iter(train_loader)
batch_unmasked, batch_masked = next(data_iter)

# checking the first batch. the unmasked data is somehow masked...
print(batch_unmasked[0:2,:].T)
print(batch_masked[0:2,:].T)

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post