Die vollständige Anleitung zum Erstellen benutzerdefinierter Datensätze und Datenlader für verschiedene Modelle in PyTorch
Bevor Sie ein maschinelles Lernmodell erstellen können, müssen Sie Ihre Daten in einen Datensatz laden. Glücklicherweise verfügt PyTorch über viele Befehle, die bei diesem gesamten Prozess helfen (wenn Sie mit PyTorch nicht vertraut sind, empfehle ich Ihnen, die Grundlagen aufzufrischen. Hier).
PyTorch bietet eine gute Dokumentation, die bei diesem Prozess hilft, aber ich habe keine umfassende Dokumentation oder Tutorials zu benutzerdefinierten Datensätzen gefunden. Ich werde zunächst mit der Erstellung grundlegender vorgefertigter Datensätze beginnen und mich dann hocharbeiten, um Datensätze von Grund auf für verschiedene Modelle zu erstellen!
Bevor wir uns in den Code für verschiedene Anwendungsfälle vertiefen, sollten wir den Unterschied zwischen den beiden Begriffen verstehen. Im Allgemeinen erstellen Sie zuerst Ihren Datensatz und dann einen Datenlader. Ein Datensatz enthält die Merkmale und Beschriftungen von jedem Datenpunkt, der in das Modell eingespeist wird. Datenlader ist ein benutzerdefiniertes PyTorch-Iterable, das das Laden von Daten mit zusätzlichen Funktionen erleichtert.
DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
batch_sampler=None, num_workers=0, collate_fn=None,
pin_memory=False, drop_last=False, timeout=0,
worker_init_fn=None, *, prefetch_factor=2,
persistent_workers=False)
Die häufigsten Argumente im Datenlader sind Batchgröße, Mischen (normalerweise nur für die Trainingsdaten), Anzahl_Arbeiter (zum Multi-Prozess-Laden der Daten) und Pin-Speicher (um die abgerufenen Datentensoren im fixierten Speicher abzulegen und eine schnellere Datenübertragung an CUDA-fähige GPUs zu ermöglichen).
Aufgrund von Multiprocessing-Komplikationen mit CUDA wird empfohlen, pin_memory = True festzulegen, anstatt num_workers anzugeben.
Falls Ihr Datensatz on-line oder lokal heruntergeladen wird, ist es äußerst einfach, den Datensatz zu erstellen. Ich denke, PyTorch hat gute Dokumentation Ich werde mich kurz fassen.
Wenn Sie wissen, dass der Datensatz entweder von PyTorch stammt oder PyTorch-kompatibel ist, rufen Sie einfach die erforderlichen Importe und den Datensatz Ihrer Wahl auf:
from torch.utils.information import Dataset
from torchvision import datasets
from torchvision.transforms imports ToTensorinformation = torchvision.datasets.CIFAR10('path', prepare=True, remodel=ToTensor())
Jeder Datensatz hat eindeutige Argumente, die ihm übergeben werden müssen (gefunden Hier). Im Allgemeinen handelt es sich dabei um den Pfad, unter dem der Datensatz gespeichert ist, einen Booleschen Wert, der angibt, ob er heruntergeladen werden muss oder nicht (praktischerweise „Obtain“ genannt), ob es sich um Coaching oder Check handelt und ob Transformationen angewendet werden müssen.
Ich habe am Ende des letzten Abschnitts erwähnt, dass Transformationen auf einen Datensatz angewendet werden können, aber was ist eigentlich eine Transformation?
A verwandeln ist eine Methode zur Manipulation von Daten zur Vorverarbeitung eines Bildes. Transformationen haben viele verschiedene Facetten. Die häufigste Transformation ist ToTensor()konvertiert den Datensatz in Tensoren (wird als Eingabe in jedes Modell benötigt). Andere in PyTorch integrierte Transformationen (torchvision.transforms) umfassen das Spiegeln, Drehen, Zuschneiden, Normalisieren und Verschieben von Bildern. Diese werden normalerweise verwendet, damit das Modell besser verallgemeinern kann und nicht zu stark an die Trainingsdaten angepasst wird. Datenerweiterungen können auch verwendet werden, um die Größe des Datensatzes bei Bedarf künstlich zu erhöhen.
Beachten Sie, dass die meisten Torchvision-Transformationen nur Pillow-Bild- oder Tensorformate akzeptieren (nicht Numpy). Zum Konvertieren verwenden Sie einfach
Um von Numpy zu konvertieren, erstellen Sie entweder einen Fackel-Tensor oder verwenden Sie Folgendes:
From PIL import Picture
# assume arr is a numpy array
# you might have to normalize and solid arr to np.uint8 relying on format
img = Picture.fromarray(arr)
Transformationen können gleichzeitig angewendet werden mit torchvision.transforms.compose. Sie können so viele Transformationen kombinieren, wie für den Datensatz erforderlich sind. Ein Beispiel wird unten angezeigt:
import torchvision.transforms.Composedataset_transform = transforms.Compose((
transforms.RandomResizedCrop(256),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))
))
Denken Sie daran, die gespeicherte Transformation als Argument an den Datensatz zu übergeben, damit sie im Datenlader angewendet werden kann.
Wenn Sie Ihr eigenes Modell entwickeln, benötigen Sie in den meisten Fällen einen benutzerdefinierten Datensatz. Ein häufiger Anwendungsfall wäre Transferlernen, um Ihren eigenen Datensatz auf ein vorab trainiertes Modell anzuwenden.
Eine PyTorch-Dataset-Klasse besteht aus drei erforderlichen Teilen: Initialisierung, LängeUnd Abrufen eines Components.
__drin__: Um den Datensatz zu initialisieren, geben Sie die Rohdaten und die beschrifteten Daten ein. Am besten geben Sie die Rohbilddaten und die beschrifteten Daten separat ein.
__Länge__: Gibt die Länge des Datensatzes zurück. Vor dem Erstellen des Datensatzes sollte überprüft werden, ob die Rohdaten und die beschrifteten Daten die gleiche Größe haben.
__getitem__: Hier erfolgt die gesamte Datenverarbeitung, um einen bestimmten Index (idx) der Roh- und beschrifteten Daten zurückzugeben. Wenn Transformationen angewendet werden müssen, müssen die Daten in einen Tensor konvertiert und transformiert werden. Wenn die Initialisierung einen Pfad zum Datensatz enthielt, muss der Pfad geöffnet und auf die Daten zugegriffen/sie vorverarbeitet werden, bevor sie zurückgegeben werden können.
Beispieldatensatz für ein semantisches Segmentierungsmodell:
from torch.utils.information import Dataset
from torchvision import transformsclass ExampleDataset(Dataset):
"""Instance dataset"""
def __init__(self, raw_img, data_mask, remodel=None):
self.raw_img = raw_img
self.data_mask = data_mask
self.remodel = remodel
def __len__(self):
return len(self.raw_img)
def __getitem__(self, idx):
if torch.is_tensor(idx):
idx = idx.tolist()
picture = self.raw_img(idx)
masks = self.data_mask(idx)
pattern = {'picture': picture, 'masks': masks}
if self.remodel:
pattern = self.remodel(pattern)
return pattern